[pypy-commit] pypy optresult: enough virtual array of structs support
fijal
noreply at buildbot.pypy.org
Sun Mar 8 09:47:41 CET 2015
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult
Changeset: r76278:9508bc587256
Date: 2015-03-08 10:47 +0200
http://bitbucket.org/pypy/pypy/changeset/9508bc587256/
Log: enough virtual array of structs support
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
@@ -151,7 +151,7 @@
rffi.cast(TYPE, -1) == -1)
class ArrayDescr(AbstractDescr):
- def __init__(self, A):
+ def __init__(self, A, runner):
self.A = self.OUTERA = A
if isinstance(A, lltype.Struct):
self.A = A._flds[A._arrayfld]
@@ -191,10 +191,12 @@
class InteriorFieldDescr(AbstractDescr):
- def __init__(self, A, fieldname):
+ def __init__(self, A, fieldname, runner):
self.A = A
self.fieldname = fieldname
self.FIELD = getattr(A.OF, fieldname)
+ self.arraydescr = runner.arraydescrof(A)
+ self.fielddescr = runner.fielddescrof(A.OF, fieldname)
def __repr__(self):
return 'InteriorFieldDescr(%r, %r)' % (self.A, self.fieldname)
@@ -397,8 +399,12 @@
try:
return self.descrs[key]
except KeyError:
- descr = ArrayDescr(A)
+ descr = ArrayDescr(A, self)
self.descrs[key] = descr
+ if isinstance(A.OF, lltype.Struct):
+ descrs = heaptracker.all_interiorfielddescrs(self,
+ A, get_field_descr=LLGraphCPU.interiorfielddescrof)
+ descr.all_interiorfielddescrs = descrs
return descr
def interiorfielddescrof(self, A, fieldname):
@@ -406,7 +412,7 @@
try:
return self.descrs[key]
except KeyError:
- descr = InteriorFieldDescr(A, fieldname)
+ descr = InteriorFieldDescr(A, fieldname, self)
self.descrs[key] = descr
return descr
diff --git a/rpython/jit/codewriter/heaptracker.py b/rpython/jit/codewriter/heaptracker.py
--- a/rpython/jit/codewriter/heaptracker.py
+++ b/rpython/jit/codewriter/heaptracker.py
@@ -157,6 +157,25 @@
res.append(get_field_descr(gccache, STRUCT, name))
return res
+def all_interiorfielddescrs(gccache, ARRAY, get_field_descr=None):
+ from rpython.jit.backend.llsupport import descr
+
+ if get_field_descr is None:
+ get_field_descr = descr.get_field_descr
+ # order is not relevant, except for tests
+ STRUCT = ARRAY.OF
+ res = []
+ for name in STRUCT._names:
+ FIELD = getattr(STRUCT, name)
+ if FIELD is lltype.Void:
+ continue
+ if name == 'typeptr':
+ continue # dealt otherwise
+ elif isinstance(FIELD, lltype.Struct):
+ raise Exception("unexpected array(struct(struct))")
+ res.append(get_field_descr(gccache, ARRAY, name))
+ return res
+
def gc_fielddescrs(gccache, STRUCT):
return all_fielddescrs(gccache, STRUCT, True)
diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -53,9 +53,8 @@
def is_nonnull(self):
return True
-
-class AbstractStructPtrInfo(NonNullPtrInfo):
- _attrs_ = ('_is_virtual', '_fields')
+class AbstractVirtualPtrInfo(NonNullPtrInfo):
+ _attrs_ = ('_is_virtual',)
def force_box(self, op, optforce):
if self._is_virtual:
@@ -65,18 +64,16 @@
op.set_forwarded(newop)
newop.set_forwarded(self)
self._is_virtual = False
- if self._fields is not None:
- descr = op.getdescr()
- for i, flddescr in enumerate(descr.all_fielddescrs):
- fld = self._fields[i]
- if fld is not None:
- subbox = optforce.force_box(fld)
- setfieldop = ResOperation(rop.SETFIELD_GC, [op, subbox],
- descr=flddescr)
- optforce.emit_operation(setfieldop)
+ self._force_elements(newop, optforce)
return newop
return op
+ def is_virtual(self):
+ return self._is_virtual
+
+class AbstractStructPtrInfo(AbstractVirtualPtrInfo):
+ _attrs_ = ('_is_virtual', '_fields')
+
def init_fields(self, descr):
self._fields = [None] * len(descr.all_fielddescrs)
@@ -86,8 +83,17 @@
def getfield_virtual(self, descr):
return self._fields[descr.index]
- def is_virtual(self):
- return self._is_virtual
+ def _force_elements(self, op, optforce):
+ if self._fields is None:
+ return
+ descr = op.getdescr()
+ for i, flddescr in enumerate(descr.all_fielddescrs):
+ fld = self._fields[i]
+ if fld is not None:
+ subbox = optforce.force_box(fld)
+ setfieldop = ResOperation(rop.SETFIELD_GC, [op, subbox],
+ descr=flddescr)
+ optforce.emit_operation(setfieldop)
class InstancePtrInfo(AbstractStructPtrInfo):
_attrs_ = ('_known_class')
@@ -100,13 +106,44 @@
def get_known_class(self, cpu):
return self._known_class
-class StructPtrInfo(NonNullPtrInfo):
- _attrs_ = ('is_virtual', '_fields')
+class StructPtrInfo(AbstractStructPtrInfo):
+ pass
+
+class ArrayPtrInfo(AbstractVirtualPtrInfo):
+ _attrs_ = ('_is_virtual', 'length', '_items', '_descr')
-
-class ArrayPtrInfo(NonNullPtrInfo):
- _attrs_ = ('is_virtual', 'length', '_items')
+class ArrayStructInfo(ArrayPtrInfo):
+ def __init__(self, descr, size, is_virtual):
+ self.length = size
+ lgt = len(descr.all_interiorfielddescrs)
+ self._is_virtual = is_virtual
+ self._items = [None] * (size * lgt)
+ def _compute_index(self, index, fielddescr):
+ one_size = len(fielddescr.arraydescr.all_interiorfielddescrs)
+ return index * one_size + fielddescr.fielddescr.index
+
+ def setinteriorfield_virtual(self, index, fielddescr, fld):
+ index = self._compute_index(index, fielddescr)
+ self._items[index] = fld
+
+ def getinteriorfield_virtual(self, index, fielddescr):
+ index = self._compute_index(index, fielddescr)
+ return self._items[index]
+
+ def _force_elements(self, op, optforce):
+ i = 0
+ fielddescrs = op.getdescr().all_interiorfielddescrs
+ for index in range(self.length):
+ for flddescr in fielddescrs:
+ fld = self._items[i]
+ if fld is not None:
+ subbox = optforce.force_box(fld)
+ setfieldop = ResOperation(rop.SETINTERIORFIELD_GC,
+ [op, subbox],
+ descr=flddescr)
+ optforce.emit_operation(setfieldop)
+ i += 1
class StrPtrInfo(NonNullPtrInfo):
_attrs_ = ()
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -205,10 +205,11 @@
# Constant fold f0 * 1.0 and turn f0 * -1.0 into a FLOAT_NEG, these
# work in all cases, including NaN and inf
for lhs, rhs in [(arg1, arg2), (arg2, arg1)]:
- v1 = self.getvalue(lhs)
- v2 = self.getvalue(rhs)
+ v1 = self.get_box_replacement(lhs)
+ v2 = self.get_box_replacement(rhs)
if v1.is_constant():
+ xxxx
if v1.box.getfloatstorage() == 1.0:
self.make_equal_to(op, v2)
return
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -531,6 +531,9 @@
def make_varray(self, arraydescr, size, source_op, clear=False):
if arraydescr.is_array_of_structs():
assert clear
+ opinfo = info.ArrayStructInfo(arraydescr, size, True)
+ source_op.set_forwarded(opinfo)
+ return opinfo
vvalue = VArrayStructValue(arraydescr, size, source_op)
else:
constvalue = self.new_const_item(arraydescr)
@@ -697,7 +700,8 @@
def optimize_SETFIELD_GC(self, op):
opinfo = self.getptrinfo(op.getarg(0))
if opinfo is not None and opinfo.is_virtual():
- opinfo.setfield_virtual(op.getdescr(), op.getarg(1))
+ opinfo.setfield_virtual(op.getdescr(),
+ self.get_box_replacement(op.getarg(1)))
else:
self.make_nonnull(op.getarg(0))
self.emit_operation(op)
@@ -718,8 +722,7 @@
def optimize_NEW_ARRAY_CLEAR(self, op):
sizebox = self.get_constant_box(op.getarg(0))
if sizebox is not None:
- self.make_varray(op.getdescr(), sizebox.getint(), op,
- clear=True)
+ self.make_varray(op.getdescr(), sizebox.getint(), op, clear=True)
else:
self.emit_operation(op)
@@ -893,32 +896,33 @@
self.emit_operation(op)
def optimize_GETINTERIORFIELD_GC_I(self, op):
- value = self.getvalue(op.getarg(0))
- if value.is_virtual():
+ opinfo = self.getptrinfo(op.getarg(0))
+ if opinfo and opinfo.is_virtual():
indexbox = self.get_constant_box(op.getarg(1))
if indexbox is not None:
descr = op.getdescr()
- fieldvalue = value.getinteriorfield(
- indexbox.getint(), descr, None
- )
- if fieldvalue is None:
+ fld = opinfo.getinteriorfield_virtual(indexbox.getint(), descr)
+ if fld is None:
+ xxx
fieldvalue = self.new_const(descr)
- self.make_equal_to(op, fieldvalue)
+ self.make_equal_to(op, fld)
return
+ xxx
value.ensure_nonnull()
self.emit_operation(op)
optimize_GETINTERIORFIELD_GC_R = optimize_GETINTERIORFIELD_GC_I
optimize_GETINTERIORFIELD_GC_F = optimize_GETINTERIORFIELD_GC_I
def optimize_SETINTERIORFIELD_GC(self, op):
- value = self.getvalue(op.getarg(0))
- if value.is_virtual():
+ opinfo = self.getptrinfo(op.getarg(0))
+ if opinfo and opinfo.is_virtual():
indexbox = self.get_constant_box(op.getarg(1))
if indexbox is not None:
- value.setinteriorfield(
- indexbox.getint(), op.getdescr(), self.getvalue(op.getarg(2))
- )
+ opinfo.setinteriorfield_virtual(indexbox.getint(),
+ op.getdescr(),
+ self.get_box_replacement(op.getarg(2)))
return
+ xxx
value.ensure_nonnull()
self.emit_operation(op)
More information about the pypy-commit
mailing list