{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE DeriveFunctor #-}
module GHC.Core.Opt.Simplify.Monad (
SimplM,
initSmpl, traceSmpl,
getSimplRules, getFamEnvs,
MonadUnique(..), newId, newJoinId,
SimplCount, tick, freeTick, checkedTick,
getSimplCount, zeroSimplCount, pprSimplCount,
plusSimplCount, isZeroSimplCount
) where
import GHC.Prelude
import GHC.Types.Var ( Var, isId, mkLocalVar )
import GHC.Types.Name ( mkSystemVarName )
import GHC.Types.Id ( Id, mkSysLocalOrCoVar )
import GHC.Types.Id.Info ( IdDetails(..), vanillaIdInfo, setArityInfo )
import GHC.Core.Type ( Type, Mult )
import GHC.Core.FamInstEnv ( FamInstEnv )
import GHC.Core ( RuleEnv(..) )
import GHC.Core.Utils ( mkLamTypes )
import GHC.Types.Unique.Supply
import GHC.Driver.Session
import GHC.Core.Opt.Monad
import GHC.Utils.Outputable
import GHC.Data.FastString
import GHC.Utils.Monad
import GHC.Utils.Error as Err
import GHC.Utils.Misc ( count )
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 )
newtype SimplM result
= SM' { forall result.
SimplM result
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (result, UniqSupply, SimplCount)
unSM :: SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (result, UniqSupply, SimplCount)}
deriving ((forall a b. (a -> b) -> SimplM a -> SimplM b)
-> (forall a b. a -> SimplM b -> SimplM a) -> Functor SimplM
forall a b. a -> SimplM b -> SimplM a
forall a b. (a -> b) -> SimplM a -> SimplM b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> SimplM b -> SimplM a
$c<$ :: forall a b. a -> SimplM b -> SimplM a
fmap :: forall a b. (a -> b) -> SimplM a -> SimplM b
$cfmap :: forall a b. (a -> b) -> SimplM a -> SimplM b
Functor)
pattern SM :: (SimplTopEnv -> UniqSupply -> SimplCount
-> IO (result, UniqSupply, SimplCount))
-> SimplM result
pattern $mSM :: forall {r} {result}.
SimplM result
-> ((SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> r)
-> (Void# -> r)
-> r
$bSM :: forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM m <- SM' m
where
SM SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount)
m = (SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM' ((SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (result, UniqSupply, SimplCount)
oneShot SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount)
m)
data SimplTopEnv
= STE { SimplTopEnv -> DynFlags
st_flags :: DynFlags
, SimplTopEnv -> IntWithInf
st_max_ticks :: IntWithInf
, SimplTopEnv -> RuleEnv
st_rules :: RuleEnv
, SimplTopEnv -> (FamInstEnv, FamInstEnv)
st_fams :: (FamInstEnv, FamInstEnv) }
initSmpl :: DynFlags -> RuleEnv -> (FamInstEnv, FamInstEnv)
-> UniqSupply
-> Int
-> SimplM a
-> IO (a, SimplCount)
initSmpl :: forall a.
DynFlags
-> RuleEnv
-> (FamInstEnv, FamInstEnv)
-> UniqSupply
-> Int
-> SimplM a
-> IO (a, SimplCount)
initSmpl DynFlags
dflags RuleEnv
rules (FamInstEnv, FamInstEnv)
fam_envs UniqSupply
us Int
size SimplM a
m
= do (a
result, UniqSupply
_, SimplCount
count) <- SimplM a
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (a, UniqSupply, SimplCount)
forall result.
SimplM result
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (result, UniqSupply, SimplCount)
unSM SimplM a
m SimplTopEnv
env UniqSupply
us (DynFlags -> SimplCount
zeroSimplCount DynFlags
dflags)
(a, SimplCount) -> IO (a, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
result, SimplCount
count)
where
env :: SimplTopEnv
env = STE :: DynFlags
-> IntWithInf -> RuleEnv -> (FamInstEnv, FamInstEnv) -> SimplTopEnv
STE { st_flags :: DynFlags
st_flags = DynFlags
dflags, st_rules :: RuleEnv
st_rules = RuleEnv
rules
, st_max_ticks :: IntWithInf
st_max_ticks = DynFlags -> Int -> IntWithInf
computeMaxTicks DynFlags
dflags Int
size
, st_fams :: (FamInstEnv, FamInstEnv)
st_fams = (FamInstEnv, FamInstEnv)
fam_envs }
computeMaxTicks :: DynFlags -> Int -> IntWithInf
computeMaxTicks :: DynFlags -> Int -> IntWithInf
computeMaxTicks DynFlags
dflags Int
size
= Int -> IntWithInf
treatZeroAsInf (Int -> IntWithInf) -> Int -> IntWithInf
forall a b. (a -> b) -> a -> b
$
Integer -> Int
forall a. Num a => Integer -> a
fromInteger ((Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int
size Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
base_size)
Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int
tick_factor Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
magic_multiplier))
Integer -> Integer -> Integer
forall a. Integral a => a -> a -> a
`div` Integer
100)
where
tick_factor :: Int
tick_factor = DynFlags -> Int
simplTickFactor DynFlags
dflags
base_size :: Int
base_size = Int
100
magic_multiplier :: Int
magic_multiplier = Int
40
{-# INLINE thenSmpl #-}
{-# INLINE thenSmpl_ #-}
{-# INLINE returnSmpl #-}
instance Applicative SimplM where
pure :: forall a. a -> SimplM a
pure = a -> SimplM a
forall a. a -> SimplM a
returnSmpl
<*> :: forall a b. SimplM (a -> b) -> SimplM a -> SimplM b
(<*>) = SimplM (a -> b) -> SimplM a -> SimplM b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
*> :: forall a b. SimplM a -> SimplM b -> SimplM b
(*>) = SimplM a -> SimplM b -> SimplM b
forall a b. SimplM a -> SimplM b -> SimplM b
thenSmpl_
instance Monad SimplM where
>> :: forall a b. SimplM a -> SimplM b -> SimplM b
(>>) = SimplM a -> SimplM b -> SimplM b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
(*>)
>>= :: forall a b. SimplM a -> (a -> SimplM b) -> SimplM b
(>>=) = SimplM a -> (a -> SimplM b) -> SimplM b
forall a b. SimplM a -> (a -> SimplM b) -> SimplM b
thenSmpl
returnSmpl :: a -> SimplM a
returnSmpl :: forall a. a -> SimplM a
returnSmpl a
e = (SimplTopEnv
-> UniqSupply -> SimplCount -> IO (a, UniqSupply, SimplCount))
-> SimplM a
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
_st_env UniqSupply
us SimplCount
sc -> (a, UniqSupply, SimplCount) -> IO (a, UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
e, UniqSupply
us, SimplCount
sc))
thenSmpl :: SimplM a -> (a -> SimplM b) -> SimplM b
thenSmpl_ :: SimplM a -> SimplM b -> SimplM b
thenSmpl :: forall a b. SimplM a -> (a -> SimplM b) -> SimplM b
thenSmpl SimplM a
m a -> SimplM b
k
= (SimplTopEnv
-> UniqSupply -> SimplCount -> IO (b, UniqSupply, SimplCount))
-> SimplM b
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM ((SimplTopEnv
-> UniqSupply -> SimplCount -> IO (b, UniqSupply, SimplCount))
-> SimplM b)
-> (SimplTopEnv
-> UniqSupply -> SimplCount -> IO (b, UniqSupply, SimplCount))
-> SimplM b
forall a b. (a -> b) -> a -> b
$ \SimplTopEnv
st_env UniqSupply
us0 SimplCount
sc0 -> do
(a
m_result, UniqSupply
us1, SimplCount
sc1) <- SimplM a
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (a, UniqSupply, SimplCount)
forall result.
SimplM result
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (result, UniqSupply, SimplCount)
unSM SimplM a
m SimplTopEnv
st_env UniqSupply
us0 SimplCount
sc0
SimplM b
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (b, UniqSupply, SimplCount)
forall result.
SimplM result
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (result, UniqSupply, SimplCount)
unSM (a -> SimplM b
k a
m_result) SimplTopEnv
st_env UniqSupply
us1 SimplCount
sc1
thenSmpl_ :: forall a b. SimplM a -> SimplM b -> SimplM b
thenSmpl_ SimplM a
m SimplM b
k
= (SimplTopEnv
-> UniqSupply -> SimplCount -> IO (b, UniqSupply, SimplCount))
-> SimplM b
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM ((SimplTopEnv
-> UniqSupply -> SimplCount -> IO (b, UniqSupply, SimplCount))
-> SimplM b)
-> (SimplTopEnv
-> UniqSupply -> SimplCount -> IO (b, UniqSupply, SimplCount))
-> SimplM b
forall a b. (a -> b) -> a -> b
$ \SimplTopEnv
st_env UniqSupply
us0 SimplCount
sc0 -> do
(a
_, UniqSupply
us1, SimplCount
sc1) <- SimplM a
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (a, UniqSupply, SimplCount)
forall result.
SimplM result
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (result, UniqSupply, SimplCount)
unSM SimplM a
m SimplTopEnv
st_env UniqSupply
us0 SimplCount
sc0
SimplM b
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (b, UniqSupply, SimplCount)
forall result.
SimplM result
-> SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (result, UniqSupply, SimplCount)
unSM SimplM b
k SimplTopEnv
st_env UniqSupply
us1 SimplCount
sc1
traceSmpl :: String -> SDoc -> SimplM ()
traceSmpl :: String -> SDoc -> SimplM ()
traceSmpl String
herald SDoc
doc
= do { DynFlags
dflags <- SimplM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; IO () -> SimplM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> SimplM ()) -> IO () -> SimplM ()
forall a b. (a -> b) -> a -> b
$ DynFlags -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
Err.dumpIfSet_dyn DynFlags
dflags DumpFlag
Opt_D_dump_simpl_trace String
"Simpl Trace"
DumpFormat
FormatText
(SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text String
herald) Int
2 SDoc
doc) }
{-# INLINE traceSmpl #-}
instance MonadUnique SimplM where
getUniqueSupplyM :: SimplM UniqSupply
getUniqueSupplyM
= (SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (UniqSupply, UniqSupply, SimplCount))
-> SimplM UniqSupply
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
_st_env UniqSupply
us SimplCount
sc -> case UniqSupply -> (UniqSupply, UniqSupply)
splitUniqSupply UniqSupply
us of
(UniqSupply
us1, UniqSupply
us2) -> (UniqSupply, UniqSupply, SimplCount)
-> IO (UniqSupply, UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return (UniqSupply
us1, UniqSupply
us2, SimplCount
sc))
getUniqueM :: SimplM Unique
getUniqueM
= (SimplTopEnv
-> UniqSupply -> SimplCount -> IO (Unique, UniqSupply, SimplCount))
-> SimplM Unique
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
_st_env UniqSupply
us SimplCount
sc -> case UniqSupply -> (Unique, UniqSupply)
takeUniqFromSupply UniqSupply
us of
(Unique
u, UniqSupply
us') -> (Unique, UniqSupply, SimplCount)
-> IO (Unique, UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return (Unique
u, UniqSupply
us', SimplCount
sc))
getUniquesM :: SimplM [Unique]
getUniquesM
= (SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO ([Unique], UniqSupply, SimplCount))
-> SimplM [Unique]
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
_st_env UniqSupply
us SimplCount
sc -> case UniqSupply -> (UniqSupply, UniqSupply)
splitUniqSupply UniqSupply
us of
(UniqSupply
us1, UniqSupply
us2) -> ([Unique], UniqSupply, SimplCount)
-> IO ([Unique], UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return (UniqSupply -> [Unique]
uniqsFromSupply UniqSupply
us1, UniqSupply
us2, SimplCount
sc))
instance HasDynFlags SimplM where
getDynFlags :: SimplM DynFlags
getDynFlags = (SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (DynFlags, UniqSupply, SimplCount))
-> SimplM DynFlags
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
st_env UniqSupply
us SimplCount
sc -> (DynFlags, UniqSupply, SimplCount)
-> IO (DynFlags, UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplTopEnv -> DynFlags
st_flags SimplTopEnv
st_env, UniqSupply
us, SimplCount
sc))
instance MonadIO SimplM where
liftIO :: forall a. IO a -> SimplM a
liftIO IO a
m = (SimplTopEnv
-> UniqSupply -> SimplCount -> IO (a, UniqSupply, SimplCount))
-> SimplM a
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM ((SimplTopEnv
-> UniqSupply -> SimplCount -> IO (a, UniqSupply, SimplCount))
-> SimplM a)
-> (SimplTopEnv
-> UniqSupply -> SimplCount -> IO (a, UniqSupply, SimplCount))
-> SimplM a
forall a b. (a -> b) -> a -> b
$ \SimplTopEnv
_ UniqSupply
us SimplCount
sc -> do
a
x <- IO a
m
(a, UniqSupply, SimplCount) -> IO (a, UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
x, UniqSupply
us, SimplCount
sc)
getSimplRules :: SimplM RuleEnv
getSimplRules :: SimplM RuleEnv
getSimplRules = (SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (RuleEnv, UniqSupply, SimplCount))
-> SimplM RuleEnv
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
st_env UniqSupply
us SimplCount
sc -> (RuleEnv, UniqSupply, SimplCount)
-> IO (RuleEnv, UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplTopEnv -> RuleEnv
st_rules SimplTopEnv
st_env, UniqSupply
us, SimplCount
sc))
getFamEnvs :: SimplM (FamInstEnv, FamInstEnv)
getFamEnvs :: SimplM (FamInstEnv, FamInstEnv)
getFamEnvs = (SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO ((FamInstEnv, FamInstEnv), UniqSupply, SimplCount))
-> SimplM (FamInstEnv, FamInstEnv)
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
st_env UniqSupply
us SimplCount
sc -> ((FamInstEnv, FamInstEnv), UniqSupply, SimplCount)
-> IO ((FamInstEnv, FamInstEnv), UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplTopEnv -> (FamInstEnv, FamInstEnv)
st_fams SimplTopEnv
st_env, UniqSupply
us, SimplCount
sc))
newId :: FastString -> Mult -> Type -> SimplM Id
newId :: FastString -> Mult -> Mult -> SimplM Id
newId FastString
fs Mult
w Mult
ty = do Unique
uniq <- SimplM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
Id -> SimplM Id
forall (m :: * -> *) a. Monad m => a -> m a
return (FastString -> Unique -> Mult -> Mult -> Id
mkSysLocalOrCoVar FastString
fs Unique
uniq Mult
w Mult
ty)
newJoinId :: [Var] -> Type -> SimplM Id
newJoinId :: [Id] -> Mult -> SimplM Id
newJoinId [Id]
bndrs Mult
body_ty
= do { Unique
uniq <- SimplM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
; let name :: Name
name = Unique -> FastString -> Name
mkSystemVarName Unique
uniq (String -> FastString
fsLit String
"$j")
join_id_ty :: Mult
join_id_ty = [Id] -> Mult -> Mult
mkLamTypes [Id]
bndrs Mult
body_ty
arity :: Int
arity = (Id -> Bool) -> [Id] -> Int
forall a. (a -> Bool) -> [a] -> Int
count Id -> Bool
isId [Id]
bndrs
join_arity :: Int
join_arity = [Id] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Id]
bndrs
details :: IdDetails
details = Int -> IdDetails
JoinId Int
join_arity
id_info :: IdInfo
id_info = IdInfo
vanillaIdInfo IdInfo -> Int -> IdInfo
`setArityInfo` Int
arity
; Id -> SimplM Id
forall (m :: * -> *) a. Monad m => a -> m a
return (IdDetails -> Name -> Mult -> Mult -> IdInfo -> Id
mkLocalVar IdDetails
details Name
name Mult
Many Mult
join_id_ty IdInfo
id_info) }
getSimplCount :: SimplM SimplCount
getSimplCount :: SimplM SimplCount
getSimplCount = (SimplTopEnv
-> UniqSupply
-> SimplCount
-> IO (SimplCount, UniqSupply, SimplCount))
-> SimplM SimplCount
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
_st_env UniqSupply
us SimplCount
sc -> (SimplCount, UniqSupply, SimplCount)
-> IO (SimplCount, UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplCount
sc, UniqSupply
us, SimplCount
sc))
tick :: Tick -> SimplM ()
tick :: Tick -> SimplM ()
tick Tick
t = (SimplTopEnv
-> UniqSupply -> SimplCount -> IO ((), UniqSupply, SimplCount))
-> SimplM ()
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
st_env UniqSupply
us SimplCount
sc -> let sc' :: SimplCount
sc' = DynFlags -> Tick -> SimplCount -> SimplCount
doSimplTick (SimplTopEnv -> DynFlags
st_flags SimplTopEnv
st_env) Tick
t SimplCount
sc
in SimplCount
sc' SimplCount
-> IO ((), UniqSupply, SimplCount)
-> IO ((), UniqSupply, SimplCount)
`seq` ((), UniqSupply, SimplCount) -> IO ((), UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return ((), UniqSupply
us, SimplCount
sc'))
checkedTick :: Tick -> SimplM ()
checkedTick :: Tick -> SimplM ()
checkedTick Tick
t
= (SimplTopEnv
-> UniqSupply -> SimplCount -> IO ((), UniqSupply, SimplCount))
-> SimplM ()
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
st_env UniqSupply
us SimplCount
sc ->
if SimplTopEnv -> IntWithInf
st_max_ticks SimplTopEnv
st_env IntWithInf -> IntWithInf -> Bool
forall a. Ord a => a -> a -> Bool
<= Int -> IntWithInf
mkIntWithInf (SimplCount -> Int
simplCountN SimplCount
sc)
then GhcException -> IO ((), UniqSupply, SimplCount)
forall a. GhcException -> IO a
throwGhcExceptionIO (GhcException -> IO ((), UniqSupply, SimplCount))
-> GhcException -> IO ((), UniqSupply, SimplCount)
forall a b. (a -> b) -> a -> b
$
String -> SDoc -> GhcException
PprProgramError String
"Simplifier ticks exhausted" (SimplCount -> SDoc
msg SimplCount
sc)
else let sc' :: SimplCount
sc' = DynFlags -> Tick -> SimplCount -> SimplCount
doSimplTick (SimplTopEnv -> DynFlags
st_flags SimplTopEnv
st_env) Tick
t SimplCount
sc
in SimplCount
sc' SimplCount
-> IO ((), UniqSupply, SimplCount)
-> IO ((), UniqSupply, SimplCount)
`seq` ((), UniqSupply, SimplCount) -> IO ((), UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return ((), UniqSupply
us, SimplCount
sc'))
where
msg :: SimplCount -> SDoc
msg SimplCount
sc = [SDoc] -> SDoc
vcat
[ String -> SDoc
text String
"When trying" SDoc -> SDoc -> SDoc
<+> Tick -> SDoc
forall a. Outputable a => a -> SDoc
ppr Tick
t
, String -> SDoc
text String
"To increase the limit, use -fsimpl-tick-factor=N (default 100)."
, SDoc
space
, String -> SDoc
text String
"If you need to increase the limit substantially, please file a"
, String -> SDoc
text String
"bug report and indicate the factor you needed."
, SDoc
space
, String -> SDoc
text String
"If GHC was unable to complete compilation even"
SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"with a very large factor"
, String -> SDoc
text String
"(a thousand or more), please consult the"
SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
doubleQuotes (String -> SDoc
text String
"Known bugs or infelicities")
, String -> SDoc
text String
"section in the Users Guide before filing a report. There are a"
, String -> SDoc
text String
"few situations unlikely to occur in practical programs for which"
, String -> SDoc
text String
"simplifier non-termination has been judged acceptable."
, SDoc
space
, SimplCount -> SDoc
pp_details SimplCount
sc
, SimplCount -> SDoc
pprSimplCount SimplCount
sc ]
pp_details :: SimplCount -> SDoc
pp_details SimplCount
sc
| SimplCount -> Bool
hasDetailedCounts SimplCount
sc = SDoc
empty
| Bool
otherwise = String -> SDoc
text String
"To see detailed counts use -ddump-simpl-stats"
freeTick :: Tick -> SimplM ()
freeTick :: Tick -> SimplM ()
freeTick Tick
t
= (SimplTopEnv
-> UniqSupply -> SimplCount -> IO ((), UniqSupply, SimplCount))
-> SimplM ()
forall result.
(SimplTopEnv
-> UniqSupply -> SimplCount -> IO (result, UniqSupply, SimplCount))
-> SimplM result
SM (\SimplTopEnv
_st_env UniqSupply
us SimplCount
sc -> let sc' :: SimplCount
sc' = Tick -> SimplCount -> SimplCount
doFreeSimplTick Tick
t SimplCount
sc
in SimplCount
sc' SimplCount
-> IO ((), UniqSupply, SimplCount)
-> IO ((), UniqSupply, SimplCount)
`seq` ((), UniqSupply, SimplCount) -> IO ((), UniqSupply, SimplCount)
forall (m :: * -> *) a. Monad m => a -> m a
return ((), UniqSupply
us, SimplCount
sc'))