def test_isinstance(): class A: pass class B(A): pass def g(n): if n > 10: return A() else: b = B() b.value = 321 return b def fn(n): x = g(n) assert isinstance(x, B) return x.value t, graph = check(fn, [5], 321) assert summary(graph)['debug_assert'] == 1 from pypy.translator.backendopt.removenoops import remove_debug_assert remove_debug_assert(graph) assert "debug_assert" not in summary(graph) from pypy.translator.simplify import transform_dead_op_vars transform_dead_op_vars(graph, t) assert summary(graph)["direct_call"] == 1
def remove_obvious_noops(): for graph in graphs: removenoops.remove_same_as(graph) simplify.eliminate_empty_blocks(graph) simplify.transform_dead_op_vars(graph, translator) removenoops.remove_duplicate_casts(graph, translator) if config.print_statistics: print "after no-op removal:" print_statistics(translator.graphs[0], translator)
def test_transform_dead_op_vars_bug(): from pypy.rpython.llinterp import LLInterpreter, LLException exc = ValueError() def f1(): raise exc # this function used to be considered side-effects-free def f2(): f1() # <- so this call was removed graph, t = translate(f2, [], backend_optimize=False) transform_dead_op_vars(graph, t) interp = LLInterpreter(t.rtyper) e = py.test.raises(LLException, 'interp.eval_graph(graph, [])') assert 'ValueError' in str(e.value)
def remove_mallocs(translator, graphs=None, type_system="lltypesystem"): if graphs is None: graphs = translator.graphs tot = 0 for graph in graphs: count = remove_simple_mallocs(graph, type_system=type_system, verbose=translator.config.translation.verbose) if count: # remove typical leftovers from malloc removal removenoops.remove_same_as(graph) simplify.eliminate_empty_blocks(graph) simplify.transform_dead_op_vars(graph, translator) tot += count log.malloc("removed %d simple mallocs in total" % tot) return tot
def test_simple_melting_away(): def fn(n): assert n >= 1 return n-1 graph, t = get_graph(fn, [int]) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} remove_asserts(t, [graph]) assert summary(graph) == {'int_ge': 1, 'debug_assert': 1, 'int_sub': 1} check_graph(graph, [1], 0, t) from pypy.translator.backendopt.removenoops import remove_debug_assert remove_debug_assert(graph) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} from pypy.translator.simplify import transform_dead_op_vars transform_dead_op_vars(graph) assert summary(graph) == {'int_sub': 1}
def test_simple_melting_away(): def fn(n): assert n >= 1 return n - 1 graph, t = get_graph(fn, [int]) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} remove_asserts(t, [graph]) assert summary(graph) == {'int_ge': 1, 'debug_assert': 1, 'int_sub': 1} check_graph(graph, [1], 0, t) from pypy.translator.backendopt.removenoops import remove_debug_assert remove_debug_assert(graph) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} from pypy.translator.simplify import transform_dead_op_vars transform_dead_op_vars(graph) assert summary(graph) == {'int_sub': 1}
def remove_mallocs(translator, graphs=None, type_system="lltypesystem"): if graphs is None: graphs = translator.graphs tot = 0 for graph in graphs: count = remove_simple_mallocs( graph, type_system=type_system, verbose=translator.config.translation.verbose) if count: # remove typical leftovers from malloc removal removenoops.remove_same_as(graph) simplify.eliminate_empty_blocks(graph) simplify.transform_dead_op_vars(graph, translator) tot += count log.malloc("removed %d simple mallocs in total" % tot) return tot
def backend_optimizations(translator, graphs=None, secondary=False, **kwds): # sensible keywords are # raisingop2direct_call, inline_threshold, mallocs # merge_if_blocks, constfold, heap2stack # clever_malloc_removal, remove_asserts config = translator.config.translation.backendopt.copy(as_default=True) config.set(**kwds) if graphs is None: graphs = translator.graphs if config.print_statistics: print "before optimizations:" print_statistics(translator.graphs[0], translator, "per-graph.txt") if config.raisingop2direct_call: raisingop2direct_call(translator, graphs) if translator.rtyper.type_system.name == 'ootypesystem': check_virtual_methods() # remove obvious no-ops for graph in graphs: removenoops.remove_same_as(graph) simplify.eliminate_empty_blocks(graph) simplify.transform_dead_op_vars(graph, translator) removenoops.remove_duplicate_casts(graph, translator) if config.print_statistics: print "after no-op removal:" print_statistics(translator.graphs[0], translator) if config.inline or config.mallocs: heuristic = get_function(config.inline_heuristic) if config.inline: threshold = config.inline_threshold else: threshold = 0 inline_malloc_removal_phase(config, translator, graphs, threshold, inline_heuristic=heuristic) constfold(config, graphs) if config.clever_malloc_removal: threshold = config.clever_malloc_removal_threshold heuristic = get_function(config.clever_malloc_removal_heuristic) log.inlineandremove("phase with threshold factor: %s" % threshold) log.inlineandremove("heuristic: %s.%s" % (heuristic.__module__, heuristic.__name__)) count = mallocprediction.clever_inlining_and_malloc_removal( translator, graphs, threshold = threshold, heuristic=heuristic) log.inlineandremove("removed %d simple mallocs in total" % count) constfold(config, graphs) if config.print_statistics: print "after clever inlining and malloc removal" print_statistics(translator.graphs[0], translator) if config.profile_based_inline and not secondary: threshold = config.profile_based_inline_threshold heuristic = get_function(config.profile_based_inline_heuristic) inline.instrument_inline_candidates(graphs, threshold) counters = translator.driver_instrument_result( config.profile_based_inline) n = len(counters) def call_count_pred(label): if label >= n: return False return counters[label] > 250 # xxx introduce an option for this inline_malloc_removal_phase(config, translator, graphs, threshold, inline_heuristic=heuristic, call_count_pred=call_count_pred) constfold(config, graphs) if config.remove_asserts: remove_asserts(translator, graphs) if config.heap2stack: assert graphs is translator.graphs # XXX for now malloc_to_stack(translator) if config.merge_if_blocks: log.mergeifblocks("starting to merge if blocks") for graph in graphs: merge_if_blocks(graph, translator.config.translation.verbose) if config.print_statistics: print "after if-to-switch:" print_statistics(translator.graphs[0], translator) for graph in graphs: checkgraph(graph)