[pypy-svn] pypy jit-virtual_state: Better handling of forced virtuals

hakanardo commits-noreply at bitbucket.org
Sat Feb 12 11:57:39 CET 2011


Author: Hakan Ardo <hakan at debian.org>
Branch: jit-virtual_state
Changeset: r41835:d475e67d90a5
Date: 2011-02-12 10:48 +0100
http://bitbucket.org/pypy/pypy/changeset/d475e67d90a5/

Log:	Better handling of forced virtuals

diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -165,12 +165,13 @@
             info = self.info[box]
         except KeyError:
             value = self.getvalue(box)
-            self.info[box] = info = value.make_virtual_info(self, None)
-            if box in self.fieldboxes:
-                info.fieldstate = [self.state(b) for b in self.fieldboxes[box]]
-                # FIXME: Do we realy want to add fields to the VirtualInfo's?
-            elif isinstance(value, AbstractVirtualValue):
-                info.fieldstate = []
+            if value.is_virtual():
+                info = value.make_virtual_info(self, None)
+                flds = self.fieldboxes[box]
+                info.fieldstate = [self.state(b) for b in flds]
+            else:
+                info = self.make_not_virtual(value)
+            self.info[box] = info 
         return info
 
     def get_virtual_state(self, jump_args):
@@ -187,7 +188,10 @@
     def __init__(self, value):
         self.known_class = value.known_class
         self.level = value.level
-        self.intbound = value.intbound.clone()
+        if value.intbound is None:
+            self.intbound = IntBound(MININT, MAXINT)
+        else:
+            self.intbound = value.intbound.clone()
         if value.is_constant():
             self.constbox = value.box
         else:
@@ -661,11 +665,14 @@
                         try:
                             self.inline(sh.operations, sh.inputargs,
                                         op.getarglist())
+                            jumpop = self.optimizer.newoperations.pop()
+                            assert jumpop.getopnum() == rop.JUMP
                             for guard in extra_guards:
                                 descr = sh.start_resumedescr.clone_if_mutable()
                                 self.inliner.inline_descr_inplace(descr)
                                 guard.setdescr(descr)
                                 self.emit_operation(guard)
+                            self.optimizer.newoperations.append(jumpop)
                         except InvalidLoop:
                             debug_print("Inlining failed unexpectedly",
                                         "jumping to preamble instead")

diff --git a/pypy/jit/metainterp/test/test_virtual.py b/pypy/jit/metainterp/test/test_virtual.py
--- a/pypy/jit/metainterp/test/test_virtual.py
+++ b/pypy/jit/metainterp/test/test_virtual.py
@@ -564,6 +564,77 @@
         assert self.meta_interp(f, [40, 3]) == f(40, 3)
         self.check_loop_count(6)
 
+    def test_single_virtual_forced_in_bridge(self):
+        myjitdriver = JitDriver(greens = [], reds = ['n', 's', 'node'])
+        def externfn(node):
+            node.value *= 2
+        def f(n, s):
+            node = self._new()
+            node.value = 1
+            while n > 0:
+                myjitdriver.can_enter_jit(n=n, s=s, node=node)
+                myjitdriver.jit_merge_point(n=n, s=s, node=node)
+                next = self._new()
+                next.value = node.value + 1
+                node = next
+                if (n>>s) & 1:
+                    externfn(node)
+                n -= 1
+            return node.value
+        res = self.meta_interp(f, [48, 3], policy=StopAtXPolicy(externfn))
+        assert res == f(48, 3)
+        res = self.meta_interp(f, [40, 3], policy=StopAtXPolicy(externfn))
+        assert res == f(40, 3)
+
+    def test_forced_virtual_assigned_in_bridge(self):
+        myjitdriver = JitDriver(greens = [], reds = ['n', 's', 'node', 'node2'])
+        def externfn(node):
+            node.value += 1
+        def f(n, s):
+            node = self._new()
+            node.value = 1
+            node2 = self._new()
+            node2.value = 2
+            while n > 0:
+                myjitdriver.can_enter_jit(n=n, s=s, node=node, node2=node2)
+                myjitdriver.jit_merge_point(n=n, s=s, node=node, node2=node2)
+                next = self._new()
+                next.value = node.value + 1
+                node = next
+                if (n>>s) & 1:
+                    node2.value += node.value
+                    node = node2
+                externfn(node)
+                n -= 1
+            return node.value
+        res = self.meta_interp(f, [48, 3], policy=StopAtXPolicy(externfn))
+        assert res == f(48, 3)
+        self.check_loop_count(3)
+        res = self.meta_interp(f, [40, 3], policy=StopAtXPolicy(externfn))
+        assert res == f(40, 3)
+        self.check_loop_count(3)
+
+    def test_empty_virtual_with_bridge(self):
+        myjitdriver = JitDriver(greens = [], reds = ['n', 's', 'sa', 'node'])
+        def f(n, s):
+            node = self._new()
+            sa = 0
+            while n > 0:
+                myjitdriver.can_enter_jit(n=n, s=s, sa=sa, node=node)
+                myjitdriver.jit_merge_point(n=n, s=s, sa=sa, node=node)
+                next = self._new()
+                node = next
+                if (n>>s) & 1:
+                    sa += 1
+                else:
+                    sa += 2
+                n -= 1
+            return sa
+        res = self.meta_interp(f, [48, 3])
+        assert res == f(48, 3)
+        res = self.meta_interp(f, [40, 3])
+        assert res == f(40, 3)
+
     def test_virtual_array_bridge(self):
         myjitdriver = JitDriver(greens = [], reds = ['n', 'node'])
         def f(n):


More information about the Pypy-commit mailing list