[pypy-svn] r37448 - in pypy/dist/pypy/translator/backendopt: . test

pedronis at codespeak.net pedronis at codespeak.net
Sat Jan 27 20:35:37 CET 2007


Author: pedronis
Date: Sat Jan 27 20:35:31 2007
New Revision: 37448

Modified:
   pypy/dist/pypy/translator/backendopt/all.py
   pypy/dist/pypy/translator/backendopt/escape.py
   pypy/dist/pypy/translator/backendopt/inline.py
   pypy/dist/pypy/translator/backendopt/malloc.py
   pypy/dist/pypy/translator/backendopt/mallocprediction.py
   pypy/dist/pypy/translator/backendopt/test/test_mallocprediction.py
Log:
intermediate: try to regularize clever malloc removal interface, share some common code between it and all



Modified: pypy/dist/pypy/translator/backendopt/all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/all.py	(original)
+++ pypy/dist/pypy/translator/backendopt/all.py	Sat Jan 27 20:35:31 2007
@@ -1,13 +1,13 @@
 from pypy.translator.backendopt.raisingop2direct_call import raisingop2direct_call
 from pypy.translator.backendopt import removenoops
 from pypy.translator.backendopt import inline
-from pypy.translator.backendopt.malloc import remove_simple_mallocs
+from pypy.translator.backendopt.malloc import remove_mallocs
 from pypy.translator.backendopt.constfold import constant_fold_graph
 from pypy.translator.backendopt.stat import print_statistics
 from pypy.translator.backendopt.merge_if_blocks import merge_if_blocks
 from pypy.translator import simplify
 from pypy.translator.backendopt.escape import malloc_to_stack
-from pypy.translator.backendopt.mallocprediction import clever_inlining_and_malloc_removal
+from pypy.translator.backendopt import mallocprediction
 from pypy.translator.backendopt.removeassert import remove_asserts
 from pypy.translator.backendopt.support import log
 from pypy.translator.backendopt.checkvirtual import check_virtual_methods
@@ -66,9 +66,10 @@
                                     config.inline_threshold,
                                     call_count_pred=call_count_pred)
     else:
-        assert graphs is translator.graphs  # XXX for now
-        clever_inlining_and_malloc_removal(translator)
-
+        count = mallocprediction.preparation(translator, graphs)
+        count += mallocprediction.clever_inlining_and_malloc_removal(
+            translator, graphs)
+        log.inlineandremove("removed %d simple mallocs in total" % count)
         if config.print_statistics:
             print "after clever inlining and malloc removal"
             print_statistics(translator.graphs[0], translator)
@@ -103,14 +104,8 @@
 
     # inline functions in each other
     if inline_threshold:
-        callgraph = inline.inlinable_static_callers(graphs)
-        count = inline.auto_inlining(translator, inline_threshold,
-                                     callgraph=callgraph,
-                                     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)
+        inline.auto_inline_graphs(translator, graphs, inline_threshold,
+                                  call_count_pred=call_count_pred)
 
         if config.print_statistics:
             print "after inlining:"
@@ -118,16 +113,7 @@
 
     # vaporize mallocs
     if config.mallocs:
-        tot = 0
-        for graph in graphs:
-            count = remove_simple_mallocs(graph, type_system)
-            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)
+        remove_mallocs(translator, graphs, type_system)
 
         if config.print_statistics:
             print "after malloc removal:"

Modified: pypy/dist/pypy/translator/backendopt/escape.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/escape.py	(original)
+++ pypy/dist/pypy/translator/backendopt/escape.py	Sat Jan 27 20:35:31 2007
@@ -80,6 +80,9 @@
         self.dependencies = {} # creationpoint: {block: graph containing it}
         self.functionargs = {} # graph: list of state of args
         self.flown_blocks = {} # block: True
+
+    def seen_graphs(self):
+        return self.functionargs.keys()
     
     def getstate(self, var_or_const):
         if not isonheap(var_or_const):

