[pypy-svn] r65606 - pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp

antocuni at codespeak.net antocuni at codespeak.net
Sat Jun 6 00:38:52 CEST 2009


Author: antocuni
Date: Sat Jun  6 00:38:47 2009
New Revision: 65606

Modified:
   pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
Log:
another big refactoring: put part of InstanceNode responsibility into the new
InstanceValue class.

InstanceNode and InstanceValue are similar: the main difference is that the
former is used exclusively by the LoopSpecializer, while the latter is used
exclusively by the LoopOptimizer. 

This way, we make sure that their uses are not confounded by mistake, as I
think it happens in the old optimize.py (e.g. by using the cls attribute both
in the specialization phase and in the optimizing phase, but for slightly
different purposed)



Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py	Sat Jun  6 00:38:47 2009
@@ -15,7 +15,7 @@
 
     def __repr__(self):
         flags = ''
-        #if self.escaped:           flags += 'e'
+        if self.escaped:           flags += 'e'
         #if self.startbox:          flags += 's'
         if self.const:             flags += 'c'
         #if self.virtual:           flags += 'v'
@@ -23,6 +23,30 @@
         return "<InstanceNode %s (%s)>" % (self.source, flags)
 
 
+class InstanceValue(object):
+    """
+    optimize_operations does an abstract interpretation of the loop.
+
+    Each box is associated to an InstanceValue, that carries on extra
+    informations about the box, e.g. whether it is a constant or its class is
+    statically known.
+
+    The concrete optimizations can modify the value of the box attribute: in
+    that case, the optimized loop will contains a reference to the new box
+    instead of the old one.
+    """
+    
+    def __init__(self, box, const=False):
+        self.box = box
+        if const:
+            assert isinstance(box, Const)
+        self.const = const
+
+    def __repr__(self):
+        flags = ''
+        if self.const:             flags += 'c'
+        return "<InstanceValue %s (%s)>" % (self.box, flags)
+
 
 class LoopSpecializer(object):
 
@@ -91,23 +115,48 @@
 
 class LoopOptimizer(object):
 
-    fixedops = None
-
     def __init__(self, optlist):
-        self.spec = LoopSpecializer(optlist)
         self.optlist = optlist
+        self.spec = LoopSpecializer(optlist)
+        self.fixedops = None
+        self.values = None  # box --> InstanceValue
+        
 
     def _init(self, loop):
         self.spec._init(loop)
         self.fixedops = {}
+        self.values = {}
         self.loop = loop
 
+    def newval(self, *args, **kwds): # XXX RPython
+        val = InstanceValue(*args, **kwds)
+        for opt in self.optlist:
+            opt.init_value(val)
+        return val
+
+    def getval(self, box):
+        try:
+            return self.values[box]
+        except KeyError:
+            assert isinstance(box, Const)
+            val = self.newval(box, const=True)
+            self.values[box] = val
+            return val
+
+    def setval(self, box):
+        assert box not in self.values
+        assert not isinstance(box, Const)
+        self.values[box] = self.newval(box)
+
     def optimize_loop(self, loop):
         self._init(loop)
         self.spec.find_nodes()
         self.optimize_operations()
 
     def optimize_operations(self):
+        for box in self.loop.inputargs:
+            self.setval(box) #  startbox=True)
+
         newoperations = []
         for op in self.loop.operations:
             newop = op
@@ -117,6 +166,7 @@
                     break
             newop = self.fixop(newop)
             if newop is not None:
+                self.setval(newop.result)
                 newoperations.append(newop)
         print "Length of the loop:", len(newoperations)
         self.loop.operations = newoperations
@@ -125,12 +175,16 @@
         newboxes = []
         for box in op.args:
             if isinstance(box, Box):
-                instnode = self.spec.nodes[box]
-                box = instnode.source
+                val = self.values[box]
+                box = val.box
             newboxes.append(box)
         return newboxes
 
     def fixop(self, op):
+        """
+        Fix the arguments of the op by using the box stored on the
+        InstanceValue of each argument.
+        """
         if op is None:
             return None
         if op in self.fixedops:
@@ -153,15 +207,15 @@
                 # all constant arguments: constant-fold away
                 box = op.result
                 assert box is not None
-                instnode = self.spec.newnode(box.constbox(), const=True)
-                self.spec.nodes[box] = instnode
+                val = self.newval(box.constbox(), const=True)
+                self.values[box] = val
                 return
         return op
 
     def _fixguard(self, op):
         if op.is_foldable_guard():
             for arg in op.args:
-                if not self.spec.nodes[arg].const:
+                if not self.getval(arg).const:
                     break
             else:
                 return None
@@ -206,6 +260,9 @@
             return getattr(self, methname).im_func
         return None
 
+    # hooks for LoopSpecializer
+    # -------------------------
+    
     def init_node(self, node):
         pass
 
@@ -214,6 +271,13 @@
         if func:
             func(self, spec, op)
 
+
+    # hooks for LoopOptimizer
+    # -------------------------
+
+    def init_value(self, value):
+        pass
+
     def handle_op(self, spec, op):
         func = self.operations[op.opnum]
         return func(self, spec, op)
@@ -225,24 +289,25 @@
 
 class OptimizeGuards(AbstractOptimization):
 
+    def init_value(self, val):
+        val.cls = None
+
     def guard_class(self, opt, op):
-        spec = opt.spec
-        node = spec.nodes[op.args[0]]
-        if node.cls is not None:
+        val = opt.values[op.args[0]]
+        if val.cls is not None:
             # assert that they're equal maybe
             return
-        node.cls = spec.newnode(op.args[1], const=True)
+        val.cls = opt.newval(op.args[1], const=True)
         return op
 
     def guard_value(self, opt, op):
-        spec = opt.spec
-        instnode = spec.nodes[op.args[0]]
+        val = opt.values[op.args[0]]
         assert isinstance(op.args[1], Const)
-        if instnode.const:
+        if val.const:
             return
         op = opt.fixop(op)
-        instnode.const = True
-        instnode.source = op.args[0].constbox()
+        val.const = True
+        val.box = op.args[0].constbox()
         return op
 
 



More information about the Pypy-commit mailing list