[pypy-svn] r61827 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test

fijal at codespeak.net fijal at codespeak.net
Fri Feb 13 13:57:48 CET 2009


Author: fijal
Date: Fri Feb 13 13:57:47 2009
New Revision: 61827

Added:
   pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py   (contents, props changed)
Modified:
   pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vable_optimize.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py
Log:
Refactor pieces from optimize into specnode.py. Now it's all nicely handled
by oo-style calls instead of isintance checks a bit everywhere


Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py	Fri Feb 13 13:57:47 2009
@@ -1,75 +1,14 @@
 from pypy.jit.metainterp.history import (Box, Const, ConstInt,
                                          MergePoint, ResOperation, Jump)
 from pypy.jit.metainterp.heaptracker import always_pure_operations
+from pypy.jit.metainterp.specnode import (FixedClassSpecNode,
+                                          VirtualInstanceSpecNode,
+                                          VirtualizableSpecNode,
+                                          NotSpecNode)
 
 class CancelInefficientLoop(Exception):
     pass
 
-class FixedClassSpecNode(object):
-    def __init__(self, known_class):
-        self.known_class = known_class
-
-    def equals(self, other):
-        if type(other) is not FixedClassSpecNode:
-            return False
-        else:
-            assert isinstance(other, FixedClassSpecNode) # make annotator happy
-            return self.known_class.equals(other.known_class)
-
-    def matches(self, instnode):
-        if instnode.cls is None:
-            return False
-        return instnode.cls.source.equals(self.known_class)
-
-class SpecNodeWithFields(FixedClassSpecNode):
-    def __init__(self, known_class, fields):
-        FixedClassSpecNode.__init__(self, known_class)
-        self.fields = fields
-
-    def equals(self, other):
-        if not self.known_class.equals(other.known_class):
-            return False
-        elif len(self.fields) != len(other.fields):
-            return False
-        else:
-            for i in range(len(self.fields)):
-                key, value = self.fields[i]
-                otherkey, othervalue = other.fields[i]
-                if key != otherkey:
-                    return False
-                if value is None:
-                    if othervalue is not None:
-                        return False
-                else:
-                    if not value.equals(othervalue):
-                        return False
-            return True
-
-    def matches(self, instnode):
-        # XXX think about details of virtual vs virtualizable
-        if not FixedClassSpecNode.matches(self, instnode):
-            return False
-        for key, value in self.fields:
-            if key not in instnode.curfields:
-                return False
-            if value is not None and not value.matches(instnode.curfields[key]):
-                return False
-        return True
-
-class VirtualizableSpecNode(SpecNodeWithFields):
-
-    def equals(self, other):
-        if not isinstance(other, VirtualizableSpecNode):
-            return False
-        return SpecNodeWithFields.equals(self, other)
-
-class VirtualInstanceSpecNode(SpecNodeWithFields):
-
-    def equals(self, other):
-        if not isinstance(other, VirtualInstanceSpecNode):
-            return False
-        return SpecNodeWithFields.equals(self, other)
-
 class AllocationStorage(object):
     def __init__(self):
         # allocations: list of vtables to allocate
@@ -122,19 +61,6 @@
 type_cache = TypeCache()   # XXX remove me later
 type_cache.class_size = {}
 
-def extract_runtime_data(cpu, specnode, valuebox, resultlist):
-    if not isinstance(specnode, VirtualInstanceSpecNode):
-        resultlist.append(valuebox)
-    if isinstance(specnode, SpecNodeWithFields):
-        for ofs, subspecnode in specnode.fields:
-            cls = specnode.known_class.getint()
-            tp = cpu.typefor(ofs)
-            fieldbox = cpu.execute_operation('getfield_gc',
-                                             [valuebox, ConstInt(ofs)],
-                                             tp)
-            extract_runtime_data(cpu, subspecnode, fieldbox, resultlist)
-
-
 class InstanceNode(object):
     def __init__(self, source, escaped=True, startbox=False, const=False):
         self.source = source       # a Box
@@ -164,7 +90,7 @@
 
     def intersect(self, other):
         if not other.cls:
-            return None
+            return NotSpecNode()
         if self.cls:
             if not self.cls.source.equals(other.cls.source):
                 raise CancelInefficientLoop
@@ -173,7 +99,7 @@
             known_class = other.cls.source
         if other.escaped and not other.virtualized:
             if self.cls is None:
-                return None
+                return NotSpecNode()
             return FixedClassSpecNode(known_class)
         if not other.escaped:
             fields = []
@@ -184,7 +110,7 @@
                     specnode = self.origfields[ofs].intersect(node)
                 else:
                     self.origfields[ofs] = InstanceNode(node.source.clonebox())
