Author: Brett Cannon <[email protected]>
Branch:
Changeset: r45703:522ca49e62aa
Date: 2011-07-17 15:18 -0700
http://bitbucket.org/pypy/pypy/changeset/522ca49e62aa/
Log: (B. Cannon, A. Gaynor) Specialize math.log and math.log10.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -185,6 +185,7 @@
Jim Baker
Philip Jenvey
Rodrigo Araújo
+ Brett Cannon
Heinrich-Heine University, Germany
Open End AB (formerly AB Strakt), Sweden
diff --git a/pypy/module/pypyjit/test_pypy_c/test_math.py
b/pypy/module/pypyjit/test_pypy_c/test_math.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/pypyjit/test_pypy_c/test_math.py
@@ -0,0 +1,32 @@
+from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
+
+
+class TestMath(BaseTestPyPyC):
+ def test_log(self):
+ def main(n):
+ import math
+
+ i = 1
+ s = 0.0
+ while i < n:
+ s += math.log(i) - math.log10(i)
+ i += 1
+ return s
+ log = self.run(main, [500])
+ assert round(log.result, 6) == round(main(500), 6)
+ loop, = log.loops_by_filename(self.filepath)
+ assert loop.match("""
+ i2 = int_lt(i0, i1)
+ guard_true(i2, descr=...)
+ guard_not_invalidated(descr=...)
+ f1 = cast_int_to_float(i0)
+ i3 = float_le(f1, 0)
+ guard_false(i3, descr=...)
+ f2 = call(ConstClass(log), f1)
+ f3 = call(ConstClass(log10), f1)
+ f4 = float_sub(f2, f3)
+ f5 = float_add(f0, f4)
+ i4 = int_add(i0, 1)
+ --TICK--
+ jump(i4, i1, f5)
+ """)
diff --git a/pypy/rpython/extfuncregistry.py b/pypy/rpython/extfuncregistry.py
--- a/pypy/rpython/extfuncregistry.py
+++ b/pypy/rpython/extfuncregistry.py
@@ -30,24 +30,28 @@
export_name="ll_math.ll_math_%s" % name,
sandboxsafe=True, llimpl=llimpl)
-register_external(rfloat.isinf, [float], bool,
- export_name="ll_math.ll_math_isinf", sandboxsafe=True,
- llimpl=ll_math.ll_math_isinf)
-register_external(rfloat.isnan, [float], bool,
- export_name="ll_math.ll_math_isnan", sandboxsafe=True,
- llimpl=ll_math.ll_math_isnan)
-register_external(rfloat.isfinite, [float], bool,
- export_name="ll_math.ll_math_isfinite", sandboxsafe=True,
- llimpl=ll_math.ll_math_isfinite)
-register_external(rfloat.copysign, [float, float], float,
- export_name="ll_math.ll_math_copysign", sandboxsafe=True,
- llimpl=ll_math.ll_math_copysign)
-register_external(math.floor, [float], float,
- export_name="ll_math.ll_math_floor", sandboxsafe=True,
- llimpl=ll_math.ll_math_floor)
-register_external(math.sqrt, [float], float,
- export_name="ll_math.ll_math_sqrt", sandboxsafe=True,
- llimpl=ll_math.ll_math_sqrt)
+_register = [ # (module, [(method name, arg types, return type), ...], ...)
+ (rfloat, [
+ ('isinf', [float], bool),
+ ('isnan', [float], bool),
+ ('isfinite', [float], bool),
+ ('copysign', [float, float], float),
+ ]),
+ (math, [
+ ('floor', [float], float),
+ ('sqrt', [float], float),
+ ('log', [float], float),
+ ('log10', [float], float),
+ ]),
+]
+for module, methods in _register:
+ for name, arg_types, return_type in methods:
+ method_name = 'll_math_%s' % name
+ register_external(getattr(module, name), arg_types, return_type,
+ export_name='ll_math.%s' % method_name,
+ sandboxsafe=True,
+ llimpl=getattr(ll_math, method_name))
+
complex_math_functions = [
('frexp', [float], (float, int)),
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
@@ -68,8 +68,9 @@
math_hypot = llexternal(underscore + 'hypot',
[rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
math_floor = llexternal('floor', [rffi.DOUBLE], rffi.DOUBLE,
elidable_function=True)
-
math_sqrt = llexternal('sqrt', [rffi.DOUBLE], rffi.DOUBLE)
+math_log = llexternal('log', [rffi.DOUBLE], rffi.DOUBLE)
+math_log10 = llexternal('log10', [rffi.DOUBLE], rffi.DOUBLE)
@jit.elidable
def sqrt_nonneg(x):
@@ -329,12 +330,22 @@
def ll_math_sqrt(x):
if x < 0.0:
raise ValueError, "math domain error"
-
+
if isfinite(x):
return sqrt_nonneg(x)
return x # +inf or nan
+def ll_math_log(x):
+ if x <= 0:
+ raise ValueError("math domain error")
+ return math_log(x)
+
+def ll_math_log10(x):
+ if x <= 0:
+ raise ValueError("math domain error")
+ return math_log10(x)
+
# ____________________________________________________________
#
# Default implementations
@@ -373,7 +384,7 @@
unary_math_functions = [
'acos', 'asin', 'atan',
'ceil', 'cos', 'cosh', 'exp', 'fabs',
- 'sin', 'sinh', 'tan', 'tanh', 'log', 'log10',
+ 'sin', 'sinh', 'tan', 'tanh',
'acosh', 'asinh', 'atanh', 'log1p', 'expm1',
]
unary_math_functions_can_overflow = [
diff --git a/pypy/rpython/lltypesystem/module/test/test_llinterp_math.py
b/pypy/rpython/lltypesystem/module/test/test_llinterp_math.py
--- a/pypy/rpython/lltypesystem/module/test/test_llinterp_math.py
+++ b/pypy/rpython/lltypesystem/module/test/test_llinterp_math.py
@@ -1,6 +1,4 @@
-
-""" Just another bunch of tests for llmath, run on top of llinterp
-"""
+"""Just another bunch of tests for llmath, run on top of llinterp."""
from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin
from pypy.rpython.lltypesystem.module import ll_math
@@ -39,7 +37,7 @@
assert self.interpret(f, [0.3, 0.4]) == f(0.3, 0.4)
return next_test
- for name in ll_math.unary_math_functions + ['sqrt']:
+ for name in ll_math.unary_math_functions + ['log', 'log10', 'sqrt']:
func_name = 'test_%s' % (name,)
next_test = new_unary_test(name)
next_test.func_name = func_name
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit