[pypy-commit] pypy vecopt-merge: only one test for llgraph failing

plan_rich noreply at buildbot.pypy.org
Thu Sep 24 12:53:09 CEST 2015


Author: Richard Plangger <planrichi at gmail.com>
Branch: vecopt-merge
Changeset: r79808:ed1cb45ccbd1
Date: 2015-09-24 12:53 +0200
http://bitbucket.org/pypy/pypy/changeset/ed1cb45ccbd1/

Log:	only one test for llgraph failing

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
@@ -799,8 +799,8 @@
 
     # vector operations
     vector_arith_code = """
-    def bh_vec_{0}_{1}(self, vx, vy):
-        assert len(vx) == len(vy)
+    def bh_vec_{0}_{1}(self, vx, vy, count):
+        assert len(vx) == len(vy) == count
         return [_vx {2} _vy for _vx,_vy in zip(vx,vy)]
     """
     exec py.code.Source(vector_arith_code.format('int','add','+')).compile()
@@ -812,59 +812,66 @@
     exec py.code.Source(vector_arith_code.format('float','truediv','/')).compile()
     exec py.code.Source(vector_arith_code.format('float','eq','==')).compile()
 
-    def bh_vec_float_neg(self, vx):
+    def bh_vec_float_neg(self, vx, count):
         return [e * -1 for e in vx]
 
-    def bh_vec_float_abs(self, vx):
+    def bh_vec_float_abs(self, vx, count):
         return [abs(e) for e in vx]
 
-    def bh_vec_float_eq(self, vx, vy):
-        assert len(vx) == len(vy)
+    def bh_vec_float_eq(self, vx, vy, count):
+        assert len(vx) == len(vy) == count
         return [_vx == _vy for _vx,_vy in zip(vx,vy)]
 
-    def bh_vec_float_ne(self, vx, vy):
-        assert len(vx) == len(vy)
+    def bh_vec_float_ne(self, vx, vy, count):
+        assert len(vx) == len(vy) == count
         return [_vx != _vy for _vx,_vy in zip(vx,vy)]
 
     bh_vec_int_eq = bh_vec_float_eq
     bh_vec_int_ne = bh_vec_float_ne
 
-    def bh_vec_int_xor(self, vx, vy):
+    def bh_vec_int_xor(self, vx, vy, count):
         return [int(x) ^ int(y) for x,y in zip(vx,vy)]
 
-    def bh_vec_float_pack(self, vector, value, index, count):
-        if isinstance(value, list):
-            for i in range(count):
-                vector[index + i] = value[i]
-        else:
-            vector[index] = value
-        return vector
-
-    def bh_vec_cast_float_to_singlefloat(self, vx):
+    def bh_vec_cast_float_to_singlefloat(self, vx, count):
         return vx
 
-    def bh_vec_box(self, size):
-        return [0] * size
+    def bh_vec_f(self, count):
+        return [0.0] * count
 
-    def bh_vec_box_pack(self, vx, index, y):
-        vx[index] = y
+    def bh_vec_i(self, count):
+        return [0] * count
 
-    def bh_vec_box_unpack(self, vx, index):
-        return vx[index]
+    def _bh_vec_pack(self, tv, sv, index, count, _):
+        if not isinstance(sv, list):
+            tv[index] = sv
+            return tv
+        for i in range(count):
+            tv[index+i] = sv[i]
+        return tv
 
-    def bh_vec_float_expand(self, x, count):
+    bh_vec_pack_f = _bh_vec_pack
+    bh_vec_pack_i = _bh_vec_pack
+
+    def _bh_vec_unpack(self, vx, index, count):
+        return vx[index:index+count]
+
+    bh_vec_unpack_f = _bh_vec_unpack
+    bh_vec_unpack_i = _bh_vec_unpack
+
+    def _bh_vec_expand(self, x, count):
         return [x] * count
 
-    def bh_vec_int_expand(self, x, count):
-        return [x] * count
+    bh_vec_expand_f = _bh_vec_expand
+    bh_vec_expand_i = _bh_vec_expand
 
-    def bh_vec_int_signext(self, vx, ext):
+    def bh_vec_int_signext(self, vx, ext, count):
         return [heaptracker.int_signext(_vx, ext) for _vx in vx]
 
     def build_getarrayitem(func):
-        def method(self, struct, offset, descr):
+        def method(self, struct, offset, descr, _count):
             values = []
             count = self.vector_register_size // descr.get_item_size_in_bytes()
+            assert _count == count
             assert count > 0
             for i in range(count):
                 val = func(self, struct, offset + i, descr)
@@ -878,10 +885,11 @@
     bh_vec_getarrayitem_raw_f = build_getarrayitem(bh_getarrayitem_raw)
     del build_getarrayitem
 
-    def _bh_vec_raw_load(self, struct, offset, descr):
+    def _bh_vec_raw_load(self, struct, offset, descr, _count):
         values = []
         stride = descr.get_item_size_in_bytes()
         count = self.vector_register_size // descr.get_item_size_in_bytes()
+        assert _count == count
         assert count > 0
         for i in range(count):
             val = self.bh_raw_load(struct, offset + i*stride, descr)
@@ -891,16 +899,16 @@
     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):
+    def bh_vec_raw_store(self, struct, offset, newvalues, descr, count):
         stride = descr.get_item_size_in_bytes()
         for i,n in enumerate(newvalues):
             self.bh_raw_store(struct, offset + i*stride, n, descr)
 
-    def bh_vec_setarrayitem_raw(self, struct, offset, newvalues, descr):
+    def bh_vec_setarrayitem_raw(self, struct, offset, newvalues, descr, count):
         for i,n in enumerate(newvalues):
             self.bh_setarrayitem_raw(struct, offset + i, n, descr)
 
-    def bh_vec_setarrayitem_gc(self, struct, offset, newvalues, descr):
+    def bh_vec_setarrayitem_gc(self, struct, offset, newvalues, descr, count):
         for i,n in enumerate(newvalues):
             self.bh_setarrayitem_gc(struct, offset + i, n, descr)
 
@@ -1026,9 +1034,9 @@
             i = accuminfo.getpos_in_failargs()
             value = values[i]
             assert isinstance(value, list)
-            if accum.operator == '+':
+            if accuminfo.accum_operation == '+':
                 value = sum(value)
-            elif accum.operator == '*':
+            elif accuminfo.accum_operation == '*':
                 def prod(acc, x): return acc * x
                 value = reduce(prod, value, 1)
             else:
@@ -1404,6 +1412,10 @@
                 new_args = args + (descr,)
             else:
                 new_args = args
+            if opname.startswith('vec_'):
+                count = self.current_op.count
+                assert count > 1
+                new_args = new_args + (count,)
             return getattr(self.cpu, 'bh_' + opname)(*new_args)
         execute.func_name = 'execute_' + opname
         return execute
diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py
--- a/rpython/jit/metainterp/logger.py
+++ b/rpython/jit/metainterp/logger.py
@@ -134,6 +134,9 @@
             return str(arg.getfloatstorage())
         elif arg is None:
             return 'None'
+        elif arg.is_vector():
+            suffix = '[%dx%s%d]' % (arg.count, arg.datatype, arg.bytesize * 8)
+            return 'v' + str(mv) + suffix
         elif arg.type == 'i':
             return 'i' + str(mv)
         elif arg.type == 'r':
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
@@ -149,10 +149,6 @@
         assert operations[self.index] is self.op
         operations[self.index] = None
         descr = self.op.getdescr()
-        # TODO loop.version_info.remove(descr)
-        #if descr and descr.loop_version():
-        #    assert isinstance(descr, CompileLoopVersionDescr)
-        #    descr.version = None
         if operations[self.index-1] is self.cmp_op:
             operations[self.index-1] = None
 
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
@@ -28,12 +28,18 @@
         loop.operations = self.oplist
         loop.prefix = self.invariant_oplist
         if len(self.invariant_vector_vars) + len(self.invariant_oplist) > 0:
+            # label
             args = loop.label.getarglist_copy() + self.invariant_vector_vars
             opnum = loop.label.getopnum()
-            # TODO descr?
             op = loop.label.copy_and_change(opnum, args)
             self.renamer.rename(op)
             loop.prefix_label = op
+            # jump
+            args = loop.jump.getarglist_copy() + self.invariant_vector_vars
+            opnum = loop.jump.getopnum()
+            op = loop.jump.copy_and_change(opnum, args)
+            self.renamer.rename(op)
+            loop.jump = op
 
     def profitable(self):
         return True
@@ -56,9 +62,11 @@
     def ensure_args_unpacked(self, op):
         pass
 
-    def post_emit(self, op):
+    def post_emit(self, node):
         pass
 
+    def pre_emit(self, node):
+        pass
 
 class Scheduler(object):
     """ Create an instance of this class to (re)schedule a vector trace. """
@@ -123,7 +131,7 @@
             state.renamer.rename(op)
             if unpack:
                 state.ensure_args_unpacked(op)
-            state.post_emit(node.getoperation())
+            state.post_emit(node)
 
     def walk_and_emit(self, state):
         """ Emit all the operations into the oplist parameter.
@@ -134,6 +142,7 @@
             if node:
                 if not state.emit(node, self):
                     if not node.emitted:
+                        state.pre_emit(node)
                         self.mark_emitted(node, state)
                         if not node.is_imaginary():
                             op = node.getoperation()
@@ -259,6 +268,8 @@
     for i,node in enumerate(pack.operations):
         op = node.getoperation()
         state.setvector_of_box(op,i,vecop)
+        if pack.is_accumulating():
+            state.renamer.start_renaming(op, vecop)
     if op.is_guard():
         assert isinstance(op, GuardResOp)
         assert isinstance(vecop, GuardResOp)
@@ -452,7 +463,8 @@
         args[index] = vecop
         return vecop
 
-    vecop = OpHelpers.create_vec(arg.type, arg.bytesize, arg.signed)
+    
+    vecop = OpHelpers.create_vec(arg.type, arg.bytesize, arg.signed, pack.opnum())
     ops.append(vecop)
     for i,node in enumerate(pack.operations):
         op = node.getoperation()
@@ -519,7 +531,11 @@
                 return vecop
         return None
 
-    def post_emit(self, op):
+    def post_emit(self, node):
+        pass
+
+    def pre_emit(self, node):
+        op = node.getoperation()
         if op.is_guard():
             # add accumulation info to the descriptor
             # TODO for version in self.loop.versions:
@@ -536,8 +552,9 @@
                 accum = self.accumulation.get(arg, None)
                 if accum:
                     assert isinstance(accum, AccumPack)
-                    accum.attach_accum_info(descr, i, arg)
-                    seed = accum.getseed()
+                    descr.rd_accum_list = AccumInfo(descr.rd_accum_list, i,
+                                                    accum.operator, arg, None)
+                    seed = accum.getleftmostseed()
                     failargs[i] = self.renamer.rename_map.get(seed, seed)
 
     def profitable(self):
@@ -556,6 +573,7 @@
         if node.pack:
             assert node.pack.numops() > 1
             for node in node.pack.operations:
+                self.pre_emit(node)
                 scheduler.mark_emitted(node, self, unpack=False)
             turn_into_vector(self, node.pack)
             return True
@@ -593,6 +611,7 @@
                 if argument and not argument.is_constant():
                     arg = self.ensure_unpacked(i, argument)
                     if argument is not arg:
+                        print "exchange at", i, fail_args[i], "=", arg
                         fail_args[i] = arg
 
     def ensure_unpacked(self, index, arg):
@@ -603,7 +622,7 @@
             if var in self.invariant_vector_vars:
                 return arg
             if arg in self.accumulation:
-                return var
+                return arg
             args = [var, ConstInt(pos), ConstInt(1)]
             vecop = OpHelpers.create_vec_unpack(var.type, args, var.bytesize,
                                                 var.signed, 1)
@@ -844,35 +863,34 @@
                   rop.FLOAT_MUL: '*',
                 }
 
-    def __init__(self, nodes, operator, accum, position):
+    def __init__(self, nodes, operator, position):
         Pack.__init__(self, nodes)
-        self.accumulator = accum
         self.operator = operator
         self.position = position
 
     def getdatatype(self):
-        return self.accumulator.datatype
+        accum = self.leftmost().getarg(self.position)
+        return accum.datatype
 
     def getbytesize(self):
-        return self.accumulator.bytesize
+        accum = self.leftmost().getarg(self.position)
+        return accum.bytesize
 
-    def getseed(self):
+    def getleftmostseed(self):
+        return self.leftmost().getarg(self.position)
+
+    def getseeds(self):
         """ The accumulatoriable holding the seed value """
-        return self.accumulator
+        return [op.getoperation().getarg(self.position) for op in self.operations]
 
     def reduce_init(self):
         if self.operator == '*':
             return 1
         return 0
 
-    def attach_accum_info(self, descr, position, scalar):
-        descr.rd_accum_list = AccumInfo(descr.rd_accum_list, position, self.operator,
-                                        scalar, None)
-
     def is_accumulating(self):
         return True
 
     def clone(self):
-        return AccumPack(operations, self.operator,
-                         self.accumulator, self.position)
+        return AccumPack(operations, self.operator, self.position)
 
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
@@ -81,11 +81,11 @@
 def optimize_vector(metainterp_sd, jitdriver_sd, warmstate, loop_info, loop_ops):
     """ Enter the world of SIMD. Bails if it cannot transform the trace. """
     user_code = not jitdriver_sd.vec and warmstate.vec_all
+    loop = VectorLoop(loop_info.label_op, loop_ops[1:-1], loop_ops[-1])
     if user_code and user_loop_bail_fast_path(loop, warmstate):
         return
     # the original loop (output of optimize_unroll)
     info = LoopVersionInfo(loop_info)
-    loop = VectorLoop(loop_info.label_op, loop_ops[1:-1], loop_ops[-1])
     version = info.snapshot(loop)
     try:
         debug_start("vec-opt-loop")
@@ -134,7 +134,6 @@
     resop_count = 0 # the count of operations minus debug_merge_points
     vector_instr = 0
     guard_count = 0
-    blacklist = (rop.CALL, rop.CALL_ASSEMBLER)
     at_least_one_array_access = True
     for i,op in enumerate(loop.operations):
         if op.getopnum() == rop.DEBUG_MERGE_POINT:
@@ -149,7 +148,8 @@
             at_least_one_array_access = True
 
         if warmstate.vec_ratio > 0.0:
-            if op.getopnum() in blacklist:
+            # blacklist
+            if op.is_call() or op.is_call_assembler():
                 return True
 
         if op.is_guard():
@@ -744,7 +744,7 @@
                 # considered. => tree pattern matching problem.
                 return None
             operator = AccumPack.SUPPORTED[opnum]
-            return AccumPack([lnode, rnode], operator, scalar, index)
+            return AccumPack([lnode, rnode], operator, index)
 
         return None
 
@@ -770,7 +770,7 @@
             oplist = state.invariant_oplist
             # reset the box to zeros or ones
             if pack.reduce_init() == 0:
-                vecop = OpHelpers.create_vec(datatype, bytesize, signed)
+                vecop = OpHelpers.create_vec(datatype, bytesize, signed, count)
                 oplist.append(vecop)
                 vecop = VecOperation(rop.VEC_INT_XOR, [vecop, vecop],
                                      vecop, count)
@@ -783,14 +783,15 @@
             else:
                 raise NotImplementedError("cannot handle %s" % pack.operator)
             # pack the scalar value
-            args = [vecop, pack.getseed(), ConstInt(0), ConstInt(1)]
+            args = [vecop, pack.getleftmostseed(), ConstInt(0), ConstInt(1)]
             vecop = OpHelpers.create_vec_pack(datatype, args, bytesize,
                                               signed, count)
             oplist.append(vecop)
+            seed = pack.getleftmostseed()
+            state.accumulation[seed] = pack
             # rename the variable with the box
-            state.setvector_of_box(pack.getseed(), 0, vecop) # prevent it from expansion
-            state.renamer.start_renaming(pack.getseed(), vecop)
-
+            state.setvector_of_box(seed, 0, vecop) # prevent it from expansion
+            state.renamer.start_renaming(seed, vecop)
 
     def split_overloaded_packs(self):
         newpacks = []
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
@@ -146,6 +146,10 @@
         else:
             # pass through the type of the first input argument
             if self.numargs() == 0:
+                if self.type == 'i':
+                    self.setdatatype('i', INT_WORD, True)
+                elif self.type == 'f':
+                    self.setdatatype('f', FLOAT_WORD, False)
                 return
             i = 0
             arg = self.getarg(i)
@@ -280,6 +284,9 @@
         if descr is DONT_CHANGE:
             descr = None
         newop = ResOperation(opnum, args, descr)
+        newop.count = self.count
+        newop.bytesize = self.bytesize
+        newop.signed = self.signed
         if self.type != 'v':
             newop.copy_value_from(self)
         return newop
@@ -1602,13 +1609,13 @@
         return VecOperationNew(opnum, [arg], arg.type, bytesize, signed, count)
 
     @staticmethod
-    def create_vec(datatype, bytesize, signed):
+    def create_vec(datatype, bytesize, signed, count):
         if datatype == 'i':
             opnum = rop.VEC_I
         else:
             assert datatype == 'f'
             opnum = rop.VEC_F
-        return VecOperationNew(opnum, [], datatype, bytesize, signed, 0)
+        return VecOperationNew(opnum, [], datatype, bytesize, signed, count)
 
     @staticmethod
     def create_vec_pack(datatype, args, bytesize, signed, count):


More information about the pypy-commit mailing list