[pypy-commit] pypy stm-thread-2: Detect potential aliases and revert objects from the 'R' category

arigo noreply at buildbot.pypy.org
Sun Sep 2 16:19:41 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-thread-2
Changeset: r57081:11a7dcfce12e
Date: 2012-09-02 16:09 +0200
http://bitbucket.org/pypy/pypy/changeset/11a7dcfce12e/

Log:	Detect potential aliases and revert objects from the 'R' category to
	the 'O' category.

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
@@ -32,9 +32,11 @@
             if graphinfo is None or not graphinfo.is_fresh_malloc(op.args[0]):
                 return frozenset([
                     ("struct", op.args[0].concretetype, op.args[1].value)])
-        elif op.opname == "setarrayitem":
+        elif op.opname == ("setarrayitem", "setinteriorfield"):
             if graphinfo is None or not graphinfo.is_fresh_malloc(op.args[0]):
                 return self._array_result(op.args[0].concretetype)
+        elif op.opname == "gc_store":
+            return top_set    # xxx conservative
         return empty_set
 
     def _array_result(self, TYPE):
diff --git a/pypy/translator/stm/test/test_transform2.py b/pypy/translator/stm/test/test_transform2.py
--- a/pypy/translator/stm/test/test_transform2.py
+++ b/pypy/translator/stm/test/test_transform2.py
@@ -18,7 +18,6 @@
 
 
 class BaseTestTransform(object):
-    prebuilt = ()
 
     def build_state(self):
         self.writemode = set()
@@ -29,8 +28,8 @@
             return p._category
         if not p:
             return 'N'
-        if p in self.prebuilt:
-            return 'G'
+        if p._solid:
+            return 'G'     # allocated with immortal=True
         raise AssertionError("unknown category on %r" % (p,))
 
     def interpret(self, fn, args):
@@ -92,7 +91,6 @@
         x1.foo = 42
         x2 = lltype.malloc(X, immortal=True)
         x2.foo = 81
-        self.prebuilt = [x1, x2]
 
         def f1(n):
             if n > 1:
@@ -112,7 +110,6 @@
         X = lltype.GcStruct('X', ('foo', lltype.Signed))
         x1 = lltype.malloc(X, immortal=True)
         x1.foo = 42
-        self.prebuilt = [x1]
 
         def f1(n):
             x1.foo = n
@@ -131,7 +128,6 @@
         x2 = lltype.malloc(X, immortal=True)
         x2.foo = 81
         x2.bar = -1
-        self.prebuilt = [x1, x2]
 
         def f1(n):
             if n > 1:
@@ -153,3 +149,35 @@
         self.interpret(f1, [4])
         assert len(self.writemode) == 1
         assert self.barriers == []
+
+    def test_write_may_alias(self):
+        X = lltype.GcStruct('X', ('foo', lltype.Signed))
+        def f1(p, q):
+            x1 = p.foo
+            q.foo = 7
+            x2 = p.foo
+            return x1 * x2
+
+        x = lltype.malloc(X, immortal=True); x.foo = 6
+        y = lltype.malloc(X, immortal=True)
+        res = self.interpret(f1, [x, y])
+        assert res == 36
+        assert self.barriers == ['P2R', 'P2W', 'O2R']
+        res = self.interpret(f1, [x, x])
+        assert res == 42
+        assert self.barriers == ['P2R', 'P2W', 'O2R']
+
+    def test_write_cannot_alias(self):
+        X = lltype.GcStruct('X', ('foo', lltype.Signed))
+        Y = lltype.GcStruct('Y', ('foo', lltype.Signed))
+        def f1(p, q):
+            x1 = p.foo
+            q.foo = 7
+            x2 = p.foo
+            return x1 * x2
+
+        x = lltype.malloc(X, immortal=True); x.foo = 6
+        y = lltype.malloc(Y, immortal=True)
+        res = self.interpret(f1, [x, y])
+        assert res == 36
+        assert self.barriers == ['P2R', 'P2W']
diff --git a/pypy/translator/stm/transform2.py b/pypy/translator/stm/transform2.py
--- a/pypy/translator/stm/transform2.py
+++ b/pypy/translator/stm/transform2.py
@@ -2,6 +2,7 @@
 from pypy.objspace.flow.model import checkgraph
 from pypy.translator.unsimplify import varoftype
 from pypy.rpython.lltypesystem import lltype
+from pypy.translator.backendopt.writeanalyze import WriteAnalyzer, top_set
 
 
 
@@ -9,12 +10,13 @@
 
     def __init__(self, translator):
         self.translator = translator
+        self.write_analyzer = WriteAnalyzer(translator)
 
     def transform(self):
         assert not hasattr(self.translator, 'stm_transformation_applied')
         self.start_log()
         for graph in self.translator.graphs:
-            pre_insert_stm_barrier(self.translator, graph)
+            pre_insert_stm_barrier(self, graph)
         self.translator.stm_transformation_applied = True
         self.print_logs()
 
@@ -58,7 +60,10 @@
         return False
     raise AssertionError(op)
 
-def pre_insert_stm_barrier(translator, graph):
+
+def pre_insert_stm_barrier(stmtransformer, graph):
+    graphinfo = stmtransformer.write_analyzer.compute_graph_info(graph)
+
     for block in graph.iterblocks():
         if block.operations == ():
             continue
@@ -98,10 +103,23 @@
                         newoperations.append(newop)
                         renamings[op.args[0]] = w
                         category[w] = to
-                elif op.opname in MALLOCS:
-                    category[op.result] = 'W'
                 newop = SpaceOperation(op.opname,
                                        [renamings.get(v, v) for v in op.args],
                                        op.result)
                 newoperations.append(newop)
+                #
+                effectinfo = stmtransformer.write_analyzer.analyze(
+                    op, graphinfo=graphinfo)
+                if effectinfo:
+                    if effectinfo is top_set:
+                        category.clear()
+                    else:
+                        types = set([entry[1] for entry in effectinfo])
+                        for v in category.keys():
+                            if v.concretetype in types and category[v] == 'R':
+                                category[v] = 'O'
+                #
+                if op.opname in MALLOCS:
+                    category[op.result] = 'W'
+
             block.operations = newoperations


More information about the pypy-commit mailing list