Author: Richard Plangger <r...@pasra.at> Branch: vecopt2 Changeset: r77102:3f6c156ec0bb Date: 2015-03-31 17:46 +0200 http://bitbucket.org/pypy/pypy/changeset/3f6c156ec0bb/
Log: introducing box_vector as new boxes (work in progress) 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 @@ -340,7 +340,7 @@ rop.LABEL, ): # list of opcodes never executed by pyjitpl continue - # XXX this is temporary! after the algorithm works i have to adjust the + # XXX this is temporary! after the algorithm works adjust the # black hole interpreter! if rop._VEC_ARITHMETIC_FIRST <= value <= rop._VEC_ARITHMETIC_LAST or \ value == rop.VEC_RAW_LOAD or value == rop.VEC_RAW_STORE: 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 @@ -19,6 +19,7 @@ STRUCT = 's' HOLE = '_' VOID = 'v' +VECTOR = 'V' FAILARGS_LIMIT = 1000 @@ -509,6 +510,40 @@ # ____________________________________________________________ +class BoxVector(Box): + type = VECTOR + _attrs_ = ('item_type','byte_count','item_count','signed') + + def __init__(self, item_type=INT, byte_count=4, item_count=4, signed=True): + assert lltype.typeOf(valuestorage) is longlong.FLOATSTORAGE + self.item_type = item_type + self.byte_count = byte_count + self.item_count = item_count + self.signed = signed + + def forget_value(self): + self.value = longlong.ZEROF + + def clonebox(self): + return BoxVector(self.value) + + def constbox(self): + raise NotImplementedError("not possible to have a constant vector box") + + def _get_hash_(self): + return longlong.gethash(self.value) + + def nonnull(self): + return bool(longlong.extract_bits(self.value)) + + def _getrepr_(self): + return self.getfloat() + + def repr_rpython(self): + return repr_rpython(self, 'bv') + +# ____________________________________________________________ + def make_hashable_int(i): from rpython.rtyper.lltypesystem.ll2ctypes import NotCtypesAllocatedStructure diff --git a/rpython/jit/metainterp/optimizeopt/dependency.py b/rpython/jit/metainterp/optimizeopt/dependency.py --- a/rpython/jit/metainterp/optimizeopt/dependency.py +++ b/rpython/jit/metainterp/optimizeopt/dependency.py @@ -452,10 +452,14 @@ return dot return "" +class SchedulerData(object): + pass class Scheduler(object): - def __init__(self, graph): + def __init__(self, graph, sched_data): + assert isinstance(sched_data, SchedulerData) self.graph = graph self.schedulable_nodes = self.graph.schedulable_nodes + self.sched_data = sched_data def has_more_to_schedule(self): return len(self.schedulable_nodes) > 0 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 @@ -853,39 +853,37 @@ (6,13,20,27),(7,14,21,28)]: self.assert_has_pack_with(vopt.packset, opindices) - def test_schedule_vector_operation(self): - for op,vop in [ ('int_mul','vec_int_mul')]: #('int_add','vec_int_add'), ('int_sub','vec_int_sub'), - ops = """ - [p0,p1,p2,i0] # 0 - i10 = int_le(i0, 128) # 1, 8, 15, 22 - guard_true(i10) [p0,p1,p2,i0] # 2, 9, 16, 23 - i2 = getarrayitem_gc(p0, i0, descr=floatarraydescr) # 3, 10, 17, 24 - i3 = getarrayitem_gc(p1, i0, descr=floatarraydescr) # 4, 11, 18, 25 - i4 = {op}(i2,i3) # 5, 12, 19, 26 - setarrayitem_gc(p2, i0, i4, descr=floatarraydescr) # 6, 13, 20, 27 - i1 = int_add(i0, 1) # 7, 14, 21, 28 - jump(p0,p1,p2,i1) # 29 - """.format(op=op) - vops = """ - [p0,p1,p2,i0] - i10 = int_le(i0, 128) - guard_true(i10) [p0,p1,p2,i0] - i1 = int_add(i0, 1) - i11 = int_le(i1, 128) - guard_true(i11) [p0,p1,p2,i0] - i2 = vec_raw_load(p0, i0, 2, descr=floatarraydescr) - i3 = vec_raw_load(p1, i0, 2, descr=floatarraydescr) - i12 = int_add(i1, 1) - i4 = {op}(i2,i3,2) - vec_raw_store(p2, i0, i4, 2, descr=floatarraydescr) - jump(p0,p1,p2,i12) - """.format(op=vop) - loop = self.parse_loop(ops) - vopt = self.schedule(loop,1) - oo = self.vec_optimizer_unrolled(self.parse_loop(ops), 1) - self._write_dot_and_convert_to_svg(vopt.dependency_graph, oo.loop.operations, 'test_2') - self.debug_print_operations(vopt.loop) - self.assert_equal(loop, self.parse_loop(vops)) + @pytest.mark.parametrize('op', ['int_mul','int_add','int_sub','float_mul','float_add','float_sub']) + def test_schedule_vector_operation(self, op): + ops = """ + [p0,p1,p2,i0] # 0 + i10 = int_le(i0, 128) # 1, 8, 15, 22 + guard_true(i10) [p0,p1,p2,i0] # 2, 9, 16, 23 + i2 = getarrayitem_gc(p0, i0, descr=floatarraydescr) # 3, 10, 17, 24 + i3 = getarrayitem_gc(p1, i0, descr=floatarraydescr) # 4, 11, 18, 25 + i4 = {op}(i2,i3) # 5, 12, 19, 26 + setarrayitem_gc(p2, i0, i4, descr=floatarraydescr) # 6, 13, 20, 27 + i1 = int_add(i0, 1) # 7, 14, 21, 28 + jump(p0,p1,p2,i1) # 29 + """.format(op=op) + vops = """ + [p0,p1,p2,i0] + i10 = int_le(i0, 128) + guard_true(i10) [p0,p1,p2,i0] + i1 = int_add(i0, 1) + i11 = int_le(i1, 128) + guard_true(i11) [p0,p1,p2,i0] + v1 = vec_raw_load(p0, i0, 2, descr=floatarraydescr) + v2 = vec_raw_load(p1, i0, 2, descr=floatarraydescr) + i12 = int_add(i1, 1) + v3 = {op}(v1,v2) + vec_raw_store(p2, i0, v3, 2, descr=floatarraydescr) + jump(p0,p1,p2,i12) + """.format(op='vec_'+op) + loop = self.parse_loop(ops) + vopt = self.schedule(loop,1) + self.debug_print_operations(vopt.loop) + self.assert_equal(loop, self.parse_loop(vops)) class TestLLtype(BaseTestVectorize, LLtypeMixin): pass 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 @@ -1,11 +1,11 @@ import sys import py from rpython.rtyper.lltypesystem import lltype, rffi -from rpython.jit.metainterp.history import ConstInt +from rpython.jit.metainterp.history import ConstInt, VECTOR 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, - MemoryRef, IntegralMod, Scheduler) + MemoryRef, IntegralMod, Scheduler, SchedulerData) from rpython.jit.metainterp.resoperation import (rop, ResOperation) from rpython.jit.metainterp.resume import Snapshot from rpython.rlib.debug import debug_print, debug_start, debug_stop @@ -289,7 +289,7 @@ def schedule(self): self.clear_newoperations() - scheduler = Scheduler(self.dependency_graph) + scheduler = Scheduler(self.dependency_graph, VecScheduleData()) while scheduler.has_more_to_schedule(): candidate_index = scheduler.next_schedule_index() candidate = self.loop.operations[candidate_index] @@ -305,20 +305,57 @@ def _schedule_pack(self, scheduler, pack): opindices = [ e.opidx for e in pack.operations ] if scheduler.schedulable(opindices): - self.emit_vec_operation(pack) + self.emit_operation(ToSIMD.as_vector_operation(pack, + self.loop.operations, + scheduler) + ) scheduler.schedule_all(opindices) else: scheduler.schedule_later(0) - def emit_vec_operation(self, pack): - op0_wrapper = pack.operations[0] - op0 = self.loop.operations[op0_wrapper.opidx] - op_count = len(pack.operations) - assert op0.vector != -1 - args = op0.getarglist()[:] - args.append(ConstInt(op_count)) - vecop = ResOperation(op0.vector, args, op0.result, op0.getdescr()) - self.emit_operation(vecop) +class VecScheduleData(SchedulerData): + def as_vector_operation(pack, operations): + assert len(pack.operations) > 1 + op0 = operations[pack.operations[0].opidx] + for i,op_wrapper in enumerate(pack.operations): + op = operations[op_wrapper.opidx] + scheduler.simd.inspect_operation(op,i) + #if op0.vector not in (rop.VEC_RAW_LOAD, rop.VEC_RAW_STORE): + # op_count = len(pack.operations) + # args.append(ConstInt(op_count)) + return sisiToSimd.get_vector_op() + + def __init__(self): + self.opnum = -1 + self.args = None + self.result = None + self.descr = None + self.pack = None + + def reset(self, op, pack): + self.opnum = op.getopnum() + self.args = op.getarglist()[:] + self.result = op.result + self.descr = op.getdescr() + self.pack = pack + + def get_vector_op(self): + return ResOperation(self.opnum, self.args, self.result, self.descr) + + def vectorize_INT_ADD(op, i): + self._pack_vector_arg(0) + self._pack_vector_arg(1) + self._pack_vector_result() + + def _pack_vector_arg(self, i): + arg = self.args[i] + if arg.type != VECTOR: + box_vec = scheduler.vector_register_of(self.args[0]) + if box_vec is None: + box_vec = BoxVector(arg.type, 4, len(pack.operations), True) + self.args[i] = box_vec + +SISItoSIMD.inspect_operation = make_dispatcher_method(Pack, 'vectorize_') def isomorphic(l_op, r_op): @@ -430,7 +467,7 @@ assert isinstance(left, PackOpWrapper) assert isinstance(right, PackOpWrapper) self.left = left - self.right = right + self.right = right'V' Pack.__init__(self, [left, right]) def __eq__(self, other): 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 @@ -446,12 +446,12 @@ # # vector operations '_VEC_ARITHMETIC_FIRST', - 'VEC_INT_ADD/3d', - 'VEC_INT_SUB/3d', - 'VEC_INT_MUL/3d', - 'VEC_FLOAT_ADD/3d', - 'VEC_FLOAT_SUB/3d', - 'VEC_FLOAT_MUL/3d', + 'VEC_INT_ADD/2d', + 'VEC_INT_SUB/2d', + 'VEC_INT_MUL/2d', + 'VEC_FLOAT_ADD/2d', + 'VEC_FLOAT_SUB/2d', + 'VEC_FLOAT_MUL/2d', '_VEC_ARITHMETIC_LAST', # 'INT_LT/2b', diff --git a/rpython/jit/tool/oparser.py b/rpython/jit/tool/oparser.py --- a/rpython/jit/tool/oparser.py +++ b/rpython/jit/tool/oparser.py @@ -120,6 +120,9 @@ ts = getattr(self.cpu, 'ts', self.model.llhelper) box = ts.BoxRef() _box_counter_more_than(self.model, elem[1:]) + elif elem.startswith('v'): + box = self.model.BoxVector() + _box_counter_more_than(self.model, elem[1:]) else: for prefix, boxclass in self.boxkinds.iteritems(): if elem.startswith(prefix): diff --git a/rpython/jit/tool/oparser_model.py b/rpython/jit/tool/oparser_model.py --- a/rpython/jit/tool/oparser_model.py +++ b/rpython/jit/tool/oparser_model.py @@ -4,7 +4,7 @@ def get_real_model(): class LoopModel(object): from rpython.jit.metainterp.history import TreeLoop, JitCellToken - from rpython.jit.metainterp.history import Box, BoxInt, BoxFloat + from rpython.jit.metainterp.history import Box, BoxInt, BoxFloat, BoxVector from rpython.jit.metainterp.history import ConstInt, ConstPtr, ConstFloat from rpython.jit.metainterp.history import BasicFailDescr, BasicFinalDescr, TargetToken from rpython.jit.metainterp.typesystem import llhelper @@ -76,6 +76,9 @@ class BoxRef(Box): type = 'p' + class BoxVector(Box): + type = 'V' + class Const(object): def __init__(self, value=None): self.value = value _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit