[pypy-commit] pypy stm-thread-2: Pointer comparison barrier.
arigo
noreply at buildbot.pypy.org
Sun Sep 2 17:02:29 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-thread-2
Changeset: r57083:4f4c1bd6a4d8
Date: 2012-09-02 17:02 +0200
http://bitbucket.org/pypy/pypy/changeset/4f4c1bd6a4d8/
Log: Pointer comparison barrier.
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
@@ -10,11 +10,15 @@
class _stmptr(lltype._ptr):
"""Like lltype._ptr, but also keeps a current category level"""
- __slots__ = ['_category']
+ __slots__ = ['_category', '_original_ptr']
def __init__(self, ptr, category):
lltype._ptr.__init__(self, ptr._TYPE, ptr._obj0, ptr._solid)
_stmptr._category.__set__(self, category)
+ _stmptr._original_ptr.__set__(self, ptr)
+
+ def __eq__(self, other):
+ return self._original_ptr == other
class BaseTestTransform(object):
@@ -68,6 +72,12 @@
self.llinterpreter.tester.barriers.append(kind)
return ptr2
+ def op_stm_ptr_eq(self, obj1, obj2):
+ self.check_category(obj1, 'P')
+ self.check_category(obj2, 'P')
+ self.llinterpreter.tester.barriers.append('=')
+ return obj1 == obj2
+
def op_getfield(self, obj, field):
self.check_category(obj, 'R')
return LLFrame.op_getfield(self, obj, field)
@@ -215,3 +225,54 @@
res = self.interpret(f1, [x])
assert res == 36
assert self.barriers == ['P2R']
+
+ def test_pointer_compare_0(self):
+ X = lltype.GcStruct('X', ('foo', lltype.Signed))
+ def f1(x):
+ return x != lltype.nullptr(X)
+ x = lltype.malloc(X, immortal=True)
+ res = self.interpret(f1, [x])
+ assert res == 1
+ assert self.barriers == []
+
+ def test_pointer_compare_1(self):
+ X = lltype.GcStruct('X', ('foo', lltype.Signed))
+ def f1(x, y):
+ return x != y
+ x = lltype.malloc(X, immortal=True)
+ y = lltype.malloc(X, immortal=True)
+ res = self.interpret(f1, [x, y])
+ assert res == 1
+ assert self.barriers == ['=']
+ res = self.interpret(f1, [x, x])
+ assert res == 0
+ assert self.barriers == ['=']
+
+ def test_pointer_compare_2(self):
+ X = lltype.GcStruct('X', ('foo', lltype.Signed))
+ def f1(x, y):
+ x.foo = 41
+ return x == y
+ x = lltype.malloc(X, immortal=True)
+ y = lltype.malloc(X, immortal=True)
+ res = self.interpret(f1, [x, y])
+ assert res == 0
+ assert self.barriers == ['P2W', '=']
+ res = self.interpret(f1, [x, x])
+ assert res == 1
+ assert self.barriers == ['P2W', '=']
+
+ def test_pointer_compare_4(self):
+ X = lltype.GcStruct('X', ('foo', lltype.Signed))
+ def f1(x, y):
+ x.foo = 40
+ y.foo = 41
+ return x != y
+ x = lltype.malloc(X, immortal=True)
+ y = lltype.malloc(X, immortal=True)
+ res = self.interpret(f1, [x, y])
+ assert res == 1
+ assert self.barriers == ['P2W', 'P2W']
+ res = self.interpret(f1, [x, x])
+ assert res == 0
+ assert self.barriers == ['P2W', '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
@@ -64,11 +64,20 @@
def pre_insert_stm_barrier(stmtransformer, graph):
graphinfo = stmtransformer.write_analyzer.compute_graph_info(graph)
+ def get_category(v):
+ if isinstance(v, Constant):
+ if v.value:
+ return 'G'
+ else:
+ return 'N' # NULL
+ return category.get(v, 'P')
+
for block in graph.iterblocks():
if block.operations == ():
continue
#
wants_a_barrier = {}
+ expand_comparison = set()
for op in block.operations:
if (op.opname in ('getfield', 'getarrayitem',
'getinteriorfield', 'gc_load') and
@@ -82,8 +91,11 @@
op.args[0].concretetype.TO._gckind == 'gc' and
not is_immutable(op)):
wants_a_barrier[op] = 'W'
+ elif (op.opname in ('ptr_eq', 'ptr_ne') and
+ op.args[0].concretetype.TO._gckind == 'gc'):
+ expand_comparison.add(op)
#
- if wants_a_barrier:
+ if wants_a_barrier or expand_comparison:
renamings = {}
category = {}
newoperations = []
@@ -92,10 +104,7 @@
if to is not None:
v = op.args[0]
v = renamings.get(v, v)
- if isinstance(v, Constant):
- frm = 'G'
- else:
- frm = category.get(v, 'P')
+ frm = get_category(v)
if frm not in MORE_PRECISE_CATEGORIES[to]:
c_info = Constant('%s2%s' % (frm, to), lltype.Void)
w = varoftype(v.concretetype)
@@ -103,11 +112,24 @@
newoperations.append(newop)
renamings[op.args[0]] = w
category[w] = to
+ #
newop = SpaceOperation(op.opname,
[renamings.get(v, v) for v in op.args],
op.result)
newoperations.append(newop)
#
+ if op in expand_comparison:
+ cats = ''.join([get_category(v) for v in newop.args])
+ if ('N' not in cats and
+ cats not in ('LL', 'LW', 'WL', 'WW')):
+ if newop.opname == 'ptr_ne':
+ v = varoftype(lltype.Bool)
+ negop = SpaceOperation('bool_not', [v],
+ newop.result)
+ newoperations.append(negop)
+ newop.result = v
+ newop.opname = 'stm_ptr_eq'
+ #
effectinfo = stmtransformer.write_analyzer.analyze(
op, graphinfo=graphinfo)
if effectinfo:
More information about the pypy-commit
mailing list