def getPath(self, parts): result = ast.GetGlobal( ast.Existing(self.compiler.extractor.getObject(parts.pop(0)))) for part in parts: result = ast.GetAttr( result, ast.Existing(self.compiler.extractor.getObject(part))) return result
def serializeUniformNode(compiler, translator, self, holdingSlot, refs, root): check = symbols.SymbolRewriter(compiler.extractor, typeCheckTemplate) types = sorted(set([ref.xtype.obj.pythonType() for ref in refs])) # The tree transform should guarantee there's only one object per type typeLUT = {} for ref in refs: t = ref.xtype.obj.pythonType() assert t not in typeLUT typeLUT[t] = ref assert len(types) > 0 if len(types) == 1: t = types[0] return handleUniformType(compiler, translator, self, holdingSlot, typeLUT[t], root, t) else: switches = [] for t in types: cond = check.rewrite(root=root, type=t) body = handleUniformType(compiler, translator, self, holdingSlot, typeLUT[t], root, t) switches.append((cond, ast.Suite(body))) current = ast.Suite([ast.Assert(ast.Existing(compiler.extractor.getObject(False)), None)]) for cond, suite in reversed(switches): current = ast.Switch(ast.Condition(ast.Suite([]), cond), suite, ast.Suite([current])) return [current]
def existingFromObj(self, obj): if self.annotationsExist: cobj = self.storeGraphForExistingObject(obj) node = self.existingFromNode(cobj) return node else: return ast.Existing(obj)
def decompile(compiler, func, trace=False, ssa=True, descriptive=False): # HACK can't find modules for "fake" globals. try: mname, module = moduleForGlobalDict(func.func_globals) except: mname = 'unknown_module' code = decompileCode(compiler, func.func_code, mname, trace=trace, ssa=ssa) # Flow sensitive, works without a ssa or ssi transform. code.rewriteAnnotation(descriptive=descriptive) optimization.simplify.evaluateCode(compiler, None, code) if trace: SimpleCodeGen(sys.stdout).process(code) # HACK turn function defaults into code defaults # Really, we should check for immutability / consistency across all functions using this code if func.func_defaults is not None: defaults = [ ast.Existing(compiler.extractor.getObject(obj)) for obj in func.func_defaults ] else: defaults = [] # HACK mutate the AST node code.codeparameters.defaults = defaults return code
def existingFromNode(self, cobj): node = ast.Existing(cobj.xtype.obj) references = annotation.makeContextualAnnotation([ (cobj, ) for context in self.code.annotation.contexts ]) node.rewriteAnnotation(references=references) return node
def generateExisting(self, object): ex = ast.Existing(object) region = self.prgm.storeGraph.regionHint xtype = self.prgm.storeGraph.canonical.existingType(object) obj = region.object(xtype) refs = common.annotationFromValues(self.code, (obj,)) ex.rewriteAnnotation(references=refs) return ex
def makeStoreOp(dataflow, hyperblock, predicate, exprNode, field, valueNode): name = ast.Existing(field.name) op = ast.Store(exprNode.names[0], field.type, name, valueNode.names[0]) g = graph.GenericOp(hyperblock, op) g.setPredicate(predicate) g.addLocalRead(exprNode.names[0], exprNode) g.addLocalRead(name, dataflow.getExisting(name)) g.addLocalRead(valueNode.names[0], valueNode) return g
def handleUniformType(compiler, translator, self, holdingSlot, ref, root, t): statements = [] # Find the group name holdingSlot = translator.compatible[holdingSlot] structInfo = translator.ioRefInfo.get(holdingSlot) if structInfo: if structInfo.multipleTypes(): sub = structInfo.lut.subpools['type'] name = sub.name uid = translator.typeIDs[t] uidO = compiler.extractor.getObject(uid) statements.append(bindUniform(compiler, self, name, int, ast.Existing(uidO))) if intrinsics.isIntrinsicType(t): if t in intrinsics.samplerTypes: sg = translator.samplerGroup(ref) assert sg.unique name = sg.name else: sub = structInfo.lut.subpools[t] name = sub.name statements.append(bindUniform(compiler, self, name, t, root)) # TODO fields? get = symbols.SymbolRewriter(compiler.extractor, uniformGetTemplate) # TODO mutually exclusive? for field in ref.slots.itervalues(): if not intrinsics.isIntrinsicSlot(field): if field.slotName.type != 'Attribute': continue cls, attr = classAttrFromField(compiler, field.slotName) assert issubclass(t, cls), (ref, field) target = ast.Local('bogus') # Load the field assign = get.rewrite(cls=cls, attr=attr, root=root, target=target) statements.append(assign) # Recurse statements.extend(serializeUniformNode(compiler, translator, self, field, field, target)) return statements
def visitUnpackSequence(self, node): # HACK oh so ugly... does not resemble what actually happens. if True: dc = self.directCall( node, self.exports['interpreter_unpack%d' % len(node.targets)], None, [self(node.expr)]) return ast.Assign(dc, node.targets) else: calls = [] for i, arg in enumerate(node.targets): obj = self.extractor.getObject(i) call = self.directCall( None, self.exports['interpreter_getitem'], None, [self(node.expr), self(ast.Existing(obj))]) calls.append(ast.Assign(call, [arg])) return calls
def makeLoadOp(dataflow, hyperblock, predicate, root, field): if isinstance(root, graph.LocalNode): expr = root.names[0] else: assert isinstance(root, graph.ExistingNode) expr = root.name # Create the dataflow load name = ast.Existing(field.name) nameref = field.name # HACK incorrect op = ast.Load(expr, field.type, name) g = graph.GenericOp(hyperblock, op) g.setPredicate(predicate) g.addLocalRead(expr, root) g.addLocalRead(name, dataflow.getExisting(name, nameref)) return g
def getReplacementSource(self, dominator): if dominator not in self.newName: if isinstance(dominator, ast.Store): old = dominator.value else: assert len(dominator.lcls) == 1 old = dominator.lcls[0] if isinstance(old, ast.Existing): src = ast.Existing(old.object) else: src = ast.Local(old.name) self.replace[dominator] = [dominator, ast.Assign(old, [src])] src.annotation = old.annotation self.newName[dominator] = src else: src = self.newName[dominator] return src
def allocateObj(dioa, dataflow, subtree, slot, obj): hyperblock = dataflow.entry.hyperblock predicate = dataflow.entryPredicate objs = slot.annotation.values.flat # Allocate assert len(objs) == 1 obj = tuple(objs)[0] cls = ast.Existing(obj.xtype.obj.type) allocate = ast.Allocate(cls) g = graph.GenericOp(hyperblock, allocate) g.setPredicate(predicate) g.addLocalRead(cls, dataflow.getExisting(cls, obj)) # TODO mask? setOpAnnotation(dioa, g, allocate=dioa.set.leaf((obj, ))) return addOutput(g, subtree, slot)
def localToExisting(self, lcl, obj): node = ast.Existing(obj) node.annotation = lcl.annotation return node
def existingConstant(value): return ast.Existing(symbols.Extract(value))
def existingSymbol(name): return ast.Existing(symbols.Extract(symbols.Symbol(name)))
def wrapPyObj(self, pyobj): obj = self.compiler.extractor.getObject(pyobj) return ast.Existing(obj)
def existing(self, obj): return ast.Existing(self.extractor.getObject(obj))
def visitMerge(self, node): if node not in self.loops: node.simplify() else: assert node.numPrev() == 1 preamble = node.getExit('normal') if isinstance(preamble, graph.Switch): assert False else: assert isinstance(preamble, graph.Suite) switch = preamble.getExit('normal') # print # print preamble.ops # print switch if switch is None: # Degenerate loop body = preamble preamble = graph.Suite(body.region) switch = graph.Switch( body.region, ast.Existing(self.compiler.extractor.getObject(True))) else_ = graph.Suite(body.region) else: assert isinstance(switch, graph.Switch) body = self.getSwitchExit(switch, 'true') else_ = self.getSwitchExit(switch, 'false', ignoreRegion=True) switch.killExit('true') switch.killExit('false') # print # print "pre", preamble.ops # print "cond", switch.condition # print "body", body.ops # print "else", else_.ops if node in self.breaks: b = self.breaks[node] ee = else_.getExit('normal') assert ee is None or ee is b else_.killExit('normal') else: b = else_ else_ = graph.Suite(else_.region) # print # print "pre", preamble.ops # print "cond", switch.condition # print "body", body.ops # print "else", else_.ops # print "break", b.ops bodyast = ast.Suite(body.ops) bodyast = KillContinues()(bodyast) loop = ast.While( ast.Condition(ast.Suite(preamble.ops), switch.condition), bodyast, ast.Suite(else_.ops)) result = graph.Suite(node.region) result.ops.append(loop) node.killExit('normal') node.setExit('normal', result) result.setExit('normal', b) if isinstance(b, graph.Merge): b.simplify() node.simplify() #print list(result.forward()) self.simplifySuite(result) #print list(result.forward()) preamble.destroy() switch.destroy() body.destroy() else_.destroy()