[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