[pypy-commit] pypy optresult-unroll: (fijal, arigo, plan_rich) fix test_dont_specialize_on_boxes_equal

fijal noreply at buildbot.pypy.org
Wed Aug 12 16:34:21 CEST 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult-unroll
Changeset: r78932:09e29a495996
Date: 2015-08-12 12:50 +0200
http://bitbucket.org/pypy/pypy/changeset/09e29a495996/

Log:	(fijal, arigo, plan_rich) fix test_dont_specialize_on_boxes_equal

diff --git a/rpython/jit/metainterp/optimizeopt/shortpreamble.py b/rpython/jit/metainterp/optimizeopt/shortpreamble.py
--- a/rpython/jit/metainterp/optimizeopt/shortpreamble.py
+++ b/rpython/jit/metainterp/optimizeopt/shortpreamble.py
@@ -62,6 +62,20 @@
             assert index >= 0
             opinfo.setitem(index, self.res, pop, optheap=optheap)
 
+    def add_op_to_short(self, sb):
+        sop = self.getfield_op
+        preamble_arg = sb.produce_arg(sop.getarg(0))
+        if preamble_arg is None:
+            return None
+        if sop.is_getfield():
+            preamble_op = ResOperation(sop.getopnum(), [preamble_arg],
+                                       descr=sop.getdescr())
+        else:
+            preamble_op = ResOperation(sop.getopnum(), [preamble_arg,
+                                                        sop.getarg(1)],
+                                       descr=sop.getdescr())
+        return ProducedShortOp(self, preamble_op)
+
     def __repr__(self):
         return "HeapOp(%r)" % (self.res,)
 
@@ -79,6 +93,17 @@
         else:
             opt.pure(op.getopnum(), PreambleOp(op, preamble_op))
 
+    def add_op_to_short(self, sb):
+        op = self.res
+        arglist = []
+        for arg in op.getarglist():
+            newarg = sb.produce_arg(arg)
+            if newarg is None:
+                return None
+            arglist.append(newarg)
+        return ProducedShortOp(self, op.copy_and_change(op.getopnum(),
+                                                        args=arglist))
+
     def __repr__(self):
         return "PureOp(%r)" % (self.res,)
 
@@ -94,9 +119,39 @@
         key = make_hashable_int(op.getarg(0).getint())
         optrewrite.loop_invariant_results[key] = PreambleOp(op, preamble_op)
 
+    def add_op_to_short(self, sb):
+        op = self.res
+        arglist = []
+        for arg in op.getarglist():
+            newarg = sb.produce_arg(arg)
+            if newarg is None:
+                return None
+            arglist.append(newarg)
+        opnum = OpHelpers.call_loopinvariant_for_descr(op.getdescr())
+        return ProducedShortOp(self, op.copy_and_change(opnum, args=arglist))
+
     def __repr__(self):
         return "LoopInvariantOp(%r)" % (self.res,)
 
+class CompoundOp(AbstractShortOp):
+    def __init__(self, res, one, two):
+        self.res = res
+        self.one = one
+        self.two = two
+
+    def flatten(self, sb, l):
+        pop = self.one.add_op_to_short(sb)
+        if pop is not None:
+            l.append(pop)
+        two = self.two
+        if isinstance(two, CompoundOp):
+            two.flatten(sb, l)
+        else:
+            pop = two.add_op_to_short(sb)
+            if pop is not None:
+                l.append(pop)
+        return l
+
 class AbstractProducedShortOp(object):
     pass
 
@@ -111,6 +166,9 @@
     def __repr__(self):
         return "%r -> %r" % (self.short_op, self.preamble_op)
 
+dummy_short_op = ProducedShortOp(None, None)
+
+
 class ShortInputArg(AbstractProducedShortOp):
     def __init__(self, preamble_op):
         self.preamble_op = preamble_op
@@ -131,6 +189,7 @@
         # of AbstractShortOp
         self.potential_ops = {}
         self.produced_short_boxes = {}
+        self.extra_short_boxes = {}
         # a way to produce const boxes, e.g. setfield_gc(p0, Const).
         # We need to remember those, but they don't produce any new boxes
         self.const_short_boxes = []
@@ -151,8 +210,9 @@
             self.add_op_to_short(shortop)
         #
         for op, produced_op in self.produced_short_boxes.iteritems():
-            if isinstance(produced_op, ProducedShortOp):
+            if not isinstance(produced_op, ShortInputArg):
                 short_boxes.append(produced_op)
+        short_boxes += self.extra_short_boxes
 
         for short_op in self.const_short_boxes:
             getfield_op = short_op.getfield_op
@@ -173,7 +233,7 @@
         elif isinstance(op, Const):
             return op
         elif op in self.potential_ops:
-            return self.add_op_to_short(self.potential_ops[op])
+            return self.add_op_to_short(self.potential_ops[op]).preamble_op
         else:
             return None
 
@@ -182,37 +242,26 @@
             return # already added due to dependencies
         self.boxes_in_production[shortop.res] = None
         try:
-            op = shortop.res
-            if isinstance(shortop, HeapOp):
-                sop = shortop.getfield_op
-                preamble_arg = self.produce_arg(sop.getarg(0))
-                if preamble_arg is None:
-                    return None
-                if sop.is_getfield():
-                    preamble_op = ResOperation(sop.getopnum(), [preamble_arg],
-                                               descr=sop.getdescr())
+            if isinstance(shortop, CompoundOp):
+                lst = shortop.flatten(self, [])
+                if len(lst) == 1:
+                    pop = lst[0]
                 else:
-                    preamble_op = ResOperation(sop.getopnum(), [preamble_arg,
-                                                                sop.getarg(1)],
-                                               descr=sop.getdescr())
+                    pop = lst[0]
+                    for i in range(1, len(lst)):
+                        opnum = OpHelpers.same_as_for_type(shortop.res.type)
+                        new_name = ResOperation(opnum, [shortop.res])
+                        assert lst[i].short_op is not pop.short_op
+                        lst[i].short_op.res = new_name
+                        self.produced_short_boxes[new_name] = lst[i]
             else:
-                arglist = []
-                for arg in op.getarglist():
-                    newarg = self.produce_arg(arg)
-                    if newarg is None:
-                        return None
-                    arglist.append(newarg)
-                if isinstance(shortop, PureOp):
-                    opnum = op.getopnum()
-                else:
-                    opnum = OpHelpers.call_loopinvariant_for_descr(
-                        op.getdescr())
-                preamble_op = op.copy_and_change(opnum, args=arglist)
-            self.produced_short_boxes[op] = ProducedShortOp(shortop,
-                                                            preamble_op)
+                pop = shortop.add_op_to_short(self)
+            if pop is None:
+                return
+            self.produced_short_boxes[shortop.res] = pop
         finally:
             del self.boxes_in_production[shortop.res]
-        return preamble_op
+        return pop
 
     def create_short_inputargs(self, label_args):
         short_inpargs = []
@@ -226,18 +275,26 @@
                 short_inpargs.append(inparg.preamble_op)
         return short_inpargs
 
+    def add_potential_op(self, op, pop):
+        prev_op = self.potential_ops.get(op, None)
+        if prev_op is None:
+            self.potential_ops[op] = pop
+            return
+        self.potential_ops[op] = CompoundOp(op, pop, prev_op)
+
     def add_pure_op(self, op):
-        self.potential_ops[op] = PureOp(op)
+        assert op not in self.potential_ops
+        self.add_potential_op(op, PureOp(op))
 
     def add_loopinvariant_op(self, op):
-        self.potential_ops[op] = LoopInvariantOp(op)
+        self.add_potential_op(op, LoopInvariantOp(op))
 
     def add_heap_op(self, op, getfield_op):
         # or an inputarg
         if isinstance(op, Const) or op in self.produced_short_boxes:
             self.const_short_boxes.append(HeapOp(op, getfield_op))
             return # we should not be called from anywhere
-        self.potential_ops[op] = HeapOp(op, getfield_op)
+        self.add_potential_op(op, HeapOp(op, getfield_op))
 
 class EmptyInfo(info.AbstractInfo):
     pass
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -3678,7 +3678,6 @@
         '''
         expected = '''
         [p1, i4, i3]
-        setfield_gc(p1, i3, descr=valuedescr)
         jump(p1, i3, i3)
         '''
         preamble = '''
@@ -3704,7 +3703,6 @@
         '''
         expected = '''
         [p1, i4, i3]
-        setfield_gc(p1, i3, descr=valuedescr)
         jump(p1, i3, i3)
         '''
         preamble = '''
@@ -3747,7 +3745,7 @@
         i3 = call_i(p1, descr=elidable3calldescr)
         guard_no_exception() []
         setfield_gc(p1, i3, descr=valuedescr)
-        i167 = same_as(i3)
+        i167 = same_as_i(i3)
         jump(p1, i4, i3)
         '''
         self.optimize_loop(ops, expected, preamble)
@@ -3770,7 +3768,7 @@
         [p1, i1, i4]
         setfield_gc(p1, i1, descr=valuedescr)
         i3 = call_i(p1, descr=elidablecalldescr)
-        i151 = same_as(i3)
+        i151 = same_as_i(i3)
         jump(p1, i4, i3, i151)
         '''
         self.optimize_loop(ops, expected, preamble)
@@ -7388,7 +7386,7 @@
         setfield_gc(p1, ii, descr=otherdescr)
         jump(p0, p1, ii2, ii, ii, ii)
         """
-        self.optimize_loop(ops, expected)
+        self.optimize_loop(ops, expected, preamble)
 
     def test_dont_specialize_on_boxes_equal(self):
         ops = """
@@ -7396,7 +7394,7 @@
         i1 = getfield_gc_i(p0, descr=valuedescr)
         i2 = getfield_gc_i(p1, descr=chardescr)
         setfield_gc(p3, i1, descr=adescr)
-        setfield_gc(p3, i2, descr=bdescr)
+        setfield_gc(p3, i2, descr=abisdescr)
         i4 = int_eq(i1, i2)
         guard_true(i4) []
         i5 = int_gt(ii, 42)
@@ -7406,7 +7404,7 @@
         expected = """
         [p0, p1, p3, ii, ii2, i1, i2]
         setfield_gc(p3, i1, descr=adescr)
-        setfield_gc(p3, i2, descr=bdescr)
+        setfield_gc(p3, i2, descr=abisdescr)
         i5 = int_gt(ii, 42)
         guard_true(i5) []
         jump(p0, p1, p3, ii2, ii, i1, i2)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -172,9 +172,11 @@
     floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float))
 
     # a GcStruct not inheriting from OBJECT
-    S = lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('b', lltype.Ptr(NODE)))
+    S = lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('abis', lltype.Signed),
+                        ('b', lltype.Ptr(NODE)))
     ssize = cpu.sizeof(S, False)
     adescr = cpu.fielddescrof(S, 'a')
+    abisdescr = cpu.fielddescrof(S, 'abis')
     bdescr = cpu.fielddescrof(S, 'b')
     #sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)))
     arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S)))


More information about the pypy-commit mailing list