[pypy-svn] r7279 - in pypy/trunk/src/pypy: annotation translator translator/test

arigo at codespeak.net arigo at codespeak.net
Tue Nov 16 12:31:27 CET 2004


Author: arigo
Date: Tue Nov 16 12:31:26 2004
New Revision: 7279

Modified:
   pypy/trunk/src/pypy/annotation/unaryop.py
   pypy/trunk/src/pypy/translator/annrpython.py
   pypy/trunk/src/pypy/translator/test/snippet.py
   pypy/trunk/src/pypy/translator/test/test_annrpython.py
   pypy/trunk/src/pypy/translator/transform.py
Log:
Remove code found out to be dead by the annotator.
A new test for it.
A bug fix in transform_dead_op_vars().



Modified: pypy/trunk/src/pypy/annotation/unaryop.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/unaryop.py	(original)
+++ pypy/trunk/src/pypy/annotation/unaryop.py	Tue Nov 16 12:31:26 2004
@@ -28,7 +28,14 @@
         return SomeInteger(nonneg=True)
 
     def is_true(obj):
-        return SomeBool()
+        if obj.is_constant():
+            return immutablevalue(bool(obj.const))
+        else:
+            s_len = obj.len()
+            if s_len.is_constant():
+                return immutablevalue(s_len.const > 0)
+            else:
+                return SomeBool()
 
     def getattr(obj, s_attr):
         # get a SomeBuiltin if the SomeObject has

Modified: pypy/trunk/src/pypy/translator/annrpython.py
==============================================================================
--- pypy/trunk/src/pypy/translator/annrpython.py	(original)
+++ pypy/trunk/src/pypy/translator/annrpython.py	Tue Nov 16 12:31:26 2004
@@ -285,7 +285,14 @@
                 self.consider_op(block.operations[i])
             finally:
                 self.bookkeeper.leave()
-        for link in block.exits:
+        # dead code removal: don't follow all exits if the exitswitch is known
+        exits = block.exits
+        if isinstance(block.exitswitch, Variable):
+            s_exitswitch = self.bindings[block.exitswitch]
+            if s_exitswitch.is_constant():
+                exits = [link for link in exits
+                              if link.exitcase == s_exitswitch.const]
+        for link in exits:
             cells = [self.binding(a) for a in link.args]
             self.addpendingblock(fn, link.target, cells)
         if block in self.notify:

Modified: pypy/trunk/src/pypy/translator/test/snippet.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/snippet.py	(original)
+++ pypy/trunk/src/pypy/translator/test/snippet.py	Tue Nov 16 12:31:26 2004
@@ -267,6 +267,18 @@
     a = call_five_six()
     return len(a), a[0], a[1]
 
+def forty_two():
+    return 42
+
+def never_called():
+    return "booo"
+
+def constant_result():
+    if forty_two():
+        return "yadda"
+    else:
+        return never_called()
+
 # INHERITANCE / CLASS TESTS  
 class C(object): pass
 

Modified: pypy/trunk/src/pypy/translator/test/test_annrpython.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_annrpython.py	(original)
+++ pypy/trunk/src/pypy/translator/test/test_annrpython.py	Tue Nov 16 12:31:26 2004
@@ -251,6 +251,23 @@
         self.assert_(isinstance(s, annmodel.SomeList))
         self.assertEquals(s.s_item, annmodel.SomeInteger(nonneg=True))
 
+    def test_constant_result(self):
+        a = RPythonAnnotator()
+        s = a.build_types(snippet.constant_result, [])
+        a.translator.simplify()
+        # must return "yadda"
+        self.assertEquals(s, annmodel.immutablevalue("yadda"))
+        keys = a.translator.flowgraphs.keys()
+        keys.sort()
+        expected = [snippet.constant_result,
+                    snippet.forty_two,
+                    # and not snippet.never_called
+                    ]
+        expected.sort()
+        self.assertEquals(keys, expected)
+        a.simplify()
+        #a.translator.view()
+
 def g(n):
     return [0,1,2,n]
 

Modified: pypy/trunk/src/pypy/translator/transform.py
==============================================================================
--- pypy/trunk/src/pypy/translator/transform.py	(original)
+++ pypy/trunk/src/pypy/translator/transform.py	Tue Nov 16 12:31:26 2004
@@ -105,7 +105,8 @@
     # the set of operations that can safely be removed (no side effects)
     CanRemove = {'newtuple': True,
                  'newlist': True,
-                 'newdict': True}
+                 'newdict': True,
+                 'is_true': True}
     read_vars = {}  # set of variables really used
     variable_flow = {}  # map {Var: list-of-Vars-it-depends-on}
     
@@ -121,6 +122,9 @@
                 # on the input variables
                 deps = variable_flow.setdefault(op.result, [])
                 deps.extend(op.args)
+
+        if isinstance(block.exitswitch, Variable):
+            read_vars[block.exitswitch] = True
         
         if block.exits:
             for link in block.exits:
@@ -296,11 +300,26 @@
 ##            self.setbinding(a2, self.bindings[a1])
 ##    self.annotated[block] = True
 
+def transform_dead_code(self):
+    """Remove dead code: these are the blocks that are not annotated at all
+    because the annotation considered that no conditional jump could reach
+    them."""
+    for block in self.annotated:
+        for link in block.exits:
+            if link.target not in self.annotated:
+                lst = list(block.exits)
+                lst.remove(link)
+                block.exits = tuple(lst)
+                if len(block.exits) == 1:
+                    block.exitswitch = None
+                    block.exits[0].exitcase = None
+
 
 def transform_graph(ann):
     """Apply set of transformations available."""
     if ann.translator:
         ann.translator.checkgraphs()
+    transform_dead_code(ann)
     transform_allocate(ann)
     transform_slice(ann)
     ##transform_listextend(ann)



More information about the Pypy-commit mailing list