[pypy-svn] r52784 - in pypy/branch/jit-hotpath/pypy/rpython: . lltypesystem lltypesystem/test

arigo at codespeak.net arigo at codespeak.net
Thu Mar 20 18:34:26 CET 2008


Author: arigo
Date: Thu Mar 20 18:34:24 2008
New Revision: 52784

Modified:
   pypy/branch/jit-hotpath/pypy/rpython/llinterp.py
   pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/lloperation.py
   pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/opimpl.py
   pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/test/test_lloperation.py
Log:
(cfbolz, arigo)

Make all the 'tryfold' operations directly runnable too,
for example all ovf-checking arithmetic.
(done by moving their implementation from llinterp.py to opimpl.py)


Modified: pypy/branch/jit-hotpath/pypy/rpython/llinterp.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rpython/llinterp.py	(original)
+++ pypy/branch/jit-hotpath/pypy/rpython/llinterp.py	Thu Mar 20 18:34:24 2008
@@ -1,6 +1,4 @@
 from pypy.objspace.flow.model import FunctionGraph, Constant, Variable, c_last_exception
-from pypy.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong
-from pypy.rlib.rarithmetic import r_ulonglong, ovfcheck_lshift
 from pypy.rpython.lltypesystem import lltype, llmemory, lloperation, llheap
 from pypy.rpython.lltypesystem import rclass
 from pypy.rpython.ootypesystem import ootype
@@ -243,8 +241,19 @@
         ophandler = getattr(self, 'op_' + opname, None)
         if ophandler is None:
             # try to import the operation from opimpl.py
-            ophandler = lloperation.LL_OPERATIONS[opname].fold
-            setattr(self.__class__, 'op_' + opname, staticmethod(ophandler))
+            llop = lloperation.LL_OPERATIONS[opname]
+            if llop.canraise:
+                assert not getattr(llop.fold, 'need_result_type', False)
+                # ^^^ for now
+                def ophandler(self, *args):
+                    try:
+                        return llop.fold(*args)
+                    except llop.canraise:
+                        self.make_llexception()
+            else:
+                ophandler = staticmethod(llop.fold)
+            setattr(self.__class__, 'op_' + opname, ophandler)
+            ophandler = getattr(self, 'op_' + opname)
         return ophandler
     # _______________________________________________________
     # evaling functions
@@ -513,9 +522,6 @@
         import pdb
         pdb.set_trace()
 
-    def op_debug_assert(self, x, msg):
-        assert x, msg
-
     def op_debug_fatalerror(self, ll_msg, ll_exc=None):
         msg = ''.join(ll_msg.chars)
         if ll_exc is None:
@@ -901,129 +907,9 @@
     def op_call_boehm_gc_alloc(self):
         raise NotImplementedError("call_boehm_gc_alloc")
 
