Author: Richard Plangger <planri...@gmail.com>
Branch: vecopt-merge
Changeset: r79930:569c929fd2a1
Date: 2015-10-02 14:53 +0200
http://bitbucket.org/pypy/pypy/changeset/569c929fd2a1/

Log:    store operations did not correctly split packs (wrong size used) and
        thus did not sign extend correctly some times

diff --git a/pypy/module/micronumpy/test/test_zjit.py 
b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -844,7 +844,7 @@
     def test_where(self):
         result = self.run("where")
         assert result == -40
-        self.check_vectorized(1, 0) # TODO might be possible to vectorize
+        self.check_vectorized(1, 1)
 
     def define_searchsorted():
         return """
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
@@ -235,6 +235,34 @@
     def check_operation(self, state, pack, op):
         pass
 
+    def crop_vector(self, op, newsize, size):
+        return newsize, size
+
+    def must_crop_vector(self, op, index):
+        restrict = self.argument_restrictions[index]
+        size = op.getarg(index).bytesize
+        newsize = self.crop_to_size(op, index)
+        return not restrict.any_size() and newsize != size
+
+    @always_inline
+    def crop_to_size(self, op, index):
+        restrict = self.argument_restrictions[index]
+        return restrict.bytesize
+
+class StoreRestrict(OpRestrict):
+    def __init__(self, argument_restris):
+        self.argument_restrictions = argument_restris
+
+    def must_crop_vector(self, op, index):
+        size = op.getarg(index).bytesize
+        return self.crop_to_size(op, index) != size
+
+    @always_inline
+    def crop_to_size(self, op, index):
+        # there is only one parameter that needs to be transformed!
+        descr = op.getdescr()
+        return descr.get_item_size_in_bytes()
+
 class OpMatchSizeTypeFirst(OpRestrict):
     def check_operation(self, state, pack, op):
         i = 0
@@ -283,9 +311,9 @@
         rop.VEC_FLOAT_ABS:          OpRestrict([TR_ANY_FLOAT]),
         rop.VEC_FLOAT_NEG:          OpRestrict([TR_ANY_FLOAT]),
 
-        rop.VEC_RAW_STORE:          OpRestrict([None, None, TR_ANY]),
-        rop.VEC_SETARRAYITEM_RAW:   OpRestrict([None, None, TR_ANY]),
-        rop.VEC_SETARRAYITEM_GC:    OpRestrict([None, None, TR_ANY]),
+        rop.VEC_RAW_STORE:          StoreRestrict([None, None, TR_ANY]),
+        rop.VEC_SETARRAYITEM_RAW:   StoreRestrict([None, None, TR_ANY]),
+        rop.VEC_SETARRAYITEM_GC:    StoreRestrict([None, None, TR_ANY]),
 
         rop.GUARD_TRUE:             OpRestrict([TR_ANY_INTEGER]),
         rop.GUARD_FALSE:            OpRestrict([TR_ANY_INTEGER]),
@@ -361,16 +389,18 @@
         # 1)
         args[i] = vecop # a)
         assemble_scattered_values(state, pack, args, i) # c)
-        crop_vector(state, restrict, pack, args, i) # b)
+        crop_vector(state, oprestrict, restrict, pack, args, i) # b)
         position_values(state, restrict, pack, args, i, pos) # d)
         restrict.check(args[i])
 
 @always_inline
-def crop_vector(state, restrict, pack, args, i):
+def crop_vector(state, oprestrict, restrict, pack, args, i):
     # convert size i64 -> i32, i32 -> i64, ...
     arg = args[i]
-    newsize, size = restrict.bytesize, arg.bytesize
-    if not restrict.any_size() and newsize != size:
+    size = arg.bytesize
+    left = pack.leftmost()
+    if oprestrict.must_crop_vector(left, i):
+        newsize = oprestrict.crop_to_size(left, i)
         assert arg.type == 'i'
         state._prevent_signext(newsize, size)
         count = arg.count
@@ -713,8 +743,8 @@
     op = pack.leftmost()
     if op.returns_void():
         assert op.is_primitive_store()
-        arg = op.getarg(2)
-        return vec_reg_size // arg.bytesize
+        descr = op.getdescr()
+        return vec_reg_size // descr.get_item_size_in_bytes()
 
     if op.is_typecast():
         if op.casts_down():
@@ -788,8 +818,9 @@
             if left.is_primitive_store():
                 # make this case more general if it turns out this is
                 # not the only case where packs need to be trashed
-                indexarg = left.getarg(2)
-                return indexarg.bytesize * self.numops() - vec_reg_size
+                descr = left.getdescr()
+                bytesize = descr.get_item_size_in_bytes()
+                return bytesize * self.numops() - vec_reg_size
             return 0
         if self.numops() == 0:
             return -1
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_schedule.py 
b/rpython/jit/metainterp/optimizeopt/test/test_schedule.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_schedule.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_schedule.py
@@ -11,16 +11,11 @@
 from rpython.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin
 from rpython.jit.metainterp.optimizeopt.test.test_dependency import 
(DependencyBaseTest)
 from rpython.jit.metainterp.optimizeopt.test.test_vecopt import 
(FakeMetaInterpStaticData,
-        FakeJitDriverStaticData)
+        FakeJitDriverStaticData, FakePackSet)
 from rpython.jit.metainterp.resoperation import rop, ResOperation
 from rpython.jit.tool.oparser import parse as opparse
 from rpython.jit.tool.oparser_model import get_model
 
-class FakePackSet(PackSet):
-    def __init__(self, packs):
-        self.packs = packs
-        self.vec_reg_size = 16
-
 class FakeVecScheduleState(VecScheduleState):
     def __init__(self):
         self.expanded_map = {}
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py 
b/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py
@@ -13,17 +13,26 @@
 from rpython.jit.metainterp.optimizeopt.dependency import DependencyGraph
 from rpython.jit.metainterp.optimizeopt.vector import (VectorizingOptimizer,
         MemoryRef, isomorphic, Pair, NotAVectorizeableLoop, VectorLoop,
-        NotAProfitableLoop, GuardStrengthenOpt, CostModel, X86_CostModel)
+        NotAProfitableLoop, GuardStrengthenOpt, CostModel, X86_CostModel,
+        PackSet)
 from rpython.jit.metainterp.optimizeopt.schedule import (Scheduler,
-        SchedulerState, VecScheduleState)
+        SchedulerState, VecScheduleState, Pack)
 from rpython.jit.metainterp.optimize import InvalidLoop
 from rpython.jit.metainterp import compile
 from rpython.jit.metainterp.resoperation import rop, ResOperation
 from rpython.jit.metainterp.optimizeopt.version import LoopVersionInfo
+from rpython.jit.backend.llsupport.descr import ArrayDescr
+from rpython.jit.metainterp.optimizeopt.schedule import 
opcount_filling_vector_register
+from rpython.jit.metainterp.optimizeopt.dependency import Node, DependencyGraph
 
 class FakeJitDriverStaticData(object):
     vec=True
 
+class FakePackSet(PackSet):
+    def __init__(self, packs):
+        self.packs = packs
+        self.vec_reg_size = 16
+
 class FakeLoopInfo(LoopVersionInfo):
     def __init__(self, loop):
         self.target_token = loop.label.getdescr()
@@ -225,8 +234,24 @@
             "operation %s at pos %d has no memory ref!" % \
                 (node.getoperation(), node.getindex())
 
+class FakeInput(object):
+    def __init__(self, type='f', datatype='f', size=8, signed=False):
+        self.type = type
+        self.datatype = datatype
+        self.bytesize = size
+        self.signed = signed
+
+def arg(type='f', size=8, signed=False, datatype='f'):
+    return  FakeInput(type, datatype, size, signed)
 class BaseTestVectorize(VecTestHelper):
 
+    def test_opcount_filling(self):
+        descr = ArrayDescr(0,8, None, 'F', concrete_type='f')
+        pack = Pack([Node(ResOperation(rop.VEC_RAW_STORE, [0,0,arg('f',4)], 
descr), 0),
+                     Node(ResOperation(rop.VEC_RAW_STORE, [0,0,arg('f',4)], 
descr), 0),
+                    ])
+        assert opcount_filling_vector_register(pack, 16) == 2
+
     def test_move_guard_first(self):
         trace = self.parse_trace("""
         i10 = int_add(i0, i1)
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
@@ -123,10 +123,6 @@
                 from rpython.jit.backend.llgraph.runner import _getdescr
                 descr = _getdescr(self)
             type = self.type
-            if descr.is_array_of_floats():
-                type = 'f'
-            #if isinstance(descr, ArrayDescr) and descr.getconcrete_type() == 
'f':
-            #    type = 'f'
             self.bytesize = descr.get_item_size_in_bytes()
             self.signed = descr.is_item_signed()
             self.datatype = type
diff --git a/rpython/jit/metainterp/test/test_resoperation.py 
b/rpython/jit/metainterp/test/test_resoperation.py
--- a/rpython/jit/metainterp/test/test_resoperation.py
+++ b/rpython/jit/metainterp/test/test_resoperation.py
@@ -124,7 +124,14 @@
                           [rop.InputArgInt(), ConstInt(0)],
                           descr=descr)
     assert (op.type, op.datatype, op.bytesize, op.is_vector()) == ('i', 'i', 
4, True)
-    
+
+def test_store():
+    descr = ArrayDescr(0,8, None, 'F', concrete_type='f')
+    vec = rop.InputArgVector()
+    op = rop.ResOperation(rop.rop.VEC_RAW_STORE,
+                          [rop.InputArgRef(), ConstInt(0), vec],
+                          descr=descr)
+    assert (op.type, op.datatype, op.bytesize, op.is_vector()) == ('v', 'v', 
8, True)
 
 def test_types():
     op = rop.ResOperation(rop.rop.INT_ADD, [ConstInt(0),ConstInt(1)])
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to