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

Reply via email to