[pypy-commit] pypy vecopt-merge: saving of accum state more explicit

plan_rich noreply at buildbot.pypy.org
Sun Aug 23 15:14:45 CEST 2015


Author: Richard Plangger <rich at pasra.at>
Branch: vecopt-merge
Changeset: r79156:caedfb3ee99b
Date: 2015-08-23 15:14 +0200
http://bitbucket.org/pypy/pypy/changeset/caedfb3ee99b/

Log:	saving of accum state more explicit

diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -3,7 +3,7 @@
 from rpython.jit.backend.llsupport.symbolic import WORD
 from rpython.jit.backend.llsupport.codemap import CodemapBuilder
 from rpython.jit.metainterp.history import (INT, REF, FLOAT, VECTOR,
-    JitCellToken, ConstInt, BoxInt, AbstractFailDescr)
+    JitCellToken, ConstInt, BoxInt, AbstractFailDescr, BoxVector)
 from rpython.jit.metainterp.resoperation import ResOperation, rop
 from rpython.rlib import rgc
 from rpython.rlib.debug import (debug_start, debug_stop, have_debug_prints_for,
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -10,7 +10,6 @@
 from rpython.jit.metainterp.history import (Const, Box, VOID,
     BoxVector, ConstInt)
 from rpython.jit.metainterp.history import AbstractFailDescr, INT, REF, FLOAT
-from rpython.jit.metainterp.compile import CompileLoopVersionDescr
 from rpython.rtyper.lltypesystem import lltype, rffi, rstr, llmemory
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref
@@ -600,12 +599,12 @@
         # at the end of self.mc.
         for tok in self.pending_guard_tokens:
             descr = tok.faildescr
-            if not isinstance(descr, CompileLoopVersionDescr):
+            if descr.loop_version():
+                startpos = self.mc.get_relative_pos()
+                self.store_info_on_descr(startpos, tok)
+            else:
                 regalloc.position = tok.position
                 tok.pos_recovery_stub = self.generate_quick_failure(tok, regalloc)
-            else:
-                startpos = self.mc.get_relative_pos()
-                self.store_info_on_descr(startpos, tok)
         if WORD == 8 and len(self.pending_memoryerror_trampoline_from) > 0:
             self.error_trampoline_64 = self.generate_propagate_error_64()
 
diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -27,6 +27,7 @@
     FLOAT, VECTOR, TargetToken)
 from rpython.jit.metainterp.resoperation import rop, ResOperation
 from rpython.jit.metainterp.compile import ResumeGuardDescr
+from rpython.jit.metainterp.resume import AccumInfo
 from rpython.rlib import rgc
 from rpython.rlib.objectmodel import we_are_translated
 from rpython.rlib.rarithmetic import r_longlong, r_uint
@@ -320,37 +321,20 @@
                 continue
             accum = arg.getaccum()
             if accum:
+                # for an accumulator store the position of the original
+                # box and in llsupport/assembler save restore information
+                # on the descriptor
                 loc = self.loc(accum.getoriginalbox())
                 faillocs.append(loc)
-                self.update_accumulation_loc(arg, accum, descr, i)
+                descr.rd_accum_list = AccumInfo(descr.rd_accum_list,
+                                                i, accum.operator,
+                                                accum.getoriginalbox(),
+                                                self.loc(arg))
             else:
                 faillocs.append(self.loc(arg))
 
         return faillocs
 
-    def update_accumulation_loc(self, arg, accum, descr, pos):
-        """
-        Faillocs saved on the guard can only represent one value.
-        Accumulation has the accumulation box which need to updated uppon
-        guard exit. The fail descr saves where (regloc) the accumulator
-        is located.
-        """
-        assert isinstance(descr, ResumeGuardDescr)
-        accum_info = descr.rd_accum_list
-        count = 0
-        while accum_info:
-            if accum_info.box is accum.getoriginalbox():
-                accum_info.loc = self.loc(arg)
-                accum_info.position = pos
-                break
-            count += 1
-            accum_info = accum_info.prev
-        else:
-            msg = "[accumulator] %d accumulators, none matched box %s" % (count, accum_info.box)
-            print msg
-            import pdb; pdb.set_trace()
-            not_implemented(msg)
-
     def perform_with_guard(self, op, guard_op, arglocs, result_loc):
         faillocs = self.locs_for_fail(guard_op)
         self.rm.position += 1
