diff --git a/compiler/GHC/Core/Opt/Simplify/Monad.hs b/compiler/GHC/Core/Opt/Simplify/Monad.hs
index 5c111374c8bf6e524da6800444fa55c92442db03..3c05549ad5278f987577cb0031f3a82fa8fd60a3 100644
--- a/compiler/GHC/Core/Opt/Simplify/Monad.hs
+++ b/compiler/GHC/Core/Opt/Simplify/Monad.hs
@@ -43,6 +43,7 @@ import GHC.Utils.Panic (throwGhcExceptionIO, GhcException (..))
import GHC.Types.Basic ( IntWithInf, treatZeroAsInf, mkIntWithInf )
import Control.Monad ( ap )
import GHC.Core.Multiplicity ( pattern Many )
+import GHC.Exts( oneShot )
{-
************************************************************************
@@ -56,14 +57,25 @@ For the simplifier monad, we want to {\em thread} a unique supply and a counter.
-}
newtype SimplM result
- = SM { unSM :: SimplTopEnv -- Envt that does not change much
- -> UniqSupply -- We thread the unique supply because
- -- constantly splitting it is rather expensive
- -> SimplCount
- -> IO (result, UniqSupply, SimplCount)}
- -- we only need IO here for dump output
+ = SM' { unSM :: SimplTopEnv -- Envt that does not change much
+ -> UniqSupply -- We thread the unique supply because
+ -- constantly splitting it is rather expensive
+ -> SimplCount
+ -> IO (result, UniqSupply, SimplCount)}
+ -- We only need IO here for dump output
deriving (Functor)
+pattern SM :: (SimplTopEnv -> UniqSupply -> SimplCount
+ -> IO (result, UniqSupply, 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.Core.Unify
+pattern SM m <- SM' m
+ where
+ SM m = SM' (oneShot m)
+
data SimplTopEnv
= STE { st_flags :: DynFlags
, st_max_ticks :: IntWithInf -- Max #ticks in this simplifier run