Author: Maciej Fijalkowski <[email protected]>
Branch: backend-vector-ops
Changeset: r52688:f002fbc9d8ec
Date: 2012-02-19 23:42 +0200
http://bitbucket.org/pypy/pypy/changeset/f002fbc9d8ec/
Log: dance to make interiorfields work
diff --git a/pypy/jit/backend/llgraph/runner.py
b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -23,7 +23,8 @@
class Descr(history.AbstractDescr):
def __init__(self, ofs, typeinfo, extrainfo=None, name=None,
- arg_types=None, count_fields_if_immut=-1, ffi_flags=0,
width=-1):
+ arg_types=None, count_fields_if_immut=-1, ffi_flags=0,
+ width=-1, is_array=False, field_size=-1):
self.ofs = ofs
self.width = width
@@ -33,6 +34,11 @@
self.arg_types = arg_types
self.count_fields_if_immut = count_fields_if_immut
self.ffi_flags = ffi_flags
+ self.is_array_descr = is_array
+ self.field_size = field_size
+
+ def get_field_size(self):
+ return self.field_size
def get_arg_types(self):
return self.arg_types
@@ -43,6 +49,9 @@
def get_extra_info(self):
return self.extrainfo
+ def get_width(self):
+ return self.width
+
def sort_key(self):
"""Returns an integer that can be used as a key when sorting the
field descrs of a single structure. The property that this
@@ -121,14 +130,16 @@
return False
def getdescr(self, ofs, typeinfo='?', extrainfo=None, name=None,
- arg_types=None, count_fields_if_immut=-1, ffi_flags=0,
width=-1):
+ arg_types=None, count_fields_if_immut=-1, ffi_flags=0,
+ width=-1, is_array=False, field_size=-1):
key = (ofs, typeinfo, extrainfo, name, arg_types,
count_fields_if_immut, ffi_flags, width)
try:
return self._descrs[key]
except KeyError:
descr = Descr(ofs, typeinfo, extrainfo, name, arg_types,
- count_fields_if_immut, ffi_flags, width)
+ count_fields_if_immut, ffi_flags, width, is_array,
+ field_size)
self._descrs[key] = descr
return descr
@@ -339,7 +350,8 @@
width = symbolic.get_size(A)
ofs, size = symbolic.get_field_token(S, fieldname)
token = history.getkind(getattr(S, fieldname))
- return self.getdescr(ofs, token[0], name=fieldname, width=width)
+ return self.getdescr(ofs, token[0], name=fieldname, width=width,
+ field_size=size)
def interiorfielddescrof_dynamic(self, offset, width, fieldsize,
is_pointer, is_float, is_signed):
@@ -351,7 +363,7 @@
else:
typeinfo = INT
# we abuse the arg_types field to distinguish dynamic and static descrs
- return Descr(offset, typeinfo, arg_types='dynamic', name='<dynamic
interior field>', width=width)
+ return Descr(offset, typeinfo, arg_types='dynamic', name='<dynamic
interior field>', width=width, field_size=fieldsize)
def calldescrof(self, FUNC, ARGS, RESULT, extrainfo):
arg_types = []
@@ -397,7 +409,7 @@
token = 's'
else:
token = '?'
- return self.getdescr(size, token)
+ return self.getdescr(size, token, is_array=True)
# ---------- the backend-dependent operations ----------
diff --git a/pypy/jit/backend/llsupport/descr.py
b/pypy/jit/backend/llsupport/descr.py
--- a/pypy/jit/backend/llsupport/descr.py
+++ b/pypy/jit/backend/llsupport/descr.py
@@ -156,6 +156,7 @@
itemsize = 0
lendescr = None
flag = '\x00'
+ is_array_descr = True
def __init__(self, basesize, itemsize, lendescr, flag):
self.basesize = basesize
@@ -178,6 +179,9 @@
def repr_of_descr(self):
return '<Array%s %s>' % (self.flag, self.itemsize)
+ def get_item_size(self):
+ return self.itemsize
+
def get_array_descr(gccache, ARRAY_OR_STRUCT):
cache = gccache._cache_array
@@ -226,6 +230,12 @@
def repr_of_descr(self):
return '<InteriorFieldDescr %s>' % self.fielddescr.repr_of_descr()
+ def get_item_size(self):
+ return self.fielddescr.field_size
+
+ def get_width(self):
+ return self.arraydescr.itemsize
+
def get_interiorfield_descr(gc_ll_descr, ARRAY, name):
cache = gc_ll_descr._cache_interiorfield
try:
diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py
--- a/pypy/jit/metainterp/executor.py
+++ b/pypy/jit/metainterp/executor.py
@@ -277,7 +277,8 @@
IGNORED = ['FLOAT_VECTOR_ADD', 'FLOAT_VECTOR_SUB',
- 'GETARRAYITEM_VECTOR_RAW',
+ 'GETARRAYITEM_VECTOR_RAW', 'GETINTERIORFIELD_VECTOR_RAW',
+ 'SETINTERIORFIELD_VECTOR_RAW',
'SETARRAYITEM_VECTOR_RAW', 'ASSERT_ALIGNED']
def _make_execute_list():
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -138,6 +138,7 @@
class AbstractDescr(AbstractValue):
__slots__ = ()
+ is_array_descr = False
def repr_of_descr(self):
return '%r' % (self,)
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_vectorize.py
b/pypy/jit/metainterp/optimizeopt/test/test_vectorize.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_vectorize.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_vectorize.py
@@ -10,6 +10,8 @@
cpu = LLtypeMixin.cpu
FUNC = LLtypeMixin.FUNC
arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed))
+ interiordescr = cpu.interiorfielddescrof_dynamic(0, 1, 8, False, True,
+ False)
def calldescr(cpu, FUNC, oopspecindex, extraeffect=None):
if extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
@@ -297,7 +299,7 @@
f0 = getarrayitem_raw(p0, i0, descr=arraydescr)
f1 = getarrayitem_raw(p1, i1, descr=arraydescr)
f2 = float_add(f0, f1)
- setarrayitem_raw(p2, i2, f2)
+ setarrayitem_raw(p2, i2, f2, descr=arraydescr)
i3 = cast_float_to_int(f2)
finish(p0, p1, p2, i0, i1, i3)
"""
@@ -306,8 +308,77 @@
f0 = getarrayitem_raw(p0, i0, descr=arraydescr)
f1 = getarrayitem_raw(p1, i1, descr=arraydescr)
f2 = float_add(f0, f1)
- setarrayitem_raw(p2, i2, f2)
+ setarrayitem_raw(p2, i2, f2, descr=arraydescr)
i3 = cast_float_to_int(f2)
finish(p0, p1, p2, i0, i1, i3)
"""
self.optimize_loop(ops, expected)
+
+ def test_getinteriorfield(self):
+ ops = """
+ [p0, p1, p2, i0, i1, i2]
+ call(0, p0, i0, descr=assert_aligned)
+ call(0, p1, i1, descr=assert_aligned)
+ call(0, p1, i2, descr=assert_aligned)
+ f0 = getinteriorfield_raw(p0, i0, descr=interiordescr)
+ f1 = getinteriorfield_raw(p1, i1, descr=interiordescr)
+ f2 = float_add(f0, f1)
+ setinteriorfield_raw(p2, i2, f2, descr=interiordescr)
+ i0_1 = int_add(i0, 8)
+ i1_1 = int_add(8, i1)
+ i2_1 = int_add(i2, 8)
+ f0_1 = getinteriorfield_raw(p0, i0_1, descr=interiordescr)
+ f1_1 = getinteriorfield_raw(p1, i1_1, descr=interiordescr)
+ f2_1 = float_add(f0_1, f1_1)
+ setinteriorfield_raw(p2, i2_1, f2_1, descr=interiordescr)
+ finish(p0, p1, p2, i0_1, i1_1, i2_1)
+ """
+ expected = """
+ [p0, p1, p2, i0, i1, i2]
+ i0_1 = int_add(i0, 8)
+ i1_1 = int_add(8, i1)
+ i2_1 = int_add(i2, 8)
+ vec0 = getinteriorfield_vector_raw(p0, i0, descr=interiordescr)
+ vec1 = getinteriorfield_vector_raw(p1, i1, descr=interiordescr)
+ vec2 = float_vector_add(vec0, vec1)
+ setinteriorfield_vector_raw(p2, i2, vec2, descr=interiordescr)
+ finish(p0, p1, p2, i0_1, i1_1, i2_1)
+ """
+ self.optimize_loop(ops, expected)
+
+ def test_getinteriorfield_wrong(self):
+ ops = """
+ [p0, p1, p2, i0, i1, i2]
+ call(0, p0, i0, descr=assert_aligned)
+ call(0, p1, i1, descr=assert_aligned)
+ call(0, p1, i2, descr=assert_aligned)
+ f0 = getinteriorfield_raw(p0, i0, descr=interiordescr)
+ f1 = getinteriorfield_raw(p1, i1, descr=interiordescr)
+ f2 = float_add(f0, f1)
+ setinteriorfield_raw(p2, i2, f2, descr=interiordescr)
+ i0_1 = int_add(i0, 1)
+ i1_1 = int_add(1, i1)
+ i2_1 = int_add(i2, 1)
+ f0_1 = getinteriorfield_raw(p0, i0_1, descr=interiordescr)
+ f1_1 = getinteriorfield_raw(p1, i1_1, descr=interiordescr)
+ f2_1 = float_add(f0_1, f1_1)
+ setinteriorfield_raw(p2, i2_1, f2_1, descr=interiordescr)
+ finish(p0, p1, p2, i0_1, i1_1, i2_1)
+ """
+ expected = """
+ [p0, p1, p2, i0, i1, i2]
+ i0_1 = int_add(i0, 1)
+ i1_1 = int_add(1, i1)
+ i2_1 = int_add(i2, 1)
+ f0 = getinteriorfield_raw(p0, i0, descr=interiordescr)
+ f1 = getinteriorfield_raw(p1, i1, descr=interiordescr)
+ f2 = float_add(f0, f1)
+ setinteriorfield_raw(p2, i2, f2, descr=interiordescr)
+ f0_1 = getinteriorfield_raw(p0, i0_1, descr=interiordescr)
+ f1_1 = getinteriorfield_raw(p1, i1_1, descr=interiordescr)
+ f2_1 = float_add(f0_1, f1_1)
+ setinteriorfield_raw(p2, i2_1, f2_1, descr=interiordescr)
+ finish(p0, p1, p2, i0_1, i1_1, i2_1)
+ """
+ self.optimize_loop(ops, expected)
+
diff --git a/pypy/jit/metainterp/optimizeopt/vectorize.py
b/pypy/jit/metainterp/optimizeopt/vectorize.py
--- a/pypy/jit/metainterp/optimizeopt/vectorize.py
+++ b/pypy/jit/metainterp/optimizeopt/vectorize.py
@@ -7,7 +7,13 @@
VECTOR_SIZE = 2
VEC_MAP = {rop.FLOAT_ADD: rop.FLOAT_VECTOR_ADD,
- rop.FLOAT_SUB: rop.FLOAT_VECTOR_SUB}
+ rop.FLOAT_SUB: rop.FLOAT_VECTOR_SUB,
+ rop.GETINTERIORFIELD_RAW: rop.GETINTERIORFIELD_VECTOR_RAW,
+ rop.SETINTERIORFIELD_RAW: rop.SETINTERIORFIELD_VECTOR_RAW,
+ rop.GETARRAYITEM_RAW: rop.GETARRAYITEM_VECTOR_RAW,
+ rop.SETARRAYITEM_RAW: rop.SETARRAYITEM_VECTOR_RAW,
+ }
+
class BaseTrack(object):
pass
@@ -25,7 +31,7 @@
def emit(self, optimizer):
box = BoxVector()
- op = ResOperation(rop.GETARRAYITEM_VECTOR_RAW, [self.arr.box,
+ op = ResOperation(VEC_MAP[self.op.getopnum()], [self.arr.box,
self.index.val.box],
box, descr=self.op.getdescr())
optimizer.emit_operation(op)
@@ -41,11 +47,13 @@
def match(self, other, i):
if not isinstance(other, Write):
return False
+ descr = self.op.getdescr()
+ i = i * descr.get_field_size() / descr.get_width()
return self.v.match(other.v, i)
def emit(self, optimizer):
arg = self.v.emit(optimizer)
- op = ResOperation(rop.SETARRAYITEM_VECTOR_RAW, [self.arr.box,
+ op = ResOperation(VEC_MAP[self.op.getopnum()], [self.arr.box,
self.index.box, arg],
None, descr=self.op.getdescr())
optimizer.emit_operation(op)
@@ -78,8 +86,17 @@
self.val = val
self.index = index
- def advance(self):
- return TrackIndex(self.val, self.index + 1)
+ def advance(self, v):
+ return TrackIndex(self.val, self.index + v)
+
+ def match_descr(self, descr):
+ if self.index == 0:
+ return True
+ if descr.is_array_descr:
+ return self.index == 1
+ if descr.get_width() != 1:
+ return False # XXX this can probably be supported
+ return self.index == descr.get_field_size()
class OptVectorize(Optimization):
def __init__(self):
@@ -112,6 +129,9 @@
track = self.tracked_indexes.get(index, None)
if track is None:
self.emit_operation(op)
+ elif not track.match_descr(op.getdescr()):
+ self.reset()
+ self.emit_operation(op)
else:
self.ops_so_far.append(op)
self.track[self.getvalue(op.result)] = Read(arr, track, op)
@@ -123,20 +143,22 @@
one = self.getvalue(op.getarg(0))
two = self.getvalue(op.getarg(1))
self.emit_operation(op)
- if (one.is_constant() and one.box.getint() == 1 and
- two in self.tracked_indexes):
+ if (one.is_constant() and two in self.tracked_indexes):
index = two
- elif (two.is_constant() and two.box.getint() == 1 and
- one in self.tracked_indexes):
+ v = one.box.getint()
+ elif (two.is_constant() and one in self.tracked_indexes):
index = one
+ v = two.box.getint()
else:
return
- self.tracked_indexes[self.getvalue(op.result)] =
self.tracked_indexes[index].advance()
+ self.tracked_indexes[self.getvalue(op.result)] =
self.tracked_indexes[index].advance(v)
def _optimize_binop(self, op):
left = self.getvalue(op.getarg(0))
right = self.getvalue(op.getarg(1))
if left not in self.track or right not in self.track:
+ if left in self.track or right in self.track:
+ self.reset()
self.emit_operation(op)
else:
self.ops_so_far.append(op)
@@ -151,6 +173,9 @@
index = self.getvalue(op.getarg(1))
val = self.getvalue(op.getarg(2))
if index not in self.tracked_indexes or val not in self.track:
+ # We could detect cases here, but we're playing on the safe
+ # side and just resetting everything
+ self.reset()
self.emit_operation(op)
return
self.ops_so_far.append(op)
@@ -159,7 +184,9 @@
ti = self.tracked_indexes[index]
if arr not in self.full:
self.full[arr] = [None] * VECTOR_SIZE
- self.full[arr][ti.index] = Write(arr, index, v, op)
+ i = (ti.index * op.getdescr().get_width() //
+ op.getdescr().get_field_size())
+ self.full[arr][i] = Write(arr, index, v, op)
optimize_SETINTERIORFIELD_RAW = optimize_SETARRAYITEM_RAW
diff --git a/pypy/jit/metainterp/resoperation.py
b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -473,6 +473,7 @@
'GETARRAYITEM_VECTOR_RAW/2d',
'GETARRAYITEM_RAW/2d',
'GETINTERIORFIELD_GC/2d',
+ 'GETINTERIORFIELD_VECTOR_RAW/2d',
'GETINTERIORFIELD_RAW/2d',
'GETFIELD_GC/1d',
'GETFIELD_RAW/1d',
@@ -493,6 +494,7 @@
'SETARRAYITEM_RAW/3d',
'SETARRAYITEM_VECTOR_RAW/3d',
'SETINTERIORFIELD_GC/3d',
+ 'SETINTERIORFIELD_VECTOR_RAW/3d',
'SETINTERIORFIELD_RAW/3d',
'SETFIELD_GC/2d',
'SETFIELD_RAW/2d',
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit