[pypy-svn] r69385 - in pypy/branch/compress-virtuals-resumedata/pypy/jit: backend/llgraph backend/test metainterp metainterp/test

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Nov 18 17:43:48 CET 2009


Author: cfbolz
Date: Wed Nov 18 17:43:47 2009
New Revision: 69385

Modified:
   pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/llgraph/runner.py
   pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/test/runner_test.py
   pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/compile.py
   pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/history.py
   pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/optimizeopt.py
   pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/resume.py
   pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/test/test_resume.py
Log:
(pedronis, cfbolz): introduce "holes" into the fail_args, to make
it possible to have mostly the same numbers for boxes in consecutive guards


Modified: pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/llgraph/llimpl.py	Wed Nov 18 17:43:47 2009
@@ -363,7 +363,10 @@
     op = loop.operations[-1]
     if op.fail_args is None:
         op.fail_args = []
-    op.fail_args.append(_variables[intvar])
+    if intvar == -1:
+        op.fail_args.append(None)
+    else:
+        op.fail_args.append(_variables[intvar])
 
 def compile_redirect_fail(old_loop, old_index, new_loop):
     old_loop = _from_opaque(old_loop)
@@ -382,6 +385,8 @@
         self.memocast = memocast
 
     def getenv(self, v):
+        if v is None:
+            return None
         if isinstance(v, Constant):
             return v.value
         else:

Modified: pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/llgraph/runner.py	Wed Nov 18 17:43:47 2009
@@ -171,7 +171,10 @@
                 index = llimpl.compile_add_fail(c, fail_index)
                 faildescr._compiled_fail = c, index
                 for box in op.fail_args:
-                    llimpl.compile_add_fail_arg(c, var2index[box])
+                    if box is not None:
+                        llimpl.compile_add_fail_arg(c, var2index[box])
+                    else:
+                        llimpl.compile_add_fail_arg(c, -1)
             x = op.result
             if x is not None:
                 if isinstance(x, history.BoxInt):

Modified: pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/compress-virtuals-resumedata/pypy/jit/backend/test/runner_test.py	Wed Nov 18 17:43:47 2009
@@ -123,6 +123,27 @@
         res = self.cpu.get_latest_value_int(0)
         assert res == 10
 
+    def test_compile_with_holes_in_fail_args(self):
+        i0 = BoxInt()
+        i1 = BoxInt()
+        i2 = BoxInt()
+        looptoken = LoopToken()
+        operations = [
+            ResOperation(rop.INT_ADD, [i0, ConstInt(1)], i1),
+            ResOperation(rop.INT_LE, [i1, ConstInt(9)], i2),
+            ResOperation(rop.GUARD_TRUE, [i2], None, descr=BasicFailDescr(2)),
+            ResOperation(rop.JUMP, [i1], None, descr=looptoken),
+            ]
+        inputargs = [i0]
+        operations[2].fail_args = [None, None, i1, None]
+        
+        self.cpu.compile_loop(inputargs, operations, looptoken)
+        self.cpu.set_future_value_int(0, 2)
+        fail = self.cpu.execute_token(looptoken)
+        assert fail == 2
+        res = self.cpu.get_latest_value_int(2)
+        assert res == 10
+
     def test_backends_dont_keep_loops_alive(self):
         import weakref, gc
         self.cpu.dont_keepalive_stuff = True

Modified: pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/compile.py	Wed Nov 18 17:43:47 2009
@@ -233,7 +233,12 @@
     def store_final_boxes(self, guard_op, boxes):
         guard_op.fail_args = boxes
         self.guard_opnum = guard_op.opnum
-        self.fail_arg_types = [box.type for box in boxes]
+        fail_arg_types = [history.HOLE] * len(boxes)
+        for i in range(len(boxes)):
+            box = boxes[i]
+            if box:
+                fail_arg_types[i] = box.type
+        self.fail_arg_types = fail_arg_types
 
     def handle_fail(self, metainterp_sd):
         from pypy.jit.metainterp.pyjitpl import MetaInterp

Modified: pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/history.py	(original)
+++ pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/history.py	Wed Nov 18 17:43:47 2009
@@ -15,6 +15,7 @@
 INT   = 'i'
 REF   = 'r'
 FLOAT = 'f'
+HOLE  = '_'
 
 FAILARGS_LIMIT = 1000
 
@@ -744,8 +745,9 @@
                     ops = op.descr._debug_suboperations
                     TreeLoop.check_consistency_of_branch(ops, seen.copy())
                 for box in op.fail_args or []:
-                    assert isinstance(box, Box)
-                    assert box in seen
+                    if box is not None:
+                        assert isinstance(box, Box)
+                        assert box in seen
             else:
                 assert op.fail_args is None
             box = op.result

