[pypy-commit] pypy flowoperators: deal with xxx_ovf operators more automatically

rlamy noreply at buildbot.pypy.org
Fri Jul 5 19:42:23 CEST 2013


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: flowoperators
Changeset: r65223:6b1da459ff3a
Date: 2013-05-12 14:29 +0100
http://bitbucket.org/pypy/pypy/changeset/6b1da459ff3a/

Log:	deal with xxx_ovf operators more automatically

diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py
--- a/rpython/flowspace/objspace.py
+++ b/rpython/flowspace/objspace.py
@@ -409,7 +409,6 @@
     """Add function operation to the flow space."""
     name = oper.name
     func = oper.pyfunc
-    arithmetic = hasattr(operation.op, name + '_ovf')
 
     def generic_operator(self, *args_w):
         assert len(args_w) == oper.arity, name + " got the wrong number of arguments"
@@ -429,7 +428,7 @@
                 # result.  The result is probably meant to be sent to
                 # an intmask(), but the 'long' constant confuses the
                 # annotator a lot.
-                if arithmetic and type(result) is long:
+                if oper.can_overflow and type(result) is long:
                     pass
                 # don't constant-fold getslice on lists, either
                 elif name == 'getslice' and type(result) is list:
diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py
--- a/rpython/flowspace/operation.py
+++ b/rpython/flowspace/operation.py
@@ -15,16 +15,18 @@
 func2op = {}
 
 class SpaceOperator(object):
-    def __init__(self, name, arity, symbol, pyfunc, pure=False):
+    def __init__(self, name, arity, symbol, pyfunc, pure=False,
+            can_overflow=False):
         self.name = name
         self.arity = arity
         self.symbol = symbol
         self.pyfunc = pyfunc
         self.pure = pure
+        self.can_overflow = can_overflow
 
-def add_operator(name, arity, symbol, pyfunc=None, pure=False):
+def add_operator(name, arity, symbol, pyfunc=None, pure=False, ovf=False):
     operator_func = getattr(operator, name, None)
-    oper = SpaceOperator(name, arity, symbol, pyfunc, pure)
+    oper = SpaceOperator(name, arity, symbol, pyfunc, pure, can_overflow=ovf)
     setattr(op, name, oper)
     if pyfunc is not None:
         func2op[pyfunc] = oper
@@ -32,6 +34,9 @@
         func2op[operator_func] = oper
         if pyfunc is None:
             oper.pyfunc = operator_func
+    if ovf:
+        ovf_func = lambda *args: ovfcheck(oper.pyfunc(*args))
+        add_operator(name + '_ovf', arity, symbol, pyfunc=ovf_func)
 
 # ____________________________________________________________
 
@@ -123,33 +128,6 @@
 def userdel(x):
     x.__del__()
 
-def neg_ovf(x):
-    return ovfcheck(-x)
-
-def abs_ovf(x):
-    return ovfcheck(abs(x))
-
-def add_ovf(x, y):
-    return ovfcheck(x + y)
-
-def sub_ovf(x, y):
-    return ovfcheck(x - y)
-
-def mul_ovf(x, y):
-    return ovfcheck(x * y)
-
-def floordiv_ovf(x, y):
-    return ovfcheck(operator.floordiv(x, y))
-
-def div_ovf(x, y):
-    return ovfcheck(operator.div(x, y))
-
-def mod_ovf(x, y):
-    return ovfcheck(x % y)
-
-def lshift_ovf(x, y):
-    return ovfcheck(x << y)
-
 # slicing: operator.{get,set,del}slice() don't support b=None or c=None
 def do_getslice(a, b, c):
     return a[b:c]
@@ -185,24 +163,24 @@
 add_operator('delslice', 3, 'delslice', pyfunc=do_delslice)
 add_operator('trunc', 1, 'trunc', pyfunc=unsupported)
 add_operator('pos', 1, 'pos', pure=True)
-add_operator('neg', 1, 'neg', pure=True)
+add_operator('neg', 1, 'neg', pure=True, ovf=True)
 add_operator('nonzero', 1, 'truth', pyfunc=bool, pure=True)
 op.is_true = op.nonzero
-add_operator('abs' , 1, 'abs', pyfunc=abs, pure=True)
+add_operator('abs' , 1, 'abs', pyfunc=abs, pure=True, ovf=True)
 add_operator('hex', 1, 'hex', pyfunc=hex, pure=True)
 add_operator('oct', 1, 'oct', pyfunc=oct, pure=True)
 add_operator('ord', 1, 'ord', pyfunc=ord, pure=True)
 add_operator('invert', 1, '~', pure=True)
-add_operator('add', 2, '+', pure=True)
-add_operator('sub', 2, '-', pure=True)
-add_operator('mul', 2, '*', pure=True)
+add_operator('add', 2, '+', pure=True, ovf=True)
+add_operator('sub', 2, '-', pure=True, ovf=True)
+add_operator('mul', 2, '*', pure=True, ovf=True)
 add_operator('truediv', 2, '/', pure=True)
-add_operator('floordiv', 2, '//', pure=True)
-add_operator('div', 2, 'div', pure=True)
-add_operator('mod', 2, '%', pure=True)
+add_operator('floordiv', 2, '//', pure=True, ovf=True)
+add_operator('div', 2, 'div', pure=True, ovf=True)
+add_operator('mod', 2, '%', pure=True, ovf=True)
 add_operator('divmod', 2, 'divmod', pyfunc=divmod, pure=True)
 add_operator('pow', 3, '**', pyfunc=pow, pure=True)
-add_operator('lshift', 2, '<<', pure=True)
+add_operator('lshift', 2, '<<', pure=True, ovf=True)
 add_operator('rshift', 2, '>>', pure=True)
 add_operator('and_', 2, '&', pure=True)
 add_operator('or_', 2, '|', pure=True)
@@ -242,12 +220,6 @@
 add_operator('userdel', 1, 'del', pyfunc=userdel)
 add_operator('buffer', 1, 'buffer', pyfunc=buffer, pure=True)   # see buffer.py
 
-# --- operations added by graph transformations ---
-for oper in [op.neg, op.abs, op.add, op.sub, op.mul, op.floordiv, op.div,
-        op.mod, op.lshift]:
-    ovf_func = lambda *args: ovfcheck(oper.pyfunc(*args))
-    add_operator(oper.name + '_ovf', oper.arity, oper.symbol, pyfunc=ovf_func)
-
 # Other functions that get directly translated to SpaceOperators
 func2op[type] = op.type
 func2op[operator.truth] = op.nonzero


More information about the pypy-commit mailing list