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