-                    specnode = None
+                    specnode = NotSpecNode()
                 fields.append((ofs, specnode))
             return VirtualInstanceSpecNode(known_class, fields)
         else:
@@ -199,23 +125,16 @@
                     node = other.curfields[ofs]
                     specnode = self.origfields[ofs].intersect(node)
                 elif ofs in self.origfields:
-                    specnode = None
+                    specnode = NotSpecNode()
                 else:
                     # ofs in other.curfields
                     node = other.curfields[ofs]
                     self.origfields[ofs] = InstanceNode(node.source.clonebox())
-                    specnode = None
+                    specnode = NotSpecNode()
                 fields.append((ofs, specnode))
                     
             return VirtualizableSpecNode(known_class, fields)
 
-    def adapt_to(self, specnode):
-        if not isinstance(specnode, VirtualInstanceSpecNode):
-            self.escaped = True
-            return
-        for ofs, subspecnode in specnode.fields:
-            self.curfields[ofs].adapt_to(subspecnode)
-
     def __repr__(self):
         flags = ''
         if self.escaped:     flags += 'e'
@@ -365,41 +284,15 @@
             specnodes.append(enternode.intersect(leavenode))
         self.specnodes = specnodes
 
-    def mutate_nodes(self, instnode, specnode):
-        if specnode is not None:
-            if instnode.cls is None:
-                instnode.cls = InstanceNode(specnode.known_class)
-            else:
-                assert instnode.cls.source.equals(specnode.known_class)
-            if isinstance(specnode, SpecNodeWithFields):
-                curfields = {}
-                for ofs, subspecnode in specnode.fields:
-                    subinstnode = instnode.origfields[ofs]
-                    # should really be there
-                    self.mutate_nodes(subinstnode, subspecnode)
-                    curfields[ofs] = subinstnode
-                instnode.curfields = curfields
-                if isinstance(specnode, VirtualInstanceSpecNode):
-                    instnode.virtual = True
-
     def expanded_version_of(self, boxlist):
         newboxlist = []
         assert len(boxlist) == len(self.specnodes)
         for i in range(len(boxlist)):
             box = boxlist[i]
             specnode = self.specnodes[i]
-            self.expanded_version_of_rec(specnode, self.nodes[box], newboxlist)
+            specnode.expand_boxlist(self.nodes[box], newboxlist)
         return newboxlist
 
-    def expanded_version_of_rec(self, specnode, instnode, newboxlist):
-        if not isinstance(specnode, VirtualInstanceSpecNode):
-            newboxlist.append(instnode.source)
-        if isinstance(specnode, SpecNodeWithFields):
-            for ofs, subspecnode in specnode.fields:
-                subinstnode = instnode.curfields[ofs]  # should really be there
-                self.expanded_version_of_rec(subspecnode, subinstnode,
-                                             newboxlist)
-
     def optimize_guard(self, op):
         liveboxes = []
         storage = AllocationStorage()
@@ -437,7 +330,7 @@
             assert len(self.operations[0].args) == len(self.specnodes)
             for i in range(len(self.specnodes)):
                 box = self.operations[0].args[i]
-                self.mutate_nodes(self.nodes[box], self.specnodes[i])
+                self.specnodes[i].mutate_nodes(self.nodes[box])
         else:
             assert self.operations[0].opname == 'catch'
             for box in self.operations[0].args:
@@ -544,12 +437,8 @@
         for i in range(len(self.specnodes)):
             old_specnode = old_mp.specnodes[i]
             new_specnode = self.specnodes[i]
-            if old_specnode is None:
-                if new_specnode is not None:
-                    return False
-            else:
-                if not old_specnode.equals(new_specnode):
-                    return False
+            if not old_specnode.equals(new_specnode):
+                return False
         return True
 
     def match(self, old_operations):
@@ -560,9 +449,8 @@
         for i in range(len(old_mp.specnodes)):
             old_specnode = old_mp.specnodes[i]
             new_instnode = self.nodes[jump_op.args[i]]
-            if old_specnode is not None:
-                if not old_specnode.matches(new_instnode):
-                    return False
+            if not old_specnode.matches(new_instnode):
+                return False
         return True
 
     def adapt_for_match(self, old_operations):
@@ -572,7 +460,7 @@
         for i in range(len(old_mp.specnodes)):
             old_specnode = old_mp.specnodes[i]
             new_instnode = self.nodes[jump_op.args[i]]
-            new_instnode.adapt_to(old_specnode)
+            old_specnode.adapt_to(new_instnode)
 
 def rebuild_boxes_from_guard_failure(guard_op, history, boxes_from_frame):
     allocated_boxes = []

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/pyjitpl.py	Fri Feb 13 13:57:47 2009
@@ -762,8 +762,7 @@
         expanded_args = []
         for i in range(len(mp.specnodes)):
             specnode = mp.specnodes[i]
