def visitSetSubscript(self, node): return ast.Discard( self.directCall( node, self.exports['interpreter_setitem'], None, [self(node.expr), self(node.subscript), self(node.value)]))
def visitSetAttr(self, node): return ast.Discard( self.directCall( node, self.exports['interpreter_setattr'], None, [self(node.expr), self(node.name), self(node.value)]))
def visitSetGlobal(self, node): p = self.code.codeparameters call = self.directCall( node, self.exports['interpreterStoreGlobal'], None, [self(p.selfparam), self(node.name), self(node.value)]) return ast.Discard(call)
def visitDiscard(self, node): expr = self(node.expr) if isinstance(expr, ast.Store): return expr if expr not in self.specialGlobals: if node.expr == expr: return node else: return ast.Discard(expr) else: return ()
def methodCallToTypeSwitch(self, node, arg, pos, targets): # TODO if mutable types are allowed, we should be looking at the LowLevel type slot? # TODO localy rebuild read/modify/allocate information using filtered invokes. # TODO should the return value be SSAed? This might interfere with nessled type switches. # If so, retarget the return value and fix up return types groups = self.groupTypes(node, arg, pos) if groups is None or len(groups) <= 1: return None # Don't create trivial type switches cases = [] for group in groups: # Create a filtered version of the argument. name = arg.name if isinstance(arg, ast.Local) else None expr = ast.Local(name) expr.annotation = self.filterReferenceAnnotationByType( arg.annotation, group) # Create the new op opannotation = node.annotation # Kill contexts where the filtered expression has no references. # (In these contexts, the new op will never be evaluated.) mask = self.makeRemapMask(expr.annotation) if -1 in mask: opannotation = opannotation.contextSubset(mask) # Filter out invocations that don't have the right type for the given parameter. opannotation = self.filterOpAnnotationByType( opannotation, group, pos) # Rewrite the op to use expr instead of the original arg. newop = rewrite.rewriteTerm(node, {arg: expr}) assert newop is not node newop.annotation = opannotation # Try to reduce it to a direct call newop = self(newop) # Create the suite for this case stmts = [] if targets is None: stmts.append(ast.Discard(newop)) else: # HACK should SSA it? stmts.append(ast.Assign(newop, list(targets))) suite = ast.Suite(stmts) case = ast.TypeSwitchCase([self.existingFromObj(t) for t in group], expr, suite) cases.append(case) ts = ast.TypeSwitch(arg, cases) return ts
def visitAssign(self, node): used = any( [self.flow.lookup(lcl) is not undefined for lcl in node.lcls]) if used: for lcl in node.lcls: self.flow.undefine(lcl) self.marker(node.expr) return node elif self.hasNoSideEffects(node.expr): return [] else: node = ast.Discard(node.expr) node = self(node) return node
def visitAssign(self, node): assert self.locals if any([len(self.localuses[lcl]) > 0 for lcl in node.lcls]): expr = self(node.expr) assert self.locals, node.expr if isinstance(node.expr, ast.Local): # Assign local to local. Nullop for SSA. assert len(node.lcls) == 1 expr = self.reach(expr) self.locals.redefineLocal(node.lcls[0], expr) # Create a merge for exception handling. if self.hasExceptionHandling: el = self.exceptLocal(node.lcls[0]) easgn = ast.Assign(expr, el) easgn.markMerge() return easgn else: return None else: renames = [self.locals.writeLocal(lcl) for lcl in node.lcls] for rename in renames: self.defns[rename] = expr asgn = ast.Assign(expr, renames) if self.hasExceptionHandling: # Create a merge for exception handling. output = [asgn] for lcl, rename in zip(node.lcls, renames): el = self.exceptLocal(lcl) easgn = ast.Assign(rename, el) easgn.markMerge() output.append(easgn) asgn = ast.Suite(output) return asgn elif not node.expr.isPure(): return ast.Discard(self(node.expr)) else: return None
from util.io import filesystem from . import existingtransform def existingSymbol(name): return ast.Existing(symbols.Extract(symbols.Symbol(name))) def existingConstant(value): return ast.Existing(symbols.Extract(value)) uniformBindTemplate = ast.Discard( ast.Call( ast.GetAttr( symbols.Symbol('self'), existingSymbol('methodName') ), [existingSymbol('name'), symbols.Symbol('value')], [], None, None ) ) def bindUniform(compiler, self, name, t, value): bind = symbols.SymbolRewriter(compiler.extractor, uniformBindTemplate) methodName = "bind_uniform_" + t.__name__ return bind.rewrite(self=self, methodName=methodName, name=name, value=value) typeCheckTemplate = ast.Call( ast.GetGlobal(existingConstant('isinstance')), [symbols.Symbol('root'), existingSymbol('type')], [], None, None )