module UHC.Light.Compiler.CodeGen.TrfUtils
( TrfState (..), mkEmptyTrfState
, runTrf
, liftTrfModPlain
, liftCheckMod
, liftTrfModWithState
, liftTrfModWithStateExtra
, liftTrfWithExtraInfo
, modifyGets )
where
import qualified Data.Map as Map
import qualified Data.Set as Set
import Control.Monad
import Control.Monad.State.Strict
import Control.Monad.Reader
import UHC.Light.Compiler.Base.Target
import UHC.Light.Compiler.Base.Optimize
import UHC.Light.Compiler.EHC.Common
data TrfReader
= TrfReader
{ trfrdMustDump :: EHCOpts -> Bool
, trfrdCanDoOptScope :: [OptimizationScope] -> Bool
, trfrdOpts :: EHCOpts
, trfrdModNm :: HsName
}
data TrfState
mod
extra
= TrfState
{ trfstMod :: !mod
, trfstModStages :: [(String,Maybe mod,ErrL)]
, trfstUniq :: !UID
, trfstExtra :: extra
}
mkEmptyTrfState :: mod -> extra -> TrfState mod extra
mkEmptyTrfState m e = TrfState m [] uidStart e
type TrfM mod extra = ReaderT TrfReader (State (TrfState mod extra))
instance MonadFreshUID (TrfM mod extra) where
freshInfUID = modifyGets $ \s@(TrfState{trfstUniq=u}) ->
let (n,h) = mkNewLevUID u
in (h,s {trfstUniq = n})
runTrf
:: EHCOpts
-> HsName
-> (EHCOpts -> Bool)
-> ([OptimizationScope] -> Bool)
-> TrfState mod extra
-> (TrfM mod extra ())
-> TrfState mod extra
runTrf opts modNm mustDump canDoWRTOptScope trfst trf
= execState (runReaderT trf (TrfReader mustDump canDoWRTOptScope opts modNm)) trfst
liftTrfModPlain
:: (MonadState (TrfState mod extra) m, MonadReader TrfReader m) =>
[OptimizationScope]
-> String
-> (mod -> mod)
-> m ()
liftTrfModPlain os nm t
= liftTrfWithExtraInfo os nm (flip const) (\_ c -> (Just $ t c,(),[]))
liftCheckMod
:: (MonadState (TrfState mod extra) m, MonadReader TrfReader m) =>
[OptimizationScope]
-> String
-> (TrfState mod extra -> mod -> ErrL)
-> m ()
liftCheckMod os nm t
= liftTrfWithExtraInfo os nm (flip const) (\s c -> let e = t s c in (Nothing,(),e))
liftTrfModWithState
:: (MonadState (TrfState mod extra) m, MonadReader TrfReader m) =>
[OptimizationScope]
-> String
-> (TrfState mod extra -> mod -> mod)
-> m ()
liftTrfModWithState os nm t
= liftTrfWithExtraInfo os nm (flip const) (\s c -> (Just $ t s c,(),[]))
liftTrfModWithStateExtra
:: (MonadState (TrfState mod extra) m, MonadReader TrfReader m) =>
[OptimizationScope]
-> String
-> (t -> TrfState mod extra -> TrfState mod extra)
-> (TrfState mod extra -> mod -> (mod,t))
-> m ()
liftTrfModWithStateExtra os nm update2 t
= liftTrfWithExtraInfo os nm update2 (\s c -> let (c',e) = t s c in (Just c',e,[]))
liftTrfWithExtraInfo
:: (MonadState (TrfState mod extra) m, MonadReader TrfReader m) =>
[OptimizationScope]
-> String
-> (t -> TrfState mod extra -> TrfState mod extra)
-> (TrfState mod extra -> mod -> (Maybe mod, t, ErrL))
-> m ()
liftTrfWithExtraInfo os nm update2 t = do
canDoWRTOptScope <- asks trfrdCanDoOptScope
opts <- asks trfrdOpts
if canDoWRTOptScope os
then do
mustDump <- asks trfrdMustDump
modify $ \s@(TrfState{trfstMod=c, trfstModStages=stages}) ->
let (c',extra,errl) = t s c
in update2 extra
$ s { trfstMod = maybe c id c'
, trfstModStages = stages ++ [(nm,if mustDump opts then c' else Nothing,errl)]
}
else return ()
modifyGets :: MonadState s m => (s -> (a,s)) -> m a
modifyGets update
= do { s <- get
; let (x,s') = update s
; put s'
; return x
}