-    # ____________________________________________________________
-    # Overflow-detecting variants
-
-    def op_int_neg_ovf(self, x):
-        assert type(x) is int
-        try:
-            return ovfcheck(-x)
-        except OverflowError:
-            self.make_llexception()
-
-    def op_int_abs_ovf(self, x):
-        assert type(x) is int
-        try:
-            return ovfcheck(abs(x))
-        except OverflowError:
-            self.make_llexception()
-
-    def op_llong_neg_ovf(self, x):
-        assert type(x) is r_longlong
-        try:
-            return ovfcheck(-x)
-        except OverflowError:
-            self.make_llexception()
-
-    def op_llong_abs_ovf(self, x):
-        assert type(x) is r_longlong
-        try:
-            return ovfcheck(abs(x))
-        except OverflowError:
-            self.make_llexception()
-
-    def op_int_lshift_ovf(self, x, y):
-        assert isinstance(x, int)
-        assert isinstance(y, int)
-        try:
-            return ovfcheck_lshift(x, y)
-        except OverflowError:
-            self.make_llexception()
-
-    def op_int_lshift_ovf_val(self, x, y):
-        assert isinstance(x, int)
-        assert isinstance(y, int)
-        try:
-            return ovfcheck_lshift(x, y)
-        except (OverflowError, ValueError):
-            self.make_llexception()
-
-    def _makefunc2(fn, operator, xtype, ytype=None):
-        import sys
-        d = sys._getframe(1).f_locals
-        if ytype is None:
-            ytype = xtype
-        if '_ovf' in fn:
-            checkfn = 'ovfcheck'
-        elif fn.startswith('op_int_'):
-            checkfn = 'intmask'
-        else:
-            checkfn = ''
-        if operator == '//':
-            code = '''r = %(checkfn)s(x // y)
-                if x^y < 0 and x%%y != 0:
-                    r += 1
-                return r
-                '''%locals()
-        elif operator == '%':
-            code = '''r = %(checkfn)s(x %% y)
-                if x^y < 0 and x%%y != 0:
-                    r -= y
-                return r
-                '''%locals()
-        else:
-            code = 'return %(checkfn)s(x %(operator)s y)'%locals()
-        exec py.code.Source("""
-        def %(fn)s(self, x, y):
-            assert isinstance(x, %(xtype)s)
-            assert isinstance(y, %(ytype)s)
-            try:
-                %(code)s
-            except (OverflowError, ValueError, ZeroDivisionError):
-                self.make_llexception()
-        """ % locals()).compile() in globals(), d
-
-    _makefunc2('op_int_add_ovf', '+', '(int, llmemory.AddressOffset)')
-    _makefunc2('op_int_mul_ovf', '*', '(int, llmemory.AddressOffset)', 'int')
-    _makefunc2('op_int_sub_ovf',          '-',  'int')
-    _makefunc2('op_int_floordiv_ovf',     '//', 'int')
-    _makefunc2('op_int_floordiv_zer',     '//', 'int')
-    _makefunc2('op_int_floordiv_ovf_zer', '//', 'int')
-    _makefunc2('op_int_mod_ovf',          '%',  'int')
-    _makefunc2('op_int_mod_zer',          '%',  'int')
-    _makefunc2('op_int_mod_ovf_zer',      '%',  'int')
-    _makefunc2('op_int_lshift_val',       '<<', 'int')
-    _makefunc2('op_int_rshift_val',       '>>', 'int')
-
-    _makefunc2('op_uint_floordiv_zer',    '//', 'r_uint')
-    _makefunc2('op_uint_mod_zer',         '%',  'r_uint')
-    _makefunc2('op_uint_lshift_val',      '<<', 'r_uint')
-    _makefunc2('op_uint_rshift_val',      '>>', 'r_uint')
-
-    _makefunc2('op_llong_floordiv_zer',   '//', 'r_longlong')
-    _makefunc2('op_llong_mod_zer',        '%',  'r_longlong')
-    _makefunc2('op_llong_lshift_val',     '<<', 'r_longlong')
-    _makefunc2('op_llong_rshift_val',     '>>', 'r_longlong')
-
-    _makefunc2('op_ullong_floordiv_zer',  '//', 'r_ulonglong')
-    _makefunc2('op_ullong_mod_zer',       '%',  'r_ulonglong')
-    _makefunc2('op_ullong_lshift_val',    '<<', 'r_ulonglong')
-    _makefunc2('op_ullong_rshift_val',    '>>', 'r_ulonglong')
-
-    def op_int_add_nonneg_ovf(self, x, y):
-        if isinstance(y, int):
-            assert y >= 0
-        return self.op_int_add_ovf(x, y)
-
-    def op_cast_float_to_int(self, f):
-        assert type(f) is float
-        try:
-            return ovfcheck(int(f))
-        except OverflowError:
-            self.make_llexception()
+    # special case
 
     def op_int_is_true(self, x):
-        # special case
         if type(x) is CDefinedIntSymbolic:
             x = x.default
         assert isinstance(x, int)

Modified: pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/lloperation.py	Thu Mar 20 18:34:24 2008
@@ -44,7 +44,7 @@
                 self.canraise += (StackException,)
 
         # The operation can be run directly with __call__
-        self.canrun = canrun or canfold
+        self.canrun = canrun or self.tryfold
 
         # The operation belongs to the ootypesystem
         self.oo = oo
@@ -55,7 +55,7 @@
 
     def __call__(self, RESULTTYPE, *args):
         # llop is meant to be rtyped and not called directly, unless it is
-        # a canfold=True operation
+        # a canfold=True or tryfold=True operation
         fold = self.fold
         if getattr(fold, 'need_result_type', False):
             val = fold(RESULTTYPE, *args)

Modified: pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/opimpl.py	(original)
+++ pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/opimpl.py	Thu Mar 20 18:34:24 2008
@@ -1,7 +1,10 @@
 import sys
 import math
+import py
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rlib.objectmodel import ComputedIntSymbolic
+from pypy.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong
+from pypy.rlib.rarithmetic import r_ulonglong, ovfcheck_lshift
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.lltypesystem.lloperation import opimpls
 
@@ -402,6 +405,9 @@
         raise TypeError("cannot fold getfield on mutable array")
     return p[index]
 
+def op_debug_assert(x, msg):
+    assert x, msg
+
 def op_debug_print(*args):
     for arg in args:
         print >> sys.stderr, arg,
@@ -414,6 +420,101 @@
     raise DebugFatalError(*args)
 
 # ____________________________________________________________
+# Overflow-detecting variants
+
+def op_int_neg_ovf(x):
+    assert type(x) is int
+    return ovfcheck(-x)
+
+def op_int_abs_ovf(x):
+    assert type(x) is int
+    return ovfcheck(abs(x))
+
+def op_llong_neg_ovf(x):
+    assert type(x) is r_longlong
+    return ovfcheck(-x)
+
+def op_llong_abs_ovf(x):
+    assert type(x) is r_longlong
+    return ovfcheck(abs(x))
+
+def op_int_lshift_ovf(x, y):
+    assert isinstance(x, int)
+    assert isinstance(y, int)
+    return ovfcheck_lshift(x, y)
+
+def op_int_lshift_ovf_val(x, y):
+    assert isinstance(x, int)
+    assert isinstance(y, int)
+    return ovfcheck_lshift(x, y)
+
+def _makefunc2(fn, operator, xtype, ytype=None):
+    if ytype is None:
+        ytype = xtype
+    if '_ovf' in fn:
+        checkfn = 'ovfcheck'
+    elif fn.startswith('op_int_'):
+        checkfn = 'intmask'
+    else:
+        checkfn = ''
+    if operator == '//':
+        code = '''r = %(checkfn)s(x // y)
+            if x^y < 0 and x%%y != 0:
+                r += 1
+            return r
+            '''%locals()
+    elif operator == '%':
+        code = '''r = %(checkfn)s(x %% y)
+            if x^y < 0 and x%%y != 0:
+                r -= y
+            return r
+            '''%locals()
+    else:
+        code = 'return %(checkfn)s(x %(operator)s y)'%locals()
+    exec py.code.Source("""
+        def %(fn)s(x, y):
+            assert isinstance(x, %(xtype)s)
+            assert isinstance(y, %(ytype)s)
+            %(code)s
+    """ % locals()).compile() in globals()
+
+_makefunc2('op_int_add_ovf', '+', '(int, llmemory.AddressOffset)')
+_makefunc2('op_int_mul_ovf', '*', '(int, llmemory.AddressOffset)', 'int')
+_makefunc2('op_int_sub_ovf',          '-',  'int')
+_makefunc2('op_int_floordiv_ovf',     '//', 'int')
+_makefunc2('op_int_floordiv_zer',     '//', 'int')
+_makefunc2('op_int_floordiv_ovf_zer', '//', 'int')
+_makefunc2('op_int_mod_ovf',          '%',  'int')
+_makefunc2('op_int_mod_zer',          '%',  'int')
+_makefunc2('op_int_mod_ovf_zer',      '%',  'int')
+_makefunc2('op_int_lshift_val',       '<<', 'int')
+_makefunc2('op_int_rshift_val',       '>>', 'int')
+
+_makefunc2('op_uint_floordiv_zer',    '//', 'r_uint')
+_makefunc2('op_uint_mod_zer',         '%',  'r_uint')
+_makefunc2('op_uint_lshift_val',      '<<', 'r_uint')
+_makefunc2('op_uint_rshift_val',      '>>', 'r_uint')
+
+_makefunc2('op_llong_floordiv_zer',   '//', 'r_longlong')
+_makefunc2('op_llong_mod_zer',        '%',  'r_longlong')
+_makefunc2('op_llong_lshift_val',     '<<', 'r_longlong')
+_makefunc2('op_llong_rshift_val',     '>>', 'r_longlong')
+
+_makefunc2('op_ullong_floordiv_zer',  '//', 'r_ulonglong')
+_makefunc2('op_ullong_mod_zer',       '%',  'r_ulonglong')
+_makefunc2('op_ullong_lshift_val',    '<<', 'r_ulonglong')
+_makefunc2('op_ullong_rshift_val',    '>>', 'r_ulonglong')
+
+def op_int_add_nonneg_ovf(x, y):
+    if isinstance(y, int):
+        assert y >= 0
+    return op_int_add_ovf(x, y)
+
+def op_cast_float_to_int(f):
+    assert type(f) is float
+    return ovfcheck(int(f))
+
+# ____________________________________________________________
 
 def get_op_impl(opname):
     # get the op_xxx() function from the globals above

Modified: pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/test/test_lloperation.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/test/test_lloperation.py	(original)
+++ pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/test/test_lloperation.py	Thu Mar 20 18:34:24 2008
@@ -48,7 +48,7 @@
 
 def test_llinterp_complete():
     for opname, llop in LL_OPERATIONS.items():
-        if llop.canfold:
+        if llop.tryfold:
             continue
         if opname.startswith('gc_x_'):
             continue   # ignore experimental stuff



More information about the Pypy-commit mailing list