Modified: pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/optimizeopt.py	Wed Nov 18 17:43:47 2009
@@ -526,7 +526,7 @@
         assert isinstance(descr, compile.ResumeGuardDescr)
         modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
         newboxes = modifier.finish(self.values)
-        if len(newboxes) > self.metainterp_sd.options.failargs_limit:
+        if len(newboxes) > self.metainterp_sd.options.failargs_limit: # XXX be careful here
             raise compile.GiveUp
         descr.store_final_boxes(op, newboxes)
         #

Modified: pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/pyjitpl.py	Wed Nov 18 17:43:47 2009
@@ -1645,6 +1645,8 @@
                 box = cpu.ts.BoxRef(cpu.get_latest_value_ref(i))
             elif boxtype == history.FLOAT:
                 box = history.BoxFloat(cpu.get_latest_value_float(i))
+            elif boxtype == history.HOLE:
+                continue
             else:
                 assert False, "bad box type: num=%d" % ord(boxtype)
             inputargs.append(box)

Modified: pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/resume.py	(original)
+++ pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/resume.py	Wed Nov 18 17:43:47 2009
@@ -102,6 +102,8 @@
         self.large_ints = {}
         self.refs = cpu.ts.new_ref_dict_2()
         self.numberings = {}
+        self.cached_boxes = {}
+        self.cached_virtuals = {}
 
     def getconst(self, const):
         if const.type == INT:
@@ -136,6 +138,8 @@
         self.consts.append(const)
         return result
 
+    # env numbering
+
     def number(self, values, snapshot):
         if snapshot is None:
             return None, {}, 0
@@ -174,6 +178,41 @@
     def forget_numberings(self, virtualbox):
         # XXX ideally clear only the affected numberings
         self.numberings.clear()
+        # XXX clear cached_*
+
+    # caching for virtuals and boxes inside them
+
+    def num_cached_boxes(self):
+        return len(self.cached_boxes)
+
+    def assign_number_to_box(self, box, boxes):
+        if box in self.cached_boxes:
+            num = self.cached_boxes[box]
+            boxes[-num-1] = box
+        else:
+            boxes.append(box)
+            num = -len(boxes)
+            self.cached_boxes[box] = num
+        return num
+
+    def num_cached_virtuals(self):
+        return len(self.cached_virtuals)
+
+    def assign_number_to_virtual(self, box, vinfo, fieldboxes, virtuals, fieldboxes_list):
+        if box in self.cached_virtuals:
+            num = self.cached_virtuals[box]
+            virtuals[-num-1] = vinfo
+            fieldboxes_list[-num-1] = fieldboxes
+        else:
+            virtuals.append(vinfo)
+            fieldboxes_list.append(fieldboxes)
+            num = -len(virtuals)
+            self.cached_virtuals[box] = num
+        return num
+
+    def clear_box_virtual_numbers(self):
+        self.cached_boxes.clear()
+        self.cached_virtuals.clear()
 
 
 _frame_info_placeholder = (None, 0, 0)
@@ -264,23 +303,21 @@
     def _number_virtuals(self, liveboxes):
         prev_liveboxes_cache = 0
         prev_virtuals_cache = 0
-        new_liveboxes = []
-        new_virtuals = []
-        new_vfieldboxes = []
+        new_liveboxes = [None] * self.memo.num_cached_boxes()
+        new_virtuals = [None] * self.memo.num_cached_virtuals()
+        new_vfieldboxes = [None] * self.memo.num_cached_virtuals()
         for box, tagged in self.liveboxes.iteritems():
             i, tagbits = untag(tagged)
             if tagbits == TAGBOX:
                 assert tagged_eq(tagged, UNASSIGNED)
-                new_liveboxes.append(box)
-                index = -prev_liveboxes_cache - len(new_liveboxes)
+                index = self.memo.assign_number_to_box(box, new_liveboxes)
                 self.liveboxes[box] = tag(index, TAGBOX)
             else:
                 assert tagbits == TAGVIRTUAL
                 if tagged_eq(tagged, UNASSIGNEDVIRTUAL):
                     vinfo, fieldboxes = self.vinfos_not_env[box]
-                    new_virtuals.append(vinfo)
-                    new_vfieldboxes.append(fieldboxes)
-                    index = -prev_virtuals_cache - len(new_virtuals)
+                    index = self.memo.assign_number_to_virtual(
+                        box, vinfo, fieldboxes, new_virtuals, new_vfieldboxes)
                     self.liveboxes[box] = tag(index, TAGVIRTUAL)
         new_liveboxes.reverse()
         new_virtuals.reverse()
@@ -297,6 +334,8 @@
             storage.rd_virtuals = self.virtuals[:]
             for i in range(len(storage.rd_virtuals)):
                 vinfo = storage.rd_virtuals[i]
