Author: Hakan Ardo <ha...@debian.org>
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
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to