def _build_gen(func, annotation, graph=None, backendopt=True, exctrans=False, annotatorpolicy=None, nowrap=False): try: func = func.im_func except AttributeError: pass t = TranslationContext() if graph is not None: graph.func = func ann = t.buildannotator(policy=annotatorpolicy) inputcells = [ann.typeannotation(a) for a in annotation] ann.build_graph_types(graph, inputcells) t.graphs.insert(0, graph) else: ann = t.buildannotator(policy=annotatorpolicy) ann.build_types(func, annotation) if getoption('view'): t.view() t.buildrtyper(type_system="ootype").specialize() if backendopt: check_virtual_methods(ootype.ROOT) backend_optimizations(t) main_graph = t.graphs[0] if getoption('view'): t.view() return _build_gen_from_graph(main_graph, t, exctrans, nowrap)
def gengraph(func, argtypes=[], viewbefore='auto', policy=None, type_system="lltype", backendopt=False, config=None, **extraconfigopts): t = TranslationContext(config=config) t.config.set(**extraconfigopts) a = t.buildannotator(policy=policy) timelog("annotating", a.build_types, func, argtypes, main_entry_point=True) if viewbefore == 'auto': viewbefore = getattr(conftest.option, 'view', False) if viewbefore: a.simplify() t.view() global typer # we need it for find_exception typer = t.buildrtyper(type_system=type_system) timelog("rtyper-specializing", typer.specialize) #t.view() timelog("checking graphs", t.checkgraphs) if backendopt: from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(t) timelog("checking graphs", t.checkgraphs) if viewbefore: t.view() desc = t.annotator.bookkeeper.getdesc(func) graph = desc.specialize(argtypes) return t, typer, graph
def translate(func, argtypes, backendopt=False): t = TranslationContext() t.buildannotator().build_types(func, argtypes) t.buildrtyper(type_system='ootype').specialize() if backendopt: backend_optimizations(t, merge_if_blocks=True) return t
def annotate(func, values, inline=None, backendoptimize=True, type_system="lltype", translationoptions={}): # build the normal ll graphs for ll_function t = TranslationContext() for key, value in translationoptions.items(): setattr(t.config.translation, key, value) annpolicy = AnnotatorPolicy() annpolicy.allow_someobjects = False a = t.buildannotator(policy=annpolicy) argtypes = getargtypes(a, values) a.build_types(func, argtypes, main_entry_point=True) rtyper = t.buildrtyper(type_system=type_system) rtyper.specialize() #if inline: # auto_inlining(t, threshold=inline) if backendoptimize: from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(t, inline_threshold=inline or 0, remove_asserts=True, really_remove_asserts=True) return rtyper
def hannotate(self, func, argtypes, policy=P_DEFAULT, annotator=False, inline=None, backendoptimize=False): # build the normal ll graphs for ll_function t = TranslationContext() a = t.buildannotator() a.build_types(func, argtypes) rtyper = t.buildrtyper(type_system = self.type_system) rtyper.specialize() if inline: auto_inlining(t, threshold=inline) if backendoptimize: from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(t) graph1 = graphof(t, func) # build hint annotator types policy = self.fixpolicy(policy) hannotator = HintAnnotator(base_translator=t, policy=policy) hs = hannotator.build_types(graph1, [SomeLLAbstractConstant(v.concretetype, {OriginFlags(): True}) for v in graph1.getargs()]) hannotator.simplify() t = hannotator.translator if conftest.option.view: t.view() if annotator: return hs, hannotator else: return hs
def test_optimize_method(): def fn(n): if n > 0: x = B(n) else: x = C(n) return x.meth(100) interp, graph = get_interpreter(fn, [-1000]) t = interp.typer.annotator.translator t.config.translation.backendopt.constfold = True backend_optimizations(t) if conftest.option.view: t.view() LLFrame = interp.frame_class class MyFrame(LLFrame): def op_indirect_call(self, f, *args): raise AssertionError("this call should be optimized away") interp.frame_class = MyFrame res = interp.eval_graph(graph, [-1000]) assert res == -897
def test_llexternal_with_callback(self): from pypy.rpython.lltypesystem.rffi import llexternal from pypy.rpython.lltypesystem import lltype class Abc: pass abc = Abc() FUNC = lltype.FuncType([lltype.Signed], lltype.Signed) z = llexternal('z', [lltype.Ptr(FUNC)], lltype.Signed) def g(n): abc.foobar = n return n + 1 def f(x): return z(g) t, wa = self.translate(f, [int]) fgraph = graphof(t, f) backend_optimizations(t) assert fgraph.startblock.operations[0].opname == 'direct_call' result = wa.analyze(fgraph.startblock.operations[0]) assert len(result) == 1 (struct, T, name), = result assert struct == "struct" assert name.endswith("foobar")
def test_llexternal(self): from pypy.rpython.lltypesystem.rffi import llexternal from pypy.rpython.lltypesystem import lltype z = llexternal('z', [lltype.Signed], lltype.Signed) def f(x): return z(x) t, ra = self.translate(f, [int]) fgraph = graphof(t, f) backend_optimizations(t) assert fgraph.startblock.operations[0].opname == 'direct_call' result = ra.can_raise(fgraph.startblock.operations[0]) assert not result z = lltype.functionptr(lltype.FuncType([lltype.Signed], lltype.Signed), 'foobar') def g(x): return z(x) t, ra = self.translate(g, [int]) ggraph = graphof(t, g) assert ggraph.startblock.operations[0].opname == 'direct_call' result = ra.can_raise(ggraph.startblock.operations[0]) assert result
def rcompile(rgenop, entrypoint, argtypes, random_seed=0, type_system='lltype'): from pypy.translator.translator import TranslationContext from pypy.annotation.policy import AnnotatorPolicy from pypy import conftest t = TranslationContext() policy = AnnotatorPolicy() policy.allow_someobjects = False t.buildannotator(policy=policy).build_types(entrypoint, argtypes) t.buildrtyper(type_system=type_system).specialize() # note that backend optimizations will constant-fold simple operations, # which is required by some backends that don't accept calls like # genop1("add", constant, constant). from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(t) if conftest.option.view: t.view() entrygraph = t._graphof(entrypoint) return compile_graph(rgenop, entrygraph, random_seed=random_seed)
def wrap_stackless_function(self, fn): def entry_point(argv): os.write(1, str(fn()) + "\n") return 0 from pypy.config.pypyoption import get_pypy_config config = get_pypy_config(translating=True) config.translation.gc = self.gcpolicy config.translation.stackless = True if self.stacklessgc: config.translation.gcrootfinder = "stackless" t = TranslationContext(config=config) self.t = t t.buildannotator().build_types(entry_point, [s_list_of_strings]) t.buildrtyper().specialize() if self.backendopt: backend_optimizations(t) from pypy.translator.transform import insert_ll_stackcheck insert_ll_stackcheck(t) cbuilder = CStandaloneBuilder(t, entry_point, config=config) cbuilder.stackless = True cbuilder.generate_source() cbuilder.compile() res = cbuilder.cmdexec('') return int(res.strip())
def test_dont_remove_with__del__(self): import os delcalls = [0] class A(object): nextid = 0 def __init__(self): self.id = self.nextid self.nextid += 1 def __del__(self): delcalls[0] += 1 os.write(1, "__del__\n") def f(x=int): a = A() i = 0 while i < x: a = A() os.write(1, str(delcalls[0]) + "\n") i += 1 return 1 t = TranslationContext() t.buildannotator().build_types(f, [int]) t.buildrtyper().specialize() graph = graphof(t, f) backend_optimizations(t) op = graph.startblock.exits[0].target.exits[1].target.operations[0] assert op.opname == "malloc"
def backend_optimize(self, **flags): # only optimize the newly created graphs from pypy.translator.backendopt.all import backend_optimizations translator = self.rtyper.annotator.translator newgraphs = translator.graphs[self.original_graph_count:] self.original_graph_count = len(translator.graphs) backend_optimizations(translator, newgraphs, secondary=True, **flags)
def _build_gen(func, annotation, graph=None, backendopt=True): try: func = func.im_func except AttributeError: pass t = TranslationContext() if graph is not None: graph.func = func ann = t.buildannotator() inputcells = [ann.typeannotation(a) for a in annotation] ann.build_graph_types(graph, inputcells) t.graphs.insert(0, graph) else: ann = t.buildannotator() ann.build_types(func, annotation) if getoption('view'): t.view() t.buildrtyper(type_system="ootype").specialize() if backendopt: check_virtual_methods(ootype.ROOT) backend_optimizations(t) main_graph = t.graphs[0] if getoption('view'): t.view() if getoption('wd'): tmpdir = py.path.local('.') else: tmpdir = udir return GenCli(tmpdir, t, TestEntryPoint(main_graph, True))
def annotate(func, values, inline=None, backendoptimize=True, type_system="lltype"): # build the normal ll graphs for ll_function t = TranslationContext() annpolicy = AnnotatorPolicy() annpolicy.allow_someobjects = False a = t.buildannotator(policy=annpolicy) argtypes = getargtypes(a, values) a.build_types(func, argtypes) rtyper = t.buildrtyper(type_system=type_system) rtyper.specialize() if inline: auto_inlining(t, threshold=inline) if backendoptimize: from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(t, inline_threshold=inline or 0, remove_asserts=True, really_remove_asserts=True) #if conftest.option.view: # t.view() return rtyper
def translate(func, argtypes, backend_optimize=True): t = TranslationContext() t.buildannotator().build_types(func, argtypes) t.buildrtyper().specialize() if backend_optimize: backend_optimizations(t) return graphof(t, func), t
def backend_optimize(self, **flags): # only optimize the newly created graphs from pypy.translator.backendopt.all import backend_optimizations translator = self.rtyper.annotator.translator newgraphs = self.newgraphs.keys() backend_optimizations(translator, newgraphs, secondary=True, **flags) self.newgraphs.clear()
def getcompiled(func, view=conftest.option.view, use_boehm=False): from pypy.translator.translator import TranslationContext from pypy.translator.backendopt.all import backend_optimizations from pypy.translator.c import gc from pypy.translator.c.genc import CExtModuleBuilder global t # allow us to view later t = TranslationContext() t.buildannotator().build_types(func, get_annotation(func)) t.buildrtyper().specialize() t.checkgraphs() gcpolicy = None if use_boehm: gcpolicy = gc.BoehmGcPolicy cbuilder = CExtModuleBuilder(t, func, t.config, gcpolicy=gcpolicy) cbuilder.generate_source() cbuilder.compile() backend_optimizations(t) if view: t.viewcg() return getattr(cbuilder.import_module(), func.__name__)
def test_implicit_cast(self): z = llexternal('z', [USHORT, ULONG, USHORT, DOUBLE], USHORT) def f(x, y, xx, yy): return z(x, y, xx, yy) a = RPythonAnnotator() r = a.build_types(f, [int, int, int, int]) rtyper = RPythonTyper(a) rtyper.specialize() a.translator.rtyper = rtyper backend_optimizations(a.translator) if option.view: a.translator.view() graph = graphof(a.translator, f) s = summary(graph) # there should be not too many operations here by now expected = { 'cast_int_to_uint': 1, 'direct_call': 1, 'cast_primitive': 2, 'cast_int_to_float': 1 } for k, v in expected.items(): assert s[k] == v
def wrap_stackless_function(self, fn): def entry_point(argv): os.write(1, str(fn())+"\n") return 0 from pypy.config.pypyoption import get_pypy_config config = get_pypy_config(translating=True) config.translation.gc = self.gcpolicy config.translation.stackless = True if self.stacklessgc: config.translation.gcrootfinder = "stackless" t = TranslationContext(config=config) self.t = t t.buildannotator().build_types(entry_point, [s_list_of_strings]) t.buildrtyper().specialize() if self.backendopt: backend_optimizations(t) from pypy.translator.transform import insert_ll_stackcheck insert_ll_stackcheck(t) cbuilder = CStandaloneBuilder(t, entry_point, config=config) cbuilder.stackless = True cbuilder.generate_source() cbuilder.compile() res = cbuilder.cmdexec('') return int(res.strip())
def rtype(func, inputtypes, specialize=True, gcname='ref', stacklessgc=False, backendopt=False, **extraconfigopts): from pypy.translator.translator import TranslationContext t = TranslationContext() # XXX XXX XXX mess t.config.translation.gc = gcname t.config.translation.gcconfig.removetypeptr = True if stacklessgc: t.config.translation.gcrootfinder = "stackless" t.config.set(**extraconfigopts) ann = t.buildannotator(policy=annpolicy.StrictAnnotatorPolicy()) ann.build_types(func, inputtypes) if specialize: t.buildrtyper().specialize() if backendopt: from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(t) if conftest.option.view: t.viewcg() return t
def test_idempotent(self): def s(x): res = 0 i = 1 while i <= x: res += i i += 1 return res def g(x): return s(100) + s(1) + x def idempotent(n1, n2): c = [i for i in range(n2)] return 33 + big() + g(10) t = self.translateopt(idempotent, [int, int], raisingop2direct_call=True, constfold=False) digest1 = md5digest(t) digest2 = md5digest(t) assert digest1 == digest2 #XXX Inlining and constfold are currently non-idempotent. # Maybe they just renames variables but the graph changes in some way. backend_optimizations(t, raisingop2direct_call=True, inline_threshold=0, constfold=False) digest3 = md5digest(t) assert digest1 == digest3
def hannotate(func, argtypes, policy=P_DEFAULT, annotator=False, inline=None, backendoptimize=False): # build the normal ll graphs for ll_function t = TranslationContext() a = t.buildannotator() a.build_types(func, argtypes) rtyper = t.buildrtyper() rtyper.specialize() if inline: auto_inlining(t, threshold=inline) if backendoptimize: from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(t) graph1 = graphof(t, func) # build hint annotator types hannotator = HintAnnotator(base_translator=t, policy=policy) hs = hannotator.build_types(graph1, [SomeLLAbstractConstant(v.concretetype, {OriginFlags(): True}) for v in graph1.getargs()]) hannotator.simplify() t = hannotator.translator if conftest.option.view: t.view() if annotator: return hs, hannotator else: return hs
def task_prehannotatebackendopt_lltype(self): from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(self.translator, inline_threshold=0, merge_if_blocks=True, constfold=True, raisingop2direct_call=False, remove_asserts=True)
def translate(func, argtypes, backendopt=False): t = TranslationContext() t.buildannotator().build_types(func, argtypes) t.buildrtyper(type_system="ootype").specialize() if backendopt: backend_optimizations(t, merge_if_blocks=True) return t
def translate(func, argtypes, backend_optimize=True): t = TranslationContext() t.buildannotator().build_types(func, argtypes) t.buildrtyper().specialize() if backend_optimize: backend_optimizations(t) if conftest.option.view: t.view() return graphof(t, func), t
def prejit_optimizations(self, policy, graphs): from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(self.translator, graphs=graphs, merge_if_blocks=True, constfold=True, raisingop2direct_call=False, remove_asserts=True, really_remove_asserts=True)
def specialize_view(self, f, args=[], opt=False): t = TranslationContext() a = t.buildannotator() a = a.build_types(f, args) r = t.buildrtyper() r.specialize() if opt: from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(t) t.view()
def translateopt(self, func, sig, **optflags): t = TranslationContext() t.buildannotator().build_types(func, sig) t.buildrtyper(type_system=self.type_system).specialize() if conftest.option.view: t.view() backend_optimizations(t, **optflags) if conftest.option.view: t.view() return t
def get_graph(fn, signature, all_opts=True): t = TranslationContext() t.buildannotator().build_types(fn, signature) t.buildrtyper().specialize() if all_opts: backend_optimizations(t, inline_threshold=INLINE_THRESHOLD_FOR_TEST, constfold=False, raisingop2direct_call=False) graph = graphof(t, fn) if conftest.option.view: t.view() return graph, t
def find_mallocs(func, argtypes): t, typer, graph = gengraph(func, argtypes) backend_optimizations(t, inline_threshold=10*INLINE_THRESHOLD_FOR_TEST) if conftest.option.view: t.view() result = [] for block in t.graphs[0].iterblocks(): for op in block.operations: if op.opname.startswith('malloc'): result.append(op.result.concretetype) return result
def getgraph(f, argtypes): from pypy.translator.translator import TranslationContext, graphof from pypy.translator.backendopt.all import backend_optimizations t = TranslationContext() a = t.buildannotator() typer = t.buildrtyper() a.build_types(f, argtypes) typer.specialize() backend_optimizations(t) graph = graphof(t, f) if option.view: graph.show() return graph
def test_llexternal(self): from pypy.rpython.lltypesystem.rffi import llexternal from pypy.rpython.lltypesystem import lltype z = llexternal('z', [lltype.Signed], lltype.Signed) def f(x): return z(x) t, wa = self.translate(f, [int]) fgraph = graphof(t, f) backend_optimizations(t) assert fgraph.startblock.operations[0].opname == 'direct_call' result = wa.analyze(fgraph.startblock.operations[0]) assert not result
def specialize(self, func, argtypes): from pypy.rpython.llinterp import LLInterpreter t = TranslationContext(list_comprehension_operations=True) t.buildannotator().build_types(func, argtypes) if conftest.option.view: t.view() t.buildrtyper(self.typesystem).specialize() backend_optimizations(t) if conftest.option.view: t.view() graph = graphof(t, func) interp = LLInterpreter(t.rtyper) return interp, graph
def analyze(self, func, sig, func_to_analyze=None, backendopt=False): if func_to_analyze is None: func_to_analyze = func t = TranslationContext() t.buildannotator().build_types(func, sig) t.buildrtyper(type_system=self.type_system).specialize() if backendopt: backend_optimizations(t) if option.view: t.view() a = FinalizerAnalyzer(t) fgraph = graphof(t, func_to_analyze) result = a.analyze_light_finalizer(fgraph) return result
def test_simple(): t = TranslationContext() a = t.buildannotator() a.build_types(g, [int]) a.simplify() t.buildrtyper().specialize() backend_optimizations(t) t.checkgraphs() n = insert_ll_stackcheck(t) t.checkgraphs() assert n == 1 if conftest.option.view: t.view() check(graphof(t, f), 'f')
def test_stackless(): t = TranslationContext() a = t.buildannotator() a.build_types(g, [int]) a.simplify() t.buildrtyper().specialize() backend_optimizations(t) t.checkgraphs() n = insert_ll_stackcheck(t) t.checkgraphs() assert n == 1 t.config.translation.stackless = True stacklesstransf = StacklessTransformer(t, g) f_graph = graphof(t, f) stacklesstransf.transform_graph(f_graph) if conftest.option.view: f_graph.show() exctransf = t.getexceptiontransformer() exctransf.create_exception_handling(f_graph) if conftest.option.view: f_graph.show() check(f_graph, 'f', 'fetch_retval_void') class GCTransform(framework.FrameworkGCTransformer): from pypy.rpython.memory.gc.generation import GenerationGC as \ GCClass GC_PARAMS = {} gctransf = GCTransform(t) gctransf.transform_graph(f_graph) if conftest.option.view: f_graph.show() relevant = check(f_graph, 'f', 'fetch_retval_void') for p in relevant: in_between = False reload = 0 for spaceop in p: if spaceop.opname == 'direct_call': target = direct_target(spaceop) if target == 'f': in_between = False elif target == 'stack_check___': in_between = True if in_between and spaceop.opname == 'gc_reload_possibly_moved': reload += 1 assert reload == 1
def test_count_vars_big(): from pypy.translator.goal.targetrpystonex import make_target_definition from pypy.translator.backendopt.all import backend_optimizations entrypoint, _, _ = make_target_definition(10) t = rtype(entrypoint, [int]) backend_optimizations(t) # does not crash rel = relevant_gcvars(t) print rel print sum(rel) / float(len(rel)), max(rel), min(rel) rel = relevant_gcvars(t, filter_for_nongcptr) print rel print sum(rel) / float(len(rel)), max(rel), min(rel)
def transform_func(self, fn, inputtypes, backendopt=False): t = TranslationContext() t.buildannotator().build_types(fn, inputtypes) t.buildrtyper(type_system=self.type_system).specialize() if conftest.option.view: t.view() if backendopt: backend_optimizations(t) g = graphof(t, fn) etrafo = exceptiontransform.ExceptionTransformer(t) etrafo.create_exception_handling(g) join_blocks(g) if conftest.option.view: t.view() return t, g
def test_two_constants(): def fn(): r = range(10, 37, 4) r.reverse() return r[0] t = TranslationContext() a = t.buildannotator() a.build_types(fn, []) rtyper = t.buildrtyper() rtyper.specialize() backend_optimizations(t, merge_if_blocks=True) graph = tgraphof(t, fn) blocknum = len(list(graph.iterblocks())) merge_if_blocks(graph) assert blocknum == len(list(graph.iterblocks()))
def test_join_blocks_cleans_links(): from pypy.rpython.lltypesystem import lltype from pypy.objspace.flow.model import Constant from pypy.translator.backendopt.removenoops import remove_same_as def f(x): return bool(x + 2) def g(x): if f(x): return 1 else: return 2 graph, t = translate(g, [int], backend_optimize=False) fgraph = graphof(t, f) fgraph.startblock.exits[0].args = [Constant(True, lltype.Bool)] # does not crash: previously join_blocks would barf on this remove_same_as(graph) backend_optimizations(t)