Make small INLINE functions behave properly
Here's a desirable patch:
modified compiler/coreSyn/CoreUnfold.hs
@@ -441,10 +441,10 @@ inlineBoringOk e
go :: Int -> CoreExpr -> Bool
go credit (Lam x e) | isId x = go (credit+1) e
| otherwise = go credit e
- go credit (App f (Type {})) = go credit f
- go credit (App f a) | credit > 0
+ go credit (App f a) | isTyCoArg a = go credit f
+ | credit > 0
, exprIsTrivial a = go (credit-1) f
- go credit (Tick _ e) = go credit e -- dubious
+ go credit (Tick _ e) = go credit e -- dubious
go credit (Cast e _) = go credit e
go _ (Var {}) = boringCxtOk
go _ _ = boringCxtNotOk
f x = g <refl> x
{-# INLINE g #-}
Currently we check for a type arg rather than isTyCoArg
. This in turn makes INLINE things look bigger than they should be, and stops them being inlined into boring contexts when they perfectly well could be. E.g.
f x = g <refl> x
{-# INLINE g #-}
....(map (f x) xs)....
The context is boring, so don't inline unconditionally. But f's rhs is no bigger than its call, provided you realise that the coercion argument is ultimately cost-free.
This happens in practice for $WHRefl
.
It's not a big deal: at most it means we have an extra function call overhead. But it's untidy, and actually worse than what happens without an INLINE pragma.
So, worth fixing. Perhaps a nofib-perf-test to check I haven't messed up.
Split out of !1381 (closed)