Skip to content

Commit 4f534bc

Browse files
committed
make several pure-marked math functions actually pure
1 parent 1c5d733 commit 4f534bc

File tree

4 files changed

+30
-26
lines changed

4 files changed

+30
-26
lines changed

base/float.jl

-8
Original file line numberDiff line numberDiff line change
@@ -812,14 +812,6 @@ fpinttype(::Type{Float64}) = UInt64
812812
fpinttype(::Type{Float32}) = UInt32
813813
fpinttype(::Type{Float16}) = UInt16
814814

815-
@pure significand_bits{T<:AbstractFloat}(::Type{T}) = trailing_ones(significand_mask(T))
816-
@pure exponent_bits{T<:AbstractFloat}(::Type{T}) = sizeof(T)*8 - significand_bits(T) - 1
817-
@pure exponent_bias{T<:AbstractFloat}(::Type{T}) = Int(exponent_one(T) >> significand_bits(T))
818-
# maximum float exponent
819-
@pure exponent_max{T<:AbstractFloat}(::Type{T}) = Int(exponent_mask(T) >> significand_bits(T)) - exponent_bias(T)
820-
# maximum float exponent without bias
821-
@pure exponent_raw_max{T<:AbstractFloat}(::Type{T}) = Int(exponent_mask(T) >> significand_bits(T))
822-
823815
## TwicePrecision utilities
824816
# The numeric constants are half the number of bits in the mantissa
825817
for (F, T, n) in ((Float16, UInt16, 5), (Float32, UInt32, 12), (Float64, UInt64, 26))

base/intfuncs.jl

+10-7
Original file line numberDiff line numberDiff line change
@@ -199,16 +199,19 @@ end
199199
# to enable compile-time optimizations specialized to p.
200200
# However, we still need a fallback that calls the general ^.
201201
# To avoid ambiguities for methods that dispatch on the
202-
# first argument, we dispatch the fallback via internal_pow:
203-
^(x, p) = internal_pow(x, p)
204-
internal_pow{p}(x, ::Type{Val{p}}) = x^p
202+
# first argument, we dispatch the fallback via internal_pow.
203+
# We mark these @inline since if the target is marked @inline,
204+
# we want to make sure that gets propagated,
205+
# even if it is over the inlining threshold.
206+
@inline ^(x, p) = internal_pow(x, p)
207+
@inline internal_pow{p}(x, ::Type{Val{p}}) = x^p
205208

206209
# inference.jl has complicated logic to inline x^2 and x^3 for
207210
# numeric types. In terms of Val we can do it much more simply:
208-
internal_pow(x::Number, ::Type{Val{0}}) = one(x)
209-
internal_pow(x::Number, ::Type{Val{1}}) = x
210-
internal_pow(x::Number, ::Type{Val{2}}) = x*x
211-
internal_pow(x::Number, ::Type{Val{3}}) = x*x*x
211+
@inline internal_pow(x::Number, ::Type{Val{0}}) = one(x)
212+
@inline internal_pow(x::Number, ::Type{Val{1}}) = x
213+
@inline internal_pow(x::Number, ::Type{Val{2}}) = x*x
214+
@inline internal_pow(x::Number, ::Type{Val{3}}) = x*x*x
212215

213216
# b^p mod m
214217

base/math.jl

+16-7
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,23 @@ import Base: log, exp, sin, cos, tan, sinh, cosh, tanh, asin,
2020
max, min, minmax, ^, exp2, muladd, rem,
2121
exp10, expm1, log1p
2222

23-
using Base: sign_mask, exponent_mask, exponent_one, exponent_bias,
24-
exponent_half, exponent_max, exponent_raw_max, fpinttype,
25-
significand_mask, significand_bits, exponent_bits
23+
using Base: sign_mask, exponent_mask, exponent_one,
24+
exponent_half, fpinttype, significand_mask
2625

2726
using Core.Intrinsics: sqrt_llvm
2827