Modified: pypy/dist/pypy/translator/backendopt/inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/inline.py	(original)
+++ pypy/dist/pypy/translator/backendopt/inline.py	Sat Jan 27 20:35:31 2007
@@ -12,6 +12,7 @@
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython import rmodel
 from pypy.tool.algo import sparsemat
+from pypy.translator.backendopt import removenoops
 from pypy.translator.backendopt.support import log, split_block_with_keepalive
 from pypy.translator.backendopt.support import find_backedges, find_loop_blocks
 from pypy.translator.backendopt.canraise import RaiseAnalyzer
@@ -715,3 +716,12 @@
                     heappush(heap, (0.0, -len(callers[parentgraph]), parentgraph))
                 valid_weight[parentgraph] = False
     return count
+
+def auto_inline_graphs(translator, graphs, threshold, call_count_pred=None):
+        callgraph = inlinable_static_callers(graphs)
+        count = auto_inlining(translator, threshold, callgraph=callgraph,
+                              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)

Modified: pypy/dist/pypy/translator/backendopt/malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/malloc.py	(original)
+++ pypy/dist/pypy/translator/backendopt/malloc.py	Sat Jan 27 20:35:31 2007
@@ -3,7 +3,8 @@
 from pypy.tool.algo.unionfind import UnionFind
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.ootypesystem import ootype
-from pypy.translator.simplify import remove_identical_vars
+from pypy.translator import simplify
+from pypy.translator.backendopt import removenoops
 from pypy.translator.backendopt.support import log
 
 class LifeTime:
@@ -287,7 +288,7 @@
 
     def remove_mallocs_once(self, graph):
         """Perform one iteration of malloc removal."""
-        remove_identical_vars(graph)
+        simplify.remove_identical_vars(graph)
         lifetimes = self.compute_lifetimes(graph)
         progress = 0
         for info in lifetimes:
@@ -602,3 +603,21 @@
     else:
         remover = OOTypeMallocRemover()
     return remover.remove_simple_mallocs(graph)
+
+
+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)
+        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
+
+

Modified: pypy/dist/pypy/translator/backendopt/mallocprediction.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/mallocprediction.py	(original)
+++ pypy/dist/pypy/translator/backendopt/mallocprediction.py	Sat Jan 27 20:35:31 2007
@@ -1,9 +1,9 @@
 from pypy.translator.backendopt.escape import AbstractDataFlowInterpreter
-from pypy.translator.backendopt.malloc import remove_simple_mallocs
-from pypy.translator.backendopt.inline import auto_inlining
-from pypy.translator.backendopt import removenoops
+from pypy.translator.backendopt.all import remove_mallocs
+from pypy.translator.backendopt import inline
 from pypy.rpython.lltypesystem import lltype
 from pypy.translator import simplify
+from pypy.translator.backendopt import removenoops
 from pypy.translator.backendopt.support import log
 
 SMALL_THRESHOLD = 15
@@ -95,66 +95,67 @@
                                           adi, translator, seen)
     return interesting_creps
 
-def find_malloc_removal_candidates(t):
+def find_malloc_removal_candidates(t, graphs):
     adi = AbstractDataFlowInterpreter(t)
-    for graph in t.graphs:
+    for graph in graphs:
         if graph.startblock not in adi.flown_blocks:
             adi.schedule_function(graph)
             adi.complete()
+    targetset = dict.fromkeys(graphs)
     caller_candidates = {}
     seen = {}
-    for graph in t.graphs:
+    for graph in adi.seen_graphs():
         creps = find_malloc_creps(graph, adi, t)
         #print "malloc creps", creps
         if creps:
             find_calls_where_creps_go(creps, graph, adi, t, seen)
             if creps:
-                caller_candidates[graph] = True
+                if graph in targetset:
+                    caller_candidates[graph] = True
     callgraph = []
     for (called_graph, i), callers in seen.iteritems():
         for caller in callers:
