[pypy-svn] r63113 - in pypy/branch/virtualizable-specnodes/pypy/jit/metainterp: . test

fijal at codespeak.net fijal at codespeak.net
Fri Mar 20 09:49:35 CET 2009


Author: fijal
Date: Fri Mar 20 09:49:34 2009
New Revision: 63113

Modified:
   pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py
   pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py
   pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py
   pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_tl.py
Log:
an in-progress checkin of changes so-far


Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/compile.py	Fri Mar 20 09:49:34 2009
@@ -151,15 +151,6 @@
     metainterp.cpu.compile_operations(loop.operations, guard_op)
     metainterp.stats.loops.append(loop)
 
-def update_loop(metainterp, loop, guard_op, newboxlist):
-    mp = loop.operations[0]
-    mp.args += newboxlist
-    jump = loop.operations[-1]
-    jump.args += newboxlist
-    guard_op.liveboxes += newboxlist
-    guard_op.storage = None
-    metainterp.cpu.update_loop(loop, mp, guard_op, newboxlist)
-
 # ____________________________________________________________
 
 def matching_merge_point(metainterp, targetmp, endliveboxes):
@@ -176,14 +167,14 @@
     op = ResOperation(rop.JUMP, endliveboxes, None)
     operations.append(op)
     #
-    old_loop, newboxlist = optimize.optimize_bridge(metainterp.options,
-                                                    old_loops, bridge,
-                                                    metainterp.cpu)
+    old_loop, newboxlist, storage = optimize.optimize_bridge(metainterp.options,
+                                                             old_loops, bridge,
+                                                             metainterp.cpu)
     if old_loop is None:
         return None
     bridge.jump_to = old_loop
     if newboxlist:
         # recompile loop
-        update_loop(metainterp, old_loop, guard_op, newboxlist)
+        optimize.update_loop(metainterp, old_loop, newboxlist, storage)
     finish_loop_or_bridge(metainterp, bridge, old_loop.operations[0], guard_op)
     return bridge

Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py	(original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/optimize.py	Fri Mar 20 09:49:34 2009
@@ -27,6 +27,9 @@
         assert isinstance(other, FixedClass)
         return True
 
+    def _getrepr_(self):
+        return "FixedClass"
+
 class CancelInefficientLoop(Exception):
     pass
 
@@ -48,6 +51,8 @@
         # the same as above, but for lists and for running setitem
         self.list_allocations = []
         self.setitems = []
+        # used for merging
+        self.extras = []
 
     def deal_with_box(self, box, nodes, liveboxes, memo):
         if isinstance(box, Const) or box not in nodes:
@@ -281,13 +286,13 @@
     for old_loop in old_loops:
         if perfect_specializer.match(old_loop.operations):
             num = len(old_loop.extensions)
-            newlist, newspecnodes = perfect_specializer.adapt_for_match(
+            newlist, newspecnodes, s = perfect_specializer.adapt_for_match(
                 old_loop.operations, num)
             if newlist:
                 old_loop.extensions.append(newspecnodes)
             perfect_specializer.loop.operations[0].args.extend(newlist)
             perfect_specializer.optimize_loop()
-            return old_loop, newlist
+            return old_loop, newlist, s
     return None     # no loop matches
 
 class PerfectSpecializer(object):
@@ -831,12 +836,14 @@
         jump_op = self.loop.operations[-1]
         self.specnodes = old_mp.specnodes
         newboxlist = BoxRetriever()
+        storage = AllocationStorage()
         extensions = []
         for i in range(len(old_mp.specnodes)):
             old_specnode = old_mp.specnodes[i]
             new_instnode = self.nodes[jump_op.args[i]]
-            old_specnode.adapt_to(new_instnode, newboxlist, extensions, num)
-        return newboxlist.flatten(), extensions
+            old_specnode.adapt_to(new_instnode, newboxlist, extensions, num,
+                                  storage)
+        return newboxlist.flatten(), extensions, storage
 
 class Chooser(object):
     def __init__(self, boxes_from_frame, allocated_boxes, allocated_lists):
@@ -895,6 +902,19 @@
     return newboxes
 
 
+def update_loop(metainterp, loop, newboxlist, add_storage):
+    mp = loop.operations[0]
+    mp.args += newboxlist
+    jump = loop.operations[-1]
+    jump.args += newboxlist
+    for op in loop.operations:
+        if op.is_guard():
+            import pdb
+            pdb.set_trace()
+    metainterp.cpu.update_loop(loop, mp, newboxlist)
+
+# ----------------------------------------------------------------------
+
 def partition(array, left, right):
     last_item = array[right]
     pivot = last_item.sort_key()

Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py	(original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/specnode.py	Fri Mar 20 09:49:34 2009
@@ -38,7 +38,7 @@
     def extract_runtime_data(self, cpu, valuebox, resultlist):
         resultlist.append(valuebox)
 
-    def adapt_to(self, instnode, newboxlist, newspecnodes, num):
+    def adapt_to(self, instnode, newboxlist, newspecnodes, num, storage):
         instnode.escaped = True
 
     def mutate_nodes(self, instnode):
@@ -50,6 +50,9 @@
     def matches(self, other):
         raise NotImplementedError
 
+    def create_extra_storage(self, storage):
+        pass
+
 class RedirectingSpecNode(SpecNode):
     def __init__(self, specnode, group):
         self.redirect_to = specnode
@@ -181,10 +184,10 @@
                                             [valuebox], ofs)
                 subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
 
-    def adapt_to(self, instnode, newboxlist, newspecnodes, num):
+    def adapt_to(self, instnode, newboxlist, newspecnodes, num, storage):
         for ofs, subspecnode in self.fields:
             subspecnode.adapt_to(instnode.curfields[ofs], newboxlist,
-                                 newspecnodes, num)
+                                 newspecnodes, num, storage)
 
 class VirtualizedOrDelayedSpecNode(SpecNodeWithFields):
     
@@ -196,10 +199,10 @@
         resultlist.append(valuebox)
         SpecNodeWithFields.extract_runtime_data(self, cpu, valuebox, resultlist)
 
-    def adapt_to(self, instnode, newboxlist, newspecnodes, num):
+    def adapt_to(self, instnode, newboxlist, newspecnodes, num, storage):
         instnode.escaped = True
         SpecNodeWithFields.adapt_to(self, instnode, newboxlist, newspecnodes,
-                                    num)
+                                    num, storage)
 
 class DelayedSpecNode(VirtualizedOrDelayedSpecNode):
 
@@ -276,7 +279,7 @@
                 return False
         return True
 
-    def adapt_to(self, instnode, newboxlist, newspecnodes, num):
+    def adapt_to(self, instnode, newboxlist, newspecnodes, num, storage):
         instnode.virtualized = True
         fields = []
         for ofs, subspecnode in self.fields:
@@ -286,13 +289,15 @@
                     node = instnode.curfields[ofs]
                     subspecnode = orignode.intersect(node, {})
                     subspecnode.mutate_nodes(orignode)
+                    res = subspecnode.create_extra_storage(storage)
+                    self.add_to_storage(ofs, res, storage)
                     subspecnode = RedirectingSpecNode(subspecnode, num)
                     subspecnode.expand_boxlist(orignode, newboxlist, None)
                     newspecnodes.append(subspecnode)
                 # otherwise we simply ignore unused field
             else:
                 subspecnode.adapt_to(instnode.curfields[ofs], newboxlist,
-                                     newspecnodes, num)
+                                     newspecnodes, num, storage)
             fields.append((ofs, subspecnode))
         self.fields = fields
 
@@ -303,6 +308,9 @@
             return False
         return VirtualizedSpecNode.equals(self, other)        
 
+    def create_extra_storage(self, storage):
+        raise NotImplementedError
+
 class VirtualizableListSpecNode(VirtualizedSpecNode):
 
     def equals(self, other):
@@ -328,10 +336,10 @@
 
 class VirtualSpecNode(SpecNodeWithFields):
 
-    def adapt_to(self, instnode, newboxlist, newspecnodes, num):
+    def adapt_to(self, instnode, newboxlist, newspecnodes, num, storage):
         instnode.virtual = True
         return SpecNodeWithFields.adapt_to(self, instnode, newboxlist,
-                                           newspecnodes, num)
+                                           newspecnodes, num, storage)
 
     def mutate_nodes(self, instnode):
         SpecNodeWithFields.mutate_nodes(self, instnode)
@@ -344,30 +352,37 @@
             return False
         return SpecNodeWithFields.equals(self, other)
 
+    def create_extra_storage(self, storage):
+        xxx
+
 class VirtualFixedListSpecNode(VirtualSpecNode):
 
-   def __init__(self, known_class, fields, known_length):
-       VirtualSpecNode.__init__(self, known_class, fields)
-       self.known_length = known_length
-
-   def mutate_nodes(self, instnode):
-       VirtualSpecNode.mutate_nodes(self, instnode)
-       instnode.cursize = self.known_length
-
-   def equals(self, other):
-       if not isinstance(other, VirtualFixedListSpecNode):
-           return False
-       return SpecNodeWithFields.equals(self, other)
+    def __init__(self, known_class, fields, known_length):
+        VirtualSpecNode.__init__(self, known_class, fields)
+        self.known_length = known_length
+
+    def mutate_nodes(self, instnode):
+        VirtualSpecNode.mutate_nodes(self, instnode)
+        instnode.cursize = self.known_length
+
+    def equals(self, other):
+        if not isinstance(other, VirtualFixedListSpecNode):
+            return False
+        return SpecNodeWithFields.equals(self, other)
     
