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