Commit fcdd210a authored by Brett Cannon's avatar Brett Cannon

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

parent c340b868
......@@ -185,6 +185,7 @@ copyrighted by one or more of the following people and organizations:
Jim Baker
Philip Jenvey
Rodrigo Araújo
Brett Cannon
Heinrich-Heine University, Germany
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:
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)),
......
......@@ -68,8 +68,9 @@ math_fmod = llexternal('fmod', [rffi.DOUBLE, rffi.DOUBLE], rffi.DOUBLE)
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_pow(x, y):
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 @@ def new_unary_math_function(name, can_overflow, c99):
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 = [
......
""" 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 @@ class TestMath(BaseRtypingTest, LLRtypeMixin):
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
......
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