def check(self, fn, signature, args, expected_result, must_be_removed=True, inline=None): remover = self.MallocRemover() t = TranslationContext() t.buildannotator().build_types(fn, signature) t.buildrtyper(type_system=self.type_system).specialize() graph = graphof(t, fn) if inline is not None: from pypy.translator.backendopt.inline import auto_inline_graphs auto_inline_graphs(t, t.graphs, inline) if option.view: t.view() # to detect missing keepalives and broken intermediate graphs, # we do the loop ourselves instead of calling remove_simple_mallocs() while True: progress = remover.remove_mallocs_once(graph) simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks())) if progress and option.view: t.view() if expected_result is not Ellipsis: interp = LLInterpreter(t.rtyper) res = interp.eval_graph(graph, args) assert res == expected_result if not progress: break if must_be_removed: self.check_malloc_removed(graph) return graph
def inline_malloc_removal_phase(config, translator, graphs, inline_threshold, inline_heuristic, call_count_pred=None): type_system = translator.rtyper.type_system.name # inline functions in each other if inline_threshold: log.inlining("phase with threshold factor: %s" % inline_threshold) log.inlining("heuristic: %s.%s" % (inline_heuristic.__module__, inline_heuristic.__name__)) inline.auto_inline_graphs(translator, graphs, inline_threshold, heuristic=inline_heuristic, call_count_pred=call_count_pred) if config.print_statistics: print "after inlining:" print_statistics(translator.graphs[0], translator) # vaporize mallocs if config.mallocs: log.malloc("starting malloc removal") remove_mallocs(translator, graphs, type_system) if config.print_statistics: print "after malloc removal:" print_statistics(translator.graphs[0], translator)
def test_fold_exitswitch_along_one_path(): def g(n): if n == 42: return 5 else: return n + 1 def fn(n): if g(n) == 5: return 100 else: return 0 graph, t = get_graph(fn, [int]) from pypy.translator.backendopt import removenoops, inline inline.auto_inline_graphs(t, t.graphs, threshold=999) constant_fold_graph(graph) removenoops.remove_same_as(graph) if conftest.option.view: t.view() # check that the graph starts with a condition (which should be 'n==42') # and that if this condition is true, it goes directly to 'return 100'. assert len(graph.startblock.exits) == 2 assert graph.startblock.exits[1].exitcase == True assert graph.startblock.exits[1].target is graph.returnblock check_graph(graph, [10], 0, t) check_graph(graph, [42], 100, t)
def test_coalesce_exitswitchs(): def g(n): return n > 5 and n < 20 def fn(n): if g(n): return 100 else: return 0 graph, t = get_graph(fn, [int]) from pypy.translator.backendopt import removenoops, inline inline.auto_inline_graphs(t, t.graphs, threshold=999) removenoops.remove_same_as(graph) constant_fold_graph(graph) if conftest.option.view: t.view() # check that the graph starts with a condition (which should be 'n > 5') # and that if this condition is false, it goes directly to 'return 0'. assert summary(graph) == {'int_gt': 1, 'int_lt': 1} assert len(graph.startblock.exits) == 2 assert graph.startblock.exits[0].exitcase == False assert graph.startblock.exits[0].target is graph.returnblock check_graph(graph, [2], 0, t) check_graph(graph, [10], 100, t) check_graph(graph, [42], 0, t)
def test_fold_exitswitch_along_one_path(): def g(n): if n == 42: return 5 else: return n+1 def fn(n): if g(n) == 5: return 100 else: return 0 graph, t = get_graph(fn, [int]) from pypy.translator.backendopt import removenoops, inline inline.auto_inline_graphs(t, t.graphs, threshold=999) constant_fold_graph(graph) removenoops.remove_same_as(graph) if conftest.option.view: t.view() # check that the graph starts with a condition (which should be 'n==42') # and that if this condition is true, it goes directly to 'return 100'. assert len(graph.startblock.exits) == 2 assert graph.startblock.exits[1].exitcase == True assert graph.startblock.exits[1].target is graph.returnblock check_graph(graph, [10], 0, t) check_graph(graph, [42], 100, t)
def check(self, fn, signature, args, expected_result, must_be_removed=True, inline=None): remover = self.MallocRemover() t = TranslationContext() t.buildannotator().build_types(fn, signature) t.buildrtyper(type_system=self.type_system).specialize() graph = graphof(t, fn) if inline is not None: from pypy.translator.backendopt.inline import auto_inline_graphs auto_inline_graphs(t, t.graphs, inline) if option.view: t.view() # to detect broken intermediate graphs, # we do the loop ourselves instead of calling remove_simple_mallocs() while True: progress = remover.remove_mallocs_once(graph) simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks()), [graph]) if progress and option.view: t.view() if expected_result is not Ellipsis: interp = LLInterpreter(t.rtyper) res = interp.eval_graph(graph, args) assert res == expected_result if not progress: break if must_be_removed: self.check_malloc_removed(graph) return graph
def preparation(translator, graphs, threshold=SMALL_THRESHOLD, heuristic=inline.inlining_heuristic): count = 0 inline.auto_inline_graphs(translator, graphs, threshold, heuristic=heuristic) count += remove_mallocs(translator, graphs) log.inlineandremove("preparation removed %s mallocs in total" % count) return count
def prejit_optimizations_minimal_inline(self, policy, graphs): from pypy.translator.backendopt.inline import auto_inline_graphs auto_inline_graphs(self.translator, graphs, 0.01)