[pypy-commit] pypy jit-codewriter-force-cast-refactor: Small refactoring, gets back to where we already were, but broken on 32-bits. Pushing mostly so I can play with it more from tannit.

alex_gaynor noreply at buildbot.pypy.org
Sun Aug 28 00:33:52 CEST 2011


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: jit-codewriter-force-cast-refactor
Changeset: r46833:71b41578fb84
Date: 2011-08-27 18:33 -0400
http://bitbucket.org/pypy/pypy/changeset/71b41578fb84/

Log:	Small refactoring, gets back to where we already were, but broken on
	32-bits. Pushing mostly so I can play with it more from tannit.

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
@@ -1,4 +1,5 @@
 import py
+
 from pypy.jit.codewriter import support, heaptracker, longlong
 from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.codewriter.flatten import ListOfKind, IndirectCallTargets
@@ -22,6 +23,11 @@
     t = Transformer(cpu, callcontrol, portal_jd)
     t.transform(graph)
 
+def integer_bounds(size, unsigned):
+    if unsigned:
+        return 0, 1 << (8 * size)
+    else:
+        return -(1 << (8 * size - 1)), 1 << (8 * size - 1)
 
 class Transformer(object):
     vable_array_vars = None
@@ -780,81 +786,41 @@
             raise NotImplementedError("cast_ptr_to_int")
 
     def rewrite_op_force_cast(self, op):
-        assert not self._is_gc(op.args[0])
-        fromll = longlong.is_longlong(op.args[0].concretetype)
-        toll   = longlong.is_longlong(op.result.concretetype)
-        if fromll and toll:
+        v_arg = op.args[0]
+        v_result = op.result
+        assert not self._is_gc(v_arg)
+
+        if v_arg.concretetype == v_result.concretetype:
             return
-        if fromll:
-            args = op.args
-            opname = 'truncate_longlong_to_int'
-            RESULT = lltype.Signed
-            v = varoftype(RESULT)
-            op1 = SpaceOperation(opname, args, v)
-            op2 = self.rewrite_operation(op1)
-            oplist = self.force_cast_without_longlong(op2.result, op.result)
-            if oplist:
-                return [op2] + oplist
-            #
-            # force a renaming to put the correct result in place, even though
-            # it might be slightly mistyped (e.g. Signed versus Unsigned)
-            assert op2.result is v
-            op2.result = op.result
-            return op2
-        elif toll:
-            size, unsigned = rffi.size_and_sign(op.args[0].concretetype)
-            if unsigned:
-                INTERMEDIATE = lltype.Unsigned
-            else:
-                INTERMEDIATE = lltype.Signed
-            v = varoftype(INTERMEDIATE)
-            oplist = self.force_cast_without_longlong(op.args[0], v)
-            if not oplist:
-                v = op.args[0]
-                oplist = []
-            if unsigned:
-                opname = 'cast_uint_to_longlong'
-            else:
-                opname = 'cast_int_to_longlong'
-            op1 = SpaceOperation(opname, [v], op.result)
-            op2 = self.rewrite_operation(op1)
-            return oplist + [op2]
+
+        float_arg = v_arg.concretetype in [lltype.Float, lltype.SingleFloat]
+        float_res = v_result.concretetype in [lltype.Float, lltype.SingleFloat]
+        if not float_arg and not float_res:
+            # some int -> some int cast
+            return self._int_to_int_cast(v_arg, v_result)
+        elif float_arg and float_res:
+            # some float -> some float cast
+            return self._float_to_float_cast(v_arg, v_result)
         else:
-            return self.force_cast_without_longlong(op.args[0], op.result)
+            assert False
 
-    def force_cast_without_longlong(self, v_arg, v_result):
-        if v_result.concretetype == v_arg.concretetype:
+    def _int_to_int_cast(self, v_arg, v_result):
+        size1, unsigned1 = rffi.size_and_sign(v_arg.concretetype)
+        size2, unsigned2 = rffi.size_and_sign(v_result.concretetype)
+        assert size1 <= rffi.sizeof(lltype.Signed)
+        assert size2 <= rffi.sizeof(lltype.Signed)
+
+        # the target type is LONG or ULONG
+        if size2 == rffi.sizeof(lltype.Signed):
             return
-        if v_arg.concretetype == rffi.FLOAT:
-            assert v_result.concretetype == lltype.Float, "cast %s -> %s" % (
-                v_arg.concretetype, v_result.concretetype)
-            return SpaceOperation('cast_singlefloat_to_float', [v_arg],
-                                  v_result)
-        if v_result.concretetype == rffi.FLOAT:
-            assert v_arg.concretetype == lltype.Float, "cast %s -> %s" % (
-                v_arg.concretetype, v_result.concretetype)
-            return SpaceOperation('cast_float_to_singlefloat', [v_arg],
-                                  v_result)
-        return self.force_cast_without_singlefloat(v_arg, v_result)
 
-    def force_cast_without_singlefloat(self, v_arg, v_result):
-        size2, unsigned2 = rffi.size_and_sign(v_result.concretetype)
-        assert size2 <= rffi.sizeof(lltype.Signed)
-        if size2 == rffi.sizeof(lltype.Signed):
-            return     # the target type is LONG or ULONG
-        size1, unsigned1 = rffi.size_and_sign(v_arg.concretetype)
-        assert size1 <= rffi.sizeof(lltype.Signed)
-        #
-        def bounds(size, unsigned):
-            if unsigned:
-                return 0, 1<<(8*size)
-            else:
-                return -(1<<(8*size-1)), 1<<(8*size-1)
-        min1, max1 = bounds(size1, unsigned1)
-        min2, max2 = bounds(size2, unsigned2)
+        min1, max1 = integer_bounds(size1, unsigned1)
+        min2, max2 = integer_bounds(size2, unsigned2)
+
+        # the target type includes the source range
         if min2 <= min1 <= max1 <= max2:
-            return     # the target type includes the source range
-        #
+            return
+
         result = []
         if min2:
             c_min2 = Constant(min2, lltype.Signed)
@@ -862,15 +828,28 @@
             result.append(SpaceOperation('int_sub', [v_arg, c_min2], v2))
         else:
             v2 = v_arg
-        c_mask = Constant(int((1<<(8*size2))-1), lltype.Signed)
-        v3 = varoftype(lltype.Signed)
+        c_mask = Constant(int((1 << (8 * size2)) - 1), lltype.Signed)
+        if min2:
+            v3 = varoftype(lltype.Signed)
+        else:
+            v3 = v_result
         result.append(SpaceOperation('int_and', [v2, c_mask], v3))
         if min2:
             result.append(SpaceOperation('int_add', [v3, c_min2], v_result))
-        else:
-            result[-1].result = v_result
         return result
 
+    def _float_to_float_cast(self, v_arg, v_result):
+        if v_arg.concretetype == lltype.SingleFloat:
+            assert v_result.concretetype == lltype.Float, "cast %s -> %s" % (
+                v_arg.concretetype, v_result.concretetype)
+            return SpaceOperation('cast_singlefloat_to_float', [v_arg],
+                                  v_result)
+        if v_result.concretetype == lltype.SingleFloat:
+            assert v_arg.concretetype == lltype.Float, "cast %s -> %s" % (
+                v_arg.concretetype, v_result.concretetype)
+            return SpaceOperation('cast_float_to_singlefloat', [v_arg],
+                                  v_result)
+
     def rewrite_op_direct_ptradd(self, op):
         # xxx otherwise, not implemented:
         assert op.args[0].concretetype == rffi.CCHARP
diff --git a/pypy/jit/codewriter/test/test_flatten.py b/pypy/jit/codewriter/test/test_flatten.py
--- a/pypy/jit/codewriter/test/test_flatten.py
+++ b/pypy/jit/codewriter/test/test_flatten.py
@@ -324,7 +324,7 @@
     def test_exc_exitswitch(self):
         def g(i):
             pass
-        
+
         def f(i):
             try:
                 g(i)
@@ -862,6 +862,13 @@
             float_return %f0
         """, transform=True)
 
+        def g(n):
+            return rffi.cast(lltype.SingleFloat, n)
+        self.encoding_test(g, [12.456], """
+            cast_float_to_singlefloat %f0 -> %i0
+            int_return %i0
+        """, transform=True)
+
     def test_direct_ptradd(self):
         from pypy.rpython.lltypesystem import rffi
         def f(p, n):


More information about the pypy-commit mailing list