Commit fde2d974 authored by Brett Cannon's avatar Brett Cannon
Browse files

(B. Cannon, A. Gaynor) Specialize math.log and math.log10.

parent a4096819e9eb
...@@ -185,6 +185,7 @@ copyrighted by one or more of the following people and organizations: ...@@ -185,6 +185,7 @@ copyrighted by one or more of the following people and organizations:
Jim Baker Jim Baker
Philip Jenvey Philip Jenvey
Rodrigo Araújo Rodrigo Araújo
Brett Cannon
Heinrich-Heine University, Germany Heinrich-Heine University, Germany
Open End AB (formerly AB Strakt), Sweden Open End AB (formerly AB Strakt), Sweden
......
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)
""")
...@@ -30,24 +30,28 @@ for name in ll_math.unary_math_functions: ...@@ -30,24 +30,28 @@ for name in ll_math.unary_math_functions:
export_name="ll_math.ll_math_%s" % name, export_name="ll_math.ll_math_%s" % name,
sandboxsafe=True, llimpl=llimpl) sandboxsafe=True, llimpl=llimpl)
register_external(rfloat.isinf, [float], bool, _register = [ # (module, [(method name, arg types, return type), ...], ...)
export_name="ll_math.ll_math_isinf", sandboxsafe=True, (rfloat, [
llimpl=ll_math.ll_math_isinf) ('isinf', [float], bool),
register_external(rfloat.isnan, [float], bool, ('isnan', [float], bool),
export_name="ll_math.ll_math_isnan", sandboxsafe=True, ('isfinite', [float], bool),
llimpl=ll_math.ll_math_isnan) ('copysign', [float, float], float),
register_external(rfloat.isfinite, [float], bool, ]),
export_name="ll_math.ll_math_isfinite", sandboxsafe=True, (math, [
llimpl=ll_math.ll_math_isfinite) ('floor', [float], float),
register_external(rfloat.copysign, [float, float], float, ('sqrt', [float], float),
export_name="ll_math.ll_math_copysign", sandboxsafe=True, ('log', [float], float),
llimpl=ll_math.ll_math_copysign) ('log10', [float], float),
register_external(math.floor, [float], float, ]),
export_name="ll_math.ll_math_floor", sandboxsafe=True, ]
llimpl=ll_math.ll_math_floor) for module, methods in _register:
register_external(math.sqrt, [float], float, for name, arg_types, return_type in methods:
export_name="ll_math.ll_math_sqrt", sandboxsafe=True, method_name = 'll_math_%s' % name
llimpl=ll_math.ll_math_sqrt) 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 = [ complex_math_functions = [
('frexp', [float], (float, int)), ('frexp', [float], (float, int)),
......
...@@ -68,8 +68,9 @@ math_fmod = llexternal('fmod', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) ...@@ -68,8 +68,9 @@ math_fmod = llexternal('fmod', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
math_hypot = llexternal(underscore + 'hypot', math_hypot = llexternal(underscore + 'hypot',
[rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE) [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
math_floor = llexternal('floor', [rffi.DOUBLE], rffi.DOUBLE, elidable_function=True) math_floor = llexternal('floor', [rffi.DOUBLE], rffi.DOUBLE, elidable_function=True)
math_sqrt = llexternal('sqrt', [rffi.DOUBLE], rffi.DOUBLE) 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 @jit.elidable
def sqrt_nonneg(x): def sqrt_nonneg(x):
...@@ -329,12 +330,22 @@ def ll_math_pow(x, y): ...@@ -329,12 +330,22 @@ def ll_math_pow(x, y):
def ll_math_sqrt(x): def ll_math_sqrt(x):
if x < 0.0: if x < 0.0:
raise ValueError, "math domain error" raise ValueError, "math domain error"
if isfinite(x): if isfinite(x):
return sqrt_nonneg(x) return sqrt_nonneg(x)
return x # +inf or nan 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 # Default implementations
...@@ -373,7 +384,7 @@ def new_unary_math_function(name, can_overflow, c99): ...@@ -373,7 +384,7 @@ def new_unary_math_function(name, can_overflow, c99):
unary_math_functions = [ unary_math_functions = [
'acos', 'asin', 'atan', 'acos', 'asin', 'atan',
'ceil', 'cos', 'cosh', 'exp', 'fabs', 'ceil', 'cos', 'cosh', 'exp', 'fabs',
'sin', 'sinh', 'tan', 'tanh', 'log', 'log10', 'sin', 'sinh', 'tan', 'tanh',
'acosh', 'asinh', 'atanh', 'log1p', 'expm1', 'acosh', 'asinh', 'atanh', 'log1p', 'expm1',
] ]
unary_math_functions_can_overflow = [ unary_math_functions_can_overflow = [
......
"""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.test.tool import BaseRtypingTest, LLRtypeMixin
from pypy.rpython.lltypesystem.module import ll_math from pypy.rpython.lltypesystem.module import ll_math
...@@ -39,7 +37,7 @@ class TestMath(BaseRtypingTest, LLRtypeMixin): ...@@ -39,7 +37,7 @@ class TestMath(BaseRtypingTest, LLRtypeMixin):
assert self.interpret(f, [0.3, 0.4]) == f(0.3, 0.4) assert self.interpret(f, [0.3, 0.4]) == f(0.3, 0.4)
return next_test 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,) func_name = 'test_%s' % (name,)
next_test = new_unary_test(name) next_test = new_unary_test(name)
next_test.func_name = func_name next_test.func_name = func_name
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment