SimplM needs to be one-shot for both parameters
This is how SimplM
is currently defined:
newtype SimplM result
= SM' { unSM :: SimplTopEnv -- Envt that does not change much
-> SimplCount
-> IO (result, SimplCount)}
-- We only need IO here for dump output, but since we already have it
-- we might as well use it for uniques.
deriving (Functor)
pattern SM :: (SimplTopEnv -> SimplCount
-> IO (result, SimplCount))
-> SimplM result
-- This pattern synonym makes the simplifier monad eta-expand,
-- which as a very beneficial effect on compiler performance
-- (worth a 1-2% reduction in bytes-allocated). See #18202.
-- See Note [The one-shot state monad trick] in GHC.Utils.Monad
pattern SM m <- SM' m
where
SM m = SM' (oneShot m)
There are two problems:
- We derive the Functor instance, so it won't have the one-shot annotation
- That
oneShot
only applies to the first lambda, e.g.SimplTopEnv
.
I just looked at Core output for the Simplifier, where simplExpr1 :: SimplEnv -> CoreExpr -> SimplTopEnv -> SimplCount -> IO (CoreExpr, SimplCount)
isn't eta-expanded beyond the SimplTopEnv
, e.g. only has arity 3.
We'd better have SM m = SM' (oneShot $ \env -> oneShot $ \ct -> m env ct)
and define the Functor instance manually.