-            callgraph.append((caller, called_graph))
+            if caller in targetset:
+                callgraph.append((caller, called_graph))
+            else:
+                log.inlineandremove.WARNING("would like to inline into"
+                                            " out of target set: %r"
+                                            % caller)
     return callgraph, caller_candidates
 
-def inline_and_remove(t, threshold=BIG_THRESHOLD):
-    callgraph, caller_candidates = find_malloc_removal_candidates(t)
+def inline_and_remove(t, graphs, threshold=BIG_THRESHOLD):
+    callgraph, caller_candidates = find_malloc_removal_candidates(t, graphs)
     log.inlineandremove("found %s malloc removal candidates" %
                         len(caller_candidates))
     if callgraph:
-        count = auto_inlining(t, callgraph=callgraph, threshold=threshold)
+        count = inline.auto_inlining(t, callgraph=callgraph,
+                                     threshold=threshold)
         if not count:
             return False
+        log.inlineandremove('inlined %d callsites.'% (count,))
         count = remove_mallocs(t, caller_candidates.keys())
         return count
     else:
         return False
 
-def remove_mallocs(translator, graphs=None):
-    tot = 0
+def preparation(translator, graphs, threshold=SMALL_THRESHOLD):
+    count = 0
+    inline.auto_inline_graphs(translator, graphs, threshold)
+    count += remove_mallocs(translator, graphs)
+    log.inlineandremove("preparation removed %s mallocs in total" % count)
+    return count
+
+def clever_inlining_and_malloc_removal(translator, graphs=None,
+                                       threshold=BIG_THRESHOLD):
     if graphs is None:
         graphs = translator.graphs
-    for graph in graphs:
-        count = remove_simple_mallocs(graph)
-        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 clever_inlining_and_malloc_removal(translator):
-    count = remove_mallocs(translator)
-    auto_inlining(translator, threshold=SMALL_THRESHOLD)
-    count += remove_mallocs(translator)
+    count = 0
     while 1:
-        newcount = inline_and_remove(translator)
+        newcount = inline_and_remove(translator, graphs, threshold=threshold)
         if not newcount:
             break
         count += newcount
-    log.inlineandremove.event("removed %s mallocs in total" % count)
-    for graph in translator.graphs:
+    for graph in graphs:
         removenoops.remove_superfluous_keep_alive(graph)
         removenoops.remove_duplicate_casts(graph, translator)
     return count

Modified: pypy/dist/pypy/translator/backendopt/test/test_mallocprediction.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_mallocprediction.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_mallocprediction.py	Sat Jan 27 20:35:31 2007
@@ -20,11 +20,11 @@
     
 
 def check_inlining(t, graph, args, result):
-    callgraph, caller_candidates = find_malloc_removal_candidates(t)
+    callgraph, caller_candidates = find_malloc_removal_candidates(t, t.graphs)
     nice_callgraph = {}
     for caller, callee in callgraph:
         nice_callgraph.setdefault(caller, {})[callee] = True
-    inline_and_remove(t)
+    inline_and_remove(t, t.graphs)
     if option.view:
         t.view()
     interp = LLInterpreter(t.rtyper)
@@ -121,11 +121,13 @@
     entrypoint, _, _ = make_target_definition(10)
     # does not crash
     t, graph = rtype(entrypoint, [int])
+    total0 = preparation(t, t.graphs)
     total = clever_inlining_and_malloc_removal(t)
-    assert total == 8
+    assert total0 + total == 8
 
 def test_richards():
     from pypy.translator.goal.richards import entry_point
     t, graph = rtype(entry_point, [int])
+    total0 = preparation(t, t.graphs)
     total = clever_inlining_and_malloc_removal(t)
-    assert total == 9
+    assert total0 + total == 9



More information about the Pypy-commit mailing list