[pypy-commit] pypy default: do the error checking for math.fmod in RPython, so it can be removed by the JIT (more efficient than round tripping with geterrno/seterrno)
alex_gaynor
noreply at buildbot.pypy.org
Fri Aug 26 19:08:00 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch:
Changeset: r46801:cfeea456dc1b
Date: 2011-08-26 13:14 -0400
http://bitbucket.org/pypy/pypy/changeset/cfeea456dc1b/
Log: do the error checking for math.fmod in RPython, so it can be removed
by the JIT (more efficient than round tripping with
geterrno/seterrno)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_math.py b/pypy/module/pypyjit/test_pypy_c/test_math.py
--- a/pypy/module/pypyjit/test_pypy_c/test_math.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_math.py
@@ -60,4 +60,32 @@
i7 = int_add(i0, f1)
--TICK--
jump(..., descr=)
+ """)
+
+ def test_fmod(self):
+ def main(n):
+ import math
+
+ s = 0
+ while n > 0:
+ s += math.fmod(n, 2.0)
+ n -= 1
+ return s
+ log = self.run(main, [500])
+ assert log.result == main(500)
+ loop, = log.loops_by_filename(self.filepath)
+ assert loop.match("""
+ i1 = int_gt(i0, 0)
+ guard_true(i1, descr=...)
+ f1 = cast_int_to_float(i0)
+ i2 = float_eq(f1, inf)
+ i3 = float_eq(f1, -inf)
+ i4 = int_or(i2, i3)
+ i5 = int_is_true(i4)
+ guard_false(i5, descr=...)
+ f2 = call(ConstClass(fmod), f1, 2.0, descr=<FloatCallDescr>)
+ f3 = float_add(f0, f2)
+ i6 = int_sub(i0, 1)
+ --TICK--
+ jump(..., descr=)
""")
\ No newline at end of file
diff --git a/pypy/rpython/extfuncregistry.py b/pypy/rpython/extfuncregistry.py
--- a/pypy/rpython/extfuncregistry.py
+++ b/pypy/rpython/extfuncregistry.py
@@ -44,6 +44,13 @@
('log10', [float], float),
('sin', [float], float),
('cos', [float], float),
+ ('atan2', [float, float], float),
+ ('hypot', [float, float], float),
+ ('frexp', [float], (float, int)),
+ ('ldexp', [float, int], float),
+ ('modf', [float], (float, float)),
+ ('fmod', [float, float], float),
+ ('pow', [float, float], float),
]),
]
for module, methods in _register:
@@ -54,23 +61,6 @@
sandboxsafe=True,
llimpl=getattr(ll_math, method_name))
-
-complex_math_functions = [
- ('frexp', [float], (float, int)),
- ('ldexp', [float, int], float),
- ('modf', [float], (float, float)),
- ] + [(name, [float, float], float)
- for name in 'atan2', 'fmod', 'hypot', 'pow']
-
-for name, args, res in complex_math_functions:
- func = getattr(math, name)
- llimpl = getattr(ll_math, 'll_math_%s' % name, None)
- oofake = getattr(oo_math, 'll_math_%s' % name, None)
- register_external(func, args, res, 'll_math.ll_math_%s' % name,
- llimpl=llimpl, oofakeimpl=oofake,
- sandboxsafe=True)
-
-
# ___________________________
# os.path functions
diff --git a/pypy/rpython/lltypesystem/module/ll_math.py b/pypy/rpython/lltypesystem/module/ll_math.py
--- a/pypy/rpython/lltypesystem/module/ll_math.py
+++ b/pypy/rpython/lltypesystem/module/ll_math.py
@@ -223,22 +223,13 @@
def ll_math_fmod(x, y):
- if isinf(y):
- if isinf(x):
- raise ValueError("math domain error")
- return x # fmod(x, +/-Inf) returns x for finite x (or if x is a NaN).
+ if isinf(x) and not isnan(y):
+ raise ValueError("math domain error")
- _error_reset()
- r = math_fmod(x, y)
- errno = rposix.get_errno()
- if isnan(r):
- if isnan(x) or isnan(y):
- errno = 0
- else:
- errno = EDOM
- if errno:
- _likely_raise(errno, r)
- return r
+ if y == 0:
+ raise ValueError("math domain error")
+
+ return math_fmod(x, y)
def ll_math_hypot(x, y):
More information about the pypy-commit
mailing list