Author: Hakan Ardo <[email protected]>
Branch: jit-duplicated_short_boxes
Changeset: r46678:db795a41638f
Date: 2011-08-21 09:48 +0200
http://bitbucket.org/pypy/pypy/changeset/db795a41638f/
Log: propagate duplications of short boxes
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
@@ -476,6 +476,8 @@
except BoxNotProducable:
pass
+ self.duplicate_short_boxes_if_needed()
+
def produce_short_preamble_box(self, box):
if box in self.short_boxes:
return
@@ -494,9 +496,12 @@
if op.result not in self.potential_ops:
self.potential_ops[op.result] = op
return op
+ return self.duplicate(self.potential_ops, op)
+
+ def duplicate(self, destination, op):
newop = op.clone()
newop.result = op.result.clonebox()
- self.potential_ops[newop.result] = newop
+ destination[newop.result] = newop
if op.result in self.duplicates:
self.duplicates[op.result].append(newop.result)
else:
@@ -504,6 +509,32 @@
self.optimizer.make_equal_to(newop.result,
self.optimizer.getvalue(op.result))
return newop
+ def duplicate_short_boxes_if_needed(self):
+ may_need_duplication = {}
+ for op in self.short_boxes.values():
+ if op:
+ may_need_duplication[op] = True
+ while may_need_duplication:
+ op, _ = may_need_duplication.popitem()
+ self.maybe_duplicate_op(op, may_need_duplication)
+
+ def maybe_duplicate_op(self, op, may_need_duplication):
+ for arg in op.getarglist():
+ if arg in self.short_boxes:
+ producer = self.producer(arg)
+ if producer in may_need_duplication:
+ del may_need_duplication[producer]
+ self.maybe_duplicate_op(producer, may_need_duplication)
+ for i in range(len(op.getarglist())):
+ arg = op.getarg(i)
+ if arg in self.duplicates:
+ for box in self.duplicates[arg]:
+ if box in self.short_boxes:
+ newop = self.duplicate(self.short_boxes, op)
+ newop.setarg(i, box)
+ # XXX If more than one arg is duplicated this does not give
+ # all combinations as each argument is treated separately
+
def debug_print(self, logops):
debug_start('jit-short-boxes')
for box, op in self.short_boxes.items():
diff --git a/pypy/jit/metainterp/test/test_virtualstate.py
b/pypy/jit/metainterp/test/test_virtualstate.py
--- a/pypy/jit/metainterp/test/test_virtualstate.py
+++ b/pypy/jit/metainterp/test/test_virtualstate.py
@@ -1,7 +1,7 @@
import py
from pypy.jit.metainterp.optimize import InvalidLoop
from pypy.jit.metainterp.optimizeopt.virtualstate import VirtualStateInfo,
VStructStateInfo, \
- VArrayStateInfo, NotVirtualStateInfo, VirtualState
+ VArrayStateInfo, NotVirtualStateInfo, VirtualState, ShortBoxes
from pypy.jit.metainterp.optimizeopt.optimizer import OptValue
from pypy.jit.metainterp.history import BoxInt, BoxFloat, BoxPtr, ConstInt,
ConstPtr
from pypy.rpython.lltypesystem import lltype
@@ -10,6 +10,7 @@
from pypy.jit.metainterp.history import TreeLoop, LoopToken
from pypy.jit.metainterp.optimizeopt.test.test_optimizeopt import FakeDescr,
FakeMetaInterpStaticData
from pypy.jit.metainterp.optimize import RetraceLoop
+from pypy.jit.metainterp.resoperation import ResOperation, rop
class TestBasic:
someptr1 = LLtypeMixin.myptr
@@ -128,6 +129,7 @@
info.fieldstate = [info]
assert info.generalization_of(info, {}, {})
+
class BaseTestGenerateGuards(BaseTest):
def guards(self, info1, info2, box, expected):
info1.position = info2.position = 0
@@ -909,3 +911,88 @@
class TestLLtypeBridges(BaseTestBridges, LLtypeMixin):
pass
+class FakeOptimizer:
+ def make_equal_to(*args):
+ pass
+ def getvalue(*args):
+ pass
+
+class TestShortBoxes:
+ p1 = BoxPtr()
+ p2 = BoxPtr()
+ i1 = BoxInt()
+ i2 = BoxInt()
+ i3 = BoxInt()
+
+ def test_short_box_duplication_direct(self):
+ class Optimizer(FakeOptimizer):
+ def produce_potential_short_preamble_ops(_self, sb):
+ sb.add_potential(ResOperation(rop.GETFIELD_GC, [self.p1],
self.i1))
+ sb.add_potential(ResOperation(rop.GETFIELD_GC, [self.p2],
self.i1))
+ sb = ShortBoxes(Optimizer(), [self.p1, self.p2])
+ assert len(sb.short_boxes) == 4
+ assert self.i1 in sb.short_boxes
+ assert sum([op.result is self.i1 for op in sb.short_boxes.values() if
op]) == 1
+
+ def test_short_box_duplication_indirect1(self):
+ class Optimizer(FakeOptimizer):
+ def produce_potential_short_preamble_ops(_self, sb):
+ sb.add_potential(ResOperation(rop.GETFIELD_GC, [self.p1],
self.i1))
+ sb.add_potential(ResOperation(rop.GETFIELD_GC, [self.p2],
self.i1))
+ sb.add_potential(ResOperation(rop.INT_NEG, [self.i1], self.i2))
+ sb = ShortBoxes(Optimizer(), [self.p1, self.p2])
+ assert len(sb.short_boxes) == 6
+ for i in (self.i1, self.i2):
+ assert i in sb.short_boxes
+ assert sum([op.result is i for op in sb.short_boxes.values() if
op]) == 1
+ op1, op2 = [op for op in sb.short_boxes.values()
+ if op and op.getopnum() == rop.INT_NEG]
+ assert op1.result is not op2.result
+ pr1, pr2 = sb.producer(op1.getarg(0)), sb.producer(op2.getarg(0))
+ assert pr1 is not pr2
+ assert pr1.getopnum() == rop.GETFIELD_GC
+ assert pr2.getopnum() == rop.GETFIELD_GC
+ assert set([pr1.getarg(0), pr2.getarg(0)]) == set([self.p1, self.p2])
+
+ def test_short_box_duplication_indirect2(self):
+ class Optimizer(FakeOptimizer):
+ def produce_potential_short_preamble_ops(_self, sb):
+ sb.add_potential(ResOperation(rop.GETFIELD_GC, [self.p1],
self.i1))
+ sb.add_potential(ResOperation(rop.GETFIELD_GC, [self.p2],
self.i1))
+ sb.add_potential(ResOperation(rop.INT_NEG, [self.i1], self.i2))
+ sb.add_potential(ResOperation(rop.INT_ADD, [ConstInt(7),
self.i2],
+ self.i3))
+ sb = ShortBoxes(Optimizer(), [self.p1, self.p2])
+ assert len(sb.short_boxes) == 8
+ for i in (self.i1, self.i2):
+ assert i in sb.short_boxes
+ assert sum([op.result is i for op in sb.short_boxes.values() if
op]) == 1
+ op1, op2 = [op for op in sb.short_boxes.values()
+ if op and op.getopnum() == rop.INT_NEG]
+ assert op1.result is not op2.result
+ pr1, pr2 = sb.producer(op1.getarg(0)), sb.producer(op2.getarg(0))
+ assert pr1 is not pr2
+ assert pr1.getopnum() == rop.GETFIELD_GC
+ assert pr2.getopnum() == rop.GETFIELD_GC
+ assert set([pr1.getarg(0), pr2.getarg(0)]) == set([self.p1, self.p2])
+ op1, op2 = [op for op in sb.short_boxes.values()
+ if op and op.getopnum() == rop.INT_ADD]
+ assert op1.result is not op2.result
+ pr1, pr2 = sb.producer(op1.getarg(1)), sb.producer(op2.getarg(1))
+ assert pr1 is not pr2
+ assert pr1.getopnum() == rop.INT_NEG
+ assert pr2.getopnum() == rop.INT_NEG
+ negargs = set([pr1.getarg(0), pr2.getarg(0)])
+ assert len(negargs) == 2
+ assert self.i1 in negargs
+
+ def test_dont_duplicate_potential_boxes(self):
+ class Optimizer(FakeOptimizer):
+ def produce_potential_short_preamble_ops(_self, sb):
+ sb.add_potential(ResOperation(rop.GETFIELD_GC, [self.p1],
self.i1))
+ sb.add_potential(ResOperation(rop.GETFIELD_GC, [BoxPtr()],
self.i1))
+ sb.add_potential(ResOperation(rop.INT_NEG, [self.i1], self.i2))
+ sb.add_potential(ResOperation(rop.INT_ADD, [ConstInt(7),
self.i2],
+ self.i3))
+ sb = ShortBoxes(Optimizer(), [self.p1, self.p2])
+ assert len(sb.short_boxes) == 5
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit