[pypy-commit] pypy vecopt: added integer/float types to zjit test (int 8, 16, 32, 64, float 32, 64)
plan_rich
noreply at buildbot.pypy.org
Tue May 12 16:21:48 CEST 2015
Author: Richard Plangger <rich at pasra.at>
Branch: vecopt
Changeset: r77298:40afd88ea5d8
Date: 2015-05-12 16:21 +0200
http://bitbucket.org/pypy/pypy/changeset/40afd88ea5d8/
Log: added integer/float types to zjit test (int 8,16,32,64, float 32,64)
extended test_add to use different types than int64/float64 added
vector cast operation (float -> single float) added IR test case to
check if type size differences are handled correctly (when
shrinking) extended the transformation of a pack to a vector
operation. if an operation (like casting) shrinks the size of vector
elements, pack instructions copy them in place
diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -632,8 +632,16 @@
def execute(self, interp):
if self.v == 'int':
dtype = get_dtype_cache(interp.space).w_int64dtype
+ elif self.v == 'int8':
+ dtype = get_dtype_cache(interp.space).w_int8dtype
+ elif self.v == 'int16':
+ dtype = get_dtype_cache(interp.space).w_int16dtype
+ elif self.v == 'int32':
+ dtype = get_dtype_cache(interp.space).w_int32dtype
elif self.v == 'float':
dtype = get_dtype_cache(interp.space).w_float64dtype
+ elif self.v == 'float32':
+ dtype = get_dtype_cache(interp.space).w_float32dtype
else:
raise BadToken('unknown v to dtype "%s"' % self.v)
return dtype
@@ -864,8 +872,20 @@
stack.append(ArrayClass())
elif token.v.strip(' ') == 'int':
stack.append(DtypeClass('int'))
+ elif token.v.strip(' ') == 'int8':
+ stack.append(DtypeClass('int8'))
+ elif token.v.strip(' ') == 'int16':
+ stack.append(DtypeClass('int16'))
+ elif token.v.strip(' ') == 'int32':
+ stack.append(DtypeClass('int32'))
+ elif token.v.strip(' ') == 'int64':
+ stack.append(DtypeClass('int'))
elif token.v.strip(' ') == 'float':
stack.append(DtypeClass('float'))
+ elif token.v.strip(' ') == 'float32':
+ stack.append(DtypeClass('float32'))
+ elif token.v.strip(' ') == 'float64':
+ stack.append(DtypeClass('float'))
else:
stack.append(Variable(token.v.strip(' ')))
elif token.name == 'array_left':
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
@@ -80,26 +80,44 @@
retval = self.interp.eval_graph(self.graph, [i])
return retval
- def define_add():
+ def define_add_float():
return """
a = |30|
b = a + a
b -> 3
"""
- def test_add(self):
- result = self.run("add")
+ def define_add_float32():
+ return """
+ a = astype(|30|, float32)
+ b = a + a
+ b -> 3
+ """
+
+ def test_add_float(self):
+ result = self.run("add_float")
assert result == 3 + 3
+ result = self.run("add_float32")
+ assert result == 3.0 + 3.0
- def define_add_const():
+ def define_add_float32_const():
return """
- a = |30| + 3
+ a = astype(|30|, float32) + 3.0
a -> 29
"""
- def test_add_const(self):
- result = self.run("add_const")
- assert result == 29 + 3
+ def define_add_float_const():
+ return """
+ a = astype(|30|, float32) + 3.0
+ a -> 29
+ """
+
+ def test_add_float_const(self):
+ result = self.run("add_float_const")
+ assert result == 29.0 + 3.0
+ self.check_trace_count(1)
+ result = self.run("add_float32_const")
+ assert result == 29.0 + 3.0
self.check_trace_count(1)
def define_pow():
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
@@ -692,6 +692,9 @@
bh_vec_float_eq.argtypes = ['f','f','i']
bh_vec_float_eq.resulttype = 'i'
+ def bh_vec_cast_float_to_singlefloat(self, vx):
+ return vx
+
def bh_vec_box(self, size):
return [0] * size
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -2549,6 +2549,13 @@
exec py.code.Source(_source).compile()
del genop_vec_float_arith
+ def genop_vec_expand(self, op, arglocs, resloc):
+ loc0, sizeloc = arglocs
+ size = sizeloc.value
+ if size == 2:
+ pass
+
+
def genop_vec_box_unpack(self, op, arglocs, resloc):
loc0, indexloc, sizeloc = arglocs
size = sizeloc.value
diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -1535,16 +1535,6 @@
consider_vec_float_eq = consider_vec_logic
del consider_vec_logic
- def consider_vec_int_signext(self, op):
- # there is not much we can do in this case. arithmetic is
- # done on the vector register, if there is a wrap around,
- # it is lost, because the register does not have enough bits
- # to save it.
- #argloc = self.loc(op.getarg(0))
- self.xrm.force_result_in_reg(op.result, op.getarg(0))
- #if op.getarg(1).value != op.getarg(2).value:
- # raise NotImplementedError("signext not implemented")
-
def consider_vec_box_pack(self, op):
count = op.getarg(3)
index = op.getarg(2)
@@ -1574,6 +1564,24 @@
result = self.force_allocate_reg(op.result, args)
self.perform(op, [loc0, imm(count.value)], result)
+ def consider_vec_cast_float_to_singlefloat(self, op):
+ size = op.getarg(1)
+ args = op.getarglist()
+ loc0 = self.make_sure_var_in_reg(op.getarg(0), args)
+ result = self.force_allocate_reg(op.result, args)
+ self.perform(op, [loc0, imm(size.value)], result)
+
+ def consider_vec_int_signext(self, op):
+ # there is not much we can do in this case. arithmetic is
+ # done on the vector register, if there is a wrap around,
+ # it is lost, because the register does not have enough bits
+ # to save it.
+ #argloc = self.loc(op.getarg(0))
+ self.xrm.force_result_in_reg(op.result, op.getarg(0))
+ #if op.getarg(1).value != op.getarg(2).value:
+ # raise NotImplementedError("signext not implemented")
+
+
def consider_vec_box(self, op):
# pseudo instruction, needed to create a new variable
pass
diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -342,16 +342,11 @@
rop.LABEL,
rop.VEC_RAW_LOAD,
rop.VEC_RAW_STORE,
- rop.VEC_BOX_PACK,
- rop.VEC_BOX_UNPACK,
- rop.VEC_EXPAND,
- rop.VEC_BOX,
rop.VEC_GETARRAYITEM_RAW,
rop.VEC_SETARRAYITEM_RAW,
): # list of opcodes never executed by pyjitpl
continue
- # trace will generate such an op
- if rop._VEC_ARITHMETIC_FIRST <= value <= rop._VEC_ARITHMETIC_LAST:
+ if rop._VEC_PURE_FIRST <= value <= rop._VEC_PURE_LAST:
continue
raise AssertionError("missing %r" % (key,))
diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -512,14 +512,52 @@
# ____________________________________________________________
-class BoxVector(Box):
+class PrimitiveTypeMixin(object):
+ def gettype(self):
+ raise NotImplementedError
+ def getsize(self):
+ raise NotImplementedError
+ def getsigned(self):
+ raise NotImplementedError
+
+ def matches_type(self, other):
+ assert isinstance(other, PrimitiveTypeMixin)
+ return self.gettype() == other.gettype()
+
+ def matches_size(self, other):
+ assert isinstance(other, PrimitiveTypeMixin)
+ return self.getsize() == other.getsize()
+
+ def matches_sign(self, other):
+ assert isinstance(other, PrimitiveTypeMixin)
+ return self.getsigend() == other.signed()
+
+ def matches(self, other):
+ if isinstance(other, PrimitiveTypeMixin):
+ return self.matches_type(other) and \
+ self.matches_size(other) and \
+ self.matches_sign(other)
+ return False
+
+
+
+class BoxVector(Box, PrimitiveTypeMixin):
type = VECTOR
- _attrs_ = ('item_type','item_count')
+ _attrs_ = ('item_type','item_count','item_size','signed')
_extended_display = False
- def __init__(self, item_type=FLOAT, item_count=2):
+ def __init__(self, item_type=FLOAT, item_count=2, item_size=8, signed=True):
self.item_type = item_type
self.item_count = item_count
+ self.item_size = item_size
+ self.signed = signed
+
+ def gettype(self):
+ return self.item_type
+ def getsize(self):
+ return self.item_size
+ def getsigned(self):
+ return self.signed
def forget_value(self):
raise NotImplementedError("cannot forget value of vector")
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py b/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_vectorize.py
@@ -1109,6 +1109,41 @@
except NotAVectorizeableLoop:
pass
+ def test_shrink_vector_size(self):
+ ops = """
+ [p0,p1,i1]
+ guard_early_exit() []
+ f1 = getarrayitem_raw(p0, i1, descr=floatarraydescr)
+ i2 = cast_float_to_singlefloat(f1)
+ setarrayitem_raw(p1, i1, i2, descr=singlefloatarraydescr)
+ i3 = int_add(i1, 1)
+ i4 = int_ge(i3, 36)
+ guard_false(i4) []
+ jump(p0, p1, i3)
+ """
+ opt = """
+ [p0, p1, i1]
+ guard_early_exit() []
+ i3 = int_add(i1, 1)
+ i4 = int_ge(i3, 36)
+ i5 = int_add(i1, 2)
+ i8 = int_ge(i5, 36)
+ i6 = int_add(i1, 3)
+ i11 = int_ge(i6, 36)
+ i7 = int_add(i1, 4)
+ i14 = int_ge(i7, 36)
+ guard_false(i14) []
+ v17 = vec_getarrayitem_raw(p0, i1, 2, descr=floatarraydescr)
+ v18 = vec_getarrayitem_raw(p0, i5, 2, descr=floatarraydescr)
+ v19 = vec_cast_float_to_singlefloat(v17, 2)
+ v20 = vec_cast_float_to_singlefloat(v18, 2)
+ v21 = vec_box(4)
+ vec_box_pack(v21, v20, 2)
+ vec_setarrayitem_raw(p1, i1, v21, 4, descr=singlefloatarraydescr)
+ jump(p0, p1, i7)
+ """
+ vopt = self.vectorize(self.parse_loop(ops))
+ self.assert_equal(vopt.loop, self.parse_loop(opt))
class TestLLtype(BaseTestVectorize, LLtypeMixin):
diff --git a/rpython/jit/metainterp/optimizeopt/vectorize.py b/rpython/jit/metainterp/optimizeopt/vectorize.py
--- a/rpython/jit/metainterp/optimizeopt/vectorize.py
+++ b/rpython/jit/metainterp/optimizeopt/vectorize.py
@@ -5,7 +5,7 @@
from rpython.jit.metainterp.optimizeopt.unroll import optimize_unroll
from rpython.jit.metainterp.compile import ResumeAtLoopHeaderDescr
from rpython.jit.metainterp.history import (ConstInt, VECTOR, FLOAT, INT,
- BoxVector, TargetToken, JitCellToken, Box)
+ BoxVector, TargetToken, JitCellToken, Box, PrimitiveTypeMixin)
from rpython.jit.metainterp.optimizeopt.optimizer import Optimizer, Optimization
from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
from rpython.jit.metainterp.optimizeopt.dependency import (DependencyGraph,
@@ -300,11 +300,9 @@
if node_a.is_before(node_b):
if memref_a.is_adjacent_to(memref_b):
if self.packset.can_be_packed(node_a, node_b):
- self.packset.add_pair(node_a, node_b)
- #if memref_a.is_adjacent_with_runtime_check(memref_b, graph):
- # if self.packset.can_be_packed(node_a, node_b):
- # self.check_adjacent_at_runtime(memref_a, memref_b)
- # self.packset.add_pair(node_a, node_b)
+ pair = Pair(node_a,node_b)
+ pair.ptype = PackType.by_descr(node_a.getoperation().getdescr())
+ self.packset.packs.append(pair)
def extend_packset(self):
pack_count = self.packset.pack_count()
@@ -346,7 +344,7 @@
if savings >= 0:
assert candidate[0] is not None
assert candidate[1] is not None
- self.packset.add_pair(*candidate)
+ self.packset.add_pair(candidate[0], candidate[1])
def combine_packset(self):
if len(self.packset.packs) == 0:
@@ -373,11 +371,12 @@
i += 1
if len_before == len(self.packset.packs):
break
+ print self.packset.packs
def schedule(self):
self.guard_early_exit = -1
self.clear_newoperations()
- sched_data = VecScheduleData()
+ sched_data = VecScheduleData(self.metainterp_sd.cpu.vector_register_size)
scheduler = Scheduler(self.dependency_graph, sched_data)
while scheduler.has_more():
position = len(self._newoperations)
@@ -553,12 +552,50 @@
# this might be an indicator for edge removal
return True
+class PackArgs(object):
+ def __init__(self, arg_pos, result=True):
+ self.mask = 0
+ for p in arg_pos:
+ self.mask |= (1<<(p+1))
+ if result:
+ self.mask |= 1
+
+ def arg_is_set(self, i):
+ return bool((1<<(i+1)) & self.mask)
+
+ def result_is_set(self):
+ return bool(1 & self.mask)
+
+
+ROP_ARG_RES_VECTOR = {
+ rop.VEC_INT_ADD: PackArgs((0,1)),
+ rop.VEC_INT_SUB: PackArgs((0,1)),
+ rop.VEC_INT_MUL: PackArgs((0,1)),
+ rop.VEC_INT_SIGNEXT: PackArgs((0,)),
+
+ rop.VEC_FLOAT_ADD: PackArgs((0,1)),
+ rop.VEC_FLOAT_SUB: PackArgs((0,1)),
+ rop.VEC_FLOAT_MUL: PackArgs((0,1)),
+ rop.VEC_FLOAT_EQ: PackArgs((0,1)),
+
+ rop.VEC_RAW_LOAD: PackArgs(()),
+ rop.VEC_GETARRAYITEM_RAW: PackArgs(()),
+ rop.VEC_RAW_STORE: PackArgs((2,), result=False),
+ rop.VEC_SETARRAYITEM_RAW: PackArgs((2,), result=False),
+
+ rop.VEC_CAST_FLOAT_TO_SINGLEFLOAT: PackArgs((0,)),
+}
+
+
class VecScheduleData(SchedulerData):
- def __init__(self):
+ def __init__(self, vec_reg_size):
self.box_to_vbox = {}
self.unpack_rename_map = {}
self.preamble_ops = None
self.expansion_byte_count = -1
+ self.vec_reg_size = vec_reg_size
+ self.pack_ops = -1
+ self.pack_off = -1
def unpack_rename(self, arg):
return self.unpack_rename_map.get(arg, arg)
@@ -572,15 +609,57 @@
self.pack = pack
# properties that hold for the pack are:
# isomorphism (see func above)
- op0 = pack.operations[0].getoperation()
+
+ if pack.ptype is None:
+ self.propagete_ptype()
+
+ self.preamble_ops = []
+ if pack.is_overloaded(self.vec_reg_size):
+ self.preamble_ops = []
+ stride = pack.size_in_bytes() // self.vec_reg_size
+ for i in range(0, op_count, stride):
+ self.pack_off = i
+ self.pack_ops = stride
+ self._as_vector_op()
+ return self.preamble_ops
+ else:
+ self.pack_off = 0
+ self.pack_ops = op_count
+ self._as_vector_op()
+ return self.preamble_ops
+
+ def _as_vector_op(self):
+ op0 = self.pack.operations[self.pack_off].getoperation()
assert op0.vector != -1
args = op0.getarglist()[:]
- args.append(ConstInt(op_count))
+ args.append(ConstInt(self.pack_ops))
vop = ResOperation(op0.vector, args, op0.result, op0.getdescr())
- self.preamble_ops = []
- self._inspect_operation(vop)
+
+ packargs = ROP_ARG_RES_VECTOR.get(op0.vector, None)
+ if packargs is None:
+ raise NotImplementedError("vecop map entry missing. trans: pack -> vop")
+
+ for i,arg in enumerate(args):
+ if packargs.arg_is_set(i):
+ self.vector_arg(vop, i, True)
+ if packargs.result_is_set():
+ self.vector_result(vop)
+
self.preamble_ops.append(vop)
- return self.preamble_ops
+
+ def propagete_ptype(self):
+ op0 = self.pack.operations[self.pack_off].getoperation()
+ packargs = ROP_ARG_RES_VECTOR.get(op0.vector, None)
+ if packargs is None:
+ raise NotImplementedError("vecop map entry missing. trans: pack -> vop")
+ args = op0.getarglist()[:]
+ ptype = PackType(PackType.UNKNOWN_TYPE, 0, True)
+ for i,arg in enumerate(args):
+ if packargs.arg_is_set(i):
+ vbox = self.get_vbox_for(arg)
+ ptype.record_vbox(vbox)
+ self.pack.ptype = ptype
+
def get_vbox_for(self, arg):
try:
@@ -589,18 +668,21 @@
except KeyError:
return None
- def vector_result(self, vop, type):
+ def vector_result(self, vop):
ops = self.pack.operations
result = vop.result
- vbox = BoxVector(type, len(ops))
- vop.result = vbox
- i = 0
- while i < len(ops):
+ vop.result = vbox = self.box_vector(self.pack.ptype)
+ i = self.pack_off
+ end = i + self.pack_ops
+ while i < end:
op = ops[i].getoperation()
self.box_to_vbox[op.result] = (i, vbox)
i += 1
- def vector_arg(self, vop, argidx, expand=True):
+ def box_vector(self, ptype):
+ return BoxVector(ptype.type, self.pack_ops, ptype.size, ptype.signed)
+
+ def vector_arg(self, vop, argidx, expand):
ops = self.pack.operations
vbox = self.get_vbox_for(vop.getarg(argidx))
if not vbox:
@@ -609,26 +691,50 @@
else:
assert False, "not allowed to expand" \
", but do not have a vector box as arg"
+ # vbox is a primitive type mixin
+ if self.pack.ptype.getsize() < vbox.getsize():
+ packable = self.vec_reg_size // self.pack.ptype.getsize()
+ packed = vbox.item_count
+ vbox = self.pack_arguments(packed, [op.getoperation().getarg(argidx) for op in ops])
vop.setarg(argidx, vbox)
return vbox
+ def pack_arguments(self, index, args):
+ i = index
+ vbox = self.box_vector(self.pack.ptype)
+ op = ResOperation(rop.VEC_BOX, [ConstInt(len(args))], vbox)
+ self.preamble_ops.append(op)
+ arg_count = len(args)
+ while i < arg_count:
+ arg = args[i]
+ vbox2 = self.get_vbox_for(arg)
+ if vbox2 is None:
+ raise NotImplementedError
+ op = ResOperation(rop.VEC_BOX_PACK, [vbox, vbox2, ConstInt(i)], None)
+ self.preamble_ops.append(op)
+ i += vbox.item_count
+ return vbox
+
def expand_box_to_vector_box(self, vop, argidx):
arg = vop.getarg(argidx)
all_same_box = True
ops = self.pack.operations
- for i in range(len(ops)):
+ i = self.pack_off
+ end = i + self.pack_ops
+ while i < end:
op = ops[i]
if arg is not op.getoperation().getarg(argidx):
all_same_box = False
break
+ i += 1
- vbox = BoxVector(arg.type, len(ops))
- print "creating vectorbox", vbox, "of type",arg.type
+ vbox = BoxVector(arg.type, self.pack_ops)
+ print "creating vectorbox", vbox, "of type", arg.type
if all_same_box:
- expand_op = ResOperation(rop.VEC_EXPAND, [arg, ConstInt(len(ops))], vbox)
+ expand_op = ResOperation(rop.VEC_EXPAND, [arg, ConstInt(self.pack_ops)], vbox)
self.preamble_ops.append(expand_op)
else:
- resop = ResOperation(rop.VEC_BOX, [ConstInt(len(ops))], vbox)
+ resop = ResOperation(rop.VEC_BOX, [ConstInt(self.pack_ops)], vbox)
self.preamble_ops.append(resop)
for i,op in enumerate(ops):
arg = op.getoperation().getarg(argidx)
@@ -637,43 +743,6 @@
self.preamble_ops.append(resop)
return vbox
- bin_arith_trans = """
- def _vectorize_{name}(self, vop):
- self.vector_arg(vop, 0)
- self.vector_arg(vop, 1)
- self.vector_result(vop, vop.result.type)
- """
- for name in ['VEC_FLOAT_SUB','VEC_FLOAT_MUL','VEC_FLOAT_ADD',
- 'VEC_INT_ADD','VEC_INT_MUL', 'VEC_INT_SUB',
- ]:
- exec py.code.Source(bin_arith_trans.format(name=name)).compile()
- del bin_arith_trans
-
- def _vectorize_VEC_FLOAT_EQ(self, vop):
- self.vector_arg(vop, 0)
- self.vector_arg(vop, 1)
- self.vector_result(vop, INT)
-
- def _vectorize_VEC_INT_SIGNEXT(self, vop):
- self.vector_arg(vop, 0)
- # arg 1 is a constant
- self.vector_result(vop, vop.result.type)
-
- def _vectorize_VEC_RAW_LOAD(self, vop):
- descr = vop.getdescr()
- self.vector_result(vop, vop.result.type)
- def _vectorize_VEC_GETARRAYITEM_RAW(self, vop):
- descr = vop.getdescr()
- self.vector_result(vop, vop.result.type)
-
- def _vectorize_VEC_RAW_STORE(self, vop):
- self.vector_arg(vop, 2)
- def _vectorize_VEC_SETARRAYITEM_RAW(self, vop):
- self.vector_arg(vop, 2)
-
-VecScheduleData._inspect_operation = \
- make_dispatcher_method(VecScheduleData, '_vectorize_')
-
def isomorphic(l_op, r_op):
""" Same instructions have the same operation name.
TODO what about parameters?
@@ -682,6 +751,45 @@
return True
return False
+class PackType(PrimitiveTypeMixin):
+ UNKNOWN_TYPE = '-'
+
+ def __init__(self, type, size, signed):
+ self.type = type
+ self.size = size
+ self.signed = signed
+
+ def gettype(self):
+ return self.type
+
+ def getsize(self):
+ return self.size
+
+ def getsigned(self):
+ return self.signed
+
+ def get_byte_size(self):
+ return self.size
+
+ @staticmethod
+ def by_descr(descr):
+ _t = INT
+ if descr.is_array_of_floats():
+ _t = FLOAT
+ pt = PackType(_t, descr.get_item_size_in_bytes(), descr.is_item_signed())
+ return pt
+
+ def record_vbox(self, vbox):
+ if self.type == PackType.UNKNOWN_TYPE:
+ self.type = vbox.type
+ self.signed = vbox.signed
+ if vbox.item_size > self.size:
+ self.size = vbox.item_size
+
+ def __repr__(self):
+ return 'PackType(%s, %s, %s)' % (self.type, self.size, self.signed)
+
+
class PackSet(object):
def __init__(self, dependency_graph, operations, unroll_count,
@@ -696,9 +804,8 @@
return len(self.packs)
def add_pair(self, l, r):
- if l.op.is_guard():
- assert False
- self.packs.append(Pair(l,r))
+ p = Pair(l,r)
+ self.packs.append(p)
def can_be_packed(self, lnode, rnode):
if isomorphic(lnode.getoperation(), rnode.getoperation()):
@@ -755,8 +862,8 @@
operations = pack_i.operations
for op in pack_j.operations[1:]:
operations.append(op)
- self.packs[i] = Pack(operations)
-
+ self.packs[i] = pack = Pack(operations)
+ pack.ptype = pack_i.ptype
# instead of deleting an item in the center of pack array,
# the last element is assigned to position j and
@@ -784,6 +891,7 @@
def __init__(self, ops):
self.operations = ops
self.savings = 0
+ self.ptype = None
for node in self.operations:
node.pack = self
@@ -797,6 +905,13 @@
leftmost = other.operations[0]
return rightmost == leftmost
+ def size_in_bytes(self):
+ return self.ptype.get_byte_size() * len(self.operations)
+
+ def is_overloaded(self, vec_reg_byte_size):
+ size = self.size_in_bytes()
+ return size > vec_reg_byte_size
+
def __repr__(self):
return "Pack(%r)" % self.operations
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
@@ -451,6 +451,7 @@
'CONVERT_LONGLONG_BYTES_TO_FLOAT/1',
#
# vector operations
+ '_VEC_PURE_FIRST',
'_VEC_ARITHMETIC_FIRST',
'VEC_INT_ADD/3',
'VEC_INT_SUB/3',
@@ -459,13 +460,17 @@
'VEC_FLOAT_SUB/3',
'VEC_FLOAT_MUL/3',
'VEC_FLOAT_DIV/3',
+ '_VEC_ARITHMETIC_LAST',
'VEC_FLOAT_EQ/3',
+
'VEC_INT_SIGNEXT/3',
- '_VEC_ARITHMETIC_LAST',
+ 'VEC_CAST_FLOAT_TO_SINGLEFLOAT/2',
+
'VEC_BOX_UNPACK/3', # iX|fX = VEC_BOX_UNPACK(vX, index, item_count)
'VEC_BOX_PACK/4', # VEC_BOX_PACK(vX, var/const, index, item_count)
'VEC_EXPAND/2', # vX = VEC_EXPAND(var/const, item_count)
'VEC_BOX/1',
+ '_VEC_PURE_LAST',
#
'INT_LT/2b',
'INT_LE/2b',
@@ -716,7 +721,6 @@
_opvector = {
rop.RAW_LOAD: rop.VEC_RAW_LOAD,
rop.GETARRAYITEM_RAW: rop.VEC_GETARRAYITEM_RAW,
-
rop.RAW_STORE: rop.VEC_RAW_STORE,
rop.SETARRAYITEM_RAW: rop.VEC_SETARRAYITEM_RAW,
@@ -730,6 +734,7 @@
rop.FLOAT_EQ: rop.VEC_FLOAT_EQ,
rop.INT_SIGNEXT: rop.VEC_INT_SIGNEXT,
+ rop.CAST_FLOAT_TO_SINGLEFLOAT: rop.VEC_CAST_FLOAT_TO_SINGLEFLOAT,
}
def setup2():
More information about the pypy-commit
mailing list