diff --git a/rpython/jit/backend/x86/vector_ext.py b/rpython/jit/backend/x86/vector_ext.py
--- a/rpython/jit/backend/x86/vector_ext.py
+++ b/rpython/jit/backend/x86/vector_ext.py
@@ -84,19 +84,19 @@
         assert regalloc is not None
         accum_info = faildescr.rd_accum_list
         while accum_info:
-            pos = accum_info.position
-            loc = accum_info.loc
-            tgtloc = fail_locs[pos]
+            pos = accum_info.scalar_position
+            scalar_loc = fail_locs[pos]
+            vector_loc = accum_info.vector_loc
             # the upper elements will be lost if saved to the stack!
-            assert isinstance(loc, RegLoc)
-            if not isinstance(tgtloc, RegLoc):
-                tgtloc = regalloc.force_allocate_reg(accum_info.box)
-            arg = accum_info.box
-            assert arg is not None
-            if accum_info.operation == '+':
-                self._accum_reduce_sum(arg, loc, tgtloc)
-            elif accum_info.operation == '*':
-                self._accum_reduce_mul(arg, loc, tgtloc)
+            scalar_arg = accum_info.scalar_box
+            assert isinstance(vector_loc, RegLoc)
+            if not isinstance(scalar_loc, RegLoc):
+                scalar_loc = regalloc.force_allocate_reg(scalar_arg)
+            assert scalar_arg is not None
+            if accum_info.accum_operation == '+':
+                self._accum_reduce_sum(scalar_arg, vector_loc, scalar_loc)
+            elif accum_info.accum_operation == '*':
+                self._accum_reduce_mul(scalar_arg, vector_loc, scalar_loc)
             else:
                 not_implemented("accum operator %s not implemented" %
                                             (accum_info.operation)) 
diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -550,13 +550,6 @@
     def accumulates_value(self):
         return True
 
-    def save_to_descr(self, descr, position):
-        from rpython.jit.metainterp.compile import ResumeGuardDescr
-        from rpython.jit.metainterp.resume import AccumInfo
-        assert isinstance(descr, ResumeGuardDescr)
-        ai = AccumInfo(descr.rd_accum_list, position, self.operator, self.var)
-        descr.rd_accum_list = ai
-
 class BoxVector(Box):
     type = VECTOR
     _attrs_ = ('item_type','item_count','item_size','item_signed','accum')
@@ -819,7 +812,7 @@
         token = TargetToken(jitcell_token)
         token.original_jitcell_token = jitcell_token
         all_target_tokens.append(token)
-        if label.getdescr() is not jump.getdescr():
+        if label.getdescr() is None or label.getdescr() is not jump.getdescr():
             label_index = index_of_first(rop.LABEL, self.operations, 1)
             if label_index > 0:
                 second_label = self.operations[label_index]
diff --git a/rpython/jit/metainterp/optimizeopt/guard.py b/rpython/jit/metainterp/optimizeopt/guard.py
--- a/rpython/jit/metainterp/optimizeopt/guard.py
+++ b/rpython/jit/metainterp/optimizeopt/guard.py
@@ -213,6 +213,7 @@
         if len(others) > 0: # (2)
             replaced = False
             for i,other in enumerate(others):
+                assert guard is not other
                 if guard.implies(other, self):
                     # strengthend
                     others[i] = guard
@@ -223,6 +224,7 @@
                     continue
                 elif other.implies(guard, self):
                     # implied
+                    guard.rd_accum_list = None
                     self.guards[guard.index] = None # mark as 'do not emit'
                     replaced = True
                     continue
@@ -300,6 +302,7 @@
             for other in guards[1:]:
                 transitive_guard = one.transitive_imply(other, self, loop)
                 if transitive_guard:
+                    transitive_guard.rd_accum_list = None
                     other.set_to_none(loop.operations)
                     root_version.register_guard(transitive_guard, version)
 
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py b/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
@@ -1412,8 +1412,19 @@
         guard_false(i33, descr=<ResumeGuardFalseDescr object at 0x7f89c54cddc0>) [p1, p0, p6, p7, i29, None, None]
         jump(p0, p1, p6, p7, i29, p14, p15)
         """        
-        #opt = self.schedule(self.parse_loop(trace))
-        #self.debug_print_operations(opt.loop)
+        trace = """
+        [p0, p1, p6, p7, p8, p11, p13, p15, i46, f43, i32, i36, i40]
+        i51 = int_lt(i46, i32)
+        guard_true(i51, descr=<Guard0x7fa98ec2b780>) [p1, p0, p15, p6, p7, p8, p11, p13, f43, i46]
+        i52 = int_lt(i46, i36)
+        guard_true(i52, descr=<Guard0x7fa98ec2b7d8>) [p1, p0, p11, i46, p6, p7, p8, p13, p15, f43, None]
+        f54 = getarrayitem_raw(i40, i46, descr=floatarraydescr)
+        f55 = float_add(f43, f54)
+        i56 = int_add(i46, 1)
+        jump(p0, p1, p6, p7, p8, p11, p13, p15, i56, f55, i32, i36, i40)
+        """
+        opt = self.schedule(self.parse_loop(trace))
+        self.debug_print_operations(opt.loop)
 
 class TestLLtype(BaseTestVectorize, LLtypeMixin):
     pass
diff --git a/rpython/jit/metainterp/optimizeopt/vectorize.py b/rpython/jit/metainterp/optimizeopt/vectorize.py
--- a/rpython/jit/metainterp/optimizeopt/vectorize.py
+++ b/rpython/jit/metainterp/optimizeopt/vectorize.py
@@ -509,15 +509,16 @@
                 # this needs to be done for renamed (accum arguments)
                 version.renamed_inputargs = [ renamer.rename_map.get(arg,arg) for arg in version.inputargs ]
             self.appended_arg_count = len(sched_data.invariant_vector_vars)
-            for guard_node in self.dependency_graph.guards:
-                op = guard_node.getoperation()
-                failargs = op.getfailargs()
-                for i,arg in enumerate(failargs):
-                    if arg is None:
-                        continue
-                    accum = arg.getaccum()
-                    if accum:
-                        accum.save_to_descr(op.getdescr(),i)
+            #for guard_node in self.dependency_graph.guards:
+            #    op = guard_node.getoperation()
+            #    failargs = op.getfailargs()
+            #    for i,arg in enumerate(failargs):
+            #        if arg is None:
+            #            continue
+            #        accum = arg.getaccum()
+            #        if accum:
+            #            pass
+            #            #accum.save_to_descr(op.getdescr(),i)
             self.has_two_labels = len(sched_data.invariant_oplist) > 0
             self.loop.operations = self.prepend_invariant_operations(sched_data)
         else:
diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py
--- a/rpython/jit/metainterp/resume.py
+++ b/rpython/jit/metainterp/resume.py
@@ -35,13 +35,20 @@
         self.pc = pc
 
 class AccumInfo(object):
-    __slots__ = ('prev', 'position', 'operation', 'box', 'loc')
-    def __init__(self, prev, position, operation, box):
+    __slots__ = ('prev', 'accum_operation', 'scalar_position', 'scalar_box', 'vector_loc')
+    def __init__(self, prev, position, operation, box, loc):
         self.prev = prev
-        self.operation = operation
-        self.position = position
-        self.box = box
-        self.loc = None
+        self.accum_operation = operation
+        self.scalar_position = position
+        self.scalar_box = box
+        self.vector_loc = loc
+
+    def __repr__(self):
+        return 'AccumInfo(%s,%s,%s,%s,%s)' % (self.prev is None,
+                                              self.accum_operation,
+                                              self.scalar_position,
+                                              self.scalar_box,
+                                              self.vector_loc)
 
 def _ensure_parent_resumedata(framestack, n):
     target = framestack[n]
diff --git a/rpython/jit/metainterp/test/test_vectorize.py b/rpython/jit/metainterp/test/test_vectorize.py
--- a/rpython/jit/metainterp/test/test_vectorize.py
+++ b/rpython/jit/metainterp/test/test_vectorize.py
@@ -220,8 +220,9 @@
         res = self.meta_interp(f, [60,58.4547])
         assert res == f(60,58.4547) == 58.4547
 
-    def test_accum(self):
-        myjitdriver = JitDriver(greens = [], reds = 'auto', vectorize=True)
+    @py.test.mark.parametrize('vec,vec_all',[(False,True),(True,False),(True,True),(False,False)])
+    def test_accum(self, vec, vec_all):
+        myjitdriver = JitDriver(greens = [], reds = 'auto', vectorize=vec)
         T = lltype.Array(rffi.DOUBLE)
         def f(d, value):
             va = lltype.malloc(T, d, flavor='raw', zero=True)
@@ -239,7 +240,7 @@
                 i += 1
             lltype.free(va, flavor='raw')
             return r
-        res = self.meta_interp(f, [60,0.5], vec=True)
+        res = self.meta_interp(f, [60,0.5], vec=vec, vec_all=vec_all)
         assert res == f(60,0.5) == 60*0.5
 
 


More information about the pypy-commit mailing list