Author: Carl Friedrich Bolz <[email protected]>
Branch: int-tag-untag-as-operations
Changeset: r48364:300e42e0ee80
Date: 2011-10-22 14:13 +0200
http://bitbucket.org/pypy/pypy/changeset/300e42e0ee80/

Log:    introduce int_tag (which can overflow) and int_untag

diff --git a/pypy/jit/backend/llgraph/llimpl.py 
b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -692,6 +692,17 @@
         if not flag:
             raise GuardFailed
 
+    def op_int_tag(self, _, x):
+        try:
+            z = ovfcheck(x << 1) + 1
+        except OverflowError:
+            ovf = True
+            z = 0
+        else:
+            ovf = False
+        self.overflow_flag = ovf
+        return z
+
     def op_int_add_ovf(self, _, x, y):
         try:
             z = ovfcheck(x + y)
diff --git a/pypy/jit/codewriter/jtransform.py 
b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -269,6 +269,10 @@
         op1 = SpaceOperation('-live-', [], None)
         return [op, op1]
 
+    def rewrite_op_int_tag(self, op):
+        op1 = SpaceOperation('-live-', [], None)
+        return [op, op1]
+
     # ----------
     # Various kinds of calls
 
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -38,9 +38,10 @@
     return a.typeannotation(t)
 
 def annotate(func, values, inline=None, backendoptimize=True,
-             type_system="lltype"):
+             type_system="lltype", taggedpointers=False):
     # build the normal ll graphs for ll_function
     t = TranslationContext()
+    t.config.translation.taggedpointers = taggedpointers
     annpolicy = AnnotatorPolicy()
     annpolicy.allow_someobjects = False
     a = t.buildannotator(policy=annpolicy)
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
@@ -447,6 +447,14 @@
     def bhimpl_int_invert(a):
         return intmask(~a)
 
+    @arguments("i", returns="i")
+    def bhimpl_int_untag(a):
+        return a >> 1
+    @arguments("i", returns="i")
+    def bhimpl_int_tag(a):
+        return ovfcheck(a << 1) + 1
+
+
     @arguments("i", "i", returns="i")
     def bhimpl_int_lt(a, b):
         return a < b
diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py
--- a/pypy/jit/metainterp/executor.py
+++ b/pypy/jit/metainterp/executor.py
@@ -204,6 +204,18 @@
         z = 0
     return BoxInt(z)
 
+def do_int_tag(cpu, metainterp, box1):
+    # the overflow operations can be called without a metainterp, if an
+    # overflow cannot occur
+    a = box1.getint()
+    try:
+        z = ovfcheck(a << 1)
+    except OverflowError:
+        assert metainterp is not None
+        metainterp.execute_raised(OverflowError(), constant=True)
+        z = 0
+    return BoxInt(z + 1)
+
 def do_same_as(cpu, _, box):
     return box.clonebox()
 
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
@@ -284,6 +284,10 @@
         else:
             self.emit_operation(op)
 
+    def optimize_INT_TAG(self, op):
+        self.emit_operation(op) # XXX for now
+        self.emit_operation(self.nextop)
+
     def optimize_ARRAYLEN_GC(self, op):
         self.emit_operation(op)
         array  = self.getvalue(op.getarg(0))
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -218,7 +218,7 @@
                 return resbox
         ''' % (_opimpl, _opimpl.upper())).compile()
 
-    for _opimpl in ['int_is_true', 'int_is_zero', 'int_neg', 'int_invert',
+    for _opimpl in ['int_is_true', 'int_is_zero', 'int_neg', 'int_invert', 
'int_untag',
                     'cast_float_to_int', 'cast_int_to_float',
                     'cast_float_to_singlefloat', 'cast_singlefloat_to_float',
                     'float_neg', 'float_abs',
@@ -231,6 +231,15 @@
         ''' % (_opimpl, _opimpl.upper())).compile()
 
     @arguments("box")
+    def opimpl_int_tag(self, b1):
+        self.metainterp.clear_exception()
+        resbox = self.execute(rop.INT_TAG, b1)
+        self.make_result_of_lastop(resbox)
+        if not isinstance(resbox, Const):
+            self.metainterp.handle_possible_overflow_error()
+        return resbox
+
+    @arguments("box")
     def opimpl_ptr_nonzero(self, box):
         return self.execute(rop.PTR_NE, box, history.CONST_NULL)
 
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
@@ -431,6 +431,7 @@
     'INT_IS_TRUE/1b',
     'INT_NEG/1',
     'INT_INVERT/1',
+    'INT_UNTAG/1',
     #
     'SAME_AS/1',      # gets a Const or a Box, turns it into another Box
     'CAST_PTR_TO_INT/1',
@@ -504,6 +505,7 @@
     'INT_ADD_OVF/2',
     'INT_SUB_OVF/2',
     'INT_MUL_OVF/2',
+    'INT_TAG/1',
     '_OVF_LAST', # ----- end of is_ovf operations -----
     '_LAST',     # for the backend to add more internal operations
 ]
diff --git a/pypy/jit/metainterp/test/support.py 
b/pypy/jit/metainterp/test/support.py
--- a/pypy/jit/metainterp/test/support.py
+++ b/pypy/jit/metainterp/test/support.py
@@ -42,7 +42,7 @@
         enable_opts = ALL_OPTS_DICT
 
     func._jit_unroll_safe_ = True
-    rtyper = support.annotate(func, values, type_system=type_system)
+    rtyper = support.annotate(func, values, type_system=type_system, **kwds)
     graphs = rtyper.annotator.translator.graphs
     testself.all_graphs = graphs
     result_kind = history.getkind(graphs[0].getreturnvar().concretetype)[0]
diff --git a/pypy/rlib/rerased.py b/pypy/rlib/rerased.py
--- a/pypy/rlib/rerased.py
+++ b/pypy/rlib/rerased.py
@@ -160,7 +160,7 @@
     from pypy.rlib.debug import ll_assert
     x = llop.cast_ptr_to_int(lltype.Signed, gcref)
     ll_assert((x&1) != 0, "unerased_int(): not an integer")
-    return x >> 1
+    return llop.int_untag(lltype.Signed, x)
 
 
 class Entry(ExtRegistryEntry):
@@ -220,11 +220,9 @@
         [v_value] = hop.inputargs(lltype.Signed)
         c_one = hop.inputconst(lltype.Signed, 1)
         hop.exception_is_here()
-        v2 = hop.genop('int_add_ovf', [v_value, v_value],
+        v2 = hop.genop('int_tag', [v_value],
                        resulttype = lltype.Signed)
-        v2p1 = hop.genop('int_add', [v2, c_one],
-                         resulttype = lltype.Signed)
-        v_instance = hop.genop('cast_int_to_ptr', [v2p1],
+        v_instance = hop.genop('cast_int_to_ptr', [v2],
                                resulttype=self.lowleveltype)
         return v_instance
 
diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -1095,6 +1095,16 @@
             assert y >= 0
         return self.op_int_add_ovf(x, y)
 
+    def op_int_tag(self, x):
+        try:
+            return ovfcheck(x + x + 1)
+        except OverflowError:
+            self.make_llexception()
+
+    def op_int_untag(self, x):
+        assert x & 1, "argument has to be tagged!"
+        return x >> 1
+
     def op_cast_float_to_int(self, f):
         assert type(f) is float
         try:
diff --git a/pypy/rpython/lltypesystem/lloperation.py 
b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -207,6 +207,8 @@
     'int_abs':              LLOp(canfold=True),
     'int_abs_ovf':          LLOp(canraise=(OverflowError,), tryfold=True),
     'int_invert':           LLOp(canfold=True),
+    'int_tag':              LLOp(canraise=(OverflowError, ), tryfold=True),
+    'int_untag':            LLOp(canfold=True),
 
     'int_add':              LLOp(canfold=True),
     'int_sub':              LLOp(canfold=True),
diff --git a/pypy/translator/c/src/int.h b/pypy/translator/c/src/int.h
--- a/pypy/translator/c/src/int.h
+++ b/pypy/translator/c/src/int.h
@@ -19,6 +19,14 @@
        if ((x) == LONG_MIN) FAIL_OVF("integer absolute"); \
        OP_INT_ABS(x,r)
 
+#define OP_INT_TAG(x, r) \
+    r = (long)((unsigned long)x << 1); \
+    if ((r ^ x) < 0) FAIL_OVF("integer tagging"); \
+    r = r + 1
+
+#define OP_INT_UNTAG(x, r) \
+    r = x >> 1
+
 /***  binary operations ***/
 
 #define OP_INT_EQ(x,y,r)         r = ((x) == (y))
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to