[pypy-svn] r68198 - in pypy/trunk/pypy/jit/metainterp: . test

pedronis at codespeak.net pedronis at codespeak.net
Tue Oct 6 12:16:27 CEST 2009


Author: pedronis
Date: Tue Oct  6 12:16:26 2009
New Revision: 68198

Modified:
   pypy/trunk/pypy/jit/metainterp/optimizeopt.py
   pypy/trunk/pypy/jit/metainterp/resume.py
   pypy/trunk/pypy/jit/metainterp/simple_optimize.py
   pypy/trunk/pypy/jit/metainterp/test/test_resume.py
Log:
(cfbolz, pedronis) more sharing and interning of consts across the faildescrs of a loop



Modified: pypy/trunk/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/optimizeopt.py	Tue Oct  6 12:16:26 2009
@@ -365,6 +365,7 @@
         self.values_to_clean = {}
                                      
         self.interned_refs = {}
+        self.resumedata_memo = resume.ResumeDataLoopMemo(cpu)
 
     def getinterned(self, box):
         constbox = self.get_constant_box(box)
@@ -514,7 +515,7 @@
     def store_final_boxes_in_guard(self, op):
         descr = op.descr
         assert isinstance(descr, compile.ResumeGuardDescr)
-        modifier = resume.ResumeDataVirtualAdder(descr)
+        modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
         modifier.walk_snapshots(self.values)
         newboxes = modifier.finish(self.values)
         descr.store_final_boxes(op, newboxes)

Modified: pypy/trunk/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/resume.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/resume.py	Tue Oct  6 12:16:26 2009
@@ -1,5 +1,5 @@
 import sys
-from pypy.jit.metainterp.history import Box, Const, ConstInt
+from pypy.jit.metainterp.history import Box, Const, ConstInt, INT, REF
 from pypy.jit.metainterp.resoperation import rop
 from pypy.rpython.lltypesystem import rffi
 from pypy.rlib import rarithmetic
@@ -92,14 +92,54 @@
 VIRTUAL_FLAG = int((sys.maxint+1) // 2)
 assert not (VIRTUAL_FLAG & (VIRTUAL_FLAG-1))    # a power of two
 
+class ResumeDataLoopMemo(object):
+
+    def __init__(self, cpu):
+        self.cpu = cpu
+        self.consts = []
+        self.large_ints = {}
+        self.refs = {}
+
+    def getconst(self, const):
+        if const.type == INT:
+            val = const.getint()
+            if not we_are_translated() and not isinstance(val, int):
+                # unhappiness, probably a symbolic
+                return self._newconst(const)
+            try:
+                return tag(val, TAGINT)
+            except ValueError:
+                pass
+            tagged = self.large_ints.get(val, UNASSIGNED)
+            if not tagged_eq(tagged, UNASSIGNED):
+                return tagged
+            tagged = self._newconst(const)
+            self.large_ints[val] = tagged
+            return tagged
+        elif const.type == REF:
+            val = const.getref_base()
+            val = self.cpu.ts.cast_ref_to_hashable(self.cpu, val)
+            tagged = self.refs.get(val, UNASSIGNED)
+            if not tagged_eq(tagged, UNASSIGNED):
+                return tagged
+            tagged = self._newconst(const)
+            self.refs[val] = tagged
+            return tagged            
+        return self._newconst(const)
+
+    def _newconst(self, const):
+        result = tag(len(self.consts), TAGCONST)
+        self.consts.append(const)
+        return result        
+    
 _frame_info_placeholder = (None, 0, 0)
 
 class ResumeDataVirtualAdder(object):
 
-    def __init__(self, storage):
+    def __init__(self, storage, memo):
         self.storage = storage
+        self.memo = memo
         self.liveboxes = {}
-        self.consts = []
         self.virtuals = []
         self.vfieldboxes = []
 
@@ -124,7 +164,7 @@
     def make_constant(self, box, const):
         # this part of the interface is not used so far by optimizeopt.py
         if tagged_eq(self.liveboxes[box], UNASSIGNED):
-            self.liveboxes[box] = self._getconst(const)
+            self.liveboxes[box] = self.memo.getconst(const)
 
     def make_virtual(self, virtualbox, known_class, fielddescrs, fieldboxes):
         vinfo = VirtualInfo(known_class, fielddescrs)
@@ -208,7 +248,7 @@
                 fieldboxes = self.vfieldboxes[i]
                 vinfo.fieldnums = [self._gettagged(box)
                                    for box in fieldboxes]
-        storage.rd_consts = self.consts[:]
+        storage.rd_consts = self.memo.consts
         storage.rd_snapshot = None
         if debug:
             dump_storage(storage, liveboxes)
@@ -216,25 +256,10 @@
 
     def _gettagged(self, box):
         if isinstance(box, Const):
-            return self._getconst(box)
+            return self.memo.getconst(box)
         else:
             return self.liveboxes[box]
 
-    def _getconst(self, const):
-        if isinstance(const, ConstInt):
-            val = const.getint()
-            try:
-                if not we_are_translated() and not isinstance(val, int):
-                    # unhappiness, probably a symbolic
-                    raise ValueError
-                return tag(val, TAGINT)
-            except ValueError:
-                pass
-        result = tag(len(self.consts), TAGCONST)
-        self.consts.append(const)
-        return result
-
-
 class AbstractVirtualInfo(object):
     def allocate(self, metainterp):
         raise NotImplementedError

Modified: pypy/trunk/pypy/jit/metainterp/simple_optimize.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/simple_optimize.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/simple_optimize.py	Tue Oct  6 12:16:26 2009
@@ -7,7 +7,7 @@
 
 EMPTY_VALUES = {}
 
-def optimize_loop(options, old_loops, loop, cpu=None):
+def optimize_loop(metainterp_sd, old_loops, loop, cpu=None):
     if old_loops:
         assert len(old_loops) == 1
         return old_loops[0]
@@ -16,12 +16,13 @@
         # we need it since the backend can modify those lists, which make
         # get_guard_op in compile.py invalid
         # in fact, x86 modifies this list for moving GCs
+        memo = resume.ResumeDataLoopMemo(cpu)
         newoperations = []
         for op in loop.operations:
             if op.is_guard():
                 descr = op.descr
                 assert isinstance(descr, compile.ResumeGuardDescr)
-                modifier = resume.ResumeDataVirtualAdder(descr)
+                modifier = resume.ResumeDataVirtualAdder(descr, memo)
                 modifier.walk_snapshots(EMPTY_VALUES)
                 newboxes = modifier.finish(EMPTY_VALUES)
                 descr.store_final_boxes(op, newboxes)
@@ -29,6 +30,6 @@
         loop.operations = newoperations
         return None
 
-def optimize_bridge(options, old_loops, loop, cpu=None):
-    optimize_loop(options, [], loop, cpu)
+def optimize_bridge(metainterp_sd, old_loops, loop, cpu=None):
+    optimize_loop(metainterp_sd, [], loop, cpu)
     return old_loops[0]

Modified: pypy/trunk/pypy/jit/metainterp/test/test_resume.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_resume.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_resume.py	Tue Oct  6 12:16:26 2009
@@ -2,7 +2,7 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.jit.metainterp.resume import *
 from pypy.jit.metainterp.history import BoxInt, BoxPtr, ConstInt, ConstAddr
-from pypy.jit.metainterp.history import ConstPtr
+from pypy.jit.metainterp.history import ConstPtr, ConstFloat
 from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin
 from pypy.jit.metainterp import executor
 
@@ -230,7 +230,7 @@
     storage = Storage()
     storage.rd_snapshot = snap1
 
-    modifier = ResumeDataVirtualAdder(storage)
+    modifier = ResumeDataVirtualAdder(storage, None)
     modifier.walk_snapshots({})
 
     assert modifier.liveboxes == {b1: UNASSIGNED, b2: UNASSIGNED,
@@ -247,7 +247,7 @@
     storage = Storage()
     storage.rd_snapshot = snap1
 
-    modifier = ResumeDataVirtualAdder(storage)
+    modifier = ResumeDataVirtualAdder(storage, None)
     modifier.walk_snapshots({b1: val, b2: val})    
 
     assert modifier.liveboxes == {b1_2: UNASSIGNED, b3: UNASSIGNED}
@@ -262,7 +262,7 @@
     storage = Storage()
     storage.rd_frame_info_list = fi1
 
-    modifier = ResumeDataVirtualAdder(storage)
+    modifier = ResumeDataVirtualAdder(storage, None)
     modifier._flatten_frame_info()
     assert storage.rd_frame_info_list is None
 
@@ -270,6 +270,52 @@
                                       ("JITCODE1", 3, 4)]
 
 
+def test_ResumeDataLoopMemo_ints():
+    memo = ResumeDataLoopMemo(None)
+    tagged = memo.getconst(ConstInt(44))
+    assert untag(tagged) == (44, TAGINT)
+    tagged = memo.getconst(ConstInt(-3))
+    assert untag(tagged) == (-3, TAGINT)
+    const = ConstInt(50000)
+    tagged = memo.getconst(const)
+    index, tagbits = untag(tagged)
+    assert tagbits == TAGCONST
+    assert memo.consts[index] is const
+    tagged = memo.getconst(ConstInt(50000))
+    index2, tagbits = untag(tagged)
+    assert tagbits == TAGCONST
+    assert index2 == index
+
+demo55 = lltype.malloc(LLtypeMixin.NODE)
+demo55o = lltype.cast_opaque_ptr(llmemory.GCREF, demo55)
+demo66 = lltype.malloc(LLtypeMixin.NODE)
+demo66o = lltype.cast_opaque_ptr(llmemory.GCREF, demo66)
+    
+def test_ResumeDataLoopMemo_refs():
+    cpu = LLtypeMixin.cpu
+    memo = ResumeDataLoopMemo(cpu)
+    const = cpu.ts.ConstRef(demo55o)
+    tagged = memo.getconst(const)
+    index, tagbits = untag(tagged)
+    assert tagbits == TAGCONST
+    assert memo.consts[index] is const    
+    tagged = memo.getconst(cpu.ts.ConstRef(demo55o))
+    index2, tagbits = untag(tagged)
+    assert tagbits == TAGCONST
+    assert index2 == index
+    tagged = memo.getconst(cpu.ts.ConstRef(demo66o))
+    index3, tagbits = untag(tagged)
+    assert tagbits == TAGCONST
+    assert index3 != index    
+
+def test_ResumeDataLoopMemo_other():
+    memo = ResumeDataLoopMemo(None)
+    const = ConstFloat(-1.0)
+    tagged = memo.getconst(const)
+    index, tagbits = untag(tagged)
+    assert tagbits == TAGCONST
+    assert memo.consts[index] is const
+
 class MyMetaInterp:
     def __init__(self, cpu):
         self.cpu = cpu
@@ -282,9 +328,6 @@
                            descr))
         return resbox
 
