def auto_inline_graphs(translator, graphs, threshold, call_count_pred=None, heuristic=inlining_heuristic): callgraph = inlinable_static_callers(graphs) count = auto_inlining(translator, threshold, callgraph=callgraph, heuristic=heuristic, call_count_pred=call_count_pred) log.inlining('inlined %d callsites.'% (count,)) for graph in graphs: removenoops.remove_duplicate_casts(graph, translator)
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 auto_inline_graphs(translator, graphs, threshold, call_count_pred=None, heuristic=inlining_heuristic): callgraph = inlinable_static_callers(graphs) count = auto_inlining(translator, threshold, callgraph=callgraph, heuristic=heuristic, call_count_pred=call_count_pred) log.inlining('inlined %d callsites.'% (count,)) for graph in graphs: removenoops.remove_superfluous_keep_alive(graph) removenoops.remove_duplicate_casts(graph, translator)
def clever_inlining_and_malloc_removal(translator, graphs=None, threshold=BIG_THRESHOLD, heuristic=inline.inlining_heuristic): if graphs is None: graphs = translator.graphs count = 0 while 1: newcount = inline_and_remove(translator, graphs, threshold=threshold, heuristic=heuristic) if not newcount: break count += newcount for graph in graphs: removenoops.remove_duplicate_casts(graph, translator) return count
def test_remove_duplicate_casts(): class A(object): def __init__(self, x, y): self.x = x self.y = y def getsum(self): return self.x + self.y class B(A): def __init__(self, x, y, z): A.__init__(self, x, y) self.z = z def getsum(self): return self.x + self.y + self.z def f(x, switch): a = A(x, x + 1) b = B(x, x + 1, x + 2) if switch: c = A(x, x + 1) else: c = B(x, x + 1, x + 2) return a.x + a.y + b.x + b.y + b.z + c.getsum() assert f(10, True) == 75 graph, t = get_graph(f, [int, bool], all_opts=False) num_cast_pointer = len(getops(graph)['cast_pointer']) changed = remove_duplicate_casts(graph, t) assert changed ops = getops(graph) assert len(ops['cast_pointer']) < num_cast_pointer print len(ops['cast_pointer']), num_cast_pointer graph_getsum = graphof(t, B.getsum.im_func) num_cast_pointer = len(getops(graph_getsum)['cast_pointer']) changed = remove_duplicate_casts(graph_getsum, t) assert changed if conftest.option.view: t.view() check_graph(graph, [10, True], 75, t) ops = getops(graph_getsum) assert len(ops['cast_pointer']) < num_cast_pointer print len(ops['cast_pointer']), num_cast_pointer
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)