Skip to content

Commit

Permalink
Disable old @fastmath macro; implement new one that rewrites expressi…
Browse files Browse the repository at this point in the history
…ons instead
  • Loading branch information
eschnett committed Dec 21, 2014
1 parent fc30443 commit a16f6d2
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 21 deletions.
42 changes: 30 additions & 12 deletions base/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -237,20 +237,38 @@ macro inbounds(blk)
:(@boundscheck false $(esc(blk)))
end

macro fastmathmode(yesno,blk)
# hack: use this syntax since it avoids introducing line numbers
:($(Expr(:fastmath,yesno));
r = $(esc(blk));
$(Expr(:fastmath,:pop));
r)
end

macro fastmath(blk)
:(@fastmathmode true $(esc(blk)))
# macro fastmathmode(yesno,blk)
# # hack: use this syntax since it avoids introducing line numbers
# :($(Expr(:fastmath,yesno));
# r = $(esc(blk));
# $(Expr(:fastmath,:pop));
# r)
# end
#
# macro fastmath(blk)
# :(@fastmathmode true $(esc(blk)))
# end
#
# macro ieeemath(blk)
# :(@fastmathmode false $(esc(blk)))
# end

function make_fastmath(expr)
if isa(expr, Expr)
Expr(make_fastmath(expr.head), map(make_fastmath, expr.args)...)
elseif expr==:+; :add_fast
elseif expr==:-; :sub_fast
elseif expr==:*; :mul_fast
elseif expr==:/; :div_fast
elseif expr==:rem; :rem_fast
elseif expr==:mod; :mod_fast
elseif expr==:cmp; :cmp_fast
else expr
end
end

macro ieeemath(blk)
:(@fastmathmode false $(esc(blk)))
macro fastmath(expr)
make_fastmath(esc(expr))
end

macro label(name::Symbol)
Expand Down
13 changes: 11 additions & 2 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,15 @@ export
,
,

# fast math
add_fast,
sub_fast,
mul_fast,
div_fast,
rem_fast,
mod_fast,
cmp_fast,

# specfun
airy,
airyai,
Expand Down Expand Up @@ -1409,9 +1418,9 @@ export
@deprecate,
@boundscheck,
@inbounds,
@fastmathmode,
# @fastmathmode,
@fastmath,
@ieeemath,
# @ieeemath,
@simd,
@label,
@goto,
Expand Down
39 changes: 32 additions & 7 deletions base/float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -208,22 +208,33 @@ rem(x::Float32, y::Float32) = box(Float32,rem_float(unbox(Float32,x),unbox(Float
rem(x::Float64, y::Float64) = box(Float64,rem_float(unbox(Float64,x),unbox(Float64,y)))

# fast versions that may violate strict IEEE semantics
# TODO: isnan_fast and friends
for (op_fast, op) in ((:add_fast, :+), (:sub_fast, :-),
(:mul_fast, :*), (:div_fast, :/),
(:rem_fast, :rem), (:mod_fast, :mod),
(:cmp_fast, :cmp))
@eval begin
# fall-back implementation for non-numeric types
($op_fast)(xs...) = ($op)(xs...)
# type promotion
($op_fast)(x::Number, y::Number, zs::Number...) =
($op_fast)(promote(x,y,zs...)...)
# fall-back implementation that applies after promotion
($op_fast){T<:Number}(x::T,ys::T...) = ($op)(x,ys...)
end
end
for T in (Float32, Float64)
@eval begin
neg_fast(x::$T) = box($T,neg_float_fast(unbox($T,x)))
sub_fast(x::$T) = box($T,neg_float_fast(unbox($T,x)))
add_fast(x::$T, y::$T) = box($T,add_float_fast(unbox($T,x),unbox($T,y)))
sub_fast(x::$T, y::$T) = box($T,sub_float_fast(unbox($T,x),unbox($T,y)))
mul_fast(x::$T, y::$T) = box($T,mul_float_fast(unbox($T,x),unbox($T,y)))
div_fast(x::$T, y::$T) = box($T,div_float_fast(unbox($T,x),unbox($T,y)))
rem_fast(x::$T, y::$T) = box($T,rem_float_fast(unbox($T,x),unbox($T,y)))
add_fast(x::$T, y::$T, zs::$T...) = add_fast(add_fast(x, y), zs...)
mul_fast(x::$T, y::$T, zs::$T...) = mul_fast(mul_fast(x, y), zs...)
end
end
neg_fast(x) = -x
add_fast(x,y) = x+y
sub_fast(x,y) = x-y
mul_fast(x,y) = x*y
div_fast(x,y) = x/y
rem_fast(x,y) = rem(x,y)

cld{T<:FloatingPoint}(x::T, y::T) = -fld(-x,y)

Expand All @@ -238,6 +249,17 @@ function mod{T<:FloatingPoint}(x::T, y::T)
end
end

function mod_fast{T<:FloatingPoint}(x::T, y::T)
r = rem_fast(x,y)
if r == 0
copysign(r,y)
elseif (r > 0) $ (y > 0)
r+y
else
r
end
end


## floating point comparisons ##
==(x::Float32, y::Float32) = eq_float(unbox(Float32,x),unbox(Float32,y))
Expand Down Expand Up @@ -269,6 +291,9 @@ function cmp(x::FloatingPoint, y::Real)
ifelse(x<y, -1, ifelse(x>y, 1, 0))
end

cmp_fast(x::Float32, y::Float32) = ifelse(x<y, -1, ifelse(x>y, 1, 0))
cmp_fast(x::Float64, y::Float64) = ifelse(x<y, -1, ifelse(x>y, 1, 0))

for Ti in (Int64,UInt64,Int128,UInt128)
for Tf in (Float32,Float64)
@eval begin
Expand Down

0 comments on commit a16f6d2

Please sign in to comment.