-demo55 = lltype.malloc(LLtypeMixin.NODE)
-demo55o = lltype.cast_opaque_ptr(llmemory.GCREF, demo55)
-
 def _resume_remap(liveboxes, expected, *newvalues):
     newboxes = []
     for box in liveboxes:
@@ -306,7 +349,8 @@
 def test_virtual_adder_no_op():
     b1s, b2s, b3s = [BoxInt(1), BoxPtr(), BoxInt(3)]
     storage = make_storage(b1s, b2s, b3s)
-    modifier = ResumeDataVirtualAdder(storage)
+    memo = ResumeDataLoopMemo(LLtypeMixin.cpu)    
+    modifier = ResumeDataVirtualAdder(storage, memo)
     modifier.walk_snapshots({})
     assert not modifier.is_virtual(b1s)
     assert not modifier.is_virtual(b2s)
@@ -329,7 +373,8 @@
 def test_virtual_adder_int_constants():
     b1s, b2s, b3s = [ConstInt(sys.maxint), ConstInt(2**16), ConstInt(-65)]
     storage = make_storage(b1s, b2s, b3s)
-    modifier = ResumeDataVirtualAdder(storage)
+    memo = ResumeDataLoopMemo(LLtypeMixin.cpu)    
+    modifier = ResumeDataVirtualAdder(storage, memo)
     modifier.walk_snapshots({})
     liveboxes = modifier.finish({})
     assert storage.rd_snapshot is None
