[pypy-commit] pypy vecopt-merge: half of the llgraph tests pass again, need to push through the rest of the unported stuff and tweaking the thing here and there

plan_rich noreply at buildbot.pypy.org
Tue Sep 22 17:09:28 CEST 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: vecopt-merge
Changeset: r79769:9169c6da92d4
Date: 2015-09-22 17:09 +0200
http://bitbucket.org/pypy/pypy/changeset/9169c6da92d4/

Log:	half of the llgraph tests pass again, need to push through the rest
	of the unported stuff and tweaking the thing here and there

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
@@ -861,28 +861,36 @@
     def bh_vec_int_signext(self, vx, ext):
         return [heaptracker.int_signext(_vx, ext) for _vx in vx]
 
-    def bh_vec_getarrayitem_raw(self, struct, offset, count, descr):
-        values = []
-        for i in range(count):
-            val = self.bh_getarrayitem_raw(struct, offset + i, descr)
-            values.append(val)
-        return values
+    def build_getarrayitem(func):
+        def method(self, struct, offset, descr):
+            values = []
+            count = self.vector_register_size // descr.get_item_size_in_bytes()
+            assert count > 0
+            for i in range(count):
+                val = func(self, struct, offset + i, descr)
+                values.append(val)
+            return values
+        return method
 
-    def bh_vec_getarrayitem_gc(self, struct, offset, count, descr):
-        values = []
-        for i in range(count):
-            val = self.bh_getarrayitem_gc(struct, offset + i, descr)
-            values.append(val)
-        return values
+    bh_vec_getarrayitem_gc_i = build_getarrayitem(bh_getarrayitem_gc)
+    bh_vec_getarrayitem_gc_f = build_getarrayitem(bh_getarrayitem_gc)
+    bh_vec_getarrayitem_raw_i = build_getarrayitem(bh_getarrayitem_raw)
+    bh_vec_getarrayitem_raw_f = build_getarrayitem(bh_getarrayitem_raw)
+    del build_getarrayitem
 
-    def bh_vec_raw_load(self, struct, offset, count, descr):
+    def _bh_vec_raw_load(self, struct, offset, descr):
         values = []
         stride = descr.get_item_size_in_bytes()
+        count = self.vector_register_size // descr.get_item_size_in_bytes()
+        assert count > 0
         for i in range(count):
             val = self.bh_raw_load(struct, offset + i*stride, descr)
             values.append(val)
         return values
 
+    bh_vec_raw_load_i = _bh_vec_raw_load
+    bh_vec_raw_load_f = _bh_vec_raw_load
+
     def bh_vec_raw_store(self, struct, offset, newvalues, descr):
         stride = descr.get_item_size_in_bytes()
         for i,n in enumerate(newvalues):
@@ -944,7 +952,17 @@
         return hash(self)
 
     def setenv(self, box, arg):
-        if box.type == INT:
+        if box.is_vector():
+            if box.datatype == INT:
+                _type = lltype.Signed
+                for i,a in enumerate(arg):
+                    if isinstance(a, bool):
+                        arg[i] = int(a) 
+            elif box.datatype == FLOAT:
+                _type = longlong.FLOATSTORAGE
+            else:
+                raise AssertionError(box)
+        elif box.type == INT:
             # typecheck the result
             if isinstance(arg, bool):
                 arg = int(arg)
@@ -953,16 +971,6 @@
             assert lltype.typeOf(arg) == llmemory.GCREF
         elif box.type == FLOAT:
             assert lltype.typeOf(arg) == longlong.FLOATSTORAGE
-        elif box.type == VECTOR:
-            if box.item_type == INT:
-                _type = lltype.Signed
-                for i,a in enumerate(arg):
-                    if isinstance(a, bool):
-                        arg[i] = int(a) 
-            elif box.item_type == FLOAT:
-                _type = longlong.FLOATSTORAGE
-            else:
-                raise AssertionError(box)
         else:
             raise AssertionError(box)
         #
@@ -1013,12 +1021,9 @@
     # -----------------------------------------------------
 
     def _accumulate(self, descr, failargs, values):
-        for i,box in enumerate(self.current_op.getfailargs()):
-            if box is None:
-                continue
-            accum = box.getaccum()
-            if not accum:
-                continue
+        accuminfo = descr.rd_accum_list
+        while accuminfo:
+            i = accuminfo.getpos_in_failargs()
             value = values[i]
             assert isinstance(value, list)
             if accum.operator == '+':
@@ -1029,6 +1034,7 @@
             else:
                 raise NotImplementedError("accum operator in fail guard")
             values[i] = value
+            accuminfo = accuminfo.next()
 
     def fail_guard(self, descr, saved_data=None):
         values = []
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
@@ -18,7 +18,6 @@
 from rpython.jit.metainterp.resume import NUMBERING, PENDINGFIELDSP, ResumeDataDirectReader
 from rpython.jit.codewriter import heaptracker, longlong
 
-
 def giveup():
     from rpython.jit.metainterp.pyjitpl import SwitchToBlackhole
     raise SwitchToBlackhole(Counters.ABORT_BRIDGE)
@@ -149,7 +148,6 @@
     loop = TreeLoop(name_prefix + name)
     return loop
 
-
 def make_jitcell_token(jitdriver_sd):
     jitcell_token = JitCellToken()
     jitcell_token.outermost_jitdriver_sd = jitdriver_sd
@@ -324,55 +322,14 @@
             label_token.short_preamble, metainterp.box_names_memo)
     loop.operations = ([start_label] + preamble_ops + loop_info.extra_same_as +
                        [loop_info.label_op] + loop_ops)
-    if loop.versions is not None:
-        # every different loop version must update their target tokens
-        for version in loop.versions:
-            version.update_token(jitcell_token, all_target_tokens)
     if not we_are_translated():
         loop.check_consistency()
     send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, "loop",
                          inputargs, metainterp.box_names_memo)
-
     record_loop_or_bridge(metainterp_sd, loop)
-    generate_pending_loop_versions(loop, jitdriver_sd, metainterp, jitcell_token)
+    loop_info.post_loop_compilation(loop, jitdriver_sd, metainterp, jitcell_token)
     return start_descr
 
-def generate_pending_loop_versions(loop, jitdriver_sd, metainterp, jitcell_token):
-    """ if a loop version is created for a guard instruction (e.g. they are known
-        to fail frequently) then a version can be created that is immediatly compiled
-        and stitched to the guard.
-    """
-    metainterp_sd = metainterp.staticdata
-    cpu = metainterp_sd.cpu
-    if loop.versions:
-        # compile each version once for the first fail descr!
-        # this assumes that the root trace (= loop) is already compiled
-        compiled = {}
-        info = loop.version_info
-        for descr in info.descrs:
-            version = info.get(descr)
-            if not version:
-                # the guard might have been removed from the trace
-                continue
-            if version not in compiled:
-                assert isinstance(descr, ResumeGuardDescr)
-                vl = create_empty_loop(metainterp)
-                vl.inputargs = version.inputargs
-                vl.operations = version.operations
-                vl.original_jitcell_token = jitcell_token
-                asminfo = send_bridge_to_backend(jitdriver_sd, metainterp_sd,
-                                                 descr, version.inputargs,
-                                                 version.operations, jitcell_token)
-                record_loop_or_bridge(metainterp_sd, vl)
-                assert asminfo is not None
-                compiled[version] = (asminfo, descr, version, jitcell_token)
-            else:
-                param = compiled[version]
-                cpu.stitch_bridge(descr, param)
-
-    loop.versions = None
-    loop.version_info = None
-
 def compile_retrace(metainterp, greenkey, start,
                     inputargs, jumpargs,
                     partial_trace, resumekey, start_state):
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
@@ -501,7 +501,6 @@
 
     def __init__(self, name):
         self.name = name
-        self.versions = []
         # self.operations = list of ResOperations
         #   ops of the kind 'guard_xxx' contain a further list of operations,
         #   which may itself contain 'guard_xxx' and so on, making a tree.
@@ -520,31 +519,6 @@
             insns[opname] = insns.get(opname, 0) + 1
         return insns
 
-    # XXX VECdef append_loop(self, loop, all_target_tokens):
-    # XXX VEC    # append e.g. the peeled loop to this loop!
-    # XXX VEC    jump = loop.operations[-1]
-    # XXX VEC    assert jump.getdescr() is not None
-    # XXX VEC    target_token = None
-    # XXX VEC    i = 0
-    # XXX VEC    # adds all target token until the one is found that jumps from the 
-    # XXX VEC    # last instruction to the label
-    # XXX VEC    while i < len(loop.operations) and target_token is not jump.getdescr():
-    # XXX VEC        # there is another label
-    # XXX VEC        op = loop.operations[i]
-    # XXX VEC        if op.getopnum() == rop.LABEL:
-    # XXX VEC            target_token = op.getdescr()
-    # XXX VEC            assert isinstance(target_token, TargetToken)
-    # XXX VEC            all_target_tokens.append(target_token)
-    # XXX VEC        i += 1
-    # XXX VEC    #
-    # XXX VEC    self.operations = self.operations[:-1] + loop.operations
-    # XXX VEC    self.versions = loop.versions
-    # XXX VEC    loop.versions = None
-    # XXX VEC    self.version_info = loop.version_info
-    # XXX VEC    loop.version_info = None
-    # XXX VEC    if loop.quasi_immutable_deps:
-    # XXX VEC        self.quasi_immutable_deps.update(loop.quasi_immutable_deps)
-
     def get_operations(self):
         return self.operations
 
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
@@ -246,6 +246,7 @@
                         self.renamer.start_renaming(op, var)
                         continue
             self.emit_operation(op)
+        self.renamer.rename(loop.jump)
         #
         loop.operations = self._newoperations[:]
 
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -33,6 +33,9 @@
     def final(self):
         return True
 
+    def post_loop_compilation(self, loop, jitdriver_sd, metainterp, jitcell_token):
+        pass
+
 
 class Optimization(object):
     next_optimization = None
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
@@ -44,21 +44,39 @@
         self.jump = jump
         assert self.jump.getopnum() == rop.JUMP
 
-    def operation_list(self):
-        return [self.label] + self.operations + [self.jump]
-
-    def finaloplist(self):
+    def finaloplist(self, jitcell_token=None, label=False):
         oplist = []
+        if jitcell_token:
+            token = TargetToken(jitcell_token)
+            token.original_jitcell_token = jitcell_token
+            jitcell_token.target_tokens.append(token)
+            self.label.setdescr(token)
+            if self.prefix_label:
+                token = TargetToken(jitcell_token)
+                token.original_jitcell_token = jitcell_token
+                jitcell_token.target_tokens.append(token)
+                self.prefix_label.setdescr(token)
+            self.jump.setdescr(token)
         if self.prefix_label:
-            oplist = [self.prefix_label] + self.prefix
+            oplist = self.prefix + [self.prefix_label]
         elif self.prefix:
             oplist = self.prefix
+        if label:
+            oplist = [self.label] + oplist
         return oplist + self.operations + [self.jump]
 
-    def assemble_oplist(self):
-        oplist = self.prefix + [self.prefix_label] + \
-                 loop.operations + [loop.jump]
-        return oplist
+    def clone(self):
+        oplist = []
+        renamer = Renamer()
+        for op in self.operations:
+            newop = op.copy()
+            renamer.rename(newop)
+            if not newop.returns_void():
+                renamer.start_renaming(op, newop)
+            oplist.append(newop)
+        jump = self.jump.copy()
+        renamer.rename(jump)
+        return VectorLoop(self.label.copy(), oplist, jump)
 
 def optimize_vector(metainterp_sd, jitdriver_sd, warmstate, loop_info, loop_ops):
     """ Enter the world of SIMD. Bails if it cannot transform the trace. """
@@ -67,38 +85,37 @@
         return
     # the original loop (output of optimize_unroll)
     info = LoopVersionInfo(loop_info)
-    version = info.snapshot(loop_ops, info.label_op)
     loop = VectorLoop(loop_info.label_op, loop_ops[1:-1], loop_ops[-1])
+    version = info.snapshot(loop)
     try:
         debug_start("vec-opt-loop")
-        metainterp_sd.logger_noopt.log_loop([], loop.operation_list(), -2, None, None, "pre vectorize")
+        metainterp_sd.logger_noopt.log_loop([], loop.finaloplist(label=True), -2, None, None, "pre vectorize")
         metainterp_sd.profiler.count(Counters.OPT_VECTORIZE_TRY)
         #
         start = time.clock()
         opt = VectorizingOptimizer(metainterp_sd, jitdriver_sd, warmstate.vec_cost)
-        opt.propagate_all_forward(info, loop)
-        #
-        gso = GuardStrengthenOpt(opt.dependency_graph.index_vars, opt.has_two_labels)
+        index_vars = opt.propagate_all_forward(info, loop)
+        gso = GuardStrengthenOpt(index_vars)
         gso.propagate_all_forward(info, loop, user_code)
         end = time.clock()
         #
         metainterp_sd.profiler.count(Counters.OPT_VECTORIZED)
-        metainterp_sd.logger_noopt.log_loop([], loop.operation_list(), -2, None, None, "post vectorize")
-        #
+        metainterp_sd.logger_noopt.log_loop([], loop.finaloplist(label=True), -2, None, None, "post vectorize")
         nano = int((end-start)*10.0**9)
         debug_print("# vecopt factor: %d opcount: (%d -> %d) took %dns" % \
-                      (opt.unroll_count+1, len(version.operations), len(loop.operations), nano))
+                      (opt.unroll_count+1, len(version.loop.operations), len(loop.operations), nano))
         debug_stop("vec-opt-loop")
         #
-        return info, loop.assemble_oplist()
+        info.label_op = loop.label
+        return info, loop.finaloplist()
     except NotAVectorizeableLoop:
         debug_stop("vec-opt-loop")
         # vectorization is not possible
-        return loop_info, version.operations
+        return loop_info, version.loop.finaloplist()
     except NotAProfitableLoop:
         debug_stop("vec-opt-loop")
         # cost model says to skip this loop
-        return loop_info, version.operations
+        return loop_info, version.loop.finaloplist()
     except Exception as e:
         debug_stop("vec-opt-loop")
         debug_print("failed to vectorize loop. THIS IS A FATAL ERROR!")
@@ -162,10 +179,7 @@
         self.packset = None
         self.unroll_count = 0
         self.smallest_type_bytes = 0
-        self.sched_data = None
-        self.appended_arg_count = 0
         self.orig_label_args = None
-        self.has_two_labels = False
 
     def propagate_all_forward(self, info, loop):
         self.orig_label_args = loop.label.getarglist_copy()
@@ -198,10 +212,7 @@
         self.schedule(state)
         if not state.profitable():
             raise NotAProfitableLoop()
-
-    def emit_unrolled_operation(self, op):
-        self._last_emitted_op = op
-        self._newoperations.append(op)
+        return graph.index_vars
 
     def unroll_loop_iterations(self, loop, unroll_count):
         """ Unroll the loop X times. unroll_count + 1 = unroll_factor """
@@ -264,7 +275,6 @@
             value = renamer.rename_box(arg)
             loop.jump.setarg(i, value)
         #
-        #self.emit_unrolled_operation(jump_op)
         loop.operations = operations + unrolled
 
     def linear_find_smallest_type(self, loop):
@@ -304,15 +314,12 @@
             for node_b,memref_b in memory_refs:
                 if memref_a is memref_b:
                     continue
-                #print "???", memref_a.index_var, memref_b.index_var
                 # instead of compare every possible combination and
                 # exclue a_opidx == b_opidx only consider the ones
                 # that point forward:
                 if memref_a.is_adjacent_after(memref_b):
-                    print node_a.getindex(), "is after", node_b.getindex()
                     pair = self.packset.can_be_packed(node_a, node_b, None, False)
                     if pair:
-                        print "creating mem pair", pair
                         self.packset.add_pack(pair)
 
     def extend_packset(self):
@@ -357,13 +364,10 @@
 
     def follow_def_uses(self, pack):
         assert pack.numops() == 2
-        print "lprov", pack.leftmost(node=True).provides_count(),
-        print "rprov", pack.rightmost(node=True).provides_count()
         for ldep in pack.leftmost(node=True).provides():
             for rdep in pack.rightmost(node=True).provides():
                 lnode = ldep.to
                 rnode = rdep.to
-                print "trying", lnode.getindex(), rnode.getindex(), lnode, rnode
                 left = pack.leftmost()
                 args = lnode.getoperation().getarglist()
                 if left is None or left not in args:
@@ -372,10 +376,7 @@
                 if isomorph and lnode.is_before(rnode):
                     pair = self.packset.can_be_packed(lnode, rnode, pack, True)
                     if pair:
-                        print "creating pair" , pair, pair.operations[0].op, pair.operations[1].op
                         self.packset.add_pack(pair)
-                    else:
-                        print "!!!creating pair" , lnode, rnode
 
     def combine_packset(self):
         """ Combination is done iterating the packs that have
@@ -439,38 +440,38 @@
             return
         state.post_schedule()
 
-    def prepend_invariant_operations(self, sched_data):
-        """ Add invariant operations to the trace loop. returns the operation list
-            as first argument and a second a boolean value.
-        """
-        oplist = self._newoperations
+    #def prepend_invariant_operations(self, sched_data):
+    #    """ Add invariant operations to the trace loop. returns the operation list
+    #        as first argument and a second a boolean value.
+    #    """
+    #    oplist = self._newoperations
 
-        if len(sched_data.invariant_oplist) > 0:
-            label = oplist[0]
-            assert label.getopnum() == rop.LABEL
-            #
-            jump = oplist[-1]
-            assert jump.getopnum() == rop.JUMP
-            #
-            label_args = label.getarglist()[:]
-            jump_args = jump.getarglist()
-            for var in sched_data.invariant_vector_vars:
-                label_args.append(var)
-                jump_args.append(var)
-            #
-            # in case of any invariant_vector_vars, the label is restored
-            # and the invariant operations are added between the original label
-            # and the new label
-            descr = label.getdescr()
-            assert isinstance(descr, TargetToken)
-            token = TargetToken(descr.targeting_jitcell_token)
-            oplist[0] = label.copy_and_change(label.getopnum(), args=label_args, descr=token)
-            oplist[-1] = jump.copy_and_change(jump.getopnum(), args=jump_args, descr=token)
-            #
-            return [ResOperation(rop.LABEL, self.orig_label_args, None, descr)] + \
-                   sched_data.invariant_oplist + oplist
-        #
-        return oplist
+    #    if len(sched_data.invariant_oplist) > 0:
+    #        label = oplist[0]
+    #        assert label.getopnum() == rop.LABEL
+    #        #
+    #        jump = oplist[-1]
+    #        assert jump.getopnum() == rop.JUMP
+    #        #
+    #        label_args = label.getarglist()[:]
+    #        jump_args = jump.getarglist()
+    #        for var in sched_data.invariant_vector_vars:
+    #            label_args.append(var)
+    #            jump_args.append(var)
+    #        #
+    #        # in case of any invariant_vector_vars, the label is restored
+    #        # and the invariant operations are added between the original label
+    #        # and the new label
+    #        descr = label.getdescr()
+    #        assert isinstance(descr, TargetToken)
+    #        token = TargetToken(descr.targeting_jitcell_token)
+    #        oplist[0] = label.copy_and_change(label.getopnum(), args=label_args, descr=token)
+    #        oplist[-1] = jump.copy_and_change(jump.getopnum(), args=jump_args, descr=token)
+    #        #
+    #        return [ResOperation(rop.LABEL, self.orig_label_args, None, descr)] + \
+    #               sched_data.invariant_oplist + oplist
+    #    #
+    #    return oplist
 
     def analyse_index_calculations(self, loop):
         """ Tries to move guarding instructions an all the instructions that
@@ -586,7 +587,6 @@
             cost, benefit_factor = self.cb_signext(pack)
         #
         self.savings += benefit_factor * times - cost
-        print "$$$ recording", benefit_factor, "*", times, "-", cost, "now:", self.savings
 
     def cb_signext(self, pack):
         left = pack.leftmost()
@@ -606,10 +606,8 @@
         if src.datatype == FLOAT:
             if index == 1 and count == 1:
                 self.savings -= 2
-                print "$$$ vector pack -2 now:", self.savings
                 return
         self.savings -= count
-        print "$$$ vector pack ", count, "now", self.savings
 
     def record_vector_unpack(self, src, index, count):
         self.record_vector_pack(src, index, count)
@@ -799,16 +797,13 @@
         for i,pack in enumerate(self.packs):
             load = pack.pack_load(self.vec_reg_size)
             if load > Pack.FULL:
-                print "overloaded pack", pack
                 pack.split(newpacks, self.vec_reg_size)
                 continue
             if load < Pack.FULL:
-                print "underloaded pack", pack
                 for op in pack.operations:
                     op.priority = -100
                 pack.clear()
                 self.packs[i] = None
                 continue
-            print "fully packed", pack
         self.packs = [pack for pack in self.packs + newpacks if pack]
 
diff --git a/rpython/jit/metainterp/optimizeopt/version.py b/rpython/jit/metainterp/optimizeopt/version.py
--- a/rpython/jit/metainterp/optimizeopt/version.py
+++ b/rpython/jit/metainterp/optimizeopt/version.py
@@ -1,6 +1,9 @@
 
 from rpython.jit.metainterp.resoperation import rop
 from rpython.jit.metainterp.optimizeopt.optimizer import BasicLoopInfo
+from rpython.jit.metainterp.compile import (send_bridge_to_backend, record_loop_or_bridge,
+        ResumeGuardDescr, create_empty_loop)
+
 
 class LoopVersionInfo(BasicLoopInfo):
     def __init__(self, info):
@@ -40,21 +43,47 @@
         return self.leads_to.get(descr, None)
 
     def snapshot(self, loop):
-        operations = loop.finaloplist()
-        label = loop.label
-        oplist = []
-        ignore = (rop.DEBUG_MERGE_POINT,)
-        for op in operations:
-            if op.getopnum() in ignore:
-                continue
-            cloned = op.copy_and_change(op.getopnum())
-            oplist.append(cloned)
-        version = LoopVersion(oplist, label)
+        newloop = loop.clone()
+        version = LoopVersion(newloop)
         version.setup_once(self)
         self.versions.append(version)
         # register the faildescr for later stitching
         return version
 
+    def post_loop_compilation(self, loop, jitdriver_sd, metainterp, jitcell_token):
+        """ if a loop version is created for a guard instruction (e.g. they are known
+            to fail frequently) then a version can be created that is immediatly compiled
+            and stitched to the guard.
+        """
+        metainterp_sd = metainterp.staticdata
+        cpu = metainterp_sd.cpu
+        if not self.versions:
+            return
+        # compile each version once for the first fail descr!
+        # this assumes that the root trace (= loop) is already compiled
+        compiled = {}
+        for descr in self.descrs:
+            version = self.get(descr)
+            if not version:
+                # the guard might have been removed from the trace
+                continue
+            if version not in compiled:
+                assert isinstance(descr, ResumeGuardDescr)
+                vl = version.create_backend_loop(metainterp, jitcell_token)
+                asminfo = send_bridge_to_backend(jitdriver_sd, metainterp_sd,
+                                                 descr, vl.inputargs,
+                                                 vl.operations, jitcell_token,
+                                                 metainterp.box_names_memo)
+                record_loop_or_bridge(metainterp_sd, vl)
+                assert asminfo is not None
+                compiled[version] = (asminfo, descr, version, jitcell_token)
+            else:
+                param = compiled[version]
+                cpu.stitch_bridge(descr, param)
+
+        self.versions = None # dismiss versions
+
+
 class LoopVersion(object):
     """ A special version of a trace loop. Use loop.snaphost() to
         create one instance and attach it to a guard descr.
@@ -62,26 +91,26 @@
     """
     _attrs_ = ('label', 'operations', 'inputargs', 'renamed_inputargs')
 
-    def __init__(self, operations, label):
-        self.label = label
-        self.operations = operations
-        self.inputargs = label.getarglist()
-        self.renamed_inputargs = label.getarglist()
+    def __init__(self, loop):
+        self.loop = loop
+        self.inputargs = loop.label.getarglist()
+        self.renamed_inputargs = loop.label.getarglist()
 
     def setup_once(self, info):
-        for op in self.operations:
-            if op.is_guard():
-                olddescr = op.getdescr()
-                if not olddescr:
-                    continue
-                descr = olddescr.clone()
-                op.setdescr(descr)
-                if descr.loop_version():
-                    toversion = info.leads_to.get(olddescr,None)
-                    if toversion:
-                        info.track(op, descr, toversion)
-                    else:
-                        assert 0, "olddescr must be found"
+        for op in self.loop.operations:
+            if not op.is_guard():
+                continue
+            olddescr = op.getdescr()
+            if not olddescr:
+                continue
+            descr = olddescr.clone()
+            op.setdescr(descr)
+            if descr.loop_version():
+                toversion = info.leads_to.get(olddescr,None)
+                if toversion:
+                    info.track(op, descr, toversion)
+                else:
+                    assert 0, "olddescr must be found"
 
     def update_token(self, jitcell_token, all_target_tokens):
         # this is only invoked for versioned loops!
@@ -111,6 +140,13 @@
         label.setdescr(token)
         jump.setdescr(token)
 
+    def create_backend_loop(self, metainterp, jitcell_token):
+        vl = create_empty_loop(metainterp)
+        vl.operations = self.loop.finaloplist(jitcell_token,True)
+        vl.inputargs = self.loop.label.getarglist_copy()
+        vl.original_jitcell_token = jitcell_token
+        return vl
+
 
 #def index_of_first(opnum, operations, pass_by=0):
 #    """ returns the position of the first operation matching the opnum.
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -27,8 +27,11 @@
 class AbstractValue(object):
     _repr_memo = CountingDict()
     is_info_class = False
-    _attrs_ = ()
     namespace = None
+    _attrs_ = ('datatype', 'bytesize', 'signed')
+    datatype = '\x00'
+    bytesize = -1 # -1 means the biggest size known to the machine
+    signed = True
 
     def _get_hash_(self):
         return compute_identity_hash(self)
@@ -110,11 +113,6 @@
 
 class Typed(object):
     _mixin_ = True
-    _attrs_ = ('datatype', 'bytesize', 'signed')
-
-    datatype = '\x00'
-    bytesize = -1 # -1 means the biggest size known to the machine
-    signed = True
 
     def inittype(self):
         if self.returns_void():
@@ -124,6 +122,9 @@
 
         if self.is_primitive_array_access():
             descr = self.getdescr()
+            if not we_are_translated():
+                from rpython.jit.backend.llgraph.runner import _getdescr
+                descr = _getdescr(self)
             type = self.type
             if descr.is_array_of_floats() or descr.concrete_type == 'f':
                 type = 'f'
@@ -131,8 +132,10 @@
             self.sign = descr.is_item_signed()
             self.datatype = type
         elif self.opnum == rop.INT_SIGNEXT:
+            from rpython.jit.metainterp import history
             arg0 = self.getarg(0)
             arg1 = self.getarg(1)
+            assert isinstance(arg1, history.ConstInt)
             signed = True
             if not arg0.is_constant():
                 signed = arg0.signed
@@ -182,6 +185,7 @@
     _attrs_ = ('_forwarded',)
     _forwarded = None # either another resop or OptInfo  
 
+
     def get_forwarded(self):
         return self._forwarded
 
@@ -435,6 +439,9 @@
         primitive type (int,float) """
         if self.is_primitive_load() or self.is_primitive_store():
             descr = self.getdescr()
+            if not we_are_translated():
+                from rpython.jit.backend.llgraph.runner import _getdescr
+                descr = _getdescr(self)
             if descr and descr.is_array_of_primitives():
                 return True
         return False
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
@@ -57,6 +57,12 @@
         self.scalar_box = box
         self.vector_loc = loc
 
+    def getpos_in_failargs(self):
+        return self.scalar_position
+
+    def next(self):
+        return self.prev
+
     def __repr__(self):
         return 'AccumInfo(%s,%s,%s,%s,%s)' % (self.prev is None,
                                               self.accum_operation,
diff --git a/rpython/jit/metainterp/test/test_vector.py b/rpython/jit/metainterp/test/test_vector.py
--- a/rpython/jit/metainterp/test/test_vector.py
+++ b/rpython/jit/metainterp/test/test_vector.py
@@ -65,7 +65,7 @@
         res = self.meta_interp(f, [i])
         assert res == f(i)
 
-    @py.test.mark.parametrize('i',[1,2,3,8,17,128,130,500,501,502,1300])
+    @py.test.mark.parametrize('i',[1,2,3,8,17,128,130,131,142,143])
     def test_vectorize_array_get_set(self,i):
         myjitdriver = JitDriver(greens = [],
                                 reds = 'auto',


More information about the pypy-commit mailing list