[pypy-svn] pypy out-of-line-guards: Be a bit smarter in effectinfo.

fijal commits-noreply at bitbucket.org
Sun Jan 2 18:26:22 CET 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: out-of-line-guards
Changeset: r40328:9879e357a34b
Date: 2011-01-02 19:25 +0200
http://bitbucket.org/pypy/pypy/changeset/9879e357a34b/

Log:	Be a bit smarter in effectinfo.

	Essentially we consider that:

	def f(): a = A() a.x = 3 return a

	has no considerable side effects (indeed, nothing can be modified
	except newly create instance). Only works if malloc and set is
	within the same block.

diff --git a/pypy/translator/backendopt/test/test_writeanalyze.py b/pypy/translator/backendopt/test/test_writeanalyze.py
--- a/pypy/translator/backendopt/test/test_writeanalyze.py
+++ b/pypy/translator/backendopt/test/test_writeanalyze.py
@@ -268,11 +268,15 @@
             def f(self):
                 self.x = 1
                 return self.y
-        def h(flag):
+
+        def main(flag):
             obj = A(flag)
+            return h(obj)
+            
+        def h(obj):
             return obj.f()
         
-        t, wa = self.translate(h, [int])
+        t, wa = self.translate(main, [int])
         hgraph = graphof(t, h)
         op_call_f = hgraph.startblock.operations[-1]
 
@@ -291,6 +295,25 @@
         assert name2.endswith("x")
         assert T1 == T2
 
+    def test_not_really_read(self):
+        class A(object):
+            pass
+        
+        def h():
+            a = A()
+            a.x = 3
+            return a
+
+        def main():
+            return h()
+
+        t, wa = self.translate(main, [])
+        maingraph = graphof(t, main)
+        op = maingraph.startblock.operations[0]
+        assert op.opname == 'direct_call'
+        result = wa.analyze(op)
+        assert not result
+
     def test_contains(self):
         def g(x, y, z):
             l = [x]
@@ -314,14 +337,14 @@
         S = lltype.GcStruct('S', ('x', lltype.Signed),
                             adtmeths = {'yep': True,
                                         'callme': ll_callme})
-        def g(x, y, z):
-            p = lltype.malloc(S)
+        def g(p, x, y, z):
             p.x = x
             if p.yep:
                 z *= p.callme(y)
             return z
         def f(x, y, z):
-            return g(x, y, z)
+            p = lltype.malloc(S)
+            return g(p, x, y, z)
 
         t, wa = self.translate(f, [int, int, int])
         fgraph = graphof(t, f)

diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -8,6 +8,8 @@
 from pypy.rlib import jit
 
 class ModuleCell(object):
+    _jit_invariant_fields_ = ['w_value']
+    
     def __init__(self, w_value=None):
         self.w_value = w_value
 

diff --git a/pypy/translator/backendopt/writeanalyze.py b/pypy/translator/backendopt/writeanalyze.py
--- a/pypy/translator/backendopt/writeanalyze.py
+++ b/pypy/translator/backendopt/writeanalyze.py
@@ -6,11 +6,13 @@
 
 class WriteAnalyzer(graphanalyze.GraphAnalyzer):
 
+    def __init__(self, t):
+        graphanalyze.GraphAnalyzer.__init__(self, t)
+        self.fresh_items = set()
+
     @staticmethod
     def join_two_results(result1, result2):
-        if result1 is top_set:
-            return top_set
-        if result2 is top_set:
+        if result1 is top_set or result2 is top_set:
             return top_set
         return result1.union(result2)
 
@@ -27,7 +29,14 @@
         return result is top_set
 
     def analyze_simple_operation(self, op):
-        if op.opname in ("setfield", "oosetfield"):
+        if op.opname == 'malloc':
+            self.fresh_items.add(op.result)
+        elif op.opname == 'cast_pointer':
+            if op.args[0] in self.fresh_items:
+                self.fresh_items.add(op.result)
+        elif op.opname in ("setfield", "oosetfield"):
+            if op.args[0] in self.fresh_items:
+                return empty_set
             return frozenset([
                 ("struct", op.args[0].concretetype, op.args[1].value)])
         elif op.opname == "setarrayitem":


More information about the Pypy-commit mailing list