Author: Richard Plangger <planri...@gmail.com>
Branch: vecopt-merge
Changeset: r80076:cbbff5a45632
Date: 2015-10-09 12:26 +0200
http://bitbucket.org/pypy/pypy/changeset/cbbff5a45632/

Log:    small refactoring towards unpacking vector elements after the guard
        has failed

diff --git a/rpython/jit/backend/llgraph/runner.py 
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -1061,20 +1061,20 @@
     # -----------------------------------------------------
 
     def _accumulate(self, descr, failargs, values):
-        accuminfo = descr.rd_accum_list
-        while accuminfo:
-            i = accuminfo.getpos_in_failargs()
+        info = descr.rd_vector_info
+        while info:
+            i = info.getpos_in_failargs()
             value = values[i]
             assert isinstance(value, list)
-            if accuminfo.accum_operation == '+':
+            if info.accum_operation == '+':
                 value = sum(value)
-            elif accuminfo.accum_operation == '*':
+            elif info.accum_operation == '*':
                 def prod(acc, x): return acc * x
                 value = reduce(prod, value, 1)
             else:
                 raise NotImplementedError("accum operator in fail guard")
             values[i] = value
-            accuminfo = accuminfo.next()
+            info = info.next()
 
     def fail_guard(self, descr, saved_data=None, extra_value=None):
         values = []
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
@@ -558,7 +558,7 @@
                                              self.current_clt.frame_info)
         self._check_frame_depth(self.mc, regalloc.get_gcmap())
         bridgestartpos = self.mc.get_relative_pos()
-        self._accum_update_at_exit(arglocs, inputargs, faildescr, regalloc)
+        self._update_at_exit(arglocs, inputargs, faildescr, regalloc)
         frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, 
operations)
         codeendpos = self.mc.get_relative_pos()
         self.write_pending_failure_recoveries(regalloc)
@@ -610,15 +610,15 @@
         guard_locs = self.rebuild_faillocs_from_descr(faildescr, 
version.inputargs)
         bridge_locs = self.rebuild_faillocs_from_descr(bridge_faildescr, 
version.inputargs)
         #import pdb; pdb.set_trace()
-        guard_accum_info = faildescr.rd_accum_list
+        guard_accum_info = faildescr.rd_vector_info
         # O(n^2), but usually you only have at most 1 fail argument
         while guard_accum_info:
-            bridge_accum_info = bridge_faildescr.rd_accum_list
+            bridge_accum_info = bridge_faildescr.rd_vector_info
             while bridge_accum_info:
-                if bridge_accum_info.scalar_position == 
guard_accum_info.scalar_position:
+                if bridge_accum_info.failargs_pos == 
guard_accum_info.failargs_pos:
                     # the mapping might be wrong!
-                    if bridge_accum_info.vector_loc is not 
guard_accum_info.vector_loc:
-                        self.mov(guard_accum_info.vector_loc, 
bridge_accum_info.vector_loc)
+                    if bridge_accum_info.location is not 
guard_accum_info.location:
+                        self.mov(guard_accum_info.location, 
bridge_accum_info.location)
                 bridge_accum_info = bridge_accum_info.next()
             guard_accum_info = guard_accum_info.next()
 
@@ -1876,8 +1876,8 @@
         self.mc.force_frame_size(DEFAULT_FRAME_BYTES)
         startpos = self.mc.get_relative_pos()
         #
-        self._accum_update_at_exit(guardtok.fail_locs, guardtok.failargs,
-                                   guardtok.faildescr, regalloc)
+        self._update_at_exit(guardtok.fail_locs, guardtok.failargs,
+                             guardtok.faildescr, regalloc)
         #
         fail_descr, target = self.store_info_on_descr(startpos, guardtok)
         self.mc.PUSH(imm(fail_descr))
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
@@ -322,10 +322,10 @@
         if not descr:
             return faillocs
         assert isinstance(descr, AbstractFailDescr)
-        if descr.rd_accum_list:
-            accuminfo = descr.rd_accum_list
+        if descr.rd_vector_info:
+            accuminfo = descr.rd_vector_info
             while accuminfo:
-                accuminfo.vector_loc = faillocs[accuminfo.getpos_in_failargs()]
+                accuminfo.location = faillocs[accuminfo.getpos_in_failargs()]
                 loc = self.loc(accuminfo.getoriginal())
                 faillocs[accuminfo.getpos_in_failargs()] = loc
                 accuminfo = accuminfo.next()
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
@@ -74,20 +74,20 @@
             index += 1
         self.mc.PBLENDW_xxi(loc.value, temp.value, select)
 
-    def _accum_update_at_exit(self, fail_locs, fail_args, faildescr, regalloc):
+    def _update_at_exit(self, fail_locs, fail_args, faildescr, regalloc):
         """ If accumulation is done in this loop, at the guard exit
             some vector registers must be adjusted to yield the correct value
         """
         if not isinstance(faildescr, ResumeGuardDescr):
             return
         assert regalloc is not None
-        accum_info = faildescr.rd_accum_list
+        accum_info = faildescr.rd_vector_info
         while accum_info:
-            pos = accum_info.scalar_position
+            pos = accum_info.getpos_in_failargs()
             scalar_loc = fail_locs[pos]
-            vector_loc = accum_info.vector_loc
+            vector_loc = accum_info.location
             # the upper elements will be lost if saved to the stack!
-            scalar_arg = accum_info.scalar_box
+            scalar_arg = accum_info.getoriginal()
             assert isinstance(vector_loc, RegLoc)
             if not isinstance(scalar_loc, RegLoc):
                 scalar_loc = regalloc.force_allocate_reg(scalar_arg)
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
@@ -687,17 +687,9 @@
     def clone(self):
         return self
 
-    def exits_early(self):
-        return False
-
-    def attach_accum_info(self, pos, operator, arg, loc):
-        self.rd_accum_list = \
-                AccumInfo(self.rd_accum_list, pos, operator, arg, loc)
-
     def copy_all_attributes_from(self, other):
         pass
 
-
 class AbstractResumeGuardDescr(ResumeDescr):
     _attrs_ = ('status',)
 
@@ -873,10 +865,10 @@
         self.rd_virtuals = other.rd_virtuals
         self.rd_numb = other.rd_numb
         # we don't copy status
-        if other.rd_accum_list:
-            self.rd_accum_list = other.rd_accum_list.clone()
+        if other.rd_vector_info:
+            self.rd_vector_info = other.rd_vector_info.clone()
         else:
-            other.rd_accum_list = None
+            other.rd_vector_info = None
 
     def store_final_boxes(self, guard_op, boxes, metainterp_sd):
         guard_op.setfailargs(boxes)
@@ -907,6 +899,11 @@
     def loop_version(self):
         return True
 
+    def clone(self):
+        cloned = CompileLoopVersionDescr()
+        cloned.copy_all_attributes_from(self)
+        return cloned
+
 class AllVirtuals:
     llopaque = True
     cache = None
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
@@ -146,9 +146,9 @@
     index = -1
     final_descr = False
 
-    _attrs_ = ('adr_jump_offset', 'rd_locs', 'rd_loop_token', 'rd_accum_list')
+    _attrs_ = ('adr_jump_offset', 'rd_locs', 'rd_loop_token', 'rd_vector_info')
 
-    rd_accum_list = None
+    rd_vector_info = None
 
     def handle_fail(self, deadframe, metainterp_sd, jitdriver_sd):
         raise NotImplementedError
@@ -164,6 +164,12 @@
         # compile a loop version out of this guard?
         return False
 
+    def attach_vector_info(self, info):
+        from rpython.jit.metainterp.resume import VectorInfo
+        assert isinstance(info, VectorInfo)
+        info.prev = self.rd_vector_info
+        self.rd_vector_info = info
+
 class BasicFinalDescr(AbstractFailDescr):
     final_descr = True
 
diff --git a/rpython/jit/metainterp/optimizeopt/dependency.py 
b/rpython/jit/metainterp/optimizeopt/dependency.py
--- a/rpython/jit/metainterp/optimizeopt/dependency.py
+++ b/rpython/jit/metainterp/optimizeopt/dependency.py
@@ -192,7 +192,7 @@
     def exits_early(self):
         if self.op.is_guard():
             descr = self.op.getdescr()
-            return isinstance(descr, compile.CompileLoopVersionDescr)
+            return descr.exits_early()
         return False
 
     def loads_from_complex_object(self):
@@ -713,7 +713,7 @@
         self.guard_argument_protection(guard_node, tracker)
         #
         descr = guard_op.getdescr()
-        if isinstance(descr, compile.CompileLoopVersionDescr):
+        if descr.exits_early():
             return
         # handle fail args
         if guard_op.getfailargs():
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
@@ -87,7 +87,7 @@
         # guard
         descr = CompileLoopVersionDescr()
         descr.copy_all_attributes_from(self.op.getdescr())