+                if vinfo is None:
+                    continue
                 fieldboxes = self.vfieldboxes[i]
                 vinfo.fieldnums = [self._gettagged(box)
                                    for box in fieldboxes]
@@ -471,8 +510,14 @@
         for const in storage.rd_consts:
             debug_print('\tconst', const.repr_rpython())
         for box in liveboxes:
-            debug_print('\tbox', box.repr_rpython())
+            if box is None:
+                debug_print('\tbox', 'None')
+            else:
+                debug_print('\tbox', box.repr_rpython())
         if storage.rd_virtuals is not None:
             for virtual in storage.rd_virtuals:
-                virtual.debug_prints()
+                if virtual is None:
+                    debug_print('\t\t', 'None')
+                else:
+                    virtual.debug_prints()
     debug_stop("jit-resume")

Modified: pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/test/test_resume.py
==============================================================================
--- pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/test/test_resume.py	(original)
+++ pypy/branch/compress-virtuals-resumedata/pypy/jit/metainterp/test/test_resume.py	Wed Nov 18 17:43:47 2009
@@ -363,6 +363,7 @@
     v6 = virtual_value(b6, c2, None)
     v6.setfield(LLtypeMixin.nextdescr, v6)    
     values = {b2: virtual_value(b2, b4, v6), b6: v6}
+    memo.clear_box_virtual_numbers()
     modifier = ResumeDataVirtualAdder(storage2, memo)
     liveboxes2 = modifier.finish(values)
     assert len(storage2.rd_virtuals) == 2    
@@ -580,6 +581,75 @@
                                           tag(1, TAGVIRTUAL)]
     assert numb5.prev is numb4
 
+def test_ResumeDataLoopMemo_number_boxes():
+    memo = ResumeDataLoopMemo(LLtypeMixin.cpu)
+    b1, b2 = [BoxInt(), BoxInt()]
+    assert memo.num_cached_boxes() == 0
+    boxes = []
+    num = memo.assign_number_to_box(b1, boxes)
+    assert num == -1
+    assert boxes == [b1]
+    assert memo.num_cached_boxes() == 1
+    boxes = [None]
+    num = memo.assign_number_to_box(b1, boxes)
+    assert num == -1
+    assert boxes == [b1]
+    num = memo.assign_number_to_box(b2, boxes)
+    assert num == -2
+    assert boxes == [b1, b2]
+
+    assert memo.num_cached_boxes() == 2
+    boxes = [None, None]
+    num = memo.assign_number_to_box(b2, boxes)
+    assert num == -2
+    assert boxes == [None, b2]
+    num = memo.assign_number_to_box(b1, boxes)
+    assert num == -1
+    assert boxes == [b1, b2]
+
+    memo.clear_box_virtual_numbers()
+    assert memo.num_cached_boxes() == 0
+
+def test_ResumeDataLoopMemo_number_virtuals():
+    memo = ResumeDataLoopMemo(LLtypeMixin.cpu)
+    b1, b2 = [BoxInt(), BoxInt()]
+    vinfo1 = object()
+    vinfo2 = object()
+    fb1 = object()
+    fb2 = object()
+    assert memo.num_cached_virtuals() == 0
+    virtuals = []
+    vfieldboxes = []
+    num = memo.assign_number_to_virtual(b1, vinfo1, fb1, virtuals, vfieldboxes)
+    assert num == -1
+    assert virtuals == [vinfo1]
+    assert vfieldboxes == [fb1]
+    assert memo.num_cached_virtuals() == 1
+    virtuals = [None]
+    vfieldboxes = [None]
+    num = memo.assign_number_to_virtual(b1, vinfo1, fb1, virtuals, vfieldboxes)
+    assert num == -1
+    assert virtuals == [vinfo1]
+    assert vfieldboxes == [fb1]
+    num = memo.assign_number_to_virtual(b2, vinfo2, fb2, virtuals, vfieldboxes)
+    assert num == -2
+    assert virtuals == [vinfo1, vinfo2]
+    assert vfieldboxes == [fb1, fb2]
+
+    assert memo.num_cached_virtuals() == 2
+    virtuals = [None, None]
+    vfieldboxes = [None, None]
+    num = memo.assign_number_to_virtual(b2, vinfo2, fb2, virtuals, vfieldboxes)
+    assert num == -2
+    assert virtuals == [None, vinfo2]
+    assert vfieldboxes == [None, fb2]
+    num = memo.assign_number_to_virtual(b1, vinfo1, fb1, virtuals, vfieldboxes)
+    assert num == -1
+    assert virtuals == [vinfo1, vinfo2]
+    assert vfieldboxes == [fb1, fb2]
+
+    memo.clear_box_virtual_numbers()
+    assert memo.num_cached_virtuals() == 0
 
 def test__make_virtual():
     b1, b2 = BoxInt(), BoxInt()



More information about the Pypy-commit mailing list