Author: Armin Rigo <[email protected]>
Branch: optresult
Changeset: r76274:e25c349f8ae6
Date: 2015-03-07 15:02 +0100
http://bitbucket.org/pypy/pypy/changeset/e25c349f8ae6/
Log: merge heads
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)
+ setfieldop = ResOperation(rop.SETFIELD_GC, [op,
subbox],
+ descr=flddescr)
+ optforce.emit_operation(setfieldop)
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/optimizer.py
b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -692,26 +692,25 @@
raise compile.giveup()
descr.store_final_boxes(op, newboxes, self.metainterp_sd)
#
- if op.getopnum() == rop.GUARD_VALUE and 0: # XXX
- val = self.getvalue(op.getarg(0))
- if val in self.bool_boxes:
- # Hack: turn guard_value(bool) into guard_true/guard_false.
- # This is done after the operation is emitted to let
- # store_final_boxes_in_guard set the guard_opnum field of the
- # descr to the original rop.GUARD_VALUE.
- constvalue = op.getarg(1).getint()
- if constvalue == 0:
- opnum = rop.GUARD_FALSE
- elif constvalue == 1:
- opnum = rop.GUARD_TRUE
- else:
- raise AssertionError("uh?")
- newop = self.replace_op_with(op, opnum, [op.getarg(0)], descr)
- newop.setfailargs(op.getfailargs())
- return newop
- else:
- # a real GUARD_VALUE. Make it use one counter per value.
- descr.make_a_counter_per_value(op)
+ if op.getopnum() == rop.GUARD_VALUE:
+ if op.getarg(0).type == 'i':
+ b = self.getintbound(op.getarg(0))
+ if b.is_bool():
+ # Hack: turn guard_value(bool) into guard_true/guard_false.
+ # This is done after the operation is emitted to let
+ # store_final_boxes_in_guard set the guard_opnum field of
+ # the descr to the original rop.GUARD_VALUE.
+ constvalue = op.getarg(1).getint()
+ if constvalue == 0:
+ opnum = rop.GUARD_FALSE
+ elif constvalue == 1:
+ opnum = rop.GUARD_TRUE
+ else:
+ raise AssertionError("uh?")
+ newop = self.replace_op_with(op, opnum, [op.getarg(0)],
descr)
+ return newop
+ # a real GUARD_VALUE. Make it use one counter per value.
+ descr.make_a_counter_per_value(op)
return op
def optimize_default(self, op):
diff --git a/rpython/jit/metainterp/optimizeopt/pure.py
b/rpython/jit/metainterp/optimizeopt/pure.py
--- a/rpython/jit/metainterp/optimizeopt/pure.py
+++ b/rpython/jit/metainterp/optimizeopt/pure.py
@@ -1,5 +1,5 @@
from rpython.jit.metainterp.optimizeopt.optimizer import Optimization, REMOVED
-from rpython.jit.metainterp.resoperation import rop, ResOperation
+from rpython.jit.metainterp.resoperation import rop, OpHelpers
from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
@@ -158,8 +158,7 @@
# all identical
# this removes a CALL_PURE that has the same (non-constant)
# arguments as a previous CALL_PURE.
- oldvalue = self.getvalue(old_op.result)
- self.make_equal_to(op.result, oldvalue)
+ self.make_equal_to(op, old_op)
self.last_emitted_operation = REMOVED
return True
return False
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
@@ -408,9 +408,8 @@
self.loop_invariant_producer[key] = op
newop = self.replace_op_with(op,
OpHelpers.call_for_descr(op.getdescr()))
- resvalue = self.optimizer.getvalue(op)
self.emit_operation(newop)
- self.loop_invariant_results[key] = resvalue
+ self.loop_invariant_results[key] = op
optimize_CALL_LOOPINVARIANT_R = optimize_CALL_LOOPINVARIANT_I
optimize_CALL_LOOPINVARIANT_F = optimize_CALL_LOOPINVARIANT_I
optimize_CALL_LOOPINVARIANT_N = optimize_CALL_LOOPINVARIANT_I
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)
"""
@@ -587,10 +587,10 @@
[i1, p2, p3]
i3 = getfield_gc_i(p3, descr=valuedescr)
escape_n(i3)
- p1 = new_with_vtable(ConstClass(node_vtable))
- p1sub = new_with_vtable(ConstClass(node_vtable2))
+ p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
+ setfield_gc(p1, i1, descr=valuedescr)
+ p1sub = new_with_vtable(ConstClass(node_vtable2), descr=nodesize2)
setfield_gc(p1sub, i1, descr=valuedescr)
- setfield_gc(p1, i1, descr=valuedescr)
setfield_gc(p1, p1sub, descr=nextdescr)
jump(i1, p1, p2)
"""
@@ -604,10 +604,10 @@
p3sub = getfield_gc_r(p3, descr=nextdescr)
i3 = getfield_gc_i(p3sub, descr=valuedescr)
escape_n(i3)
- p1 = new_with_vtable(ConstClass(node_vtable))
- p2sub = new_with_vtable(ConstClass(node_vtable2))
+ p2sub = new_with_vtable(ConstClass(node_vtable2), descr=nodesize2)
setfield_gc(p2sub, i1, descr=valuedescr)
setfield_gc(p2, p2sub, descr=nextdescr)
+ p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
jump(i1, p1, p2)
"""
# The same as test_p123_simple, but in the end the "old" p2 contains
@@ -829,7 +829,7 @@
def test_virtual_3(self):
ops = """
[i]
- p1 = new_with_vtable(ConstClass(node_vtable))
+ p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
setfield_gc(p1, i, descr=valuedescr)
i0 = getfield_gc_i(p1, descr=valuedescr)
i1 = int_add(i0, 1)
@@ -894,7 +894,7 @@
def test_virtual_constant_isnull(self):
ops = """
[i0]
- p0 = new_with_vtable(ConstClass(node_vtable))
+ p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
setfield_gc(p0, NULL, descr=nextdescr)
p2 = getfield_gc_r(p0, descr=nextdescr)
i1 = ptr_eq(p2, NULL)
@@ -909,7 +909,7 @@
def test_virtual_constant_isnonnull(self):
ops = """
[i0]
- p0 = new_with_vtable(ConstClass(node_vtable))
+ p0 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
setfield_gc(p0, ConstPtr(myptr), descr=nextdescr)
p2 = getfield_gc_r(p0, descr=nextdescr)
i1 = ptr_eq(p2, NULL)
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
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit