Author: Maciej Fijalkowski <fij...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit