Skip to content

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:

  1. We derive the Functor instance, so it won't have the one-shot annotation
  2. 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.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information