-   def extract_runtime_data(self, cpu, valuebox, resultlist):
-       from pypy.jit.metainterp.resoperation import rop
-       from pypy.jit.metainterp.optimize import FixedList
-       from pypy.jit.metainterp.history import check_descr
-       cls = self.known_class
-       assert isinstance(cls, FixedList)
-       arraydescr = cls.arraydescr
-       check_descr(arraydescr)
-       for ofs, subspecnode in self.fields:
-           fieldbox = executor.execute(cpu, rop.GETARRAYITEM_GC,
-                                       [valuebox, ofs], arraydescr)
-           subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
+    def extract_runtime_data(self, cpu, valuebox, resultlist):
+        from pypy.jit.metainterp.resoperation import rop
+        from pypy.jit.metainterp.optimize import FixedList
+        from pypy.jit.metainterp.history import check_descr
+        cls = self.known_class
+        assert isinstance(cls, FixedList)
+        arraydescr = cls.arraydescr
+        check_descr(arraydescr)
+        for ofs, subspecnode in self.fields:
+            fieldbox = executor.execute(cpu, rop.GETARRAYITEM_GC,
+                                        [valuebox, ofs], arraydescr)
+            subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
+
+    def create_extra_storage(self, storage):
+        xxx
+

Modified: pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_tl.py
==============================================================================
--- pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_tl.py	(original)
+++ pypy/branch/virtualizable-specnodes/pypy/jit/metainterp/test/test_tl.py	Fri Mar 20 09:49:34 2009
@@ -107,6 +107,96 @@
                          'int_is_true':1, 'guard_false':1, 'jump':1,
                           'guard_value':1})
 
+    def test_example(self):
+        jitdriver = JitDriver(greens = ['code', 'i'], reds = ['v1', 'v2', 'v3'])
+        
+        class IntObject(object):
+            def __init__(self, value):
+                self.value = value
+
+            def add(self, other):
+                return IntObject(self.value + other.value)
+
+            def gt(self, other):
+                return self.value > other.value
+
+        def store_into_variable(num, v1, v2, v3, value_to_store):
+            if num == 0:
+                return value_to_store, v2, v3
+            elif num == 1:
+                return v1, value_to_store, v3
+            elif num == 2:
+                return v1, v2, value_to_store
+            else:
+                raise Exception("Wrong num")
+
+        def load_variable(num, v1, v2, v3):
+            if num == 0:
+                return v1
+            elif num == 1:
+                return v2
+            elif num == 2:
+                return v3
+            else:
+                raise Exception("Wrong num")
+
+        def interpret(code, i0, i1, i2):
+            v1 = IntObject(i0)
+            v2 = IntObject(i1)
+            v3 = IntObject(i2)
+            i = 0
+            while i < len(code):
+                jitdriver.jit_merge_point(code=code, i=i, v1=v1, v2=v2, v3=v3)
+                if code[i] == ADD:
+                    a = load_variable(code[i + 1], v1, v2, v3)
+                    b = load_variable(code[i + 2], v1, v2, v3)
+                    res_num = code[i + 3]
+                    res = a.add(b)
+                    v1, v2, v3 = store_into_variable(res_num, v1, v2, v3,
+                                                     res)
+                    i += 4
+                elif code[i] == JUMP_IF_GT:
+                    a = load_variable(code[i + 1], v1, v2, v3)
+                    b = load_variable(code[i + 2], v1, v2, v3)
+                    where = code[i + 3]
+                    if a.gt(b):
+                        i = where
+                        jitdriver.can_enter_jit(code=code, i=i, v1=v1, v2=v2,
+                                                v3=v3)
+                    else:
+                        i += 4
+                elif code[i] == JUMP:
+                    i = code[i + 1]
+                    jitdriver.can_enter_jit(code=code, i=i, v1=v1, v2=v2, v3=v3)
+                else:
+                    raise Exception("bytecode corruption")
+            return v1.value
+
+        ADD = 0
+        JUMP = 1
+        JUMP_IF_GT = 2
+
+        code = [
+            ADD, 0, 1, 0,
+            ADD, 0, 1, 0,
+            ADD, 0, 1, 0,
+            JUMP_IF_GT, 0, 2, 18,
+            JUMP, 0
+        ]
+
+        # v0 += v1
+        # v0 += v1
+        # v0 += v1
+        # if v1 > v2: jump 18 (after the end of the loop)
+        # jump 0
+
+        def runner(num, i0, i1, i2):
+            return interpret([code, []][num], i0, i1, i2)
+
+        assert interpret(code, 0, 1, 20) == 21
+        res = self.meta_interp(runner, [0, 0, 1, 20])
+        assert res == 21
+
 class TestOOtype(ToyLanguageTests, OOJitMixin):
     pass
 



More information about the Pypy-commit mailing list