[pypy-commit] pypy int-tag-untag-as-operations: introduce an no-overflow-check variant int_tag for when the bounds-optimizer

cfbolz noreply at buildbot.pypy.org
Mon Oct 24 11:21:36 CEST 2011


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: int-tag-untag-as-operations
Changeset: r48369:1a183750ebf7
Date: 2011-10-24 09:07 +0200
http://bitbucket.org/pypy/pypy/changeset/1a183750ebf7/

Log:	introduce an no-overflow-check variant int_tag for when the bounds-
	optimizer finds out that something cannot overflow.

diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -451,6 +451,9 @@
     def bhimpl_int_untag(a):
         return a >> 1
     @arguments("i", returns="i")
+    def bhimpl_int_tag(a):
+        return (a << 1) + 1
+    @arguments("i", returns="i")
     def bhimpl_int_tag_ovf(a):
         return ovfcheck(a << 1) + 1
 
diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py
--- a/pypy/jit/metainterp/optimizeopt/intbounds.py
+++ b/pypy/jit/metainterp/optimizeopt/intbounds.py
@@ -286,7 +286,6 @@
             self.emit_operation(op)
 
     def optimize_INT_TAG_OVF(self, op):
-        self.emit_operation(op) # XXX for now
         v1 = self.getvalue(op.getarg(0))
         r = self.getvalue(op.result)
         resbound = v1.intbound.mul(2).add(1)
@@ -297,9 +296,22 @@
             v1.intbound.intersect(maxbounds)
             self.pure(rop.INT_UNTAG, [op.result], op.getarg(0))
             no_guard = resbound.has_lower and resbound.has_upper
-        if not no_guard:
+        if no_guard:
+            op = op.copy_and_change(rop.INT_TAG)
+            self.optimize_INT_TAG(op) # emit the op
+        else:
+            self.emit_operation(op)
             self.emit_operation(self.nextop)
 
+    def optimize_INT_TAG(self, op):
+        v1 = self.getvalue(op.getarg(0))
+        r = self.getvalue(op.result)
+        resbound = v1.intbound.mul(2).add(1)
+        r.intbound.intersect(resbound)
+        maxbounds = IntBound((-sys.maxint-1) >> 1, sys.maxint >> 1)
+        v1.intbound.intersect(maxbounds)
+        self.pure(rop.INT_UNTAG, [op.result], op.getarg(0))
+
     def optimize_INT_UNTAG(self, op):
         v1 = self.getvalue(op.getarg(0))
         self.pure(rop.INT_TAG, [op.result], op.getarg(0))
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -5111,6 +5111,8 @@
     def test_int_tag_remove_overflow_checking(self):
         ops = """
         [i0]
+        i1 = int_lt(i0, 1000)
+        guard_true(i1), []
         i2 = int_tag_ovf(i0)
         guard_no_overflow() []
         i3 = int_untag(i2)
@@ -5120,13 +5122,15 @@
         """
         expected = """
         [i0]
-        i2 = int_tag_ovf(i0)
-        guard_no_overflow() []
+        i1 = int_lt(i0, 1000)
+        guard_true(i1), []
         i3 = int_add(i0, 1)
         jump(i3)
         """
         preamble = """
         [i0]
+        i1 = int_lt(i0, 1000)
+        guard_true(i1), []
         i2 = int_tag_ovf(i0)
         guard_no_overflow() []
         i3 = int_add(i0, 1)
diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -432,6 +432,7 @@
     'INT_NEG/1',
     'INT_INVERT/1',
     'INT_UNTAG/1',
+    'INT_TAG/1',
     #
     'SAME_AS/1',      # gets a Const or a Box, turns it into another Box
     'CAST_PTR_TO_INT/1',


More information about the pypy-commit mailing list