-            optimize.extract_runtime_data(self.cpu, specnode,
-                                          args[i], expanded_args)
+            specnode.extract_runtime_data(self.cpu, args[i], expanded_args)
         return expanded_args
 
     def initialize_state_from_start(self, args):

Added: pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py	Fri Feb 13 13:57:47 2009
@@ -0,0 +1,140 @@
+
+from pypy.jit.metainterp.history import ConstInt
+
+class SpecNode(object):
+
+    def expand_boxlist(self, instnode, newboxlist):
+        newboxlist.append(instnode.source)
+
+    def extract_runtime_data(self, cpu, valuebox, resultlist):
+        resultlist.append(valuebox)
+
+    def adapt_to(self, instnode):
+        instnode.escaped = True
+
+class NotSpecNode(SpecNode):
+    def mutate_nodes(self, instnode):
+        pass
+
+    def equals(self, other):
+        if type(other) is NotSpecNode:
+            return True
+        return False
+
+    def matches(self, other):
+        # NotSpecNode matches everything
+        return True
+
+class FixedClassSpecNode(SpecNode):
+    def __init__(self, known_class):
+        self.known_class = known_class
+
+    def mutate_nodes(self, instnode):
+        from pypy.jit.metainterp.optimize import InstanceNode
+        
+        if instnode.cls is None:
+            instnode.cls = InstanceNode(self.known_class)
+        else:
+            assert instnode.cls.source.equals(self.known_class)
+
+    def equals(self, other):
+        if type(other) is not FixedClassSpecNode:
+            return False
+        else:
+            assert isinstance(other, FixedClassSpecNode) # make annotator happy
+            return self.known_class.equals(other.known_class)
+
+    def matches(self, instnode):
+        if instnode.cls is None:
+            return False
+        return instnode.cls.source.equals(self.known_class)
+
+class SpecNodeWithFields(FixedClassSpecNode):
+    def __init__(self, known_class, fields):
+        FixedClassSpecNode.__init__(self, known_class)
+        self.fields = fields
+
+    def mutate_nodes(self, instnode):
+        FixedClassSpecNode.mutate_nodes(self, instnode)
+        curfields = {}
+        for ofs, subspecnode in self.fields:
+            subinstnode = instnode.origfields[ofs]
+            # should really be there
+            subspecnode.mutate_nodes(subinstnode)
+            curfields[ofs] = subinstnode
+        instnode.curfields = curfields
+
+    def equals(self, other):
+        if not self.known_class.equals(other.known_class):
+            return False
+        elif len(self.fields) != len(other.fields):
+            return False
+        else:
+            for i in range(len(self.fields)):
+                key, value = self.fields[i]
+                otherkey, othervalue = other.fields[i]
+                if key != otherkey:
+                    return False
+                if not value.equals(othervalue):
+                    return False
+            return True
+
+    def matches(self, instnode):
+        # XXX think about details of virtual vs virtualizable
+        if not FixedClassSpecNode.matches(self, instnode):
+            return False
+        for key, value in self.fields:
+            if key not in instnode.curfields:
+                return False
+            if value is not None and not value.matches(instnode.curfields[key]):
+                return False
+        return True
+
+    def expand_boxlist(self, instnode, newboxlist):
+        for ofs, subspecnode in self.fields:
+            subinstnode = instnode.curfields[ofs]  # should really be there
+            subspecnode.expand_boxlist(subinstnode, newboxlist)
+
+    def extract_runtime_data(self, cpu, valuebox, resultlist):
+        for ofs, subspecnode in self.fields:
+            cls = self.known_class.getint()
+            tp = cpu.typefor(ofs)
+            fieldbox = cpu.execute_operation('getfield_gc',
+                                             [valuebox, ConstInt(ofs)],
+                                             tp)
+            subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)
+
+    def adapt_to(self, instnode):
+        for ofs, subspecnode in self.fields:
+            subspecnode.adapt_to(instnode.curfields[ofs])
+
+class VirtualizableSpecNode(SpecNodeWithFields):
+
+    def equals(self, other):
+        if not isinstance(other, VirtualizableSpecNode):
+            return False
+        return SpecNodeWithFields.equals(self, other)
+
+    def expand_boxlist(self, instnode, newboxlist):
+        newboxlist.append(instnode.source)        
+        SpecNodeWithFields.expand_boxlist(self, instnode, newboxlist)
+
+    def extract_runtime_data(self, cpu, valuebox, resultlist):
+        resultlist.append(valuebox)
+        SpecNodeWithFields.extract_runtime_data(self, cpu, valuebox, resultlist)
+
+    def adapt_to(self, instnode):
+        instnode.escaped = True
+        SpecNodeWithFields.adapt_to(self, instnode)
+
+class VirtualInstanceSpecNode(SpecNodeWithFields):
+
+    def mutate_nodes(self, instnode):
+        SpecNodeWithFields.mutate_nodes(self, instnode)
+        instnode.virtual = True
+
+    def equals(self, other):
+        if not isinstance(other, VirtualInstanceSpecNode):
+            return False
+        return SpecNodeWithFields.equals(self, other)
+

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_optimize.py	Fri Feb 13 13:57:47 2009
@@ -10,7 +10,8 @@
                                          Jump, GuardOp)
 from pypy.jit.metainterp.optimize import (PerfectSpecializer,
     CancelInefficientLoop, VirtualInstanceSpecNode, FixedClassSpecNode,
-    rebuild_boxes_from_guard_failure, type_cache, AllocationStorage)
+    rebuild_boxes_from_guard_failure, type_cache, AllocationStorage,
+    NotSpecNode)
 
 cpu = runner.CPU(None)
 
@@ -109,10 +110,11 @@
     spec.intersect_input_and_output()
     assert len(spec.specnodes) == 2
     spec_sum, spec_n = spec.specnodes
-    assert spec_sum is None      # for now
+    assert isinstance(spec_sum, NotSpecNode)
     assert isinstance(spec_n, VirtualInstanceSpecNode)
     assert spec_n.known_class.value == node_vtable_adr
-    assert spec_n.fields == [(A.ofs_value, None)]
+    assert spec_n.fields[0][0] == A.ofs_value
+    assert isinstance(spec_n.fields[0][1], NotSpecNode)
 
 def test_A_optimize_loop():
     operations = A.ops[:]
@@ -158,7 +160,7 @@
     spec.intersect_input_and_output()
     assert len(spec.specnodes) == 2
     spec_sum, spec_n = spec.specnodes
-    assert spec_sum is None      # for now
+    assert isinstance(spec_sum, NotSpecNode)
     assert type(spec_n) is FixedClassSpecNode
     assert spec_n.known_class.value == node_vtable_adr
 
@@ -213,7 +215,7 @@
     assert spec.nodes[C.n2].escaped
     assert len(spec.specnodes) == 2
     spec_sum, spec_n = spec.specnodes
-    assert spec_sum is None      # for now
+    assert isinstance(spec_sum, NotSpecNode)
     assert type(spec_n) is FixedClassSpecNode
     assert spec_n.known_class.value == node_vtable_adr
 

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vable_optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vable_optimize.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vable_optimize.py	Fri Feb 13 13:57:47 2009
@@ -7,7 +7,8 @@
                                          ConstInt, ConstAddr, BoxInt, BoxPtr)
 from pypy.jit.metainterp.optimize import (PerfectSpecializer,
                                           VirtualizableSpecNode,
-                                          VirtualInstanceSpecNode)
+                                          VirtualInstanceSpecNode,
+                                          NotSpecNode)
 from pypy.jit.metainterp.virtualizable import VirtualizableDesc
 from pypy.jit.metainterp.test.test_optimize import (cpu, NODE, node_vtable,
                                                     equaloplists)
@@ -153,7 +154,7 @@
     assert isinstance(spec.specnodes[0], VirtualizableSpecNode)
     assert len(spec.specnodes[0].fields) == 1
     assert spec.specnodes[0].fields[0][0] == B.ofs_node
-    assert spec.specnodes[0].fields[0][1] is None
+    assert isinstance(spec.specnodes[0].fields[0][1], NotSpecNode)
 
 # ____________________________________________________________
 
@@ -189,4 +190,4 @@
     assert isinstance(spec.specnodes[0], VirtualizableSpecNode)
     assert len(spec.specnodes[0].fields) == 1
     assert spec.specnodes[0].fields[0][0] == C.ofs_node
-    assert spec.specnodes[0].fields[0][1] is None
+    assert isinstance(spec.specnodes[0].fields[0][1], NotSpecNode)

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_warmspot.py	Fri Feb 13 13:57:47 2009
@@ -1,5 +1,5 @@
 from pypy.jit.metainterp.warmspot import ll_meta_interp
-from pypy.rlib.jit import hint, JitDriver
+from pypy.rlib.jit import JitDriver
 
 class Exit(Exception):
     def __init__(self, result):
@@ -20,11 +20,9 @@
             i = 0
             while True:
                 mydriver.jit_merge_point(i=i, a=a)
-                lst2 = hint(lst, deepfreeze=True)
-                if i >= len(lst2):
+                if i >= len(lst):
                     break
-                elem = lst2[i]
-                hint(elem, concrete=True)
+                elem = lst[i]
                 if elem == CODE_INCREASE:
                     a = a + 1
                     i += 1



More information about the Pypy-commit mailing list