[pypy-commit] pypy optresult: basic virtuals
fijal
noreply at buildbot.pypy.org
Sat Mar 7 13:17:03 CET 2015
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: optresult
Changeset: r76269:917cc4c8ef85
Date: 2015-03-07 14:05 +0200
http://bitbucket.org/pypy/pypy/changeset/917cc4c8ef85/
Log: basic virtuals
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
@@ -89,8 +89,10 @@
return getkind(self.RESULT)[0]
class SizeDescr(AbstractDescr):
- def __init__(self, S):
+ def __init__(self, S, runner):
self.S = S
+ self.all_fielddescrs = heaptracker.all_fielddescrs(runner, S,
+ get_field_descr=LLGraphCPU.fielddescrof)
def as_vtable_size_descr(self):
return self
@@ -106,6 +108,7 @@
self.S = S
self.fieldname = fieldname
self.FIELD = getattr(S, fieldname)
+ self.index = heaptracker.get_fielddescr_index_in(S, fieldname)
def get_vinfo(self):
return self.vinfo
@@ -374,7 +377,7 @@
try:
return self.descrs[key]
except KeyError:
- descr = SizeDescr(S)
+ descr = SizeDescr(S, self)
self.descrs[key] = descr
return descr
diff --git a/rpython/jit/backend/llsupport/descr.py b/rpython/jit/backend/llsupport/descr.py
--- a/rpython/jit/backend/llsupport/descr.py
+++ b/rpython/jit/backend/llsupport/descr.py
@@ -36,10 +36,11 @@
tid = llop.combine_ushort(lltype.Signed, 0, 0)
def __init__(self, size, count_fields_if_immut=-1,
- gc_fielddescrs=None):
+ gc_fielddescrs=None, all_fielddescrs=None):
self.size = size
self.count_fields_if_immut = count_fields_if_immut
self.gc_fielddescrs = gc_fielddescrs
+ self.all_fielddescrs = all_fielddescrs
def count_fields_if_immutable(self):
return self.count_fields_if_immut
@@ -61,12 +62,13 @@
size = symbolic.get_size(STRUCT, gccache.translate_support_code)
count_fields_if_immut = heaptracker.count_fields_if_immutable(STRUCT)
gc_fielddescrs = heaptracker.gc_fielddescrs(gccache, STRUCT)
+ all_fielddescrs = heaptracker.all_fielddescrs(gccache, STRUCT)
if heaptracker.has_gcstruct_a_vtable(STRUCT):
sizedescr = SizeDescrWithVTable(size, count_fields_if_immut,
- gc_fielddescrs)
+ gc_fielddescrs, all_fielddescrs)
else:
sizedescr = SizeDescr(size, count_fields_if_immut,
- gc_fielddescrs)
+ gc_fielddescrs, all_fielddescrs)
gccache.init_size_descr(STRUCT, sizedescr)
cache[STRUCT] = sizedescr
return sizedescr
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
@@ -136,9 +136,12 @@
vtable = llmemory.cast_ptr_to_adr(vtable)
return adr2int(vtable)
-def fielddescrs_from_struct(gccache, STRUCT, only_gc=False, res=None):
+def all_fielddescrs(gccache, STRUCT, only_gc=False, res=None,
+ get_field_descr=None):
from rpython.jit.backend.llsupport import descr
+ if get_field_descr is None:
+ get_field_descr = descr.get_field_descr
if res is None:
res = []
# order is not relevant, except for tests
@@ -146,11 +149,31 @@
FIELD = getattr(STRUCT, name)
if FIELD is lltype.Void:
continue
+ if name == 'typeptr':
+ continue # dealt otherwise
elif isinstance(FIELD, lltype.Struct):
- fielddescrs_from_struct(gccache, FIELD, only_gc, res)
+ all_fielddescrs(gccache, FIELD, only_gc, res, get_field_descr)
elif (not only_gc) or (isinstance(FIELD, lltype.Ptr) and FIELD._needsgc()):
- res.append(descr.get_field_descr(gccache, STRUCT, name))
+ res.append(get_field_descr(gccache, STRUCT, name))
return res
def gc_fielddescrs(gccache, STRUCT):
- return fielddescrs_from_struct(gccache, STRUCT, True)
+ return all_fielddescrs(gccache, STRUCT, True)
+
+def get_fielddescr_index_in(STRUCT, fieldname, cur_index=0):
+ 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):
+ r = get_fielddescr_index_in(FIELD, fieldname, cur_index)
+ if r != -1:
+ return r
+ continue
+ elif name == fieldname:
+ return cur_index
+ cur_index += 1
+ return -1 # not found
+
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -478,6 +478,8 @@
return pendingfields
def optimize_GETFIELD_GC_I(self, op):
+ self.emit_operation(op)
+ return
structvalue = self.getvalue(op.getarg(0))
cf = self.field_cache(op.getdescr())
fieldvalue = cf.getfield_from_cache(self, structvalue)
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
@@ -1,5 +1,6 @@
-from rpython.jit.metainterp.resoperation import AbstractValue
+from rpython.jit.metainterp.resoperation import AbstractValue, ResOperation,\
+ rop
""" The tag field on PtrOptInfo has a following meaning:
@@ -52,14 +53,9 @@
def is_nonnull(self):
return True
-
-class InstancePtrInfo(NonNullPtrInfo):
- _attrs_ = ('_known_class', '_is_virtual', '_fields')
- _fields = None
- def __init__(self, known_class=None, is_virtual=False):
- self._known_class = known_class
- self._is_virtual = is_virtual
+class AbstractStructPtrInfo(NonNullPtrInfo):
+ _attrs_ = ('_is_virtual', '_fields')
def force_box(self, op, optforce):
if self._is_virtual:
@@ -69,20 +65,38 @@
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)
+ op = ResOperation(rop.SETFIELD_GC, [op, subbox],
+ descr=flddescr)
+ optforce.emit_operation(op)
return newop
return op
+ def init_fields(self, descr):
+ self._fields = [None] * len(descr.all_fielddescrs)
+
def setfield_virtual(self, descr, op):
- if self._fields is None:
- self._fields = {}
- self._fields[descr] = op
+ self._fields[descr.index] = op
def getfield_virtual(self, descr):
- return self._fields.get(descr, None)
+ return self._fields[descr.index]
def is_virtual(self):
return self._is_virtual
+class InstancePtrInfo(AbstractStructPtrInfo):
+ _attrs_ = ('_known_class')
+ _fields = None
+
+ def __init__(self, known_class=None, is_virtual=False):
+ self._known_class = known_class
+ self._is_virtual = is_virtual
+
def get_known_class(self, cpu):
return self._known_class
diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py
--- a/rpython/jit/metainterp/optimizeopt/intbounds.py
+++ b/rpython/jit/metainterp/optimizeopt/intbounds.py
@@ -441,12 +441,12 @@
self.propagate_bounds_backward(box2)
def make_int_le(self, box1, box2):
- v1 = self.getvalue(box1)
- v2 = self.getvalue(box2)
- if v1.getintbound().make_le(v2.getintbound()):
- self.propagate_bounds_backward(box1, v1)
- if v2.getintbound().make_ge(v1.getintbound()):
- self.propagate_bounds_backward(box2, v2)
+ b1 = self.getintbound(box1)
+ b2 = self.getintbound(box2)
+ if b1.make_le(b2):
+ self.propagate_bounds_backward(box1)
+ if b2.make_ge(b1):
+ self.propagate_bounds_backward(box2)
def make_int_gt(self, box1, box2):
self.make_int_lt(box2, box1)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -199,14 +199,14 @@
def test_remove_guard_class_2(self):
ops = """
[i0]
- p0 = new_with_vtable(ConstClass(node_vtable))
+ p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
escape_n(p0)
guard_class(p0, ConstClass(node_vtable)) []
jump(i0)
"""
expected = """
[i0]
- p0 = new_with_vtable(ConstClass(node_vtable))
+ p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
escape_n(p0)
jump(i0)
"""
@@ -426,7 +426,7 @@
def test_ooisnull_oononnull_via_virtual(self):
ops = """
[p0]
- pv = new_with_vtable(ConstClass(node_vtable))
+ pv = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
setfield_gc(pv, p0, descr=valuedescr)
guard_nonnull(p0) []
p1 = getfield_gc_r(pv, descr=valuedescr)
@@ -575,7 +575,7 @@
[i1, p2, p3]
i3 = getfield_gc_i(p3, descr=valuedescr)
escape_n(i3)
- p1 = new_with_vtable(ConstClass(node_vtable))
+ p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
setfield_gc(p1, i1, descr=valuedescr)
jump(i1, p1, p2)
"""
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
@@ -524,6 +524,7 @@
def make_virtual(self, known_class, source_op, descr):
opinfo = info.InstancePtrInfo(known_class, is_virtual=True)
+ opinfo.init_fields(descr)
source_op.set_forwarded(opinfo)
return opinfo
@@ -682,8 +683,7 @@
fieldvalue = self.optimizer.new_const(op.getdescr())
self.make_equal_to(op, fieldop)
else:
- yyyy
- value.ensure_nonnull()
+ self.make_nonnull(op.getarg(0))
self.emit_operation(op)
optimize_GETFIELD_GC_R = optimize_GETFIELD_GC_I
optimize_GETFIELD_GC_F = optimize_GETFIELD_GC_I
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
@@ -719,7 +719,7 @@
'GETFIELD_RAW/1d/fi',
'_MALLOC_FIRST',
'NEW/0d/r', #-> GcStruct, gcptrs inside are zeroed (not the rest)
- 'NEW_WITH_VTABLE/1/r',#-> GcStruct with vtable, gcptrs inside are zeroed
+ 'NEW_WITH_VTABLE/1d/r',#-> GcStruct with vtable, gcptrs inside are zeroed
'NEW_ARRAY/1d/r', #-> GcArray, not zeroed. only for arrays of primitives
'NEW_ARRAY_CLEAR/1d/r',#-> GcArray, fully zeroed
'NEWSTR/1/r', #-> STR, the hash field is zeroed
More information about the pypy-commit
mailing list