Author: Hakan Ardo <[email protected]>
Branch: jit-short_from_state
Changeset: r45984:f4b02767e294
Date: 2011-07-24 21:22 +0200
http://bitbucket.org/pypy/pypy/changeset/f4b02767e294/
Log: generalize the renaming of result boxes on conflicts to support all
kind of ops in the short preamble, not only setfields
diff --git a/pypy/jit/metainterp/optimizeopt/heap.py
b/pypy/jit/metainterp/optimizeopt/heap.py
--- a/pypy/jit/metainterp/optimizeopt/heap.py
+++ b/pypy/jit/metainterp/optimizeopt/heap.py
@@ -125,15 +125,9 @@
if op and structvalue in self._cached_fields:
if op.getopnum() == rop.SETFIELD_GC:
result = op.getarg(1)
- if result in shortboxes.potential_ops and \
- shortboxes.potential_ops[result] is None:
- newresult = result.clonebox()
- optimizer.make_equal_to(newresult,
optimizer.getvalue(result))
- result = newresult
- # XXX this will not allow for chains of operations
getop = ResOperation(rop.GETFIELD_GC, [op.getarg(0)],
result, op.getdescr())
- shortboxes.add_potential(getop)
+ getop = shortboxes.add_potential(getop)
self._cached_fields_getfield_op[structvalue] = getop
self._cached_fields[structvalue] =
optimizer.getvalue(result)
elif op.result is not None:
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -899,8 +899,6 @@
setfield_gc(p3, i2, descr=nextdescr)
# XXX: VIRTUALHEAP (see above)
i3 = getfield_gc(p3, descr=nextdescr)
- i7 = int_is_true(i3)
- guard_true(i7) []
jump(p3, i3)
"""
self.optimize_loop(ops, expected, preamble)
@@ -2009,15 +2007,14 @@
guard_true(i3) []
i4 = int_neg(i2)
setfield_gc(p1, i2, descr=valuedescr)
- jump(p1, i1, i2, i4)
- """
- expected = """
- [p1, i1, i2, i4]
+ jump(p1, i1, i2, i4, i4)
+ """
+ expected = """
+ [p1, i1, i2, i4, i5]
setfield_gc(p1, i1, descr=valuedescr)
guard_true(i4) []
- i5 = int_neg(i2)
setfield_gc(p1, i2, descr=valuedescr)
- jump(p1, i1, i2, i5)
+ jump(p1, i1, i2, i5, i5)
"""
self.optimize_loop(ops, expected, preamble)
@@ -2040,15 +2037,14 @@
i4 = int_neg(i2)
setfield_gc(p1, NULL, descr=nextdescr)
escape()
- jump(p1, i2, i4)
- """
- expected = """
- [p1, i2, i4]
+ jump(p1, i2, i4, i4)
+ """
+ expected = """
+ [p1, i2, i4, i5]
guard_true(i4) [p1]
- i5 = int_neg(i2)
setfield_gc(p1, NULL, descr=nextdescr)
escape()
- jump(p1, i2, i5)
+ jump(p1, i2, i5, i5)
"""
self.optimize_loop(ops, expected, preamble)
@@ -2070,15 +2066,14 @@
i4 = int_neg(i2)
setfield_gc(p1, NULL, descr=nextdescr)
escape()
- jump(p1, i2, i4)
- """
- expected = """
- [p1, i2, i4]
+ jump(p1, i2, i4, i4)
+ """
+ expected = """
+ [p1, i2, i4, i5]
guard_true(i4) [i2, p1]
- i5 = int_neg(i2)
setfield_gc(p1, NULL, descr=nextdescr)
escape()
- jump(p1, i2, i5)
+ jump(p1, i2, i5, i5)
"""
self.optimize_loop(ops, expected)
@@ -2094,15 +2089,22 @@
setfield_gc(p1, i2, descr=valuedescr)
jump(p1, i1, i2, i4)
"""
- preamble = ops
- expected = """
- [p1, i1, i2, i4]
+ preamble = """
+ [p1, i1, i2, i3]
+ setfield_gc(p1, i1, descr=valuedescr)
+ i5 = int_eq(i3, 5)
+ guard_true(i5) []
+ i4 = int_neg(i2)
+ setfield_gc(p1, i2, descr=valuedescr)
+ jump(p1, i1, i2, i4, i4)
+ """
+ expected = """
+ [p1, i1, i2, i4, i7]
setfield_gc(p1, i1, descr=valuedescr)
i5 = int_eq(i4, 5)
guard_true(i5) []
- i7 = int_neg(i2)
setfield_gc(p1, i2, descr=valuedescr)
- jump(p1, i1, i2, i7)
+ jump(p1, i1, i2, i7, i7)
"""
self.optimize_loop(ops, expected, preamble)
@@ -2323,13 +2325,12 @@
jump(p1, i2, i4, p4)
"""
expected = """
- [p1, i2, i4, p4]
+ [p1, i2, i4, p4, i5]
guard_true(i4) [p1, p4]
- i5 = int_neg(i2)
p2 = new_with_vtable(ConstClass(node_vtable))
setfield_gc(p2, p4, descr=nextdescr)
setfield_gc(p1, p2, descr=nextdescr)
- jump(p1, i2, i5, p4)
+ jump(p1, i2, i5, p4, i5)
"""
self.optimize_loop(ops, expected, preamble)
@@ -5205,7 +5206,6 @@
"""
expected = """
[p0]
- p1 = getfield_gc(p0, descr=valuedescr)
setfield_gc(p0, p0, descr=valuedescr)
jump(p0)
"""
@@ -6216,12 +6216,25 @@
p25 = getfield_gc(ConstPtr(myptr), descr=otherdescr)
jump(p25, p187, i184)
"""
- expected = """
- [p25, p187, i184]
- jump(p25, p187, i184)
- """
- self.optimize_loop(ops, expected, ops)
- # FIXME: check jumparg 0 == getfield_gc()
+ preamble = """
+ [p1, p187, i184]
+ p188 = getarrayitem_gc(p187, 42, descr=<GcPtrArrayDescr>)
+ guard_value(p188, ConstPtr(myptr)) []
+ p25 = getfield_gc(ConstPtr(myptr), descr=otherdescr)
+ jump(p25, p187, i184, p25)
+ """
+ short = """
+ [p1, p187, i184]
+ p188 = getarrayitem_gc(p187, 42, descr=<GcPtrArrayDescr>)
+ guard_value(p188, ConstPtr(myptr)) []
+ p25 = getfield_gc(ConstPtr(myptr), descr=otherdescr)
+ jump(p1, p187, i184, p25)
+ """
+ expected = """
+ [p25, p187, i184, p189]
+ jump(p189, p187, i184, p189)
+ """
+ self.optimize_loop(ops, expected, preamble, expected_short=short)
def test_constant_getfield1bis(self):
ops = """
@@ -6305,9 +6318,11 @@
self.optimize_loop(ops, expected)
def test_dont_cache_setfields(self):
- # Caching the last two getfields here would specialize the loop to the
state where
- # the first two getfields return the same value. This state needs to
be guarded for
- # in the short preamble.
+ # Naivly caching the last two getfields here would specialize
+ # the loop to the state where the first two getfields return
+ # the same value. That state would need to be guarded for
+ # in the short preamble. Instead we make sure to keep the
+ # results of the two getfields as separate boxes.
ops = """
[p0, p1, ii, ii2]
i1 = getfield_gc(p0, descr=valuedescr)
@@ -6319,14 +6334,21 @@
i5 = getfield_gc(p1, descr=otherdescr)
jump(p0, p1, ii2, ii)
"""
- expected = """
+ preamble = """
[p0, p1, ii, ii2]
i1 = getfield_gc(p0, descr=valuedescr)
i2 = getfield_gc(p1, descr=otherdescr)
i3 = int_add(i1, i2)
setfield_gc(p0, ii, descr=valuedescr)
setfield_gc(p1, ii, descr=otherdescr)
- jump(p0, p1, ii2, ii)
+ jump(p0, p1, ii2, ii, ii, ii)
+ """
+ expected = """
+ [p0, p1, ii, ii2, i1, i2]
+ i3 = int_add(i1, i2)
+ setfield_gc(p0, ii, descr=valuedescr)
+ setfield_gc(p1, ii, descr=otherdescr)
+ jump(p0, p1, ii2, ii, ii, ii)
"""
self.optimize_loop(ops, expected)
@@ -6743,6 +6765,22 @@
"""
self.optimize_loop(ops, expected)
+ def test_keep_getfields_and_inputargs_separate(self):
+ ops = """
+ [p0]
+ call(p0, descr=nonwritedescr)
+ p1 = getfield_gc(ConstPtr(myptr), descr=nextdescr)
+ call(p1, descr=writeadescr)
+ jump(p1)
+ """
+ expected = """
+ [p0, p1]
+ call(p0, descr=nonwritedescr)
+ call(p1, descr=writeadescr)
+ jump(p1, p1)
+ """
+ self.optimize_loop(ops, expected)
+
class TestLLtype(OptimizeOptTest, LLtypeMixin):
pass
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py
b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -209,7 +209,7 @@
debug_print('inputargs: ' + args)
args = ", ".join([logops.repr_of_arg(arg) for arg in
short_inputargs])
debug_print('short inputargs: ' + args)
- self.short_boxes.debug_print(logops)
+ self.short_boxes.debug_print(logops)
# Force virtuals amoung the jump_args of the preamble to get the
# operations needed to setup the proper state of those virtuals
@@ -249,7 +249,7 @@
newresult =
self.optimizer.getvalue(op.result).get_key_box()
if newresult is not op.result:
self.short_boxes.alias(newresult, op.result)
-
+
self.optimizer.flush()
self.optimizer.emitting_dissabled = False
@@ -268,7 +268,8 @@
# preamble_optimizer.send_extra_operation(jumpop)
# return
loop.inputargs = inputargs
- args = [self.short_boxes.original(a) for a in inputargs]
+ args =
[preamble_optimizer.getvalue(self.short_boxes.original(a)).force_box()\
+ for a in inputargs]
jmp = ResOperation(rop.JUMP, args, None)
jmp.setdescr(loop.token)
loop.preamble.operations.append(jmp)
@@ -376,29 +377,29 @@
i = j = 0
- while i < len(self.optimizer.newoperations):
- op = self.optimizer.newoperations[i]
-
- self.boxes_created_this_iteration[op.result] = True
- args = op.getarglist()
- if op.is_guard():
- args = args + op.getfailargs()
-
- if self.optimizer.loop.logops:
- debug_print('OP: ' +
self.optimizer.loop.logops.repr_of_resop(op))
- for a in args:
- if self.optimizer.loop.logops:
- debug_print('A: ' +
self.optimizer.loop.logops.repr_of_arg(a))
- self.import_box(a, inputargs, short, short_jumpargs,
- jumpargs, short_seen)
- i += 1
-
+ while i < len(self.optimizer.newoperations) or j < len(jumpargs):
if i == len(self.optimizer.newoperations):
while j < len(jumpargs):
a = jumpargs[j]
self.import_box(a, inputargs, short, short_jumpargs,
jumpargs, short_seen)
j += 1
+ else:
+ op = self.optimizer.newoperations[i]
+
+ self.boxes_created_this_iteration[op.result] = True
+ args = op.getarglist()
+ if op.is_guard():
+ args = args + op.getfailargs()
+
+ if self.optimizer.loop.logops:
+ debug_print('OP: ' +
self.optimizer.loop.logops.repr_of_resop(op))
+ for a in args:
+ if self.optimizer.loop.logops:
+ debug_print('A: ' +
self.optimizer.loop.logops.repr_of_arg(a))
+ self.import_box(a, inputargs, short, short_jumpargs,
+ jumpargs, short_seen)
+ i += 1
jumpop.initarglist(jumpargs)
self.optimizer.send_extra_operation(jumpop)
@@ -445,6 +446,7 @@
return self.short_inliner.inline_arg(op.result)
else:
return None
+
for a in op.getarglist():
if not isinstance(a, Const) and a not in short_seen:
self.add_op_to_short(self.short_boxes.producer(a), short,
short_seen,
@@ -479,7 +481,6 @@
def import_box(self, box, inputargs, short, short_jumpargs,
jumpargs, short_seen):
-
if isinstance(box, Const) or box in inputargs:
return
if box in self.boxes_created_this_iteration:
diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py
b/pypy/jit/metainterp/optimizeopt/virtualstate.py
--- a/pypy/jit/metainterp/optimizeopt/virtualstate.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py
@@ -456,12 +456,14 @@
class ShortBoxes(object):
def __init__(self, optimizer, surviving_boxes):
self.potential_ops = {}
+ self.duplicates = {}
+ self.optimizer = optimizer
+ for box in surviving_boxes:
+ self.potential_ops[box] = None
optimizer.produce_potential_short_preamble_ops(self)
self.aliases = {}
self.short_boxes = {}
- for box in surviving_boxes:
- self.short_boxes[box] = None
for box in self.potential_ops.keys():
try:
@@ -476,14 +478,30 @@
return
if box in self.potential_ops:
op = self.potential_ops[box]
- for arg in op.getarglist():
- self.produce_short_preamble_box(arg)
+ if op:
+ for arg in op.getarglist():
+ self.produce_short_preamble_box(arg)
self.short_boxes[box] = op
else:
raise BoxNotProducable
def add_potential(self, op):
- self.potential_ops[op.result] = op
+ if op.result not in self.potential_ops:
+ self.potential_ops[op.result] = op
+ return op
+ newop = op.clone()
+ newop.result = op.result.clonebox()
+ self.potential_ops[newop.result] = newop
+ if op.result in self.duplicates:
+ self.duplicates[op.result].append(newop.result)
+ else:
+ self.duplicates[op.result] = [newop.result]
+ self.optimizer.send_extra_operation(newop)
+ if newop.is_ovf():
+ guard = ResOperation(rop.GUARD_NO_OVERFLOW, [], None)
+ self.optimizer.send_extra_operation(guard)
+ return newop
+
def debug_print(self, logops):
debug_start('jit-short-boxes')
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit