Author: Richard Plangger <[email protected]>
Branch: vecopt-merge
Changeset: r80032:10f70b96e015
Date: 2015-10-03 10:00 +0200
http://bitbucket.org/pypy/pypy/changeset/10f70b96e015/

Log:    missing restriction on the input arguments of guarding values

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
@@ -250,6 +250,29 @@
         restrict = self.argument_restrictions[index]
         return restrict.bytesize
 
+    def opcount_filling_vector_register(self, op, vec_reg_size):
+        """ How many operations of that kind can one execute
+            with a machine instruction of register size X?
+        """
+        if op.is_typecast():
+            if op.casts_down():
+                size = op.cast_input_bytesize(vec_reg_size)
+                return size // op.cast_from_bytesize()
+            else:
+                return vec_reg_size // op.cast_to_bytesize()
+        return  vec_reg_size // op.bytesize
+
+class GuardRestrict(OpRestrict):
+    def opcount_filling_vector_register(self, op, vec_reg_size):
+        arg = op.getarg(0)
+        return vec_reg_size // arg.bytesize
+
+class LoadRestrict(OpRestrict):
+    def opcount_filling_vector_register(self, op, vec_reg_size):
+        assert op.is_primitive_load()
+        descr = op.getdescr()
+        return vec_reg_size // descr.get_item_size_in_bytes()
+
 class StoreRestrict(OpRestrict):
     def __init__(self, argument_restris):
         self.argument_restrictions = argument_restris
@@ -264,6 +287,11 @@
         descr = op.getdescr()
         return descr.get_item_size_in_bytes()
 
+    def opcount_filling_vector_register(self, op, vec_reg_size):
+        assert op.is_primitive_store()
+        descr = op.getdescr()
+        return vec_reg_size // descr.get_item_size_in_bytes()
+
 class OpMatchSizeTypeFirst(OpRestrict):
     def check_operation(self, state, pack, op):
         i = 0
@@ -293,6 +321,9 @@
 
     OR_MSTF_I = OpMatchSizeTypeFirst([TR_ANY_INTEGER, TR_ANY_INTEGER])
     OR_MSTF_F = OpMatchSizeTypeFirst([TR_ANY_FLOAT, TR_ANY_FLOAT])
+    STORE_RESTRICT = StoreRestrict([None, None, TR_ANY])
+    LOAD_RESTRICT = LoadRestrict([])
+    GUARD_RESTRICT = GuardRestrict([TR_ANY_INTEGER])
 
     # note that the following definition is x86 arch specific
     MAPPING = {
@@ -312,12 +343,19 @@
         rop.VEC_FLOAT_ABS:          OpRestrict([TR_ANY_FLOAT]),
         rop.VEC_FLOAT_NEG:          OpRestrict([TR_ANY_FLOAT]),
 
-        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.VEC_RAW_STORE:          STORE_RESTRICT,
+        rop.VEC_SETARRAYITEM_RAW:   STORE_RESTRICT,
+        rop.VEC_SETARRAYITEM_GC:    STORE_RESTRICT,
 
-        rop.GUARD_TRUE:             OpRestrict([TR_ANY_INTEGER]),
-        rop.GUARD_FALSE:            OpRestrict([TR_ANY_INTEGER]),
+        rop.VEC_RAW_LOAD_I:         LOAD_RESTRICT,
+        rop.VEC_RAW_LOAD_F:         LOAD_RESTRICT,
+        rop.VEC_GETARRAYITEM_RAW_I: LOAD_RESTRICT,
+        rop.VEC_GETARRAYITEM_RAW_F: LOAD_RESTRICT,
+        rop.VEC_GETARRAYITEM_GC_I:  LOAD_RESTRICT,
+        rop.VEC_GETARRAYITEM_GC_F:  LOAD_RESTRICT,
+
+        rop.GUARD_TRUE:             GUARD_RESTRICT,
+        rop.GUARD_FALSE:            GUARD_RESTRICT,
 
         ## irregular
         rop.VEC_INT_SIGNEXT:        OpRestrict([TR_ANY_INTEGER]),
@@ -333,12 +371,19 @@
         rop.VEC_INT_IS_TRUE:        
OpRestrict([TR_ANY_INTEGER,TR_ANY_INTEGER]),
     }
 
+    @staticmethod
+    def get(op):
+        res = trans.MAPPING.get(op.vector, None)
+        if not res:
+            failnbail_transformation("could not get OpRestrict for " + str(op))
+        return res
+
 def turn_into_vector(state, pack):
     """ Turn a pack into a vector instruction """
     check_if_pack_supported(state, pack)
     state.costmodel.record_pack_savings(pack, pack.numops())
     left = pack.leftmost()
-    oprestrict = trans.MAPPING.get(pack.leftmost().vector, None)
+    oprestrict = trans.get(left)
     if oprestrict is not None:
         oprestrict.check_operation(state, pack, left)
     args = left.getarglist_copy()
@@ -733,24 +778,6 @@
                 break
             self.setvector_of_box(arg, i, box)
 
-def opcount_filling_vector_register(pack, vec_reg_size):
-    """ How many operations of that kind can one execute
-        with a machine instruction of register size X?
-    """
-    op = pack.leftmost()
-    if op.returns_void():
-        assert op.is_primitive_store()
-        descr = op.getdescr()
-        return vec_reg_size // descr.get_item_size_in_bytes()
-
-    if op.is_typecast():
-        if op.casts_down():
-            size = op.cast_input_bytesize(vec_reg_size)
-            return size // op.cast_from_bytesize()
-        else:
-            return vec_reg_size // op.cast_to_bytesize()
-    return  vec_reg_size // op.bytesize
-
 class Pack(object):
     """ A pack is a set of n statements that are:
         * isomorphic
@@ -880,8 +907,13 @@
                 break
         pack.update_pack_of_nodes()
 
+    def opcount_filling_vector_register(self, vec_reg_size):
+        left = self.leftmost()
+        oprestrict = trans.get(left)
+        return oprestrict.opcount_filling_vector_register(left, vec_reg_size)
+
     def slice_operations(self, vec_reg_size):
-        count = opcount_filling_vector_register(self, vec_reg_size)
+        count = self.opcount_filling_vector_register(vec_reg_size)
         assert count > 0
         newoplist = self.operations[count:]
         oplist = self.operations[:count]
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
@@ -22,7 +22,6 @@
 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):
@@ -245,12 +244,32 @@
     return  FakeInput(type, datatype, size, signed)
 class BaseTestVectorize(VecTestHelper):
 
-    def test_opcount_filling(self):
+    def test_opcount_filling_store(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),
+        pack = Pack([Node(ResOperation(rop.RAW_STORE, [0,0,arg('f',4)], 
descr), 0),
+                     Node(ResOperation(rop.RAW_STORE, [0,0,arg('f',4)], 
descr), 0),
                     ])
-        assert opcount_filling_vector_register(pack, 16) == 2
+        assert pack.opcount_filling_vector_register(16) == 2
+
+    def test_opcount_filling_guard(self):
+        descr = ArrayDescr(0,4, None, 'S')
+        vec = ResOperation(rop.VEC_RAW_LOAD_I, ['a','i'], descr=descr)
+        vec.count = 4
+        pack = Pack([Node(ResOperation(rop.GUARD_TRUE, [vec]), 0),
+                     Node(ResOperation(rop.GUARD_TRUE, [vec]), 1),
+                     Node(ResOperation(rop.GUARD_TRUE, [vec]), 2),
+                     Node(ResOperation(rop.GUARD_TRUE, [vec]), 3),
+                     Node(ResOperation(rop.GUARD_TRUE, [vec]), 4),
+                     Node(ResOperation(rop.GUARD_TRUE, [vec]), 5),
+                    ])
+        assert pack.opcount_filling_vector_register(16) == 4
+        ops, newops = pack.slice_operations(16)
+        assert len(ops) == 4
+        assert len(newops) == 2
+        assert pack.opcount_filling_vector_register(8) == 2
+        ops, newops = pack.slice_operations(8)
+        assert len(ops) == 2
+        assert len(newops) == 4
 
     def test_move_guard_first(self):
         trace = self.parse_trace("""
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
@@ -125,7 +125,7 @@
                           descr=descr)
     assert (op.type, op.datatype, op.bytesize, op.is_vector()) == ('i', 'i', 
4, True)
 
-def test_store():
+def test_vec_store():
     descr = ArrayDescr(0,8, None, 'F', concrete_type='f')
     vec = rop.InputArgVector()
     op = rop.ResOperation(rop.rop.VEC_RAW_STORE,
@@ -133,6 +133,14 @@
                           descr=descr)
     assert (op.type, op.datatype, op.bytesize, op.is_vector()) == ('v', 'v', 
8, True)
 
+def test_vec_guard():
+    vec = rop.InputArgVector()
+    vec.bytesize = 4
+    vec.type = vec.datatype = 'i'
+    vec.sigend = True
+    op = rop.ResOperation(rop.rop.GUARD_TRUE, [vec])
+    assert (op.type, op.datatype, op.bytesize, op.is_vector()) == ('v', 'i', 
4, False)
+
 def test_types():
     op = rop.ResOperation(rop.rop.INT_ADD, [ConstInt(0),ConstInt(1)])
     assert op.type == 'i'
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to