Author: Alex Gaynor <[email protected]>
Branch:
Changeset: r45959:af99487db00f
Date: 2011-07-24 18:10 -0700
http://bitbucket.org/pypy/pypy/changeset/af99487db00f/
Log: (zain, alex): specialize the error checking for math.{sin,cos} this
way is much cleaner, plus the error checking is written in terms of
the input, which means the JIT can often remove duplicate checks.
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
@@ -30,3 +30,34 @@
--TICK--
jump(..., descr=<Loop0>)
""")
+
+ def test_sin_cos(self):
+ def main(n):
+ import math
+
+ i = 1
+ s = 0.0
+ while i < n:
+ s += math.sin(i) - math.cos(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=...)
+ f1 = cast_int_to_float(i0)
+ i3 = float_eq(f1, inf)
+ i4 = float_eq(f1, -inf)
+ i5 = int_or(i3, i4)
+ i6 = int_is_true(i5)
+ guard_false(i6, descr=...)
+ f2 = call(ConstClass(sin), f1, descr=<FloatCallDescr>)
+ f3 = call(ConstClass(cos), f1, descr=<FloatCallDescr>)
+ f4 = float_sub(f2, f3)
+ f5 = float_add(f0, f4)
+ i7 = int_add(i0, f1)
+ --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
@@ -42,6 +42,8 @@
('sqrt', [float], float),
('log', [float], float),
('log10', [float], float),
+ ('sin', [float], float),
+ ('cos', [float], float),
]),
]
for module, methods in _register:
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
@@ -69,6 +69,8 @@
[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_sin = llexternal('sin', [rffi.DOUBLE], rffi.DOUBLE)
+math_cos = llexternal('cos', [rffi.DOUBLE], rffi.DOUBLE)
@jit.elidable
def sqrt_nonneg(x):
@@ -340,6 +342,16 @@
raise ValueError("math domain error")
return math_log10(x)
+def ll_math_sin(x):
+ if isinf(x):
+ raise ValueError("math domain error")
+ return math_sin(x)
+
+def ll_math_cos(x):
+ if isinf(x):
+ raise ValueError("math domain error")
+ return math_cos(x)
+
# ____________________________________________________________
#
# Default implementations
@@ -377,8 +389,8 @@
unary_math_functions = [
'acos', 'asin', 'atan',
- 'ceil', 'cos', 'cosh', 'exp', 'fabs',
- 'sin', 'sinh', 'tan', 'tanh',
+ 'ceil', 'cosh', 'exp', 'fabs',
+ '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
@@ -37,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 + ['log', 'log10', 'sqrt']:
+ for name in ll_math.unary_math_functions + ['log', 'log10', 'sin', 'cos',
'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