Author: Hakan Ardo <[email protected]>
Branch: jit-usable_retrace_2
Changeset: r51030:75ff444ada2d
Date: 2012-01-04 19:25 +0100
http://bitbucket.org/pypy/pypy/changeset/75ff444ada2d/

Log:    Make kill_consts separate from force_at_end_of_preamble to be able
        to call it earlier and thereby allow the jumpargs to be updated
        which is needed for non-virtal constants among the original jumpargs

diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py 
b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -124,15 +124,18 @@
     def get_key_box(self):
         return self.box
 
-    def force_at_end_of_preamble(self, already_forced, optforce):
-        if optforce.optimizer.kill_consts_at_end_of_preamble and 
self.is_constant():
+    def kill_consts(self, already_killed, opt):
+        if self.is_constant():
             constbox = self.box
             box = constbox.clonebox()
             op = ResOperation(rop.SAME_AS, [constbox], box)
-            optforce.optimizer._newoperations.append(op)
+            opt.optimizer._newoperations.append(op)
             return OptValue(box)
         return self
 
+    def force_at_end_of_preamble(self, already_forced, optforce):        
+        return self
+
     def get_args_for_fail(self, modifier):
         pass
 
@@ -358,7 +361,6 @@
         self.optimizer = self
         self.optpure = None
         self.optearlyforce = None
-        self.kill_consts_at_end_of_preamble = False
         if loop is not None:
             self.call_pure_results = loop.call_pure_results
 
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
@@ -152,7 +152,12 @@
             # At the end of a bridge about to force a retrcae
             debug_print('Generalize for retrace')
             KillIntBounds(self.optimizer).apply()
-            self.optimizer.kill_consts_at_end_of_preamble = True
+
+            jump_args = stop_label.getarglist()
+            already_killed = {}
+            values = [self.getvalue(box).kill_consts(already_killed, 
self.optimizer)
+                      for box in jump_args]
+            stop_label.initarglist([v.get_key_box() for v in values])
 
     def jump_to_start_label(self, start_label, stop_label):
         if not start_label or not stop_label:
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py 
b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -40,6 +40,9 @@
             return value
         return OptValue(self.force_box(optforce))
 
+    def kill_consts(self, already_killed, opt):
+        return self
+
     def make_virtual_info(self, modifier, fieldnums):
         if fieldnums is None:
             return self._make_virtual(modifier)
@@ -128,6 +131,15 @@
                 self._fields[ofs] = 
self._fields[ofs].force_at_end_of_preamble(already_forced, optforce)
         return self
 
+    def kill_consts(self, already_killed, opt):
+        if self in already_killed:
+            return self
+        already_killed[self] = self
+        if self._fields:
+            for ofs in self._fields.keys():
+                self._fields[ofs] = 
self._fields[ofs].kill_consts(already_killed, opt)
+        return self
+        
     def _really_force(self, optforce):
         op = self.source_op
         assert op is not None
@@ -262,6 +274,14 @@
             self._items[index] = 
self._items[index].force_at_end_of_preamble(already_forced, optforce)
         return self
 
+    def kill_consts(self, already_killed, opt):
+        if self in already_killed:
+            return self
+        already_killed[self] = self
+        for index in range(len(self._items)):
+            self._items[index] = 
self._items[index].kill_consts(already_killed, opt)
+        return self
+
     def _really_force(self, optforce):
         assert self.source_op is not None
         if not we_are_translated():
@@ -357,6 +377,15 @@
                 self._items[index][descr] = 
self._items[index][descr].force_at_end_of_preamble(already_forced, optforce)
         return self
 
+    def kill_consts(self, already_killed, opt):
+        if self in already_killed:
+            return self
+        already_killed[self] = self
+        for index in range(len(self._items)):
+            for descr in self._items[index].keys():
+                self._items[index][descr] = 
self._items[index][descr].kill_consts(already_killed, opt)
+        return self
+
     def _make_virtual(self, modifier):
         return modifier.make_varraystruct(self.arraydescr, 
self._get_list_of_descrs())
 
diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py 
b/pypy/jit/metainterp/optimizeopt/virtualstate.py
--- a/pypy/jit/metainterp/optimizeopt/virtualstate.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py
@@ -520,8 +520,7 @@
     def getvalue(self, box):
         return self.optimizer.getvalue(box)
 
-    def state(self, box):
-        value = self.getvalue(box)
+    def state(self, value):
         box = value.get_key_box()
         try:
             info = self.info[box]
@@ -529,7 +528,7 @@
             if value.is_virtual():
                 self.info[box] = info = value.make_virtual_info(self, None)
                 flds = self.fieldboxes[box]
-                info.fieldstate = [self.state(b) for b in flds]
+                info.fieldstate = [self.state(self.getvalue(b)) for b in flds]
             else:
                 self.info[box] = info = self.make_not_virtual(value)
         return info
@@ -550,7 +549,7 @@
                 value.get_args_for_fail(self)
             else:
                 self.make_not_virtual(value)
-        return VirtualState([self.state(box) for box in jump_args])
+        return VirtualState([self.state(value) for value in values])
 
     def make_not_virtual(self, value):
         return NotVirtualStateInfo(value)
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
@@ -949,6 +949,151 @@
         self.check_aborted_count(0)
         self.check_target_token_count(3)
 
+    def test_nested_loops_const(self):
+        class Int(object):
+            def __init__(self, val):
+                self.val = val
+        bytecode = "iajb+JI"
+        def get_printable_location(i):
+            return "%d: %s" % (i, bytecode[i])
+        myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'c', 'sa', 'i', 
'j'],
+                                get_printable_location=get_printable_location)
+        def f(n):
+            pc = sa = c = 0
+            i = j = Int(0)
+            while pc < len(bytecode):
+                myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j, c=c)
+                op = bytecode[pc]
+                if op == 'i':
+                    i = Int(0)
+                elif op == 'j':
+                    j = Int(0)
+                elif op == '+':
+                    sa += (i.val + 2) * (j.val + 2) + c
+                elif op == 'a':
+                    i = Int(i.val + 1)
+                    c = 42
+                elif op == 'b':
+                    j = Int(j.val + 1)
+                    c = 7
+                elif op == 'J':
+                    if j.val < n:
+                        pc -= 2
+                        myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, 
c=c)
+                        continue
+                elif op == 'I':
+                    if i.val < n:
+                        pc -= 5
+                        myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, 
c=c)
+                        continue
+                pc += 1
+            return sa
+
+        res = self.meta_interp(f, [10])
+        assert res == f(10)
+        self.check_aborted_count(0)
+        self.check_target_token_count(3)
+        self.check_trace_count(3)
+        self.check_resops(int_mul=3)
+
+    def test_nested_loops_const_array(self):
+        class Int(object):
+            def __init__(self, val):
+                self.val = val
+        bytecode = "iajb+JI"
+        def get_printable_location(i):
+            return "%d: %s" % (i, bytecode[i])
+        myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'sa', 'i', 'j', 
'c'],
+                                get_printable_location=get_printable_location)
+        def f(n):
+            pc = sa = 0
+            c = [0]
+            i = j = Int(0)
+            while pc < len(bytecode):
+                myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j, c=c)
+                op = bytecode[pc]
+                if op == 'i':
+                    i = Int(0)
+                elif op == 'j':
+                    j = Int(0)
+                elif op == '+':
+                    sa += (i.val + 2) * (j.val + 2) + c[0]
+                elif op == 'a':
+                    i = Int(i.val + 1)
+                    c = [42, 2]
+                elif op == 'b':
+                    j = Int(j.val + 1)
+                    c = [7, 3]
+                elif op == 'J':
+                    if j.val < n:
+                        pc -= 2
+                        myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, 
c=c)
+                        continue
+                elif op == 'I':
+                    if i.val < n:
+                        pc -= 5
+                        myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, 
c=c)
+                        continue
+                pc += 1
+            return sa
+
+        res = self.meta_interp(f, [10])
+        assert res == f(10)
+        self.check_aborted_count(0)
+        self.check_target_token_count(3)
+        self.check_trace_count(3)
+        self.check_resops(int_mul=3)
+
+    def test_nested_loops_const_dict(self):
+        class Int(object):
+            def __init__(self, val):
+                self.val = val
+        bytecode = "iajb+JI"
+        def get_printable_location(i):
+            return "%d: %s" % (i, bytecode[i])
+        myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'sa', 'i', 'j', 
'c'],
+                                get_printable_location=get_printable_location)
+        def f(n):
+            pc = sa = 0
+            c = {}
+            i = j = Int(0)
+            while pc < len(bytecode):
+                myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j, c=c)
+                op = bytecode[pc]
+                if op == 'i':
+                    i = Int(0)
+                elif op == 'j':
+                    j = Int(0)
+                elif op == '+':
+                    sa += (i.val + 2) * (j.val + 2) + c[0]
+                elif op == 'a':
+                    i = Int(i.val + 1)
+                    c = {}
+                    c[0] = 42
+                elif op == 'b':
+                    j = Int(j.val + 1)
+                    c = {}
+                    c[0] = 7
+                elif op == 'J':
+                    if j.val < n:
+                        pc -= 2
+                        myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, 
c=c)
+                        continue
+                elif op == 'I':
+                    if i.val < n:
+                        pc -= 5
+                        myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, 
c=c)
+                        continue
+                pc += 1
+            return sa
+
+        res = self.meta_interp(f, [10])
+        assert res == f(10)
+        self.check_aborted_count(0)
+        self.check_target_token_count(3)
+        self.check_trace_count(3)
+        self.check_resops(int_mul=3)
+
 class VirtualMiscTests:
 
     def test_multiple_equal_virtuals(self):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to