@@ -345,10 +390,30 @@
     assert metainterp.trace == []
 
 
+def test_virtual_adder_memo_const_sharing():
+    b1s, b2s, b3s = [ConstInt(sys.maxint), ConstInt(2**16), ConstInt(-65)]
+    storage = make_storage(b1s, b2s, b3s)
+    memo = ResumeDataLoopMemo(LLtypeMixin.cpu)
+    modifier = ResumeDataVirtualAdder(storage, memo)
+    modifier.walk_snapshots({})
+    modifier.finish({})
+    assert len(memo.consts) == 2
+    assert storage.rd_consts is memo.consts
+
+    b1s, b2s, b3s = [ConstInt(sys.maxint), ConstInt(2**17), ConstInt(-65)]
+    storage2 = make_storage(b1s, b2s, b3s)
+    modifier2 = ResumeDataVirtualAdder(storage2, memo)
+    modifier2.walk_snapshots({})
+    modifier2.finish({})
+    assert len(memo.consts) == 3    
+    assert storage2.rd_consts is memo.consts
+
+
 def test_virtual_adder_no_op_renaming():
     b1s, b2s, b3s = [BoxInt(1), BoxInt(2), BoxInt(3)]
     storage = make_storage(b1s, b2s, b3s)
-    modifier = ResumeDataVirtualAdder(storage)
+    memo = ResumeDataLoopMemo(LLtypeMixin.cpu)
+    modifier = ResumeDataVirtualAdder(storage, memo)
     b1_2 = BoxInt()
     class FakeValue(object):
 
@@ -383,7 +448,8 @@
                                BoxPtr(), BoxPtr()]  
     c1s = ConstInt(111)
     storage = make_storage(b1s, b2s, b3s)
-    modifier = ResumeDataVirtualAdder(storage)
+    memo = ResumeDataLoopMemo(LLtypeMixin.cpu)    
+    modifier = ResumeDataVirtualAdder(storage, memo)
     modifier.walk_snapshots({})
     modifier.make_virtual(b2s,
                           ConstAddr(LLtypeMixin.node_vtable_adr,
@@ -454,7 +520,8 @@
             #    the list of liveboxes
             b1s = ConstInt(111)
         storage = make_storage(b1s, b2s, b3s)
-        modifier = ResumeDataVirtualAdder(storage)
+        memo = ResumeDataLoopMemo(LLtypeMixin.cpu)        
+        modifier = ResumeDataVirtualAdder(storage, memo)
         modifier.walk_snapshots({})
 
         if testnumber == 1:
@@ -484,7 +551,8 @@
     b1s, b2s, b3s, b4s = [BoxInt(1), BoxPtr(), BoxInt(3), BoxInt(4)]
     c1s = ConstInt(111)
     storage = make_storage(b1s, b2s, b3s)
-    modifier = ResumeDataVirtualAdder(storage)
+    memo = ResumeDataLoopMemo(LLtypeMixin.cpu)
+    modifier = ResumeDataVirtualAdder(storage, memo)
     modifier.walk_snapshots({})    
     modifier.make_varray(b2s,
                          LLtypeMixin.arraydescr,
@@ -531,7 +599,8 @@
     b1s, b2s, b3s, b4s = [BoxInt(1), BoxPtr(), BoxInt(3), BoxPtr()]
     c1s = ConstInt(111)
     storage = make_storage(b1s, b2s, b3s)
-    modifier = ResumeDataVirtualAdder(storage)
+    memo = ResumeDataLoopMemo(LLtypeMixin.cpu)    
+    modifier = ResumeDataVirtualAdder(storage, memo)
     modifier.walk_snapshots({})
     modifier.make_vstruct(b2s,
                           LLtypeMixin.ssize,



More information about the Pypy-commit mailing list