Skip to content

Commit 639e18b

Browse files
authored
Merge pull request #43 from NHDaly/fldmod_inline
Improve performance for FD multiplication: allow LLVM to optimize away the division by a constant.
2 parents 1768c58 + c119821 commit 639e18b

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

src/FixedPointDecimals.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,18 @@ function _round_to_even(quotient::T, remainder::T, divisor::T) where {T <: Integ
154154
end
155155
_round_to_even(q, r, d) = _round_to_even(promote(q, r, d)...)
156156

157+
# In many of our calls to fldmod, `y` is a constant (the coefficient, 10^f). However, since
158+
# `fldmod` is sometimes not being inlined, that constant information is not available to the
159+
# optimizer. We need an inlined version of fldmod so that the compiler can replace expensive
160+
# divide-by-power-of-ten instructions with the cheaper multiply-by-inverse-coefficient.
161+
@inline fldmodinline(x,y) = (fld(x,y), mod(x,y))
162+
157163
# multiplication rounds to nearest even representation
158164
# TODO: can we use floating point to speed this up? after we build a
159165
# correctness test suite.
160166
function *(x::FD{T, f}, y::FD{T, f}) where {T, f}
161167
powt = coefficient(FD{T, f})
162-
quotient, remainder = fldmod(widemul(x.i, y.i), powt)
168+
quotient, remainder = fldmodinline(widemul(x.i, y.i), powt)
163169
reinterpret(FD{T, f}, _round_to_even(quotient, remainder, powt))
164170
end
165171

@@ -195,12 +201,12 @@ floor(x::FD{T, f}) where {T, f} = FD{T, f}(fld(x.i, coefficient(FD{T, f})))
195201
# TODO: round with number of digits; should be easy
196202
function round(x::FD{T, f}, ::RoundingMode{:Nearest}=RoundNearest) where {T, f}
197203
powt = coefficient(FD{T, f})
198-
quotient, remainder = fldmod(x.i, powt)
204+
quotient, remainder = fldmodinline(x.i, powt)
199205
FD{T, f}(_round_to_even(quotient, remainder, powt))
200206
end
201207
function ceil(x::FD{T, f}) where {T, f}
202208
powt = coefficient(FD{T, f})
203-
quotient, remainder = fldmod(x.i, powt)
209+
quotient, remainder = fldmodinline(x.i, powt)
204210
if remainder > 0
205211
FD{T, f}(quotient + one(quotient))
206212
else

0 commit comments

Comments
 (0)