[pypy-commit] pypy optresult-unroll: (fijal, arigo, plan_rich) fix the handling of extra same_as and really test it in test_optimizeopt

fijal noreply at buildbot.pypy.org
Thu Aug 13 11:41:15 CEST 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult-unroll
Changeset: r78957:f5479d770a54
Date: 2015-08-13 11:41 +0200
http://bitbucket.org/pypy/pypy/changeset/f5479d770a54/

Log:	(fijal, arigo, plan_rich) fix the handling of extra same_as and
	really test it in test_optimizeopt

diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -250,7 +250,8 @@
                              descr=mid_descr_token)
     # XXX assign short preamble and virtual state
     loop_ops[-1].setdescr(mid_descr_token)
-    loop.operations = [start_label] + preamble_ops + [mid_label] + loop_ops
+    loop.operations = ([start_label] + preamble_ops + loop_info.extra_same_as +
+                       [mid_label] + loop_ops)
     loop.check_consistency()
     jitcell_token.all_target_tokens = [start_descr, mid_descr_token]
     send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop")
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
@@ -16,9 +16,10 @@
     See force_op_from_preamble for details how the extra things are put.
     """
     
-    def __init__(self, op, preamble_op):
+    def __init__(self, op, preamble_op, invented_name):
         self.op = op
         self.preamble_op = preamble_op
+        self.invented_name = invented_name
 
     def numargs(self):
         return self.op.numargs()
@@ -45,7 +46,7 @@
         self.res = res
         self.getfield_op = getfield_op
 
-    def produce_op(self, opt, preamble_op, exported_infos):
+    def produce_op(self, opt, preamble_op, exported_infos, invented_name):
         optheap = opt.optimizer.optheap
         if optheap is None:
             return
@@ -56,7 +57,7 @@
                                                 exported_infos[g.getarg(0)],
                                                 exported_infos)
         opinfo = opt.optimizer.ensure_ptr_info_arg0(g)
-        pop = PreambleOp(self.res, preamble_op)
+        pop = PreambleOp(self.res, preamble_op, invented_name)
         assert not opinfo.is_virtual()
         descr = self.getfield_op.getdescr()
         if g.is_getfield():
@@ -89,15 +90,17 @@
     def __init__(self, res):
         self.res = res
 
-    def produce_op(self, opt, preamble_op, exported_infos):
+    def produce_op(self, opt, preamble_op, exported_infos, invented_name):
         optpure = opt.optimizer.optpure
         if optpure is None:
             return
         op = self.res
         if preamble_op.is_call():
-            optpure.extra_call_pure.append(PreambleOp(op, preamble_op))
+            optpure.extra_call_pure.append(PreambleOp(op, preamble_op,
+                                                      invented_name))
         else:
-            opt.pure(op.getopnum(), PreambleOp(op, preamble_op))
+            opt.pure(op.getopnum(), PreambleOp(op, preamble_op,
+                                               invented_name))
 
     def add_op_to_short(self, sb):
         op = self.res
@@ -120,13 +123,14 @@
     def __init__(self, res):
         self.res = res
 
-    def produce_op(self, opt, preamble_op, exported_infos):
+    def produce_op(self, opt, preamble_op, exported_infos, invented_name):
         optrewrite = opt.optimizer.optrewrite
         if optrewrite is None:
             return
         op = self.res
         key = make_hashable_int(op.getarg(0).getint())
-        optrewrite.loop_invariant_results[key] = PreambleOp(op, preamble_op)
+        optrewrite.loop_invariant_results[key] = PreambleOp(op, preamble_op,
+                                                            invented_name)
 
     def add_op_to_short(self, sb):
         op = self.res
@@ -165,12 +169,15 @@
     pass
 
 class ProducedShortOp(AbstractProducedShortOp):
+    invented_name = False
+    
     def __init__(self, short_op, preamble_op):
         self.short_op = short_op
         self.preamble_op = preamble_op
 
     def produce_op(self, opt, exported_infos):
-        self.short_op.produce_op(opt, self.preamble_op, exported_infos)
+        self.short_op.produce_op(opt, self.preamble_op, exported_infos,
+                                 invented_name=self.invented_name)
 
     def __repr__(self):
         return "%r -> %r" % (self.short_op, self.preamble_op)
@@ -189,10 +196,9 @@
         return "INP(%r)" % (self.preamble_op,)
 
 class ShortBoxes(object):
-    def __init__(self):
-        #self.extra_same_as = []
-        pass
-
+    """ This is a container used for creating all the exported short
+    boxes from the preamble
+    """
     def create_short_boxes(self, optimizer, inputargs, label_args):
         # all the potential operations that can be produced, subclasses
         # of AbstractShortOp
@@ -272,6 +278,7 @@
                         new_name = ResOperation(opnum, [shortop.res])
                         assert lst[i].short_op is not pop.short_op
                         lst[i].short_op.res = new_name
+                        lst[i].invented_name = True
                         self.produced_short_boxes[new_name] = lst[i]
             else:
                 pop = shortop.add_op_to_short(self)
@@ -321,6 +328,10 @@
 empty_info = EmptyInfo()
 
 class ShortPreambleBuilder(object):
+    """ ShortPreambleBuilder is used during optimizing of the peeled loop,
+    starting from short_boxes exported from the preamble. It will build
+    the short preamble and necessary extra label arguments
+    """
     def __init__(self, short_boxes, short_inputargs, exported_infos,
                  optimizer=None):
         for produced_op in short_boxes:
@@ -336,6 +347,7 @@
         self.short = []
         self.used_boxes = []
         self.short_preamble_jump = []
+        self.extra_same_as = []
         self.short_inputargs = short_inputargs
 
     def use_box(self, box, preamble_op, optimizer=None):
@@ -363,6 +375,8 @@
         return preamble_op
 
     def add_preamble_op(self, preamble_op):
+        if preamble_op.invented_name:
+            self.extra_same_as.append(preamble_op.op)
         self.used_boxes.append(preamble_op.op)
         self.short_preamble_jump.append(preamble_op.preamble_op)
 
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
@@ -1159,8 +1159,7 @@
         i1 = getfield_gc_i(p0, descr=valuedescr)
         i2 = int_sub(i1, 1)
         i3 = int_add(i0, i1)
-        #i4 = same_as_i(i2) # This same_as should be killed by backend
-        jump(i3, i1, i2)
+        jump(i3, i2, i1)
         """
         expected = """
         [i0, i1bis, i1]
@@ -8654,5 +8653,34 @@
         """
         self.optimize_loop(ops, expected, preamble)
 
+    def test_unroll_two_boxes_used_differently(self):
+        ops = """
+        [p0, i0, i2]
+        i1 = int_add(i0, 1)
+        i3 = int_add(i1, i2)
+        i4 = getfield_gc_i(p0, descr=valuedescr)
+        escape_n(i4)
+        setfield_gc(p0, i1, descr=valuedescr)
+        jump(p0, i0, i3)
+        """
+        preamble = """
+        [p0, i0, i2]
+        i1 = int_add(i0, 1)
+        i3 = int_add(i1, i2)
+        i4 = getfield_gc_i(p0, descr=valuedescr)
+        escape_n(i4)
+        setfield_gc(p0, i1, descr=valuedescr)
+        ii = same_as_i(i1)
+        jump(p0, i0, i3, i1, ii)        
+        """
+        expected = """
+        [p0, i0, i2, i4, i5]
+        i3 = int_add(i4, i2)
+        escape_n(i5)
+        setfield_gc(p0, i4, descr=valuedescr)
+        jump(p0, i0, i3, i4, i4)
+        """
+        self.optimize_loop(ops, expected, preamble)
+
 class TestLLtype(OptimizeOptTest, LLtypeMixin):
     pass
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
@@ -474,9 +474,10 @@
         preamble = TreeLoop('preamble')
         preamble.inputargs = start_state.renamed_inputargs
         start_label = ResOperation(rop.LABEL, start_state.renamed_inputargs)
-        preamble.operations = [start_label] + preamble_ops
         inputargs = start_state.end_args + loop_info.extra_label_args
         emit_end_label = ResOperation(rop.LABEL, inputargs)
+        preamble.operations = ([start_label] + preamble_ops +
+                               loop_info.extra_same_as + [emit_end_label])
         loop.inputargs = inputargs
         loop.operations = [emit_end_label] + ops
         return Info(preamble, loop_info.short_preamble)
@@ -495,7 +496,8 @@
                       loop.operations
     if not jump:
         assert newloop.operations[-1].getopnum() == rop.JUMP
-        newloop.operations = newloop.operations[:-1]
+        newloop.operations[-1] = newloop.operations[-1].copy_and_change(
+            rop.LABEL)
     return newloop
 
 # ____________________________________________________________
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -124,7 +124,8 @@
         jump_op = ResOperation(rop.JUMP, jump_args)
         self.optimizer._newoperations.append(jump_op)
         return (UnrollInfo(self.short_preamble_producer.build_short_preamble(),
-                           used_boxes),
+                           used_boxes,
+                           self.short_preamble_producer.extra_same_as),
                 self.optimizer._newoperations)
 
     def filter_extra_jump_args(self, sp, jump_args, extra_jump_args):
@@ -222,10 +223,12 @@
 
     * short_preamble - list of operations that go into short preamble
     * extra_label_args - additional things to put in the label
+    * extra_same_as - list of extra same as to add at the end of the preamble
     """
-    def __init__(self, short_preamble, extra_label_args):
+    def __init__(self, short_preamble, extra_label_args, extra_same_as):
         self.short_preamble = short_preamble
         self.extra_label_args = extra_label_args
+        self.extra_same_as = extra_same_as
             
 class ExportedState(LoopInfo):
     """ Exported state consists of a few pieces of information:


More information about the pypy-commit mailing list