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

pedronis at codespeak.net pedronis at codespeak.net
Sat Oct 14 01:04:47 CEST 2006


Author: pedronis
Date: Sat Oct 14 01:04:45 2006
New Revision: 33278

Modified:
   pypy/dist/pypy/translator/backendopt/constfold.py
   pypy/dist/pypy/translator/backendopt/test/test_all.py
Log:
try to have constfold move much more constants from links into blocks and into operations as arguments.

This makes the line count of the implement*.c 2.5% smaller for pypy.

It may help doing some very specific and late folding in funcgen itself.
 


Modified: pypy/dist/pypy/translator/backendopt/constfold.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/constfold.py	(original)
+++ pypy/dist/pypy/translator/backendopt/constfold.py	Sat Oct 14 01:04:45 2006
@@ -1,5 +1,6 @@
 from pypy.objspace.flow.model import Constant, Variable, SpaceOperation
 from pypy.objspace.flow.model import c_last_exception
+from pypy.objspace.flow.model import mkentrymap
 from pypy.translator.backendopt.support import split_block_with_keepalive
 from pypy.translator.backendopt.support import log
 from pypy.translator.simplify import eliminate_empty_blocks
@@ -196,6 +197,41 @@
             link.target = splitlink.target
 
 
+def constant_diffuse(graph):
+    # if the same constants appear at the same positions in all links
+    # into a block remove them from the links, remove the corresponding
+    # input variables and introduce equivalent same_as at the beginning
+    # of the block then try to fold the block further
+    count = 0
+    for block, links in mkentrymap(graph).iteritems():
+        if block is graph.startblock:
+            continue
+        if block.exits == ():
+            continue
+        firstlink = links[0]
+        rest = links[1:]
+        diffuse = []
+        for i, c in enumerate(firstlink.args):
+            if not isinstance(c, Constant):
+                continue
+            for lnk in rest:
+                if lnk.args[i] != c:
+                    break
+            else:
+                diffuse.append((i, c))
+        diffuse.reverse()
+        same_as = []
+        for i, c in diffuse:
+            for lnk in links:
+                del lnk.args[i]
+            v = block.inputargs.pop(i)
+            same_as.append(SpaceOperation('same_as', [c], v))
+            count += 1
+        block.operations = same_as + block.operations
+        if same_as:
+            constant_fold_block(block)
+    return count
+                
 def constant_fold_graph(graph):
     # first fold inside the blocks
     for block in graph.iterblocks():
@@ -205,15 +241,20 @@
     # with new constants show up, even though we can probably prove that
     # a single iteration is enough under some conditions, like the graph
     # is in a join_blocks() form.
+    first = True
     while 1:
+        diffused = constant_diffuse(graph)
         splitblocks = {}
-        for link in list(graph.iterlinks()):
-            constants = {}
-            for v1, v2 in zip(link.args, link.target.inputargs):
-                if isinstance(v1, Constant):
-                    constants[v2] = v1
-            if constants:
-                prepare_constant_fold_link(link, constants, splitblocks)
-        if not splitblocks:
-            break   # finished
-        rewire_links(splitblocks, graph)
+        if first or diffused:
+            first = False
+            for link in list(graph.iterlinks()):
+                constants = {}
+                for v1, v2 in zip(link.args, link.target.inputargs):
+                    if isinstance(v1, Constant):
+                        constants[v2] = v1
+                if constants:
+                    prepare_constant_fold_link(link, constants, splitblocks)
+            if  splitblocks:
+                rewire_links(splitblocks, graph)
+        if not diffused and not splitblocks:
+            break # finished

Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_all.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_all.py	Sat Oct 14 01:04:45 2006
@@ -189,4 +189,19 @@
     for args in [2, 7, 0], [7, 2, 0], [10, 50, 7], [50, -10, -3]:
         assert interp.eval_graph(graphof(t, fn), args) == intmask(fn(*args))
 
+def test_constant_diffuse():
+    def g(x,y):
+        if x < 0:
+            return 0
+        return x + y
 
+    def f(x):
+        return g(x,7)+g(x,11)
+    
+    t = translateopt(f, [int])
+    fgraph = graphof(t, f)
+
+    for link in fgraph.iterlinks():
+        assert Constant(7) not in link.args
+        assert Constant(11) not in link.args
+    



More information about the Pypy-commit mailing list