Error calls in INLINE functions
Here is a function from testsuite/test/perf/compiler/SuperRecord.hs
{-# INLINE rcons #-}
rcons (_ := val) lts =
unsafePerformIO $! IO $ \s# ->
case newSmallArray# newSize# (error "No value") s# of
(# s'#, arr# #) ->
case recCopyInto (Proxy :: Proxy lts) lts (Proxy :: Proxy (Sort (l := t ': lts))) arr# s'# of
s''# ->
case writeSmallArray# arr# setAt# (unsafeCoerce# val) s''# of
s'''# ->
case unsafeFreezeSmallArray# arr# s'''# of
(# s''''#, a# #) -> (# s''''#, Rec a# #)
where
!(I# setAt#) =
fromIntegral (natVal' (proxy# :: Proxy# (RecVecIdxPos l (Sort (l := t ': lts)))))
newSize# = size# +# 1#
!(I# size#) = fromIntegral $ natVal' (proxy# :: Proxy# s)
That INLINE inlines a copy of the function at every call site, including the call to error "No value"
, which expands to this Core
(error
@LiftedRep
@Any
((GHC.Stack.Types.pushCallStack
(unpackCString# "error"#,
GHC.Stack.Types.SrcLoc
(unpackCString# "main"#)
(unpackCString# "SuperRecord"#)
(unpackCString# "SuperRecord.hs"#)
(GHC.Types.I# 106#)
(GHC.Types.I# 35#)
(GHC.Types.I# 106#)
(GHC.Types.I# 40#))
GHC.Stack.Types.emptyCallStack)
`cast` <Co:4> :: GHC.Stack.Types.CallStack
~R# (?callStack::GHC.Stack.Types.CallStack))
(unpackCString# "No value"#))
Since it's inside an INLINE unfolding (which promises to inline what the user wrote), it won't get floated out, so we just repeatedly duplicate this thing.
Silly. I can't see an easy way to avoid it (FloatOut doesn't look inside stable unfoldings), so I'm just recording it for now. Perhaps we should float bottoming expressions (and maybe other constants) out of INLINE unfoldings?