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

nik at codespeak.net nik at codespeak.net
Sun Apr 2 19:20:47 CEST 2006


Author: nik
Date: Sun Apr  2 19:20:46 2006
New Revision: 25232

Modified:
   pypy/dist/pypy/translator/backendopt/removenoops.py
   pypy/dist/pypy/translator/backendopt/test/test_removenoops.py
Log:
light getting-into-pypy-mood hacking. take remove_same_as backendopt and
generalize it to remove_unaryops, to remove any unary low-level operation.
to be used to remove e.g. oodowncast/upcast in gensqueak.


Modified: pypy/dist/pypy/translator/backendopt/removenoops.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/removenoops.py	(original)
+++ pypy/dist/pypy/translator/backendopt/removenoops.py	Sun Apr  2 19:20:46 2006
@@ -2,38 +2,38 @@
 from pypy.objspace.flow.model import traverse
 from pypy.rpython.lltypesystem.lltype import Void
 
-def remove_same_as(graph):
-    """Remove all 'same_as' operations.
+def remove_unaryops(graph, opnames):
+    """Removes unary low-level ops with a name appearing in the opnames list.
     """
-    same_as_positions = []
+    positions = []
     def visit(node): 
         if isinstance(node, Block): 
             for i, op in enumerate(node.operations):
-                if op.opname == 'same_as': 
-                    same_as_positions.append((node, i))
+                if op.opname in opnames:
+                    positions.append((node, i))
     traverse(visit, graph)
-    while same_as_positions:
-        block, index = same_as_positions.pop()
-        same_as_result = block.operations[index].result
-        same_as_arg = block.operations[index].args[0]
-        # replace the new variable (same_as_result) with the old variable
+    while positions:
+        block, index = positions.pop()
+        op_result = block.operations[index].result
+        op_arg = block.operations[index].args[0]
+        # replace the new variable (op_result) with the old variable
         # (from all subsequent positions)
         for op in block.operations[index:]:
             if op is not None:
                 for i in range(len(op.args)):
-                    if op.args[i] == same_as_result:
-                        op.args[i] = same_as_arg
+                    if op.args[i] == op_result:
+                        op.args[i] = op_arg
         for link in block.exits:
             for i in range(len(link.args)):
-                if link.args[i] == same_as_result:
-                    link.args[i] = same_as_arg
-        if block.exitswitch == same_as_result:
-            if isinstance(same_as_arg, Variable):
-                block.exitswitch = same_as_arg
+                if link.args[i] == op_result:
+                    link.args[i] = op_arg
+        if block.exitswitch == op_result:
+            if isinstance(op_arg, Variable):
+                block.exitswitch = op_arg
             else:
-                assert isinstance(same_as_arg, Constant)
+                assert isinstance(op_arg, Constant)
                 newexits = [link for link in block.exits
-                                 if link.exitcase == same_as_arg.value]
+                                 if link.exitcase == op_arg.value]
                 assert len(newexits) == 1
                 newexits[0].exitcase = None
                 if hasattr(newexits[0], 'llexitcase'):
@@ -42,12 +42,15 @@
                 block.recloseblock(*newexits)
         block.operations[index] = None
        
-    # remove all same_as operations
+    # remove all operations
     def visit(node): 
         if isinstance(node, Block) and node.operations:
             node.operations[:] = filter(None, node.operations)
     traverse(visit, graph)
 
+def remove_same_as(graph):
+    remove_unaryops(graph, ["same_as"])
+
 
 def remove_void(translator):
     for graph in translator.graphs:

Modified: pypy/dist/pypy/translator/backendopt/test/test_removenoops.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_removenoops.py	(original)
+++ pypy/dist/pypy/translator/backendopt/test/test_removenoops.py	Sun Apr  2 19:20:46 2006
@@ -1,9 +1,11 @@
-from pypy.translator.backendopt.removenoops import remove_void, remove_same_as
+from pypy.translator.backendopt.removenoops import remove_void, remove_same_as, \
+        remove_unaryops
 from pypy.translator.backendopt.inline import inline_function
 from pypy.translator.translator import TranslationContext, graphof
 from pypy.translator.test.snippet import simple_method
 from pypy.objspace.flow.model import checkgraph, flatten, Block
-from pypy.rpython.lltypesystem.lltype import Void
+from pypy.rpython.lltypesystem.lltype import Void, Signed
+from pypy.rpython.lltypesystem.lloperation import llop
 from pypy.rpython.llinterp import LLInterpreter
 
 import py
@@ -67,3 +69,23 @@
     interp = LLInterpreter(t.rtyper)
     result = interp.eval_graph(f_graph, [])
     assert result == 42
+
+def test_remove_unaryops():
+    # We really want to use remove_unaryops for things like ooupcast and
+    # oodowncast in dynamically typed languages, but it's easier to test
+    # it with operations on ints here.
+    def f(x):
+        i = llop.int_invert(Signed, x)
+        i = llop.int_add(Signed, x, 1)
+        return llop.int_neg(Signed, i)
+    t = TranslationContext()
+    t.buildannotator().build_types(f, [int])
+    t.buildrtyper().specialize()
+    f_graph = graphof(t, f)
+    remove_unaryops(f_graph, ["int_neg", "int_invert"])
+    t.checkgraphs()
+
+    interp = LLInterpreter(t.rtyper)
+    result = interp.eval_graph(f_graph, [-2])
+    assert result == -1
+



More information about the Pypy-commit mailing list