29-
const IEEEFloat = Union{Float16,Float32,Float64}
28+
const IEEEFloat = Union{Float16, Float32, Float64}
29+
30+
for T in (Float16, Float32, Float64)
31+
@eval significand_bits(::Type{$T}) = $(trailing_ones(significand_mask(T)))
32+
@eval exponent_bits(::Type{$T}) = $(sizeof(T)*8 - significand_bits(T) - 1)
33+
@eval exponent_bias(::Type{$T}) = $(Int(exponent_one(T) >> significand_bits(T)))
34+
# maximum float exponent
35+
@eval exponent_max(::Type{$T}) = $(Int(exponent_mask(T) >> significand_bits(T)) - exponent_bias(T))
36+
# maximum float exponent without bias
37+
@eval exponent_raw_max(::Type{$T}) = $(Int(exponent_mask(T) >> significand_bits(T)))
38+
end
39+
3040
# non-type specific math functions
3141

3242
"""
@@ -229,8 +239,6 @@ for f in (:cbrt, :sinh, :cosh, :tanh, :atan, :asinh, :exp2, :expm1)
229239
($f)(x::Real) = ($f)(float(x))
230240
end
231241
end
232-
# pure julia exp function
233-
include("special/exp.jl")
234242
exp(x::Real) = exp(float(x))
235243

236244
# fallback definitions to prevent infinite loop from $f(x::Real) def above
@@ -690,7 +698,7 @@ end
690698
@inline ^(x::Float64, y::Integer) = x ^ Float64(y)
691699
@inline ^(x::Float32, y::Integer) = x ^ Float32(y)
692700
@inline ^(x::Float16, y::Integer) = Float16(Float32(x) ^ Float32(y))
693-
^{p}(x::Float16, ::Type{Val{p}}) = Float16(Float32(x)^Val{p})
701+
@inline ^{p}(x::Float16, ::Type{Val{p}}) = Float16(Float32(x) ^ Val{p})
694702

695703
function angle_restrict_symm(theta)
696704
const P1 = 4 * 7.8539812564849853515625e-01
@@ -950,6 +958,7 @@ end
950958
cbrt(a::Float16) = Float16(cbrt(Float32(a)))
951959

952960
# More special functions
961+
include("special/exp.jl")
953962
include("special/trig.jl")
954963
include("special/gamma.jl")
955964

base/special/exp.jl

+4-4
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ MINEXP(::Type{Float32}) = -103.97207708f0 # log 2^-150
5656
@inline exp_kernel(x::Float32) = @horner(x, 1.6666625440f-1, -2.7667332906f-3)
5757

5858
# for values smaller than this threshold just use a Taylor expansion
59-
exp_small_thres(::Type{Float64}) = 2.0^-28
60-
exp_small_thres(::Type{Float32}) = 2.0f0^-13
59+
@eval exp_small_thres(::Type{Float64}) = $(2.0^-28)
60+
@eval exp_small_thres(::Type{Float32}) = $(2.0f0^-13)
6161

6262
"""
6363
exp(x)
@@ -114,13 +114,13 @@ function exp{T<:Union{Float32,Float64}}(x::T)
114114
# scale back
115115
if k > -significand_bits(T)
116116
# multiply by 2.0 first to prevent overflow, which helps extends the range
117-
k == exponent_max(T) && return y*T(2.0)*T(2.0)^(exponent_max(T) - 1)
117+
k == exponent_max(T) && return y * T(2.0) * T(2.0)^(exponent_max(T) - 1)
118118
twopk = reinterpret(T, rem(exponent_bias(T) + k, fpinttype(T)) << significand_bits(T))
119119
return y*twopk
120120
else
121121
# add significand_bits(T) + 1 to lift the range outside the subnormals
122122
twopk = reinterpret(T, rem(exponent_bias(T) + significand_bits(T) + 1 + k, fpinttype(T)) << significand_bits(T))
123-
return y*twopk*T(2.0)^(-significand_bits(T) - 1)
123+
return y * twopk * T(2.0)^(-significand_bits(T) - 1)
124124
end
125125
elseif xa < reinterpret(Unsigned, exp_small_thres(T)) # |x| < exp_small_thres
126126
# Taylor approximation for small x

0 commit comments

Comments
 (0)