Author: Richard Plangger <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit