@@ -154,12 +154,18 @@ function _round_to_even(quotient::T, remainder::T, divisor::T) where {T <: Integ
154154end
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.
160166function * (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))
164170end
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
196202function 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))
200206end
201207function 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