@@ -154,12 +154,18 @@ function _round_to_even(quotient::T, remainder::T, divisor::T) where {T <: Integ
154
154
end
155
155
_round_to_even (q, r, d) = _round_to_even (promote (q, r, d)... )
156
156
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
+
157
163
# multiplication rounds to nearest even representation
158
164
# TODO : can we use floating point to speed this up? after we build a
159
165
# correctness test suite.
160
166
function * (x:: FD{T, f} , y:: FD{T, f} ) where {T, f}
161
167
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)
163
169
reinterpret (FD{T, f}, _round_to_even (quotient, remainder, powt))
164
170
end
165
171
@@ -195,12 +201,12 @@ floor(x::FD{T, f}) where {T, f} = FD{T, f}(fld(x.i, coefficient(FD{T, f})))
195
201
# TODO : round with number of digits; should be easy
196
202
function round (x:: FD{T, f} , :: RoundingMode{:Nearest} = RoundNearest) where {T, f}
197
203
powt = coefficient (FD{T, f})
198
- quotient, remainder = fldmod (x. i, powt)
204
+ quotient, remainder = fldmodinline (x. i, powt)
199
205
FD {T, f} (_round_to_even (quotient, remainder, powt))
200
206
end
201
207
function ceil (x:: FD{T, f} ) where {T, f}
202
208
powt = coefficient (FD{T, f})
203
- quotient, remainder = fldmod (x. i, powt)
209
+ quotient, remainder = fldmodinline (x. i, powt)
204
210
if remainder > 0
205
211
FD {T, f} (quotient + one (quotient))
206
212
else
@@ -484,6 +490,9 @@ function max_exp10(::Type{T}) where {T <: Integer}
484
490
end
485
491
486
492
max_exp10 (:: Type{BigInt} ) = - 1
493
+ # Freeze the evaluation for Int128, since max_exp10(Int128) is too compilicated to get
494
+ # optimized away by the compiler during const-folding.
495
+ @eval max_exp10 (:: Type{Int128} ) = $ (max_exp10 (Int128))
487
496
488
497
"""
489
498
coefficient(::Type{FD{T, f}}) -> T
0 commit comments