[pypy-commit] pypy vecopt-merge: only one test for llgraph failing
plan_rich
noreply at buildbot.pypy.org
Thu Sep 24 12:53:09 CEST 2015
Author: Richard Plangger <planrichi at gmail.com>
Branch: vecopt-merge
Changeset: r79808:ed1cb45ccbd1
Date: 2015-09-24 12:53 +0200
http://bitbucket.org/pypy/pypy/changeset/ed1cb45ccbd1/
Log: only one test for llgraph failing
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
@@ -799,8 +799,8 @@
# vector operations
vector_arith_code = """
- def bh_vec_{0}_{1}(self, vx, vy):
- assert len(vx) == len(vy)
+ def bh_vec_{0}_{1}(self, vx, vy, count):
+ assert len(vx) == len(vy) == count
return [_vx {2} _vy for _vx,_vy in zip(vx,vy)]
"""
exec py.code.Source(vector_arith_code.format('int','add','+')).compile()
@@ -812,59 +812,66 @@
exec py.code.Source(vector_arith_code.format('float','truediv','/')).compile()
exec py.code.Source(vector_arith_code.format('float','eq','==')).compile()
- def bh_vec_float_neg(self, vx):
+ def bh_vec_float_neg(self, vx, count):
return [e * -1 for e in vx]
- def bh_vec_float_abs(self, vx):
+ def bh_vec_float_abs(self, vx, count):
return [abs(e) for e in vx]
- def bh_vec_float_eq(self, vx, vy):
- assert len(vx) == len(vy)
+ def bh_vec_float_eq(self, vx, vy, count):
+ assert len(vx) == len(vy) == count
return [_vx == _vy for _vx,_vy in zip(vx,vy)]
- def bh_vec_float_ne(self, vx, vy):
- assert len(vx) == len(vy)
+ def bh_vec_float_ne(self, vx, vy, count):
+ assert len(vx) == len(vy) == count
return [_vx != _vy for _vx,_vy in zip(vx,vy)]
bh_vec_int_eq = bh_vec_float_eq
bh_vec_int_ne = bh_vec_float_ne
- def bh_vec_int_xor(self, vx, vy):
+ def bh_vec_int_xor(self, vx, vy, count):
return [int(x) ^ int(y) for x,y in zip(vx,vy)]
- def bh_vec_float_pack(self, vector, value, index, count):
- if isinstance(value, list):
- for i in range(count):
- vector[index + i] = value[i]
- else:
- vector[index] = value
- return vector
-
- def bh_vec_cast_float_to_singlefloat(self, vx):
+ def bh_vec_cast_float_to_singlefloat(self, vx, count):
return vx
- def bh_vec_box(self, size):
- return [0] * size
+ def bh_vec_f(self, count):
+ return [0.0] * count
- def bh_vec_box_pack(self, vx, index, y):
- vx[index] = y
+ def bh_vec_i(self, count):
+ return [0] * count
- def bh_vec_box_unpack(self, vx, index):
- return vx[index]
+ def _bh_vec_pack(self, tv, sv, index, count, _):
+ if not isinstance(sv, list):
+ tv[index] = sv
+ return tv
+ for i in range(count):
+ tv[index+i] = sv[i]
+ return tv
- def bh_vec_float_expand(self, x, count):
+ bh_vec_pack_f = _bh_vec_pack
+ bh_vec_pack_i = _bh_vec_pack
+
+ def _bh_vec_unpack(self, vx, index, count):
+ return vx[index:index+count]
+
+ bh_vec_unpack_f = _bh_vec_unpack
+ bh_vec_unpack_i = _bh_vec_unpack
+
+ def _bh_vec_expand(self, x, count):
return [x] * count
- def bh_vec_int_expand(self, x, count):
- return [x] * count
+ bh_vec_expand_f = _bh_vec_expand
+ bh_vec_expand_i = _bh_vec_expand
- def bh_vec_int_signext(self, vx, ext):
+ def bh_vec_int_signext(self, vx, ext, count):
return [heaptracker.int_signext(_vx, ext) for _vx in vx]
def build_getarrayitem(func):
- def method(self, struct, offset, descr):
+ def method(self, struct, offset, descr, _count):
values = []
count = self.vector_register_size // descr.get_item_size_in_bytes()
+ assert _count == count
assert count > 0
for i in range(count):
val = func(self, struct, offset + i, descr)
@@ -878,10 +885,11 @@
bh_vec_getarrayitem_raw_f = build_getarrayitem(bh_getarrayitem_raw)
del build_getarrayitem
- def _bh_vec_raw_load(self, struct, offset, descr):
+ def _bh_vec_raw_load(self, struct, offset, descr, _count):
values = []
stride = descr.get_item_size_in_bytes()
count = self.vector_register_size // descr.get_item_size_in_bytes()
+ assert _count == count
assert count > 0
for i in range(count):
val = self.bh_raw_load(struct, offset + i*stride, descr)
@@ -891,16 +899,16 @@
bh_vec_raw_load_i = _bh_vec_raw_load
bh_vec_raw_load_f = _bh_vec_raw_load
- def bh_vec_raw_store(self, struct, offset, newvalues, descr):
+ def bh_vec_raw_store(self, struct, offset, newvalues, descr, count):
stride = descr.get_item_size_in_bytes()
for i,n in enumerate(newvalues):
self.bh_raw_store(struct, offset + i*stride, n, descr)
- def bh_vec_setarrayitem_raw(self, struct, offset, newvalues, descr):
+ def bh_vec_setarrayitem_raw(self, struct, offset, newvalues, descr, count):
for i,n in enumerate(newvalues):
self.bh_setarrayitem_raw(struct, offset + i, n, descr)
- def bh_vec_setarrayitem_gc(self, struct, offset, newvalues, descr):
+ def bh_vec_setarrayitem_gc(self, struct, offset, newvalues, descr, count):
for i,n in enumerate(newvalues):
self.bh_setarrayitem_gc(struct, offset + i, n, descr)
@@ -1026,9 +1034,9 @@
i = accuminfo.getpos_in_failargs()
value = values[i]
assert isinstance(value, list)
- if accum.operator == '+':
+ if accuminfo.accum_operation == '+':
value = sum(value)
- elif accum.operator == '*':
+ elif accuminfo.accum_operation == '*':
def prod(acc, x): return acc * x
value = reduce(prod, value, 1)
else:
@@ -1404,6 +1412,10 @@
new_args = args + (descr,)
else:
new_args = args
+ if opname.startswith('vec_'):
+ count = self.current_op.count
+ assert count > 1
+ new_args = new_args + (count,)
return getattr(self.cpu, 'bh_' + opname)(*new_args)
execute.func_name = 'execute_' + opname
return execute
diff --git a/rpython/jit/metainterp/logger.py b/rpython/jit/metainterp/logger.py
--- a/rpython/jit/metainterp/logger.py
+++ b/rpython/jit/metainterp/logger.py
@@ -134,6 +134,9 @@
return str(arg.getfloatstorage())
elif arg is None:
return 'None'
+ elif arg.is_vector():
+ suffix = '[%dx%s%d]' % (arg.count, arg.datatype, arg.bytesize * 8)
+ return 'v' + str(mv) + suffix
elif arg.type == 'i':
return 'i' + str(mv)
elif arg.type == 'r':
diff --git a/rpython/jit/metainterp/optimizeopt/guard.py b/rpython/jit/metainterp/optimizeopt/guard.py
--- a/rpython/jit/metainterp/optimizeopt/guard.py
+++ b/rpython/jit/metainterp/optimizeopt/guard.py
@@ -149,10 +149,6 @@
assert operations[self.index] is self.op
operations[self.index] = None
descr = self.op.getdescr()
- # TODO loop.version_info.remove(descr)
- #if descr and descr.loop_version():
- # assert isinstance(descr, CompileLoopVersionDescr)
- # descr.version = None
if operations[self.index-1] is self.cmp_op:
operations[self.index-1] = None
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
@@ -28,12 +28,18 @@
loop.operations = self.oplist
loop.prefix = self.invariant_oplist
if len(self.invariant_vector_vars) + len(self.invariant_oplist) > 0:
+ # label
args = loop.label.getarglist_copy() + self.invariant_vector_vars
opnum = loop.label.getopnum()
- # TODO descr?
op = loop.label.copy_and_change(opnum, args)
self.renamer.rename(op)
loop.prefix_label = op
+ # jump
+ args = loop.jump.getarglist_copy() + self.invariant_vector_vars
+ opnum = loop.jump.getopnum()
+ op = loop.jump.copy_and_change(opnum, args)
+ self.renamer.rename(op)
+ loop.jump = op
def profitable(self):
return True
@@ -56,9 +62,11 @@
def ensure_args_unpacked(self, op):
pass
- def post_emit(self, op):
+ def post_emit(self, node):
pass
+ def pre_emit(self, node):
+ pass
class Scheduler(object):
""" Create an instance of this class to (re)schedule a vector trace. """
@@ -123,7 +131,7 @@
state.renamer.rename(op)
if unpack:
state.ensure_args_unpacked(op)
- state.post_emit(node.getoperation())
+ state.post_emit(node)
def walk_and_emit(self, state):
""" Emit all the operations into the oplist parameter.
@@ -134,6 +142,7 @@
if node:
if not state.emit(node, self):
if not node.emitted:
+ state.pre_emit(node)
self.mark_emitted(node, state)
if not node.is_imaginary():
op = node.getoperation()
@@ -259,6 +268,8 @@
for i,node in enumerate(pack.operations):
op = node.getoperation()
state.setvector_of_box(op,i,vecop)
+ if pack.is_accumulating():
+ state.renamer.start_renaming(op, vecop)
if op.is_guard():
assert isinstance(op, GuardResOp)
assert isinstance(vecop, GuardResOp)
@@ -452,7 +463,8 @@
args[index] = vecop
return vecop
- vecop = OpHelpers.create_vec(arg.type, arg.bytesize, arg.signed)
+
+ vecop = OpHelpers.create_vec(arg.type, arg.bytesize, arg.signed, pack.opnum())
ops.append(vecop)
for i,node in enumerate(pack.operations):
op = node.getoperation()
@@ -519,7 +531,11 @@
return vecop
return None
- def post_emit(self, op):
+ def post_emit(self, node):
+ pass
+
+ def pre_emit(self, node):
+ op = node.getoperation()
if op.is_guard():
# add accumulation info to the descriptor
# TODO for version in self.loop.versions:
@@ -536,8 +552,9 @@
accum = self.accumulation.get(arg, None)
if accum:
assert isinstance(accum, AccumPack)
- accum.attach_accum_info(descr, i, arg)
- seed = accum.getseed()
+ descr.rd_accum_list = AccumInfo(descr.rd_accum_list, i,
+ accum.operator, arg, None)
+ seed = accum.getleftmostseed()
failargs[i] = self.renamer.rename_map.get(seed, seed)
def profitable(self):
@@ -556,6 +573,7 @@
if node.pack:
assert node.pack.numops() > 1
for node in node.pack.operations:
+ self.pre_emit(node)
scheduler.mark_emitted(node, self, unpack=False)
turn_into_vector(self, node.pack)
return True
@@ -593,6 +611,7 @@
if argument and not argument.is_constant():
arg = self.ensure_unpacked(i, argument)
if argument is not arg:
+ print "exchange at", i, fail_args[i], "=", arg
fail_args[i] = arg
def ensure_unpacked(self, index, arg):
@@ -603,7 +622,7 @@
if var in self.invariant_vector_vars:
return arg
if arg in self.accumulation:
- return var
+ return arg
args = [var, ConstInt(pos), ConstInt(1)]
vecop = OpHelpers.create_vec_unpack(var.type, args, var.bytesize,
var.signed, 1)
@@ -844,35 +863,34 @@
rop.FLOAT_MUL: '*',
}
- def __init__(self, nodes, operator, accum, position):
+ def __init__(self, nodes, operator, position):
Pack.__init__(self, nodes)
- self.accumulator = accum
self.operator = operator
self.position = position
def getdatatype(self):
- return self.accumulator.datatype
+ accum = self.leftmost().getarg(self.position)
+ return accum.datatype
def getbytesize(self):
- return self.accumulator.bytesize
+ accum = self.leftmost().getarg(self.position)
+ return accum.bytesize
- def getseed(self):
+ def getleftmostseed(self):
+ return self.leftmost().getarg(self.position)
+
+ def getseeds(self):
""" The accumulatoriable holding the seed value """
- return self.accumulator
+ return [op.getoperation().getarg(self.position) for op in self.operations]
def reduce_init(self):
if self.operator == '*':
return 1
return 0
- def attach_accum_info(self, descr, position, scalar):
- descr.rd_accum_list = AccumInfo(descr.rd_accum_list, position, self.operator,
- scalar, None)
-
def is_accumulating(self):
return True
def clone(self):
- return AccumPack(operations, self.operator,
- self.accumulator, self.position)
+ return AccumPack(operations, self.operator, self.position)
diff --git a/rpython/jit/metainterp/optimizeopt/vector.py b/rpython/jit/metainterp/optimizeopt/vector.py
--- a/rpython/jit/metainterp/optimizeopt/vector.py
+++ b/rpython/jit/metainterp/optimizeopt/vector.py
@@ -81,11 +81,11 @@
def optimize_vector(metainterp_sd, jitdriver_sd, warmstate, loop_info, loop_ops):
""" Enter the world of SIMD. Bails if it cannot transform the trace. """
user_code = not jitdriver_sd.vec and warmstate.vec_all
+ loop = VectorLoop(loop_info.label_op, loop_ops[1:-1], loop_ops[-1])
if user_code and user_loop_bail_fast_path(loop, warmstate):
return
# the original loop (output of optimize_unroll)
info = LoopVersionInfo(loop_info)
- loop = VectorLoop(loop_info.label_op, loop_ops[1:-1], loop_ops[-1])
version = info.snapshot(loop)
try:
debug_start("vec-opt-loop")
@@ -134,7 +134,6 @@
resop_count = 0 # the count of operations minus debug_merge_points
vector_instr = 0
guard_count = 0
- blacklist = (rop.CALL, rop.CALL_ASSEMBLER)
at_least_one_array_access = True
for i,op in enumerate(loop.operations):
if op.getopnum() == rop.DEBUG_MERGE_POINT:
@@ -149,7 +148,8 @@
at_least_one_array_access = True
if warmstate.vec_ratio > 0.0:
- if op.getopnum() in blacklist:
+ # blacklist
+ if op.is_call() or op.is_call_assembler():
return True
if op.is_guard():
@@ -744,7 +744,7 @@
# considered. => tree pattern matching problem.
return None
operator = AccumPack.SUPPORTED[opnum]
- return AccumPack([lnode, rnode], operator, scalar, index)
+ return AccumPack([lnode, rnode], operator, index)
return None
@@ -770,7 +770,7 @@
oplist = state.invariant_oplist
# reset the box to zeros or ones
if pack.reduce_init() == 0:
- vecop = OpHelpers.create_vec(datatype, bytesize, signed)
+ vecop = OpHelpers.create_vec(datatype, bytesize, signed, count)
oplist.append(vecop)
vecop = VecOperation(rop.VEC_INT_XOR, [vecop, vecop],
vecop, count)
@@ -783,14 +783,15 @@
else:
raise NotImplementedError("cannot handle %s" % pack.operator)
# pack the scalar value
- args = [vecop, pack.getseed(), ConstInt(0), ConstInt(1)]
+ args = [vecop, pack.getleftmostseed(), ConstInt(0), ConstInt(1)]
vecop = OpHelpers.create_vec_pack(datatype, args, bytesize,
signed, count)
oplist.append(vecop)
+ seed = pack.getleftmostseed()
+ state.accumulation[seed] = pack
# rename the variable with the box
- state.setvector_of_box(pack.getseed(), 0, vecop) # prevent it from expansion
- state.renamer.start_renaming(pack.getseed(), vecop)
-
+ state.setvector_of_box(seed, 0, vecop) # prevent it from expansion
+ state.renamer.start_renaming(seed, vecop)
def split_overloaded_packs(self):
newpacks = []
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
@@ -146,6 +146,10 @@
else:
# pass through the type of the first input argument
if self.numargs() == 0:
+ if self.type == 'i':
+ self.setdatatype('i', INT_WORD, True)
+ elif self.type == 'f':
+ self.setdatatype('f', FLOAT_WORD, False)
return
i = 0
arg = self.getarg(i)
@@ -280,6 +284,9 @@
if descr is DONT_CHANGE:
descr = None
newop = ResOperation(opnum, args, descr)
+ newop.count = self.count
+ newop.bytesize = self.bytesize
+ newop.signed = self.signed
if self.type != 'v':
newop.copy_value_from(self)
return newop
@@ -1602,13 +1609,13 @@
return VecOperationNew(opnum, [arg], arg.type, bytesize, signed, count)
@staticmethod
- def create_vec(datatype, bytesize, signed):
+ def create_vec(datatype, bytesize, signed, count):
if datatype == 'i':
opnum = rop.VEC_I
else:
assert datatype == 'f'
opnum = rop.VEC_F
- return VecOperationNew(opnum, [], datatype, bytesize, signed, 0)
+ return VecOperationNew(opnum, [], datatype, bytesize, signed, count)
@staticmethod
def create_vec_pack(datatype, args, bytesize, signed, count):
More information about the pypy-commit
mailing list