`GHC.Base.divModInt` and variants should be marked INLINE
While grooming Core output of !1866 (closed), I discovered that we seem to allocate a wrapper for the following function:
divModInt :: Int -> Int -> (Int, Int)
(I# x) `divModInt` (I# y) = case x `divModInt#` y of
(# q, r #) -> (I# q, I# r)
where divModInt#
is the unboxed "worker" function. Note how this is exactly the manual application of strictness and CPR worker/wrapper! And also note the lack of an INLINE pragma, that makes WW split divModInt
into the following worker, $wdivModInt
:
$wdivModInt :: Int# -> Int# -> (# Int, Int #)
x `$wdivModInt` y = case x `divModInt#` y of
(# q, r #) -> (# I# q, I# r #)
which is nuts. Marking divModInt
as INLINE prevents that.
Incidentally, Nested CPR (!1866 (closed)) would WW for the I#
boxes and allocate a worker $wdivModInt
which would then be just an alias for divModInt#
. But divModInt#
seemingly is small enough to inline back into the wrapper divModInt
, making that whole process futile. I think. At least that's what I see in the interface file. In this case, the INLINE would prevent WW and make sure we don't inline divModInt#
into divModInt
, so that the Simplifier can decide in isolation whether to inline divModInt#
after having cancelled the allocation in divModInt
.
Bottom line: Mark those wrappers as INLINE and don't worry again.