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