-        descr.rd_accum_list = None # do not copy the accum list
+        descr.rd_vector_info = None # do not copy the accum list
         assert isinstance(descr, ResumeGuardDescr)
         guard = ResOperation(self.op.getopnum(), [compare], descr=descr)
         guard.setfailargs(loop.label.getarglist_copy())
diff --git a/rpython/jit/metainterp/optimizeopt/schedule.py 
b/rpython/jit/metainterp/optimizeopt/schedule.py
--- a/rpython/jit/metainterp/optimizeopt/schedule.py
+++ b/rpython/jit/metainterp/optimizeopt/schedule.py
@@ -694,7 +694,8 @@
                     from rpython.jit.metainterp.compile import 
AbstractResumeGuardDescr
                     assert isinstance(accum, AccumPack)
                     assert isinstance(descr, AbstractResumeGuardDescr)
-                    descr.attach_accum_info(i, accum.operator, arg, None)
+                    info = AccumInfo(i, arg, accum.operator)
+                    descr.attach_vector_info(info)
                     seed = accum.getleftmostseed()
                     failargs[i] = self.renamer.rename_map.get(seed, seed)
 
diff --git a/rpython/jit/metainterp/optimizeopt/vector.py 
b/rpython/jit/metainterp/optimizeopt/vector.py
--- a/rpython/jit/metainterp/optimizeopt/vector.py
+++ b/rpython/jit/metainterp/optimizeopt/vector.py
@@ -10,7 +10,6 @@
 
 from rpython.jit.metainterp.resume import Snapshot
 from rpython.jit.metainterp.jitexc import NotAVectorizeableLoop, 
NotAProfitableLoop
-#from rpython.jit.metainterp.optimizeopt.unroll import optimize_unroll
 from rpython.jit.metainterp.compile import (CompileLoopVersionDescr, 
ResumeDescr)
 from rpython.jit.metainterp.history import (INT, FLOAT, VECTOR, ConstInt, 
ConstFloat,
         TargetToken, JitCellToken, AbstractFailDescr)
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
@@ -34,38 +34,67 @@
         self.jitcode = jitcode
         self.pc = pc
 
-class AccumInfo(object):
-    _attrs_ = ('prev', 'accum_operation', 'scalar_position', 'scalar_box', 
'vector_loc')
+class VectorInfo(object):
+    """
+        prev: the previous VectorInfo or None
+        failargs_pos: the index where to find it in the fail arguments
+        location: the register location (an integer), specified by the backend
+        variable: the original variable that lived at failargs_pos
+    """
+    _attrs_ = ('prev', 'failargs_pos', 'location', 'variable')
+    prev = None
+    failargs_pos = -1
+    location = None
+    variable = None
 
-    def __init__(self, prev, position, operation, box, loc):
-        self.prev = prev
-        self.accum_operation = operation
-        self.scalar_position = position
-        self.scalar_box = box
-        self.vector_loc = loc
-
-    def getoriginal(self):
-        return self.scalar_box
+    def __init__(self, position, variable):
+        self.failargs_pos = position
+        self.variable = variable
 
     def getpos_in_failargs(self):
-        return self.scalar_position
+        return self.failargs_pos
 
     def next(self):
         return self.prev
 
+    def getoriginal(self):
+        return self.variable
+
     def clone(self):
         prev = None
         if self.prev:
             prev = self.prev.clone()
-        return AccumInfo(prev, self.scalar_position, self.accum_operation,
-                         self.scalar_box, None)
+        return self.instance_clone(prev)
+
+    def instance_clone(self, prev):
+        raise NotImplementedError
+
+class UnpackAtExitInfo(VectorInfo):
+    def instance_clone(self, prev):
+        info = UnpackAtExitInfo(self.failargs_pos, self.variable)
+        info.prev = prev
+        return info
+
+class AccumInfo(VectorInfo):
+    _attrs_ = ('accum_operation', 'scalar')
+
+    def __init__(self, position, variable, operation):
+        VectorInfo.__init__(self, position, variable)
+        self.accum_operation = operation
+
+    def instance_clone(self, prev):
+        info = AccumInfo(self.failargs_pos, self.variable,
+                         self.accum_operation)
+        info.location = self.location
+        info.prev = prev
+        return info
 
     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)
+                                              self.failargs_pos,
+                                              self.variable,
+                                              self.location)
 
 def _ensure_parent_resumedata(framestack, n):
     target = framestack[n]
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to