[pypy-commit] pypy vecopt2: tested and adapted the trace optimizer for loops.

plan_rich noreply at buildbot.pypy.org
Tue May 5 09:46:08 CEST 2015


Author: Richard Plangger <rich at pasra.at>
Branch: vecopt2
Changeset: r77115:0b90aa19f600
Date: 2015-04-16 13:01 +0200
http://bitbucket.org/pypy/pypy/changeset/0b90aa19f600/

Log:	tested and adapted the trace optimizer for loops. trace jump targets
	are correctly set and the vec. optimizer avoids the unroller added
	vec_int_signext

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
@@ -563,14 +563,6 @@
         else:
             return self.bh_raw_load_i(struct, offset, descr)
 
-    def bh_vec_raw_load(self, struct, offset, count, descr):
-        values = []
-        stride = descr.get_item_size_in_bytes()
-        for i in range(count):
-            val = self.bh_raw_load(struct, offset + i*stride, descr)
-            values.append(val)
-        return values
-
     def bh_increment_debug_counter(self, addr):
         p = rffi.cast(rffi.CArrayPtr(lltype.Signed), addr)
         p[0] += 1
@@ -603,11 +595,6 @@
         else:
             self.bh_raw_store_i(struct, offset, newvalue, descr)
 
-    def bh_vec_raw_store(self, struct, offset, newvalues, count, descr):
-        stride = descr.get_item_size_in_bytes()
-        for i in range(count):
-            self.bh_raw_store(struct, offset + i*stride, newvalues[i], descr)
-
     def bh_newstr(self, length):
         return lltype.cast_opaque_ptr(llmemory.GCREF,
                                       lltype.malloc(rstr.STR, length,
@@ -678,6 +665,39 @@
     def bh_new_raw_buffer(self, size):
         return lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
 
+    # vector operations
+    def bh_vec_int_add(self, vx, vy, count):
+        assert len(vx) == count
+        assert len(vy) == count
+        return [_vx + _vy for _vx,_vy in zip(vx,vy)]
+
+    def bh_vec_int_mul(self, vx, vy, count):
+        assert len(vx) == count
+        assert len(vy) == count
+        return [_vx * _vy for _vx,_vy in zip(vx,vy)]
+
+    def bh_vec_int_sub(self, vx, vy, count):
+        assert len(vx) == count
+        assert len(vy) == count
+        return [_vx - _vy for _vx,_vy in zip(vx,vy)]
+
+    def bh_vec_int_signext(self, vx, ext, count):
+        return [heaptracker.int_signext(_vx, ext) for _vx in vx]
+
+    def bh_vec_raw_load(self, struct, offset, count, descr):
+        values = []
+        stride = descr.get_item_size_in_bytes()
+        for i in range(count):
+            val = self.bh_raw_load(struct, offset + i*stride, descr)
+            values.append(val)
+        return values
+
+    def bh_vec_raw_store(self, struct, offset, newvalues, count, descr):
+        stride = descr.get_item_size_in_bytes()
+        for i in range(count):
+            self.bh_raw_store(struct, offset + i*stride, newvalues[i], descr)
+
+
     def store_fail_descr(self, deadframe, descr):
         pass # I *think*
 
@@ -826,6 +846,10 @@
         argboxes = self.current_op.getarglist()
         self.do_renaming(argboxes, args)
 
+    def execute_guard_no_early_exit(self, descr):
+        # TODO
+        pass
+
     def execute_guard_true(self, descr, arg):
         if not arg:
             self.fail_guard(descr)
@@ -930,15 +954,6 @@
         if not self.overflow_flag:
             self.fail_guard(descr)
 
-    def execute_vec_int_add(self, _, vx, vy):
-        return [_vx + _vy for _vx,_vy in zip(vx,vy)]
-
-    def execute_vec_int_mul(self, _, vx, vy):
-        return [_vx * _vy for _vx,_vy in zip(vx,vy)]
-
-    def execute_vec_int_sub(self, _, vx, vy):
-        return [_vx - _vy for _vx,_vy in zip(vx,vy)]
-
     def execute_jump(self, descr, *args):
         raise Jump(descr._llgraph_target, args)
 
diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -1482,6 +1482,8 @@
         #
         if opnum == rop.GUARD_FUTURE_CONDITION:
             pass
+        elif opnum == rop.GUARD_NO_EARLY_EXIT:
+            self.position = 0
         elif opnum == rop.GUARD_TRUE:
             # Produced directly by some goto_if_not_xxx() opcode that did not
             # jump, but which must now jump.  The pc is just after the opcode.
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
@@ -685,6 +685,9 @@
 class ResumeAtPositionDescr(ResumeGuardDescr):
     guard_opnum = rop.GUARD_FUTURE_CONDITION
 
+class ResumeAtEarylExitDescr(ResumeGuardDescr):
+    guard_opnum = rop.GUARD_NO_EARLY_EXIT
+
 class AllVirtuals:
     llopaque = True
     cache = None
@@ -773,7 +776,7 @@
     elif opnum == rop.GUARD_FUTURE_CONDITION:
         resumedescr = ResumeAtPositionDescr()
     elif opnum == rop.GUARD_NO_EARLY_EXIT:
-        resumedescr = ResumeAtPositionDescr()
+        resumedescr = ResumeAtEarylExitDescr()
     elif opnum == rop.GUARD_VALUE:
         resumedescr = ResumeGuardValueDescr()
     elif opnum == rop.GUARD_NONNULL:
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
@@ -1,4 +1,6 @@
 import py
+
+from rpython.jit.metainterp.compile import ResumeAtEarylExitDescr
 from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
 from rpython.jit.metainterp.resoperation import rop
 from rpython.jit.codewriter.effectinfo import EffectInfo
@@ -77,14 +79,29 @@
     def getindex(self):
         return self.opidx
 
-    def dependency_count(self):
-        return len(self.adjacent_list)
-
     def getopnum(self):
         return self.op.getopnum()
     def getopname(self):
         return self.op.getopname()
 
+    def getfailarg_set(self):
+        args = set()
+        op = self.getoperation()
+        if op.getfailargs():
+            for arg in op.getfailargs():
+                args.add(arg)
+            return args
+        elif op.rd_snapshot:
+            ss = op.rd_snapshot
+            while ss != None:
+                for box in ss.boxes:
+                    args.add(box)
+                ss = ss.prev
+
+        return args
+ #set(target_guard.getoperation().getfailargs())
+
+
     def relax_guard_to(self, guard):
         """ Relaxes a guard operation to an earlier guard. """
         assert self.op.is_guard()
@@ -92,7 +109,8 @@
 
         my_op = self.getoperation()
         op = guard.getoperation()
-        my_op.setdescr(op.getdescr())
+        my_op.setdescr(ResumeAtEarylExitDescr())
+        print "set ", my_op.getdescr(), "=>", op.getdescr()
         my_op.setfailargs(op.getfailargs())
         my_op.rd_snapshot = op.rd_snapshot
 
@@ -116,16 +134,6 @@
                 _label = getattr(dep, 'label', '')
                 dep.label = _label + ", " + label
 
-    def depends_on(self, to):
-        """ Does there exist a dependency from the instruction to another?
-            Returns None if there is no dependency or the Dependency object in
-            any other case.
-        """
-        for edge in self.adjacent_list:
-            if edge.to == to:
-                return edge
-        return None 
-
     def clear_dependencies(self):
         self.adjacent_list = []
         self.adjacent_list_back = []
@@ -176,6 +184,16 @@
     def depends(self):
         return self.adjacent_list_back
 
+    def depends_on(self, to):
+        """ Does there exist a dependency from the instruction to another?
+            Returns None if there is no dependency or the Dependency object in
+            any other case.
+        """
+        for edge in self.adjacent_list:
+            if edge.to == to:
+                return edge
+        return None 
+
     def dependencies(self):
         return self.adjacent_list[:] + self.adjacent_list_back[:] # COPY
 
@@ -444,10 +462,9 @@
         # pass 3 find schedulable nodes
         jump_node = self.nodes[jump_pos]
         label_node = self.nodes[label_pos]
-        self.schedulable_nodes.append(label_node)
         for node in self.nodes:
             if node != jump_node:
-                if node.dependency_count() == 0:
+                if node.depends_count() == 0:
                     self.schedulable_nodes.append(node)
                 # every leaf instruction points to the jump_op. in theory every instruction
                 # points to jump_op. this forces the jump/finish op to be the last operation
@@ -633,15 +650,16 @@
 
     def schedule(self, index):
         node = self.schedulable_nodes[index]
-        assert not node.emitted
+        assert not node.emitted, "node " + str(node) + " cannot be emitted twice! op: " + str(node.getoperation())
         del self.schedulable_nodes[index]
         to_del = []
         print "  schedule", node.getoperation()
         for dep in node.provides()[:]: # COPY
-            node.remove_edge_to(dep.to)
-            print "    >=X=>", node, dep.to, "count",dep.to.depends_count()
-            if dep.to.depends_count() == 0:
-                self.schedulable_nodes.append(dep.to)
+            to = dep.to
+            node.remove_edge_to(to)
+            print "    >=X=>", node, to, "count",to.depends_count()
+            if not to.emitted and to.depends_count() == 0:
+                self.schedulable_nodes.append(to)
         node.clear_dependencies()
         node.emitted = True
 
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
@@ -796,7 +796,9 @@
         assert pendingfields is not None
         if op.getdescr() is not None:
             descr = op.getdescr()
-            assert isinstance(descr, compile.ResumeAtPositionDescr)
+            assert isinstance(descr, compile.ResumeAtPositionDescr) or \
+                   isinstance(descr, compile.ResumeAtEarylExitDescr)
+
         else:
             descr = compile.invent_fail_descr_for_op(op.getopnum(), self)
             op.setdescr(descr)
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
@@ -1,7 +1,8 @@
 import sys
 import py
 from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.jit.metainterp.history import ConstInt, VECTOR, BoxVector
+from rpython.jit.metainterp.history import (ConstInt, VECTOR, BoxVector,
+        TargetToken, JitCellToken)
 from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer, Optimization
 from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
 from rpython.jit.metainterp.optimizeopt.dependency import (DependencyGraph, 
@@ -57,17 +58,24 @@
         self.memory_refs = []
         self.dependency_graph = None
         self.first_debug_merge_point = False
-        self.last_debug_merge_point = None
         self.packset = None
         self.unroll_count = 0
         self.smallest_type_bytes = 0
 
     def propagate_all_forward(self):
         self.clear_newoperations()
+        label = self.loop.operations[0]
+        jump = self.loop.operations[-1]
+        if jump.getopnum() != rop.LABEL:
+            # compile_loop appends a additional label to all loops
+            # we cannot optimize normal traces
+            raise NotAVectorizeableLoop()
+
         self.linear_find_smallest_type(self.loop)
         byte_count = self.smallest_type_bytes
-        if byte_count == 0:
+        if byte_count == 0 or label.getopnum() != rop.LABEL:
             # stop, there is no chance to vectorize this trace
+            # we cannot optimize normal traces (if there is no label)
             raise NotAVectorizeableLoop()
 
         # unroll
@@ -88,15 +96,8 @@
         self._newoperations.append(op)
 
     def emit_unrolled_operation(self, op):
-        if op.getopnum() == rop.DEBUG_MERGE_POINT:
-            self.last_debug_merge_point = op
-            if not self.first_debug_merge_point:
-                self.first_debug_merge_point = True
-            else:
-                return False
         self._last_emitted_op = op
         self._newoperations.append(op)
-        return True
 
     def unroll_loop_iterations(self, loop, unroll_count):
         """ Unroll the loop X times. unroll_count is an integral how
@@ -104,10 +105,12 @@
         """
         op_count = len(loop.operations)
 
-        label_op = loop.operations[0]
-        jump_op = loop.operations[op_count-1]
+        label_op = loop.operations[0].clone()
+        jump_op = loop.operations[op_count-1].clone()
+        # use the target token of the label
+        jump_op = ResOperation(rop.JUMP, jump_op.getarglist(), None, label_op.getdescr())
         assert label_op.getopnum() == rop.LABEL
-        assert jump_op.is_final() or jump_op.getopnum() == rop.LABEL
+        assert jump_op.is_final()
 
         # XXX self.vec_info.track_memory_refs = True
 
@@ -124,8 +127,6 @@
             op = loop.operations[i].clone()
             operations.append(op)
             self.emit_unrolled_operation(op)
-            #self.vec_info.index = len(self._newoperations)-1
-            #self.vec_info.inspect_operation(op)
 
         orig_jump_args = jump_op.getarglist()[:]
         # it is assumed that #label_args == #jump_args
@@ -167,14 +168,15 @@
                     copied_op.rd_snapshot = snapshot
                     if not we_are_translated():
                         # ensure that in a test case the renaming is correct
-                        args = copied_op.getfailargs()[:]
-                        for i,arg in enumerate(args):
-                            try:
-                                value = rename_map[arg]
-                                args[i] = value
-                            except KeyError:
-                                pass
-                        copied_op.setfailargs(args)
+                        if copied_op.getfailargs():
+                            args = copied_op.getfailargs()[:]
+                            for i,arg in enumerate(args):
+                                try:
+                                    value = rename_map[arg]
+                                    args[i] = value
+                                except KeyError:
+                                    pass
+                            copied_op.setfailargs(args)
                 #
                 self.emit_unrolled_operation(copied_op)
 
@@ -189,9 +191,6 @@
             except KeyError:
                 pass
 
-        if self.last_debug_merge_point is not None:
-            self._last_emitted_op = self.last_debug_merge_point
-            self._newoperations.append(self.last_debug_merge_point)
         self.emit_unrolled_operation(jump_op)
 
     def clone_snapshot(self, snapshot, rename_map):
@@ -335,10 +334,10 @@
                 print " P:", pack
 
     def schedule(self):
+        print self.dependency_graph.as_dot()
         self.clear_newoperations()
         scheduler = Scheduler(self.dependency_graph, VecScheduleData())
-        print "scheduling loop"
-        i = 100
+        print "scheduling loop. scheduleable are: " + str(scheduler.schedulable_nodes)
         while scheduler.has_more():
             candidate = scheduler.next()
             print "  candidate", candidate, "has pack?", candidate.pack != None, "pack", candidate.pack
@@ -353,9 +352,6 @@
             else:
                 self.emit_operation(candidate.getoperation())
                 scheduler.schedule(0)
-            i += 1
-            if i > 200:
-                assert False
 
         self.loop.operations = self._newoperations[:]
         if not we_are_translated():
@@ -415,8 +411,8 @@
     return False
 
 def fail_args_break_dependency(guard, prev_op, target_guard):
-    failargs = set(guard.getoperation().getfailargs())
-    new_failargs = set(target_guard.getoperation().getfailargs())
+    failargs = guard.getfailarg_set()
+    new_failargs = target_guard.getfailarg_set()
 
     op = prev_op.getoperation()
     if not op.is_always_pure(): # TODO has_no_side_effect():
@@ -439,53 +435,52 @@
         self.box_to_vbox = {}
 
     def as_vector_operation(self, pack):
-        assert len(pack.operations) > 1
+        op_count = pack.operations
+        assert op_count > 1
         self.pack = pack
+        # properties that hold for the pack are:
+        # isomorphism (see func above)
         op0 = pack.operations[0].getoperation()
         assert op0.vector != -1
         args = op0.getarglist()[:]
-        if op0.vector in (rop.VEC_RAW_LOAD, rop.VEC_RAW_STORE):
-            args.append(ConstInt(0))
-        vop = ResOperation(op0.vector, args,
-                            op0.result, op0.getdescr())
-        self._inspect_operation(vop) # op0 is for dispatch only
-        #if op0.vector not in (rop.VEC_RAW_LOAD, rop.VEC_RAW_STORE):
-        #    op_count = len(pack.operations)
-        #    args.append(ConstInt(op_count))
+        args.append(ConstInt(len(op_count)))
+        vop = ResOperation(op0.vector, args, op0.result, op0.getdescr())
+        self._inspect_operation(vop)
         return vop
 
-    def _pack_vector_arg(self, vop, op, i, vbox):
-        arg = op.getarg(i)
-        if vbox is None:
-            try:
-                _, vbox = self.box_to_vbox[arg]
-            except KeyError:
-                vbox = BoxVector(arg.type, 4, 0, True)
-            vop.setarg(i, vbox)
-        self.box_to_vbox[arg] = (i,vbox)
-        return vbox
+    def get_vbox_for(self, arg):
+        try:
+            _, vbox = self.box_to_vbox[arg]
+            return vbox
+        except KeyError:
+            # if this is not the case, then load operations must
+            # be emitted
+            assert False, "vector box MUST be defined before"
 
-    def _pack_vector_result(self, vop, op, vbox):
-        result = op.result
-        if vbox is None:
-            vbox = BoxVector(result.type, 4, 0, True)
-            vop.result = vbox
-        self.box_to_vbox[result] = (-1,vbox)
-        return vbox
+    def vector_result(self, vop): 
+        ops = self.pack.operations
+        op0 = ops[0].getoperation()
+        result = op0.result
+        vbox = BoxVector(result.type, 4, 0, True)
+        vop.result = vbox
+        i = 0
+        vboxcount = vbox.item_count = len(ops)
+        while i < vboxcount:
+            op = ops[i].getoperation()
+            self.box_to_vbox[result] = (i, vbox)
+            i += 1
+
+    def vector_arg(self, vop, argidx):
+        ops = self.pack.operations
+        op0 = ops[0].getoperation()
+        vbox = self.get_vbox_for(op0.getarg(argidx))
+        vop.setarg(argidx, vbox)
 
     bin_arith_trans = """
     def _vectorize_{name}(self, vop):
-        vbox_arg_0 = None
-        vbox_arg_1 = None
-        vbox_result = None
-        ops = self.pack.operations
-        for i, node in enumerate(ops):
-            op = node.getoperation()
-            vbox_arg_0 = self._pack_vector_arg(vop, op, 0, vbox_arg_0)
-            vbox_arg_1 = self._pack_vector_arg(vop, op, 1, vbox_arg_1)
-            vbox_result= self._pack_vector_result(vop, op, vbox_result)
-        vbox_arg_0.item_count = vbox_arg_1.item_count = \
-                vbox_result.item_count = len(ops)
+        self.vector_arg(vop, 0)
+        self.vector_arg(vop, 1)
+        self.vector_result(vop)
     """
     exec py.code.Source(bin_arith_trans.format(name='VEC_INT_ADD')).compile()
     exec py.code.Source(bin_arith_trans.format(name='VEC_INT_MUL')).compile()
@@ -495,23 +490,16 @@
     exec py.code.Source(bin_arith_trans.format(name='VEC_FLOAT_SUB')).compile()
     del bin_arith_trans
 
+    def _vectorize_VEC_INT_SIGNEXT(self, vop):
+        self.vector_arg(vop, 0)
+        # arg 1 is a constant
+        self.vector_result(vop)
+
     def _vectorize_VEC_RAW_LOAD(self, vop):
-        vbox_result = None
-        ops = self.pack.operations
-        for i, node in enumerate(ops):
-            op = node.getoperation()
-            vbox_result= self._pack_vector_result(vop, op, vbox_result)
-        vbox_result.item_count = len(ops)
-        vop.setarg(vop.numargs()-1,ConstInt(len(ops)))
+        self.vector_result(vop)
 
     def _vectorize_VEC_RAW_STORE(self, vop):
-        vbox_arg_2 = None
-        ops = self.pack.operations
-        for i, node in enumerate(ops):
-            op = node.getoperation()
-            vbox_arg_2 = self._pack_vector_arg(vop, op, 2, vbox_arg_2)
-        vbox_arg_2.item_count = len(ops)
-        vop.setarg(vop.numargs()-1,ConstInt(len(ops)))
+        self.vector_arg(vop, 2)
 
 VecScheduleData._inspect_operation = \
         make_dispatcher_method(VecScheduleData, '_vectorize_')
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
@@ -452,12 +452,13 @@
     #
     # vector operations
     '_VEC_ARITHMETIC_FIRST',
-    'VEC_INT_ADD/2d',
-    'VEC_INT_SUB/2d',
-    'VEC_INT_MUL/2d',
-    'VEC_FLOAT_ADD/2d',
-    'VEC_FLOAT_SUB/2d',
-    'VEC_FLOAT_MUL/2d',
+    'VEC_INT_ADD/3',
+    'VEC_INT_SUB/3',
+    'VEC_INT_MUL/3',
+    'VEC_FLOAT_ADD/3',
+    'VEC_FLOAT_SUB/3',
+    'VEC_FLOAT_MUL/3',
+    'VEC_INT_SIGNEXT/3',
     '_VEC_ARITHMETIC_LAST',
     #
     'INT_LT/2b',
@@ -703,20 +704,22 @@
     rop.PTR_NE: rop.PTR_NE,
 }
 _opvector = {
-    rop.RAW_LOAD: rop.VEC_RAW_LOAD,
+    rop.RAW_LOAD:         rop.VEC_RAW_LOAD,
     rop.GETARRAYITEM_RAW: rop.VEC_RAW_LOAD,
-    rop.GETARRAYITEM_GC: rop.VEC_RAW_LOAD,
+    rop.GETARRAYITEM_GC:  rop.VEC_RAW_LOAD,
 
-    rop.RAW_STORE: rop.VEC_RAW_STORE,
+    rop.RAW_STORE:        rop.VEC_RAW_STORE,
     rop.SETARRAYITEM_RAW: rop.VEC_RAW_STORE,
-    rop.SETARRAYITEM_GC: rop.VEC_RAW_STORE,
+    rop.SETARRAYITEM_GC:  rop.VEC_RAW_STORE,
 
-    rop.INT_ADD: rop.VEC_INT_ADD,
-    rop.INT_SUB: rop.VEC_INT_SUB,
-    rop.INT_MUL: rop.VEC_INT_MUL,
+    rop.INT_ADD:   rop.VEC_INT_ADD,
+    rop.INT_SUB:   rop.VEC_INT_SUB,
+    rop.INT_MUL:   rop.VEC_INT_MUL,
     rop.FLOAT_ADD: rop.VEC_FLOAT_ADD,
     rop.FLOAT_SUB: rop.VEC_FLOAT_SUB,
     rop.FLOAT_MUL: rop.VEC_FLOAT_MUL,
+
+    rop.INT_SIGNEXT: rop.VEC_INT_SIGNEXT,
 }
 
 def setup2():
@@ -730,7 +733,6 @@
             cls.boolinverse = _opboolinverse[opnum]
         if opnum in _opvector:
             cls.vector = _opvector[opnum]
-
 setup2()
 del _opboolinverse
 del _opboolreflex
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
@@ -21,63 +21,24 @@
                               CPUClass=self.CPUClass,
                               type_system=self.type_system)
 
-    def test_vectorize_simple_load_arith_store_mul(self):
-        myjitdriver = JitDriver(greens = [],
-                                reds = ['i','d','va','vb','vc'],
-                                vectorize=False)
-        def f(d):
-            va = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
-            vb = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
-            vc = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
-            for i in range(d):
-                raw_storage_setitem(va, i*rffi.sizeof(rffi.SIGNED),
-                                    rffi.cast(rffi.SIGNED,i))
-                raw_storage_setitem(vb, i*rffi.sizeof(rffi.SIGNED),
-                                    rffi.cast(rffi.SIGNED,i))
-            i = 0
-            while i < d:
-                myjitdriver.can_enter_jit(i=i, d=d, va=va, vb=vb, vc=vc)
-                myjitdriver.jit_merge_point(i=i, d=d, va=va, vb=vb, vc=vc)
-                pos = i*rffi.sizeof(rffi.SIGNED)
-                a = raw_storage_getitem(rffi.SIGNED,va,pos)
-                b = raw_storage_getitem(rffi.SIGNED,vb,pos)
-                c = a+b
-                raw_storage_setitem(vc, pos, rffi.cast(rffi.SIGNED,c))
-                i += 1
-            res = 0
-            for i in range(d):
-                res += raw_storage_getitem(rffi.SIGNED,vc,i*rffi.sizeof(rffi.SIGNED))
-
-            free_raw_storage(va)
-            free_raw_storage(vb)
-            free_raw_storage(vc)
-            return res
-        i = 32
-        res = self.meta_interp(f, [i])
-        assert res == f(i)
-        self.check_trace_count(1)
-        i = 31
-        res = self.meta_interp(f, [i])
-        assert res == f(i)
-
-    @py.test.mark.parametrize('i',range(0,32))
+    @py.test.mark.parametrize('i',[3,4,5,6,7,8,9,50])
     def test_vectorize_simple_load_arith_store_int_add_index(self,i):
         myjitdriver = JitDriver(greens = [],
-                                reds = ['i','d','va','vb','vc'],
+                                reds = ['i','d','bc','va','vb','vc'],
                                 vectorize=True)
         def f(d):
-            va = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
-            vb = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
-            vc = alloc_raw_storage(d*rffi.sizeof(rffi.SIGNED), zero=True)
+            bc = d*rffi.sizeof(rffi.SIGNED)
+            va = alloc_raw_storage(bc, zero=True)
+            vb = alloc_raw_storage(bc, zero=True)
+            vc = alloc_raw_storage(bc, zero=True)
             for i in range(d):
-                raw_storage_setitem(va, i*rffi.sizeof(rffi.SIGNED),
-                                    rffi.cast(rffi.SIGNED,i))
-                raw_storage_setitem(vb, i*rffi.sizeof(rffi.SIGNED),
-                                    rffi.cast(rffi.SIGNED,i))
+                j = i*rffi.sizeof(rffi.SIGNED)
+                raw_storage_setitem(va, j, rffi.cast(rffi.SIGNED,i))
+                raw_storage_setitem(vb, j, rffi.cast(rffi.SIGNED,i))
             i = 0
-            while i < d*8:
-                myjitdriver.can_enter_jit(i=i, d=d, va=va, vb=vb, vc=vc)
-                myjitdriver.jit_merge_point(i=i, d=d, va=va, vb=vb, vc=vc)
+            while i < bc:
+                myjitdriver.can_enter_jit(i=i, d=d, va=va, vb=vb, vc=vc, bc=bc)
+                myjitdriver.jit_merge_point(i=i, d=d, va=va, vb=vb, vc=vc, bc=bc)
                 a = raw_storage_getitem(rffi.SIGNED,va,i)
                 b = raw_storage_getitem(rffi.SIGNED,vb,i)
                 c = a+b
@@ -92,8 +53,9 @@
             free_raw_storage(vc)
             return res
         res = self.meta_interp(f, [i])
-        assert res == f(i) #sum(range(i)) * 2
-        self.check_trace_count(1)
+        assert res == f(i)
+        if i > 3:
+            self.check_trace_count(1)
 
     def test_guard(self):
         py.test.skip('abc')


More information about the pypy-commit mailing list