{-# LANGUAGE BangPatterns, CPP, MultiWayIf #-}
module CorePrep (
corePrepPgm, corePrepExpr, cvtLitInteger, cvtLitNatural,
lookupMkIntegerName, lookupIntegerSDataConName,
lookupMkNaturalName, lookupNaturalSDataConName
) where
#include "HsVersions.h"
import GhcPrelude
import OccurAnal
import HscTypes
import PrelNames
import MkId ( realWorldPrimId )
import CoreUtils
import CoreArity
import CoreFVs
import CoreMonad ( CoreToDo(..) )
import CoreLint ( endPassIO )
import CoreSyn
import CoreSubst
import MkCore hiding( FloatBind(..) )
import Type
import Literal
import Coercion
import TcEnv
import TyCon
import Demand
import Var
import VarSet
import VarEnv
import Id
import IdInfo
import TysWiredIn
import DataCon
import BasicTypes
import Module
import UniqSupply
import Maybes
import OrdList
import ErrUtils
import DynFlags
import Util
import Pair
import Outputable
import Platform
import FastString
import Config
import Name ( NamedThing(..), nameSrcSpan )
import SrcLoc ( SrcSpan(..), realSrcLocSpan, mkRealSrcLoc )
import Data.Bits
import MonadUtils ( mapAccumLM )
import Data.List ( mapAccumL )
import Control.Monad
import CostCentre ( CostCentre, ccFromThisModule )
import qualified Data.Set as S
type CpeArg = CoreExpr
type CpeApp = CoreExpr
type CpeBody = CoreExpr
type CpeRhs = CoreExpr
corePrepPgm :: HscEnv -> Module -> ModLocation -> CoreProgram -> [TyCon]
-> IO (CoreProgram, S.Set CostCentre)
corePrepPgm :: HscEnv
-> Module
-> ModLocation
-> CoreProgram
-> [TyCon]
-> IO (CoreProgram, Set CostCentre)
corePrepPgm hsc_env :: HscEnv
hsc_env this_mod :: Module
this_mod mod_loc :: ModLocation
mod_loc binds :: CoreProgram
binds data_tycons :: [TyCon]
data_tycons =
IO DynFlags
-> SDoc
-> ((CoreProgram, Set CostCentre) -> ())
-> IO (CoreProgram, Set CostCentre)
-> IO (CoreProgram, Set CostCentre)
forall (m :: * -> *) a.
MonadIO m =>
m DynFlags -> SDoc -> (a -> ()) -> m a -> m a
withTiming (DynFlags -> IO DynFlags
forall (f :: * -> *) a. Applicative f => a -> f a
pure DynFlags
dflags)
(String -> SDoc
text "CorePrep"SDoc -> SDoc -> SDoc
<+>SDoc -> SDoc
brackets (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
this_mod))
(() -> (CoreProgram, Set CostCentre) -> ()
forall a b. a -> b -> a
const ()) (IO (CoreProgram, Set CostCentre)
-> IO (CoreProgram, Set CostCentre))
-> IO (CoreProgram, Set CostCentre)
-> IO (CoreProgram, Set CostCentre)
forall a b. (a -> b) -> a -> b
$ do
UniqSupply
us <- Char -> IO UniqSupply
mkSplitUniqSupply 's'
CorePrepEnv
initialCorePrepEnv <- DynFlags -> HscEnv -> IO CorePrepEnv
mkInitialCorePrepEnv DynFlags
dflags HscEnv
hsc_env
let cost_centres :: Set CostCentre
cost_centres
| Way
WayProf Way -> [Way] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` DynFlags -> [Way]
ways DynFlags
dflags
= Module -> CoreProgram -> Set CostCentre
collectCostCentres Module
this_mod CoreProgram
binds
| Bool
otherwise
= Set CostCentre
forall a. Set a
S.empty
implicit_binds :: CoreProgram
implicit_binds = DynFlags -> ModLocation -> [TyCon] -> CoreProgram
mkDataConWorkers DynFlags
dflags ModLocation
mod_loc [TyCon]
data_tycons
binds_out :: CoreProgram
binds_out = UniqSupply -> UniqSM CoreProgram -> CoreProgram
forall a. UniqSupply -> UniqSM a -> a
initUs_ UniqSupply
us (UniqSM CoreProgram -> CoreProgram)
-> UniqSM CoreProgram -> CoreProgram
forall a b. (a -> b) -> a -> b
$ do
Floats
floats1 <- CorePrepEnv -> CoreProgram -> UniqSM Floats
corePrepTopBinds CorePrepEnv
initialCorePrepEnv CoreProgram
binds
Floats
floats2 <- CorePrepEnv -> CoreProgram -> UniqSM Floats
corePrepTopBinds CorePrepEnv
initialCorePrepEnv CoreProgram
implicit_binds
CoreProgram -> UniqSM CoreProgram
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats -> CoreProgram
deFloatTop (Floats
floats1 Floats -> Floats -> Floats
`appendFloats` Floats
floats2))
HscEnv
-> PrintUnqualified
-> CoreToDo
-> CoreProgram
-> [CoreRule]
-> IO ()
endPassIO HscEnv
hsc_env PrintUnqualified
alwaysQualify CoreToDo
CorePrep CoreProgram
binds_out []
(CoreProgram, Set CostCentre) -> IO (CoreProgram, Set CostCentre)
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreProgram
binds_out, Set CostCentre
cost_centres)
where
dflags :: DynFlags
dflags = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
corePrepExpr :: DynFlags -> HscEnv -> CoreExpr -> IO CoreExpr
corePrepExpr :: DynFlags -> HscEnv -> CoreExpr -> IO CoreExpr
corePrepExpr dflags :: DynFlags
dflags hsc_env :: HscEnv
hsc_env expr :: CoreExpr
expr =
IO DynFlags
-> SDoc -> (CoreExpr -> ()) -> IO CoreExpr -> IO CoreExpr
forall (m :: * -> *) a.
MonadIO m =>
m DynFlags -> SDoc -> (a -> ()) -> m a -> m a
withTiming (DynFlags -> IO DynFlags
forall (f :: * -> *) a. Applicative f => a -> f a
pure DynFlags
dflags) (String -> SDoc
text "CorePrep [expr]") (() -> CoreExpr -> ()
forall a b. a -> b -> a
const ()) (IO CoreExpr -> IO CoreExpr) -> IO CoreExpr -> IO CoreExpr
forall a b. (a -> b) -> a -> b
$ do
UniqSupply
us <- Char -> IO UniqSupply
mkSplitUniqSupply 's'
CorePrepEnv
initialCorePrepEnv <- DynFlags -> HscEnv -> IO CorePrepEnv
mkInitialCorePrepEnv DynFlags
dflags HscEnv
hsc_env
let new_expr :: CoreExpr
new_expr = UniqSupply -> UniqSM CoreExpr -> CoreExpr
forall a. UniqSupply -> UniqSM a -> a
initUs_ UniqSupply
us (CorePrepEnv -> CoreExpr -> UniqSM CoreExpr
cpeBodyNF CorePrepEnv
initialCorePrepEnv CoreExpr
expr)
DynFlags -> DumpFlag -> String -> SDoc -> IO ()
dumpIfSet_dyn DynFlags
dflags DumpFlag
Opt_D_dump_prep "CorePrep" (CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
new_expr)
CoreExpr -> IO CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
new_expr
corePrepTopBinds :: CorePrepEnv -> [CoreBind] -> UniqSM Floats
corePrepTopBinds :: CorePrepEnv -> CoreProgram -> UniqSM Floats
corePrepTopBinds initialCorePrepEnv :: CorePrepEnv
initialCorePrepEnv binds :: CoreProgram
binds
= CorePrepEnv -> CoreProgram -> UniqSM Floats
go CorePrepEnv
initialCorePrepEnv CoreProgram
binds
where
go :: CorePrepEnv -> CoreProgram -> UniqSM Floats
go _ [] = Floats -> UniqSM Floats
forall (m :: * -> *) a. Monad m => a -> m a
return Floats
emptyFloats
go env :: CorePrepEnv
env (bind :: CoreBind
bind : binds :: CoreProgram
binds) = do (env' :: CorePrepEnv
env', floats :: Floats
floats, maybe_new_bind :: Maybe CoreBind
maybe_new_bind)
<- TopLevelFlag
-> CorePrepEnv
-> CoreBind
-> UniqSM (CorePrepEnv, Floats, Maybe CoreBind)
cpeBind TopLevelFlag
TopLevel CorePrepEnv
env CoreBind
bind
MASSERT(isNothing maybe_new_bind)
Floats
floatss <- CorePrepEnv -> CoreProgram -> UniqSM Floats
go CorePrepEnv
env' CoreProgram
binds
Floats -> UniqSM Floats
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats Floats -> Floats -> Floats
`appendFloats` Floats
floatss)
mkDataConWorkers :: DynFlags -> ModLocation -> [TyCon] -> [CoreBind]
mkDataConWorkers :: DynFlags -> ModLocation -> [TyCon] -> CoreProgram
mkDataConWorkers dflags :: DynFlags
dflags mod_loc :: ModLocation
mod_loc data_tycons :: [TyCon]
data_tycons
= [ Id -> CoreExpr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec Id
id (Name -> CoreExpr -> CoreExpr
forall b. Name -> Expr b -> Expr b
tick_it (DataCon -> Name
forall a. NamedThing a => a -> Name
getName DataCon
data_con) (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
id))
| TyCon
tycon <- [TyCon]
data_tycons,
DataCon
data_con <- TyCon -> [DataCon]
tyConDataCons TyCon
tycon,
let id :: Id
id = DataCon -> Id
dataConWorkId DataCon
data_con
]
where
tick_it :: Name -> Expr b -> Expr b
tick_it name :: Name
name
| DynFlags -> Int
debugLevel DynFlags
dflags Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 = Expr b -> Expr b
forall a. a -> a
id
| RealSrcSpan span :: RealSrcSpan
span <- Name -> SrcSpan
nameSrcSpan Name
name = RealSrcSpan -> Expr b -> Expr b
forall b. RealSrcSpan -> Expr b -> Expr b
tick RealSrcSpan
span
| Just file :: String
file <- ModLocation -> Maybe String
ml_hs_file ModLocation
mod_loc = RealSrcSpan -> Expr b -> Expr b
forall b. RealSrcSpan -> Expr b -> Expr b
tick (String -> RealSrcSpan
span1 String
file)
| Bool
otherwise = RealSrcSpan -> Expr b -> Expr b
forall b. RealSrcSpan -> Expr b -> Expr b
tick (String -> RealSrcSpan
span1 "???")
where tick :: RealSrcSpan -> Expr b -> Expr b
tick span :: RealSrcSpan
span = Tickish Id -> Expr b -> Expr b
forall b. Tickish Id -> Expr b -> Expr b
Tick (RealSrcSpan -> String -> Tickish Id
forall id. RealSrcSpan -> String -> Tickish id
SourceNote RealSrcSpan
span (String -> Tickish Id) -> String -> Tickish Id
forall a b. (a -> b) -> a -> b
$ DynFlags -> SDoc -> String
showSDoc DynFlags
dflags (Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
name))
span1 :: String -> RealSrcSpan
span1 file :: String
file = RealSrcLoc -> RealSrcSpan
realSrcLocSpan (RealSrcLoc -> RealSrcSpan) -> RealSrcLoc -> RealSrcSpan
forall a b. (a -> b) -> a -> b
$ FastString -> Int -> Int -> RealSrcLoc
mkRealSrcLoc (String -> FastString
mkFastString String
file) 1 1
cpeBind :: TopLevelFlag -> CorePrepEnv -> CoreBind
-> UniqSM (CorePrepEnv,
Floats,
Maybe CoreBind)
cpeBind :: TopLevelFlag
-> CorePrepEnv
-> CoreBind
-> UniqSM (CorePrepEnv, Floats, Maybe CoreBind)
cpeBind top_lvl :: TopLevelFlag
top_lvl env :: CorePrepEnv
env (NonRec bndr :: Id
bndr rhs :: CoreExpr
rhs)
| Bool -> Bool
not (Id -> Bool
isJoinId Id
bndr)
= do { (_, bndr1 :: Id
bndr1) <- CorePrepEnv -> Id -> UniqSM (CorePrepEnv, Id)
cpCloneBndr CorePrepEnv
env Id
bndr
; let dmd :: Demand
dmd = Id -> Demand
idDemandInfo Id
bndr
is_unlifted :: Bool
is_unlifted = HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType (Id -> Type
idType Id
bndr)
; (floats :: Floats
floats, rhs1 :: CoreExpr
rhs1) <- TopLevelFlag
-> RecFlag
-> Demand
-> Bool
-> CorePrepEnv
-> Id
-> CoreExpr
-> UniqSM (Floats, CoreExpr)
cpePair TopLevelFlag
top_lvl RecFlag
NonRecursive
Demand
dmd Bool
is_unlifted
CorePrepEnv
env Id
bndr1 CoreExpr
rhs
; if CoreExpr -> Bool
exprIsTrivial CoreExpr
rhs1 Bool -> Bool -> Bool
&& TopLevelFlag -> Bool
isNotTopLevel TopLevelFlag
top_lvl
then (CorePrepEnv, Floats, Maybe CoreBind)
-> UniqSM (CorePrepEnv, Floats, Maybe CoreBind)
forall (m :: * -> *) a. Monad m => a -> m a
return (CorePrepEnv -> Id -> CoreExpr -> CorePrepEnv
extendCorePrepEnvExpr CorePrepEnv
env Id
bndr CoreExpr
rhs1, Floats
floats, Maybe CoreBind
forall a. Maybe a
Nothing)
else do {
; let new_float :: FloatingBind
new_float = Demand -> Bool -> Id -> CoreExpr -> FloatingBind
mkFloat Demand
dmd Bool
is_unlifted Id
bndr1 CoreExpr
rhs1
; (CorePrepEnv, Floats, Maybe CoreBind)
-> UniqSM (CorePrepEnv, Floats, Maybe CoreBind)
forall (m :: * -> *) a. Monad m => a -> m a
return (CorePrepEnv -> Id -> Id -> CorePrepEnv
extendCorePrepEnv CorePrepEnv
env Id
bndr Id
bndr1,
Floats -> FloatingBind -> Floats
addFloat Floats
floats FloatingBind
new_float,
Maybe CoreBind
forall a. Maybe a
Nothing) }}
| Bool
otherwise
= ASSERT(not (isTopLevel top_lvl))
do { (_, bndr1 :: Id
bndr1) <- CorePrepEnv -> Id -> UniqSM (CorePrepEnv, Id)
cpCloneBndr CorePrepEnv
env Id
bndr
; (bndr2 :: Id
bndr2, rhs1 :: CoreExpr
rhs1) <- CorePrepEnv -> Id -> CoreExpr -> UniqSM (Id, CoreExpr)
cpeJoinPair CorePrepEnv
env Id
bndr1 CoreExpr
rhs
; (CorePrepEnv, Floats, Maybe CoreBind)
-> UniqSM (CorePrepEnv, Floats, Maybe CoreBind)
forall (m :: * -> *) a. Monad m => a -> m a
return (CorePrepEnv -> Id -> Id -> CorePrepEnv
extendCorePrepEnv CorePrepEnv
env Id
bndr Id
bndr2,
Floats
emptyFloats,
CoreBind -> Maybe CoreBind
forall a. a -> Maybe a
Just (Id -> CoreExpr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec Id
bndr2 CoreExpr
rhs1)) }
cpeBind top_lvl :: TopLevelFlag
top_lvl env :: CorePrepEnv
env (Rec pairs :: [(Id, CoreExpr)]
pairs)
| Bool -> Bool
not (Id -> Bool
isJoinId ([Id] -> Id
forall a. [a] -> a
head [Id]
bndrs))
= do { (env' :: CorePrepEnv
env', bndrs1 :: [Id]
bndrs1) <- CorePrepEnv -> [Id] -> UniqSM (CorePrepEnv, [Id])
cpCloneBndrs CorePrepEnv
env [Id]
bndrs
; [(Floats, CoreExpr)]
stuff <- (Id -> CoreExpr -> UniqSM (Floats, CoreExpr))
-> [Id] -> [CoreExpr] -> UniqSM [(Floats, CoreExpr)]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (TopLevelFlag
-> RecFlag
-> Demand
-> Bool
-> CorePrepEnv
-> Id
-> CoreExpr
-> UniqSM (Floats, CoreExpr)
cpePair TopLevelFlag
top_lvl RecFlag
Recursive Demand
topDmd Bool
False CorePrepEnv
env')
[Id]
bndrs1 [CoreExpr]
rhss
; let (floats_s :: [Floats]
floats_s, rhss1 :: [CoreExpr]
rhss1) = [(Floats, CoreExpr)] -> ([Floats], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Floats, CoreExpr)]
stuff
all_pairs :: [(Id, CoreExpr)]
all_pairs = (FloatingBind -> [(Id, CoreExpr)] -> [(Id, CoreExpr)])
-> [(Id, CoreExpr)] -> OrdList FloatingBind -> [(Id, CoreExpr)]
forall a b. (a -> b -> b) -> b -> OrdList a -> b
foldrOL FloatingBind -> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
add_float ([Id]
bndrs1 [Id] -> [CoreExpr] -> [(Id, CoreExpr)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [CoreExpr]
rhss1)
([Floats] -> OrdList FloatingBind
concatFloats [Floats]
floats_s)
; (CorePrepEnv, Floats, Maybe CoreBind)
-> UniqSM (CorePrepEnv, Floats, Maybe CoreBind)
forall (m :: * -> *) a. Monad m => a -> m a
return (CorePrepEnv -> [(Id, Id)] -> CorePrepEnv
extendCorePrepEnvList CorePrepEnv
env ([Id]
bndrs [Id] -> [Id] -> [(Id, Id)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [Id]
bndrs1),
FloatingBind -> Floats
unitFloat (CoreBind -> FloatingBind
FloatLet ([(Id, CoreExpr)] -> CoreBind
forall b. [(b, Expr b)] -> Bind b
Rec [(Id, CoreExpr)]
all_pairs)),
Maybe CoreBind
forall a. Maybe a
Nothing) }
| Bool
otherwise
= do { (env' :: CorePrepEnv
env', bndrs1 :: [Id]
bndrs1) <- CorePrepEnv -> [Id] -> UniqSM (CorePrepEnv, [Id])
cpCloneBndrs CorePrepEnv
env [Id]
bndrs
; [(Id, CoreExpr)]
pairs1 <- (Id -> CoreExpr -> UniqSM (Id, CoreExpr))
-> [Id] -> [CoreExpr] -> UniqSM [(Id, CoreExpr)]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (CorePrepEnv -> Id -> CoreExpr -> UniqSM (Id, CoreExpr)
cpeJoinPair CorePrepEnv
env') [Id]
bndrs1 [CoreExpr]
rhss
; let bndrs2 :: [Id]
bndrs2 = ((Id, CoreExpr) -> Id) -> [(Id, CoreExpr)] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (Id, CoreExpr) -> Id
forall a b. (a, b) -> a
fst [(Id, CoreExpr)]
pairs1
; (CorePrepEnv, Floats, Maybe CoreBind)
-> UniqSM (CorePrepEnv, Floats, Maybe CoreBind)
forall (m :: * -> *) a. Monad m => a -> m a
return (CorePrepEnv -> [(Id, Id)] -> CorePrepEnv
extendCorePrepEnvList CorePrepEnv
env' ([Id]
bndrs [Id] -> [Id] -> [(Id, Id)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [Id]
bndrs2),
Floats
emptyFloats,
CoreBind -> Maybe CoreBind
forall a. a -> Maybe a
Just ([(Id, CoreExpr)] -> CoreBind
forall b. [(b, Expr b)] -> Bind b
Rec [(Id, CoreExpr)]
pairs1)) }
where
(bndrs :: [Id]
bndrs, rhss :: [CoreExpr]
rhss) = [(Id, CoreExpr)] -> ([Id], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Id, CoreExpr)]
pairs
add_float :: FloatingBind -> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
add_float (FloatLet (NonRec b :: Id
b r :: CoreExpr
r)) prs2 :: [(Id, CoreExpr)]
prs2 = (Id
b,CoreExpr
r) (Id, CoreExpr) -> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
forall a. a -> [a] -> [a]
: [(Id, CoreExpr)]
prs2
add_float (FloatLet (Rec prs1 :: [(Id, CoreExpr)]
prs1)) prs2 :: [(Id, CoreExpr)]
prs2 = [(Id, CoreExpr)]
prs1 [(Id, CoreExpr)] -> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
forall a. [a] -> [a] -> [a]
++ [(Id, CoreExpr)]
prs2
add_float b :: FloatingBind
b _ = String -> SDoc -> [(Id, CoreExpr)]
forall a. HasCallStack => String -> SDoc -> a
pprPanic "cpeBind" (FloatingBind -> SDoc
forall a. Outputable a => a -> SDoc
ppr FloatingBind
b)
cpePair :: TopLevelFlag -> RecFlag -> Demand -> Bool
-> CorePrepEnv -> OutId -> CoreExpr
-> UniqSM (Floats, CpeRhs)
cpePair :: TopLevelFlag
-> RecFlag
-> Demand
-> Bool
-> CorePrepEnv
-> Id
-> CoreExpr
-> UniqSM (Floats, CoreExpr)
cpePair top_lvl :: TopLevelFlag
top_lvl is_rec :: RecFlag
is_rec dmd :: Demand
dmd is_unlifted :: Bool
is_unlifted env :: CorePrepEnv
env bndr :: Id
bndr rhs :: CoreExpr
rhs
= ASSERT(not (isJoinId bndr))
do { (floats1 :: Floats
floats1, rhs1 :: CoreExpr
rhs1) <- CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeRhsE CorePrepEnv
env CoreExpr
rhs
; (floats2 :: Floats
floats2, rhs2 :: CoreExpr
rhs2) <- Floats -> CoreExpr -> UniqSM (Floats, CoreExpr)
float_from_rhs Floats
floats1 CoreExpr
rhs1
; (floats3 :: Floats
floats3, rhs3 :: CoreExpr
rhs3)
<- if CoreExpr -> Int
manifestArity CoreExpr
rhs1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
arity
then (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats2, Int -> CoreExpr -> CoreExpr
cpeEtaExpand Int
arity CoreExpr
rhs2)
else WARN(True, text "CorePrep: silly extra arguments:" <+> ppr bndr)
(do { Id
v <- Type -> UniqSM Id
newVar (Id -> Type
idType Id
bndr)
; let float :: FloatingBind
float = Demand -> Bool -> Id -> CoreExpr -> FloatingBind
mkFloat Demand
topDmd Bool
False Id
v CoreExpr
rhs2
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return ( Floats -> FloatingBind -> Floats
addFloat Floats
floats2 FloatingBind
float
, Int -> CoreExpr -> CoreExpr
cpeEtaExpand Int
arity (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
v)) })
; let (floats4 :: Floats
floats4, rhs4 :: CoreExpr
rhs4) = Floats -> CoreExpr -> (Floats, CoreExpr)
wrapTicks Floats
floats3 CoreExpr
rhs3
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats4, CoreExpr
rhs4) }
where
platform :: Platform
platform = DynFlags -> Platform
targetPlatform (CorePrepEnv -> DynFlags
cpe_dynFlags CorePrepEnv
env)
arity :: Int
arity = Id -> Int
idArity Id
bndr
float_from_rhs :: Floats -> CoreExpr -> UniqSM (Floats, CoreExpr)
float_from_rhs floats :: Floats
floats rhs :: CoreExpr
rhs
| Floats -> Bool
isEmptyFloats Floats
floats = (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
emptyFloats, CoreExpr
rhs)
| TopLevelFlag -> Bool
isTopLevel TopLevelFlag
top_lvl = Floats -> CoreExpr -> UniqSM (Floats, CoreExpr)
float_top Floats
floats CoreExpr
rhs
| Bool
otherwise = Floats -> CoreExpr -> UniqSM (Floats, CoreExpr)
float_nested Floats
floats CoreExpr
rhs
float_nested :: Floats -> CoreExpr -> UniqSM (Floats, CoreExpr)
float_nested floats :: Floats
floats rhs :: CoreExpr
rhs
| RecFlag -> Demand -> Bool -> Floats -> CoreExpr -> Bool
wantFloatNested RecFlag
is_rec Demand
dmd Bool
is_unlifted Floats
floats CoreExpr
rhs
= (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats, CoreExpr
rhs)
| Bool
otherwise = Floats -> CoreExpr -> UniqSM (Floats, CoreExpr)
dontFloat Floats
floats CoreExpr
rhs
float_top :: Floats -> CoreExpr -> UniqSM (Floats, CoreExpr)
float_top floats :: Floats
floats rhs :: CoreExpr
rhs
| CafInfo -> Bool
mayHaveCafRefs (Id -> CafInfo
idCafInfo Id
bndr)
, Floats -> Bool
allLazyTop Floats
floats
= (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats, CoreExpr
rhs)
| Just (floats' :: Floats
floats', rhs' :: CoreExpr
rhs') <- Platform -> Floats -> CoreExpr -> Maybe (Floats, CoreExpr)
canFloatFromNoCaf Platform
platform Floats
floats CoreExpr
rhs
= (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats', CoreExpr
rhs')
| Bool
otherwise
= Floats -> CoreExpr -> UniqSM (Floats, CoreExpr)
dontFloat Floats
floats CoreExpr
rhs
dontFloat :: Floats -> CpeRhs -> UniqSM (Floats, CpeBody)
dontFloat :: Floats -> CoreExpr -> UniqSM (Floats, CoreExpr)
dontFloat floats1 :: Floats
floats1 rhs :: CoreExpr
rhs
= do { (floats2 :: Floats
floats2, body :: CoreExpr
body) <- CoreExpr -> UniqSM (Floats, CoreExpr)
rhsToBody CoreExpr
rhs
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
emptyFloats, Floats -> CoreExpr -> CoreExpr
wrapBinds Floats
floats1 (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$
Floats -> CoreExpr -> CoreExpr
wrapBinds Floats
floats2 CoreExpr
body) }
cpeJoinPair :: CorePrepEnv -> JoinId -> CoreExpr
-> UniqSM (JoinId, CpeRhs)
cpeJoinPair :: CorePrepEnv -> Id -> CoreExpr -> UniqSM (Id, CoreExpr)
cpeJoinPair env :: CorePrepEnv
env bndr :: Id
bndr rhs :: CoreExpr
rhs
= ASSERT(isJoinId bndr)
do { let Just join_arity :: Int
join_arity = Id -> Maybe Int
isJoinId_maybe Id
bndr
(bndrs :: [Id]
bndrs, body :: CoreExpr
body) = Int -> CoreExpr -> ([Id], CoreExpr)
forall b. Int -> Expr b -> ([b], Expr b)
collectNBinders Int
join_arity CoreExpr
rhs
; (env' :: CorePrepEnv
env', bndrs' :: [Id]
bndrs') <- CorePrepEnv -> [Id] -> UniqSM (CorePrepEnv, [Id])
cpCloneBndrs CorePrepEnv
env [Id]
bndrs
; CoreExpr
body' <- CorePrepEnv -> CoreExpr -> UniqSM CoreExpr
cpeBodyNF CorePrepEnv
env' CoreExpr
body
; let rhs' :: CoreExpr
rhs' = [Id] -> CoreExpr -> CoreExpr
mkCoreLams [Id]
bndrs' CoreExpr
body'
bndr' :: Id
bndr' = Id
bndr Id -> Unfolding -> Id
`setIdUnfolding` Unfolding
evaldUnfolding
Id -> Int -> Id
`setIdArity` (Id -> Bool) -> [Id] -> Int
forall a. (a -> Bool) -> [a] -> Int
count Id -> Bool
isId [Id]
bndrs
; (Id, CoreExpr) -> UniqSM (Id, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Id
bndr', CoreExpr
rhs') }
cpeRhsE :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs)
cpeRhsE :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeRhsE _env :: CorePrepEnv
_env expr :: CoreExpr
expr@(Type {}) = (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
emptyFloats, CoreExpr
expr)
cpeRhsE _env :: CorePrepEnv
_env expr :: CoreExpr
expr@(Coercion {}) = (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
emptyFloats, CoreExpr
expr)
cpeRhsE env :: CorePrepEnv
env (Lit (LitNumber LitNumInteger i :: Integer
i _))
= CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeRhsE CorePrepEnv
env (DynFlags -> Id -> Maybe DataCon -> Integer -> CoreExpr
cvtLitInteger (CorePrepEnv -> DynFlags
cpe_dynFlags CorePrepEnv
env) (CorePrepEnv -> Id
getMkIntegerId CorePrepEnv
env)
(CorePrepEnv -> Maybe DataCon
cpe_integerSDataCon CorePrepEnv
env) Integer
i)
cpeRhsE env :: CorePrepEnv
env (Lit (LitNumber LitNumNatural i :: Integer
i _))
= CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeRhsE CorePrepEnv
env (DynFlags -> Id -> Maybe DataCon -> Integer -> CoreExpr
cvtLitNatural (CorePrepEnv -> DynFlags
cpe_dynFlags CorePrepEnv
env) (CorePrepEnv -> Id
getMkNaturalId CorePrepEnv
env)
(CorePrepEnv -> Maybe DataCon
cpe_naturalSDataCon CorePrepEnv
env) Integer
i)
cpeRhsE _env :: CorePrepEnv
_env expr :: CoreExpr
expr@(Lit {}) = (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
emptyFloats, CoreExpr
expr)
cpeRhsE env :: CorePrepEnv
env expr :: CoreExpr
expr@(Var {}) = CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeApp CorePrepEnv
env CoreExpr
expr
cpeRhsE env :: CorePrepEnv
env expr :: CoreExpr
expr@(App {}) = CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeApp CorePrepEnv
env CoreExpr
expr
cpeRhsE env :: CorePrepEnv
env (Let bind :: CoreBind
bind body :: CoreExpr
body)
= do { (env' :: CorePrepEnv
env', bind_floats :: Floats
bind_floats, maybe_bind' :: Maybe CoreBind
maybe_bind') <- TopLevelFlag
-> CorePrepEnv
-> CoreBind
-> UniqSM (CorePrepEnv, Floats, Maybe CoreBind)
cpeBind TopLevelFlag
NotTopLevel CorePrepEnv
env CoreBind
bind
; (body_floats :: Floats
body_floats, body' :: CoreExpr
body') <- CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeRhsE CorePrepEnv
env' CoreExpr
body
; let expr' :: CoreExpr
expr' = case Maybe CoreBind
maybe_bind' of Just bind' :: CoreBind
bind' -> CoreBind -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let CoreBind
bind' CoreExpr
body'
Nothing -> CoreExpr
body'
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
bind_floats Floats -> Floats -> Floats
`appendFloats` Floats
body_floats, CoreExpr
expr') }
cpeRhsE env :: CorePrepEnv
env (Tick tickish :: Tickish Id
tickish expr :: CoreExpr
expr)
| Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
tickish TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
== TickishPlacement
PlaceNonLam Bool -> Bool -> Bool
&& Tickish Id
tickish Tickish Id -> TickishScoping -> Bool
forall id. Tickish id -> TickishScoping -> Bool
`tickishScopesLike` TickishScoping
SoftScope
= do { (floats :: Floats
floats, body :: CoreExpr
body) <- CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeRhsE CorePrepEnv
env CoreExpr
expr
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (FloatingBind -> Floats
unitFloat (Tickish Id -> FloatingBind
FloatTick Tickish Id
tickish) Floats -> Floats -> Floats
`appendFloats` Floats
floats, CoreExpr
body) }
| Bool
otherwise
= do { CoreExpr
body <- CorePrepEnv -> CoreExpr -> UniqSM CoreExpr
cpeBodyNF CorePrepEnv
env CoreExpr
expr
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
emptyFloats, Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
tickish' CoreExpr
body) }
where
tickish' :: Tickish Id
tickish' | Breakpoint n :: Int
n fvs :: [Id]
fvs <- Tickish Id
tickish
= Int -> [Id] -> Tickish Id
forall id. Int -> [id] -> Tickish id
Breakpoint Int
n ((Id -> Id) -> [Id] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (HasDebugCallStack => CoreExpr -> Id
CoreExpr -> Id
getIdFromTrivialExpr (CoreExpr -> Id) -> (Id -> CoreExpr) -> Id -> Id
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CorePrepEnv -> Id -> CoreExpr
lookupCorePrepEnv CorePrepEnv
env) [Id]
fvs)
| Bool
otherwise
= Tickish Id
tickish
cpeRhsE env :: CorePrepEnv
env (Cast expr :: CoreExpr
expr co :: Coercion
co)
= do { (floats :: Floats
floats, expr' :: CoreExpr
expr') <- CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeRhsE CorePrepEnv
env CoreExpr
expr
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats, CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
expr' Coercion
co) }
cpeRhsE env :: CorePrepEnv
env expr :: CoreExpr
expr@(Lam {})
= do { let (bndrs :: [Id]
bndrs,body :: CoreExpr
body) = CoreExpr -> ([Id], CoreExpr)
forall b. Expr b -> ([b], Expr b)
collectBinders CoreExpr
expr
; (env' :: CorePrepEnv
env', bndrs' :: [Id]
bndrs') <- CorePrepEnv -> [Id] -> UniqSM (CorePrepEnv, [Id])
cpCloneBndrs CorePrepEnv
env [Id]
bndrs
; CoreExpr
body' <- CorePrepEnv -> CoreExpr -> UniqSM CoreExpr
cpeBodyNF CorePrepEnv
env' CoreExpr
body
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
emptyFloats, [Id] -> CoreExpr -> CoreExpr
forall b. [b] -> Expr b -> Expr b
mkLams [Id]
bndrs' CoreExpr
body') }
cpeRhsE env :: CorePrepEnv
env (Case scrut :: CoreExpr
scrut bndr :: Id
bndr ty :: Type
ty alts :: [Alt Id]
alts)
= do { (floats :: Floats
floats, scrut' :: CoreExpr
scrut') <- CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeBody CorePrepEnv
env CoreExpr
scrut
; (env' :: CorePrepEnv
env', bndr2 :: Id
bndr2) <- CorePrepEnv -> Id -> UniqSM (CorePrepEnv, Id)
cpCloneBndr CorePrepEnv
env Id
bndr
; let alts' :: [Alt Id]
alts'
| GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_CatchBottoms (CorePrepEnv -> DynFlags
cpe_dynFlags CorePrepEnv
env)
, Bool -> Bool
not ([Alt Id] -> Bool
forall b. [Alt b] -> Bool
altsAreExhaustive [Alt Id]
alts)
= [Alt Id] -> Maybe CoreExpr -> [Alt Id]
forall a b. [(AltCon, [a], b)] -> Maybe b -> [(AltCon, [a], b)]
addDefault [Alt Id]
alts (CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just CoreExpr
err)
| Bool
otherwise = [Alt Id]
alts
where err :: CoreExpr
err = Id -> Type -> String -> CoreExpr
mkRuntimeErrorApp Id
rUNTIME_ERROR_ID Type
ty
"Bottoming expression returned"
; [Alt Id]
alts'' <- (Alt Id -> UniqSM (Alt Id)) -> [Alt Id] -> UniqSM [Alt Id]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (CorePrepEnv -> Alt Id -> UniqSM (Alt Id)
forall a.
CorePrepEnv -> (a, [Id], CoreExpr) -> UniqSM (a, [Id], CoreExpr)
sat_alt CorePrepEnv
env') [Alt Id]
alts'
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats, CoreExpr -> Id -> Type -> [Alt Id] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case CoreExpr
scrut' Id
bndr2 Type
ty [Alt Id]
alts'') }
where
sat_alt :: CorePrepEnv -> (a, [Id], CoreExpr) -> UniqSM (a, [Id], CoreExpr)
sat_alt env :: CorePrepEnv
env (con :: a
con, bs :: [Id]
bs, rhs :: CoreExpr
rhs)
= do { (env2 :: CorePrepEnv
env2, bs' :: [Id]
bs') <- CorePrepEnv -> [Id] -> UniqSM (CorePrepEnv, [Id])
cpCloneBndrs CorePrepEnv
env [Id]
bs
; CoreExpr
rhs' <- CorePrepEnv -> CoreExpr -> UniqSM CoreExpr
cpeBodyNF CorePrepEnv
env2 CoreExpr
rhs
; (a, [Id], CoreExpr) -> UniqSM (a, [Id], CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
con, [Id]
bs', CoreExpr
rhs') }
cvtLitInteger :: DynFlags -> Id -> Maybe DataCon -> Integer -> CoreExpr
cvtLitInteger :: DynFlags -> Id -> Maybe DataCon -> Integer -> CoreExpr
cvtLitInteger dflags :: DynFlags
dflags _ (Just sdatacon :: DataCon
sdatacon) i :: Integer
i
| DynFlags -> Integer -> Bool
inIntRange DynFlags
dflags Integer
i
= DataCon -> [CoreExpr] -> CoreExpr
forall b. DataCon -> [Arg b] -> Arg b
mkConApp DataCon
sdatacon [Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> Integer -> Literal
mkLitInt DynFlags
dflags Integer
i)]
cvtLitInteger dflags :: DynFlags
dflags mk_integer :: Id
mk_integer _ i :: Integer
i
= CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
mk_integer) [CoreExpr
forall b. Expr b
isNonNegative, CoreExpr
ints]
where isNonNegative :: Expr b
isNonNegative = if Integer
i Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< 0 then DataCon -> [Expr b] -> Expr b
forall b. DataCon -> [Arg b] -> Arg b
mkConApp DataCon
falseDataCon []
else DataCon -> [Expr b] -> Expr b
forall b. DataCon -> [Arg b] -> Arg b
mkConApp DataCon
trueDataCon []
ints :: CoreExpr
ints = Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
intTy (Integer -> [CoreExpr]
forall b. Integer -> [Expr b]
f (Integer -> Integer
forall a. Num a => a -> a
abs Integer
i))
f :: Integer -> [Expr b]
f 0 = []
f x :: Integer
x = let low :: Integer
low = Integer
x Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
mask
high :: Integer
high = Integer
x Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
bits
in DataCon -> [Expr b] -> Expr b
forall b. DataCon -> [Arg b] -> Arg b
mkConApp DataCon
intDataCon [Literal -> Expr b
forall b. Literal -> Expr b
Lit (DynFlags -> Integer -> Literal
mkLitInt DynFlags
dflags Integer
low)] Expr b -> [Expr b] -> [Expr b]
forall a. a -> [a] -> [a]
: Integer -> [Expr b]
f Integer
high
bits :: Int
bits = 31
mask :: Integer
mask = 2 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
bits Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- 1
cvtLitNatural :: DynFlags -> Id -> Maybe DataCon -> Integer -> CoreExpr
cvtLitNatural :: DynFlags -> Id -> Maybe DataCon -> Integer -> CoreExpr
cvtLitNatural dflags :: DynFlags
dflags _ (Just sdatacon :: DataCon
sdatacon) i :: Integer
i
| DynFlags -> Integer -> Bool
inWordRange DynFlags
dflags Integer
i
= DataCon -> [CoreExpr] -> CoreExpr
forall b. DataCon -> [Arg b] -> Arg b
mkConApp DataCon
sdatacon [Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (DynFlags -> Integer -> Literal
mkLitWord DynFlags
dflags Integer
i)]
cvtLitNatural dflags :: DynFlags
dflags mk_natural :: Id
mk_natural _ i :: Integer
i
= CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
mk_natural) [CoreExpr
words]
where words :: CoreExpr
words = Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
wordTy (Integer -> [CoreExpr]
forall b. Integer -> [Expr b]
f Integer
i)
f :: Integer -> [Expr b]
f 0 = []
f x :: Integer
x = let low :: Integer
low = Integer
x Integer -> Integer -> Integer
forall a. Bits a => a -> a -> a
.&. Integer
mask
high :: Integer
high = Integer
x Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
bits
in DataCon -> [Expr b] -> Expr b
forall b. DataCon -> [Arg b] -> Arg b
mkConApp DataCon
wordDataCon [Literal -> Expr b
forall b. Literal -> Expr b
Lit (DynFlags -> Integer -> Literal
mkLitWord DynFlags
dflags Integer
low)] Expr b -> [Expr b] -> [Expr b]
forall a. a -> [a] -> [a]
: Integer -> [Expr b]
f Integer
high
bits :: Int
bits = 32
mask :: Integer
mask = 2 Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
bits Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- 1
cpeBodyNF :: CorePrepEnv -> CoreExpr -> UniqSM CpeBody
cpeBodyNF :: CorePrepEnv -> CoreExpr -> UniqSM CoreExpr
cpeBodyNF env :: CorePrepEnv
env expr :: CoreExpr
expr
= do { (floats :: Floats
floats, body :: CoreExpr
body) <- CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeBody CorePrepEnv
env CoreExpr
expr
; CoreExpr -> UniqSM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats -> CoreExpr -> CoreExpr
wrapBinds Floats
floats CoreExpr
body) }
cpeBody :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeBody)
cpeBody :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeBody env :: CorePrepEnv
env expr :: CoreExpr
expr
= do { (floats1 :: Floats
floats1, rhs :: CoreExpr
rhs) <- CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeRhsE CorePrepEnv
env CoreExpr
expr
; (floats2 :: Floats
floats2, body :: CoreExpr
body) <- CoreExpr -> UniqSM (Floats, CoreExpr)
rhsToBody CoreExpr
rhs
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats1 Floats -> Floats -> Floats
`appendFloats` Floats
floats2, CoreExpr
body) }
rhsToBody :: CpeRhs -> UniqSM (Floats, CpeBody)
rhsToBody :: CoreExpr -> UniqSM (Floats, CoreExpr)
rhsToBody (Tick t :: Tickish Id
t expr :: CoreExpr
expr)
| Tickish Id -> TickishScoping
forall id. Tickish id -> TickishScoping
tickishScoped Tickish Id
t TickishScoping -> TickishScoping -> Bool
forall a. Eq a => a -> a -> Bool
== TickishScoping
NoScope
= do { (floats :: Floats
floats, expr' :: CoreExpr
expr') <- CoreExpr -> UniqSM (Floats, CoreExpr)
rhsToBody CoreExpr
expr
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats, Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
t CoreExpr
expr') }
rhsToBody (Cast e :: CoreExpr
e co :: Coercion
co)
= do { (floats :: Floats
floats, e' :: CoreExpr
e') <- CoreExpr -> UniqSM (Floats, CoreExpr)
rhsToBody CoreExpr
e
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats, CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
e' Coercion
co) }
rhsToBody expr :: CoreExpr
expr@(Lam {})
| Just no_lam_result :: CoreExpr
no_lam_result <- [Id] -> CoreExpr -> Maybe CoreExpr
tryEtaReducePrep [Id]
bndrs CoreExpr
body
= (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
emptyFloats, CoreExpr
no_lam_result)
| (Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Id -> Bool
isTyVar [Id]
bndrs
= (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
emptyFloats, CoreExpr
expr)
| Bool
otherwise
= do { Id
fn <- Type -> UniqSM Id
newVar (CoreExpr -> Type
exprType CoreExpr
expr)
; let rhs :: CoreExpr
rhs = Int -> CoreExpr -> CoreExpr
cpeEtaExpand (CoreExpr -> Int
exprArity CoreExpr
expr) CoreExpr
expr
float :: FloatingBind
float = CoreBind -> FloatingBind
FloatLet (Id -> CoreExpr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec Id
fn CoreExpr
rhs)
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (FloatingBind -> Floats
unitFloat FloatingBind
float, Id -> CoreExpr
forall b. Id -> Expr b
Var Id
fn) }
where
(bndrs :: [Id]
bndrs,body :: CoreExpr
body) = CoreExpr -> ([Id], CoreExpr)
forall b. Expr b -> ([b], Expr b)
collectBinders CoreExpr
expr
rhsToBody expr :: CoreExpr
expr = (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
emptyFloats, CoreExpr
expr)
data ArgInfo = CpeApp CoreArg
| CpeCast Coercion
| CpeTick (Tickish Id)
cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs)
cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeApp top_env :: CorePrepEnv
top_env expr :: CoreExpr
expr
= do { let (terminal :: CoreExpr
terminal, args :: [ArgInfo]
args, depth :: Int
depth) = CoreExpr -> (CoreExpr, [ArgInfo], Int)
collect_args CoreExpr
expr
; CorePrepEnv
-> CoreExpr -> [ArgInfo] -> Int -> UniqSM (Floats, CoreExpr)
cpe_app CorePrepEnv
top_env CoreExpr
terminal [ArgInfo]
args Int
depth
}
where
collect_args :: CoreExpr -> (CoreExpr, [ArgInfo], Int)
collect_args :: CoreExpr -> (CoreExpr, [ArgInfo], Int)
collect_args e :: CoreExpr
e = CoreExpr -> [ArgInfo] -> Int -> (CoreExpr, [ArgInfo], Int)
forall c.
Num c =>
CoreExpr -> [ArgInfo] -> c -> (CoreExpr, [ArgInfo], c)
go CoreExpr
e [] 0
where
go :: CoreExpr -> [ArgInfo] -> c -> (CoreExpr, [ArgInfo], c)
go (App fun :: CoreExpr
fun arg :: CoreExpr
arg) as :: [ArgInfo]
as !c
depth
= CoreExpr -> [ArgInfo] -> c -> (CoreExpr, [ArgInfo], c)
go CoreExpr
fun (CoreExpr -> ArgInfo
CpeApp CoreExpr
arg ArgInfo -> [ArgInfo] -> [ArgInfo]
forall a. a -> [a] -> [a]
: [ArgInfo]
as)
(if CoreExpr -> Bool
forall b. Expr b -> Bool
isTyCoArg CoreExpr
arg then c
depth else c
depth c -> c -> c
forall a. Num a => a -> a -> a
+ 1)
go (Cast fun :: CoreExpr
fun co :: Coercion
co) as :: [ArgInfo]
as depth :: c
depth
= CoreExpr -> [ArgInfo] -> c -> (CoreExpr, [ArgInfo], c)
go CoreExpr
fun (Coercion -> ArgInfo
CpeCast Coercion
co ArgInfo -> [ArgInfo] -> [ArgInfo]
forall a. a -> [a] -> [a]
: [ArgInfo]
as) c
depth
go (Tick tickish :: Tickish Id
tickish fun :: CoreExpr
fun) as :: [ArgInfo]
as depth :: c
depth
| Tickish Id -> TickishPlacement
forall id. Tickish id -> TickishPlacement
tickishPlace Tickish Id
tickish TickishPlacement -> TickishPlacement -> Bool
forall a. Eq a => a -> a -> Bool
== TickishPlacement
PlaceNonLam
Bool -> Bool -> Bool
&& Tickish Id
tickish Tickish Id -> TickishScoping -> Bool
forall id. Tickish id -> TickishScoping -> Bool
`tickishScopesLike` TickishScoping
SoftScope
= CoreExpr -> [ArgInfo] -> c -> (CoreExpr, [ArgInfo], c)
go CoreExpr
fun (Tickish Id -> ArgInfo
CpeTick Tickish Id
tickish ArgInfo -> [ArgInfo] -> [ArgInfo]
forall a. a -> [a] -> [a]
: [ArgInfo]
as) c
depth
go terminal :: CoreExpr
terminal as :: [ArgInfo]
as depth :: c
depth = (CoreExpr
terminal, [ArgInfo]
as, c
depth)
cpe_app :: CorePrepEnv
-> CoreExpr
-> [ArgInfo]
-> Int
-> UniqSM (Floats, CpeRhs)
cpe_app :: CorePrepEnv
-> CoreExpr -> [ArgInfo] -> Int -> UniqSM (Floats, CoreExpr)
cpe_app env :: CorePrepEnv
env (Var f :: Id
f) (CpeApp Type{} : CpeApp arg :: CoreExpr
arg : args :: [ArgInfo]
args) depth :: Int
depth
| Id
f Id -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
lazyIdKey
Bool -> Bool -> Bool
|| Id
f Id -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
noinlineIdKey
= let (terminal :: CoreExpr
terminal, args' :: [ArgInfo]
args', depth' :: Int
depth') = CoreExpr -> (CoreExpr, [ArgInfo], Int)
collect_args CoreExpr
arg
in CorePrepEnv
-> CoreExpr -> [ArgInfo] -> Int -> UniqSM (Floats, CoreExpr)
cpe_app CorePrepEnv
env CoreExpr
terminal ([ArgInfo]
args' [ArgInfo] -> [ArgInfo] -> [ArgInfo]
forall a. [a] -> [a] -> [a]
++ [ArgInfo]
args) (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
depth' Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)
cpe_app env :: CorePrepEnv
env (Var f :: Id
f) [CpeApp _runtimeRep :: CoreExpr
_runtimeRep@Type{}, CpeApp _type :: CoreExpr
_type@Type{}, CpeApp arg :: CoreExpr
arg] 1
| Id
f Id -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
runRWKey
= case CoreExpr
arg of
Lam s :: Id
s body :: CoreExpr
body -> CorePrepEnv
-> CoreExpr -> [ArgInfo] -> Int -> UniqSM (Floats, CoreExpr)
cpe_app (CorePrepEnv -> Id -> Id -> CorePrepEnv
extendCorePrepEnv CorePrepEnv
env Id
s Id
realWorldPrimId) CoreExpr
body [] 0
_ -> CorePrepEnv
-> CoreExpr -> [ArgInfo] -> Int -> UniqSM (Floats, CoreExpr)
cpe_app CorePrepEnv
env CoreExpr
arg [CoreExpr -> ArgInfo
CpeApp (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
realWorldPrimId)] 1
cpe_app env :: CorePrepEnv
env (Var v :: Id
v) args :: [ArgInfo]
args depth :: Int
depth
= do { Id
v1 <- Id -> UniqSM Id
fiddleCCall Id
v
; let e2 :: CoreExpr
e2 = CorePrepEnv -> Id -> CoreExpr
lookupCorePrepEnv CorePrepEnv
env Id
v1
hd :: Maybe Id
hd = CoreExpr -> Maybe Id
getIdFromTrivialExpr_maybe CoreExpr
e2
; (app :: CoreExpr
app, floats :: Floats
floats) <- [ArgInfo]
-> CoreExpr
-> Type
-> Floats
-> [Demand]
-> UniqSM (CoreExpr, Floats)
rebuild_app [ArgInfo]
args CoreExpr
e2 (CoreExpr -> Type
exprType CoreExpr
e2) Floats
emptyFloats [Demand]
stricts
; Maybe Id -> CoreExpr -> Floats -> Int -> UniqSM (Floats, CoreExpr)
forall a. Maybe Id -> CoreExpr -> a -> Int -> UniqSM (a, CoreExpr)
mb_saturate Maybe Id
hd CoreExpr
app Floats
floats Int
depth }
where
stricts :: [Demand]
stricts = case Id -> StrictSig
idStrictness Id
v of
StrictSig (DmdType _ demands :: [Demand]
demands _)
| [Demand] -> Int -> Ordering
forall a. [a] -> Int -> Ordering
listLengthCmp [Demand]
demands Int
depth Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
GT -> [Demand]
demands
| Bool
otherwise -> []
cpe_app env :: CorePrepEnv
env fun :: CoreExpr
fun [] _ = CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeRhsE CorePrepEnv
env CoreExpr
fun
cpe_app env :: CorePrepEnv
env fun :: CoreExpr
fun args :: [ArgInfo]
args depth :: Int
depth
= do { (fun_floats :: Floats
fun_floats, fun' :: CoreExpr
fun') <- CorePrepEnv
-> Demand -> CoreExpr -> Type -> UniqSM (Floats, CoreExpr)
cpeArg CorePrepEnv
env Demand
evalDmd CoreExpr
fun Type
ty
; (app :: CoreExpr
app, floats :: Floats
floats) <- [ArgInfo]
-> CoreExpr
-> Type
-> Floats
-> [Demand]
-> UniqSM (CoreExpr, Floats)
rebuild_app [ArgInfo]
args CoreExpr
fun' Type
ty Floats
fun_floats []
; Maybe Id -> CoreExpr -> Floats -> Int -> UniqSM (Floats, CoreExpr)
forall a. Maybe Id -> CoreExpr -> a -> Int -> UniqSM (a, CoreExpr)
mb_saturate Maybe Id
forall a. Maybe a
Nothing CoreExpr
app Floats
floats Int
depth }
where
ty :: Type
ty = CoreExpr -> Type
exprType CoreExpr
fun
mb_saturate :: Maybe Id -> CoreExpr -> a -> Int -> UniqSM (a, CoreExpr)
mb_saturate head :: Maybe Id
head app :: CoreExpr
app floats :: a
floats depth :: Int
depth =
case Maybe Id
head of
Just fn_id :: Id
fn_id -> do { CoreExpr
sat_app <- Id -> CoreExpr -> Int -> UniqSM CoreExpr
maybeSaturate Id
fn_id CoreExpr
app Int
depth
; (a, CoreExpr) -> UniqSM (a, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
floats, CoreExpr
sat_app) }
_other :: Maybe Id
_other -> (a, CoreExpr) -> UniqSM (a, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
floats, CoreExpr
app)
rebuild_app
:: [ArgInfo]
-> CpeApp
-> Type
-> Floats
-> [Demand]
-> UniqSM (CpeApp, Floats)
rebuild_app :: [ArgInfo]
-> CoreExpr
-> Type
-> Floats
-> [Demand]
-> UniqSM (CoreExpr, Floats)
rebuild_app [] app :: CoreExpr
app _ floats :: Floats
floats ss :: [Demand]
ss = do
MASSERT(null ss)
(CoreExpr, Floats) -> UniqSM (CoreExpr, Floats)
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreExpr
app, Floats
floats)
rebuild_app (a :: ArgInfo
a : as :: [ArgInfo]
as) fun' :: CoreExpr
fun' fun_ty :: Type
fun_ty floats :: Floats
floats ss :: [Demand]
ss = case ArgInfo
a of
CpeApp arg :: CoreExpr
arg@(Type arg_ty :: Type
arg_ty) ->
[ArgInfo]
-> CoreExpr
-> Type
-> Floats
-> [Demand]
-> UniqSM (CoreExpr, Floats)
rebuild_app [ArgInfo]
as (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
fun' CoreExpr
arg) (HasDebugCallStack => Type -> Type -> Type
Type -> Type -> Type
piResultTy Type
fun_ty Type
arg_ty) Floats
floats [Demand]
ss
CpeApp arg :: CoreExpr
arg@(Coercion {}) ->
[ArgInfo]
-> CoreExpr
-> Type
-> Floats
-> [Demand]
-> UniqSM (CoreExpr, Floats)
rebuild_app [ArgInfo]
as (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
fun' CoreExpr
arg) (Type -> Type
funResultTy Type
fun_ty) Floats
floats [Demand]
ss
CpeApp arg :: CoreExpr
arg -> do
let (ss1 :: Demand
ss1, ss_rest :: [Demand]
ss_rest)
= case ([Demand]
ss, CoreExpr -> Bool
isLazyExpr CoreExpr
arg) of
(_ : ss_rest :: [Demand]
ss_rest, True) -> (Demand
topDmd, [Demand]
ss_rest)
(ss1 :: Demand
ss1 : ss_rest :: [Demand]
ss_rest, False) -> (Demand
ss1, [Demand]
ss_rest)
([], _) -> (Demand
topDmd, [])
(arg_ty :: Type
arg_ty, res_ty :: Type
res_ty) = String -> Maybe (Type, Type) -> (Type, Type)
forall a. HasCallStack => String -> Maybe a -> a
expectJust "cpeBody:collect_args" (Maybe (Type, Type) -> (Type, Type))
-> Maybe (Type, Type) -> (Type, Type)
forall a b. (a -> b) -> a -> b
$
Type -> Maybe (Type, Type)
splitFunTy_maybe Type
fun_ty
(fs :: Floats
fs, arg' :: CoreExpr
arg') <- CorePrepEnv
-> Demand -> CoreExpr -> Type -> UniqSM (Floats, CoreExpr)
cpeArg CorePrepEnv
top_env Demand
ss1 CoreExpr
arg Type
arg_ty
[ArgInfo]
-> CoreExpr
-> Type
-> Floats
-> [Demand]
-> UniqSM (CoreExpr, Floats)
rebuild_app [ArgInfo]
as (CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App CoreExpr
fun' CoreExpr
arg') Type
res_ty (Floats
fs Floats -> Floats -> Floats
`appendFloats` Floats
floats) [Demand]
ss_rest
CpeCast co :: Coercion
co ->
let Pair _ty1 :: Type
_ty1 ty2 :: Type
ty2 = Coercion -> Pair Type
coercionKind Coercion
co
in [ArgInfo]
-> CoreExpr
-> Type
-> Floats
-> [Demand]
-> UniqSM (CoreExpr, Floats)
rebuild_app [ArgInfo]
as (CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
fun' Coercion
co) Type
ty2 Floats
floats [Demand]
ss
CpeTick tickish :: Tickish Id
tickish ->
[ArgInfo]
-> CoreExpr
-> Type
-> Floats
-> [Demand]
-> UniqSM (CoreExpr, Floats)
rebuild_app [ArgInfo]
as CoreExpr
fun' Type
fun_ty (Floats -> FloatingBind -> Floats
addFloat Floats
floats (Tickish Id -> FloatingBind
FloatTick Tickish Id
tickish)) [Demand]
ss
isLazyExpr :: CoreExpr -> Bool
isLazyExpr :: CoreExpr -> Bool
isLazyExpr (Cast e :: CoreExpr
e _) = CoreExpr -> Bool
isLazyExpr CoreExpr
e
isLazyExpr (Tick _ e :: CoreExpr
e) = CoreExpr -> Bool
isLazyExpr CoreExpr
e
isLazyExpr (Var f :: Id
f `App` _ `App` _) = Id
f Id -> Unique -> Bool
forall a. Uniquable a => a -> Unique -> Bool
`hasKey` Unique
lazyIdKey
isLazyExpr _ = Bool
False
okCpeArg :: CoreExpr -> Bool
okCpeArg :: CoreExpr -> Bool
okCpeArg (Lit _) = Bool
False
okCpeArg expr :: CoreExpr
expr = Bool -> Bool
not (CoreExpr -> Bool
exprIsTrivial CoreExpr
expr)
cpeArg :: CorePrepEnv -> Demand
-> CoreArg -> Type -> UniqSM (Floats, CpeArg)
cpeArg :: CorePrepEnv
-> Demand -> CoreExpr -> Type -> UniqSM (Floats, CoreExpr)
cpeArg env :: CorePrepEnv
env dmd :: Demand
dmd arg :: CoreExpr
arg arg_ty :: Type
arg_ty
= do { (floats1 :: Floats
floats1, arg1 :: CoreExpr
arg1) <- CorePrepEnv -> CoreExpr -> UniqSM (Floats, CoreExpr)
cpeRhsE CorePrepEnv
env CoreExpr
arg
; (floats2 :: Floats
floats2, arg2 :: CoreExpr
arg2) <- if Floats -> CoreExpr -> Bool
want_float Floats
floats1 CoreExpr
arg1
then (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats1, CoreExpr
arg1)
else Floats -> CoreExpr -> UniqSM (Floats, CoreExpr)
dontFloat Floats
floats1 CoreExpr
arg1
; if CoreExpr -> Bool
okCpeArg CoreExpr
arg2
then do { Id
v <- Type -> UniqSM Id
newVar Type
arg_ty
; let arg3 :: CoreExpr
arg3 = Int -> CoreExpr -> CoreExpr
cpeEtaExpand (CoreExpr -> Int
exprArity CoreExpr
arg2) CoreExpr
arg2
arg_float :: FloatingBind
arg_float = Demand -> Bool -> Id -> CoreExpr -> FloatingBind
mkFloat Demand
dmd Bool
is_unlifted Id
v CoreExpr
arg3
; (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats -> FloatingBind -> Floats
addFloat Floats
floats2 FloatingBind
arg_float, Id -> CoreExpr
forall b. Id -> Expr b
varToCoreExpr Id
v) }
else (Floats, CoreExpr) -> UniqSM (Floats, CoreExpr)
forall (m :: * -> *) a. Monad m => a -> m a
return (Floats
floats2, CoreExpr
arg2)
}
where
is_unlifted :: Bool
is_unlifted = HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType Type
arg_ty
want_float :: Floats -> CoreExpr -> Bool
want_float = RecFlag -> Demand -> Bool -> Floats -> CoreExpr -> Bool
wantFloatNested RecFlag
NonRecursive Demand
dmd Bool
is_unlifted
maybeSaturate :: Id -> CpeApp -> Int -> UniqSM CpeRhs
maybeSaturate :: Id -> CoreExpr -> Int -> UniqSM CoreExpr
maybeSaturate fn :: Id
fn expr :: CoreExpr
expr n_args :: Int
n_args
| Id -> Bool
hasNoBinding Id
fn
= CoreExpr -> UniqSM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
sat_expr
| Bool
otherwise
= CoreExpr -> UniqSM CoreExpr
forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
expr
where
fn_arity :: Int
fn_arity = Id -> Int
idArity Id
fn
excess_arity :: Int
excess_arity = Int
fn_arity Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n_args
sat_expr :: CoreExpr
sat_expr = Int -> CoreExpr -> CoreExpr
cpeEtaExpand Int
excess_arity CoreExpr
expr
cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs
cpeEtaExpand :: Int -> CoreExpr -> CoreExpr
cpeEtaExpand arity :: Int
arity expr :: CoreExpr
expr
| Int
arity Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 = CoreExpr
expr
| Bool
otherwise = Int -> CoreExpr -> CoreExpr
etaExpand Int
arity CoreExpr
expr
tryEtaReducePrep :: [CoreBndr] -> CoreExpr -> Maybe CoreExpr
tryEtaReducePrep :: [Id] -> CoreExpr -> Maybe CoreExpr
tryEtaReducePrep bndrs :: [Id]
bndrs expr :: CoreExpr
expr@(App _ _)
| CoreExpr -> Bool
forall b. Expr b -> Bool
ok_to_eta_reduce CoreExpr
f
, Int
n_remaining Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 0
, [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ((Id -> CoreExpr -> Bool) -> [Id] -> [CoreExpr] -> [Bool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Id -> CoreExpr -> Bool
forall b. Id -> Expr b -> Bool
ok [Id]
bndrs [CoreExpr]
last_args)
, Bool -> Bool
not ((Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Id -> VarSet -> Bool
`elemVarSet` VarSet
fvs_remaining) [Id]
bndrs)
, CoreExpr -> Bool
exprIsHNF CoreExpr
remaining_expr
= CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just CoreExpr
remaining_expr
where
(f :: CoreExpr
f, args :: [CoreExpr]
args) = CoreExpr -> (CoreExpr, [CoreExpr])
forall b. Expr b -> (Expr b, [Expr b])
collectArgs CoreExpr
expr
remaining_expr :: CoreExpr
remaining_expr = CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps CoreExpr
f [CoreExpr]
remaining_args
fvs_remaining :: VarSet
fvs_remaining = CoreExpr -> VarSet
exprFreeVars CoreExpr
remaining_expr
(remaining_args :: [CoreExpr]
remaining_args, last_args :: [CoreExpr]
last_args) = Int -> [CoreExpr] -> ([CoreExpr], [CoreExpr])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n_remaining [CoreExpr]
args
n_remaining :: Int
n_remaining = [CoreExpr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [CoreExpr]
args Int -> Int -> Int
forall a. Num a => a -> a -> a
- [Id] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Id]
bndrs
ok :: Id -> Expr b -> Bool
ok bndr :: Id
bndr (Var arg :: Id
arg) = Id
bndr Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
== Id
arg
ok _ _ = Bool
False
ok_to_eta_reduce :: Expr b -> Bool
ok_to_eta_reduce (Var f :: Id
f) = Bool -> Bool
not (Id -> Bool
hasNoBinding Id
f)
ok_to_eta_reduce _ = Bool
False
tryEtaReducePrep bndrs :: [Id]
bndrs (Let bind :: CoreBind
bind@(NonRec _ r :: CoreExpr
r) body :: CoreExpr
body)
| Bool -> Bool
not ((Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Id -> VarSet -> Bool
`elemVarSet` VarSet
fvs) [Id]
bndrs)
= case [Id] -> CoreExpr -> Maybe CoreExpr
tryEtaReducePrep [Id]
bndrs CoreExpr
body of
Just e :: CoreExpr
e -> CoreExpr -> Maybe CoreExpr
forall a. a -> Maybe a
Just (CoreBind -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let CoreBind
bind CoreExpr
e)
Nothing -> Maybe CoreExpr
forall a. Maybe a
Nothing
where
fvs :: VarSet
fvs = CoreExpr -> VarSet
exprFreeVars CoreExpr
r
tryEtaReducePrep _ _ = Maybe CoreExpr
forall a. Maybe a
Nothing
data FloatingBind
= FloatLet CoreBind
| FloatCase
Id CpeBody
Bool
| FloatTick (Tickish Id)
data Floats = Floats OkToSpec (OrdList FloatingBind)
instance Outputable FloatingBind where
ppr :: FloatingBind -> SDoc
ppr (FloatLet b :: CoreBind
b) = CoreBind -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreBind
b
ppr (FloatCase b :: Id
b r :: CoreExpr
r ok :: Bool
ok) = SDoc -> SDoc
brackets (Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bool
ok) SDoc -> SDoc -> SDoc
<+> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
b SDoc -> SDoc -> SDoc
<+> SDoc
equals SDoc -> SDoc -> SDoc
<+> CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
r
ppr (FloatTick t :: Tickish Id
t) = Tickish Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Tickish Id
t
instance Outputable Floats where
ppr :: Floats -> SDoc
ppr (Floats flag :: OkToSpec
flag fs :: OrdList FloatingBind
fs) = String -> SDoc
text "Floats" SDoc -> SDoc -> SDoc
<> SDoc -> SDoc
brackets (OkToSpec -> SDoc
forall a. Outputable a => a -> SDoc
ppr OkToSpec
flag) SDoc -> SDoc -> SDoc
<+>
SDoc -> SDoc
braces ([SDoc] -> SDoc
vcat ((FloatingBind -> SDoc) -> [FloatingBind] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map FloatingBind -> SDoc
forall a. Outputable a => a -> SDoc
ppr (OrdList FloatingBind -> [FloatingBind]
forall a. OrdList a -> [a]
fromOL OrdList FloatingBind
fs)))
instance Outputable OkToSpec where
ppr :: OkToSpec -> SDoc
ppr OkToSpec = String -> SDoc
text "OkToSpec"
ppr IfUnboxedOk = String -> SDoc
text "IfUnboxedOk"
ppr NotOkToSpec = String -> SDoc
text "NotOkToSpec"
data OkToSpec
= OkToSpec
| IfUnboxedOk
| NotOkToSpec
mkFloat :: Demand -> Bool -> Id -> CpeRhs -> FloatingBind
mkFloat :: Demand -> Bool -> Id -> CoreExpr -> FloatingBind
mkFloat dmd :: Demand
dmd is_unlifted :: Bool
is_unlifted bndr :: Id
bndr rhs :: CoreExpr
rhs
| Bool
use_case = Id -> CoreExpr -> Bool -> FloatingBind
FloatCase Id
bndr CoreExpr
rhs (CoreExpr -> Bool
exprOkForSpeculation CoreExpr
rhs)
| Bool
is_hnf = CoreBind -> FloatingBind
FloatLet (Id -> CoreExpr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec Id
bndr CoreExpr
rhs)
| Bool
otherwise = CoreBind -> FloatingBind
FloatLet (Id -> CoreExpr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec (Id -> Demand -> Id
setIdDemandInfo Id
bndr Demand
dmd) CoreExpr
rhs)
where
is_hnf :: Bool
is_hnf = CoreExpr -> Bool
exprIsHNF CoreExpr
rhs
is_strict :: Bool
is_strict = Demand -> Bool
forall s u. JointDmd (Str s) (Use u) -> Bool
isStrictDmd Demand
dmd
use_case :: Bool
use_case = Bool
is_unlifted Bool -> Bool -> Bool
|| Bool
is_strict Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
is_hnf
emptyFloats :: Floats
emptyFloats :: Floats
emptyFloats = OkToSpec -> OrdList FloatingBind -> Floats
Floats OkToSpec
OkToSpec OrdList FloatingBind
forall a. OrdList a
nilOL
isEmptyFloats :: Floats -> Bool
isEmptyFloats :: Floats -> Bool
isEmptyFloats (Floats _ bs :: OrdList FloatingBind
bs) = OrdList FloatingBind -> Bool
forall a. OrdList a -> Bool
isNilOL OrdList FloatingBind
bs
wrapBinds :: Floats -> CpeBody -> CpeBody
wrapBinds :: Floats -> CoreExpr -> CoreExpr
wrapBinds (Floats _ binds :: OrdList FloatingBind
binds) body :: CoreExpr
body
= (FloatingBind -> CoreExpr -> CoreExpr)
-> CoreExpr -> OrdList FloatingBind -> CoreExpr
forall a b. (a -> b -> b) -> b -> OrdList a -> b
foldrOL FloatingBind -> CoreExpr -> CoreExpr
mk_bind CoreExpr
body OrdList FloatingBind
binds
where
mk_bind :: FloatingBind -> CoreExpr -> CoreExpr
mk_bind (FloatCase bndr :: Id
bndr rhs :: CoreExpr
rhs _) body :: CoreExpr
body = CoreExpr -> Id -> Type -> [Alt Id] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case CoreExpr
rhs Id
bndr (CoreExpr -> Type
exprType CoreExpr
body) [(AltCon
DEFAULT, [], CoreExpr
body)]
mk_bind (FloatLet bind :: CoreBind
bind) body :: CoreExpr
body = CoreBind -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let CoreBind
bind CoreExpr
body
mk_bind (FloatTick tickish :: Tickish Id
tickish) body :: CoreExpr
body = Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
tickish CoreExpr
body
addFloat :: Floats -> FloatingBind -> Floats
addFloat :: Floats -> FloatingBind -> Floats
addFloat (Floats ok_to_spec :: OkToSpec
ok_to_spec floats :: OrdList FloatingBind
floats) new_float :: FloatingBind
new_float
= OkToSpec -> OrdList FloatingBind -> Floats
Floats (OkToSpec -> OkToSpec -> OkToSpec
combine OkToSpec
ok_to_spec (FloatingBind -> OkToSpec
check FloatingBind
new_float)) (OrdList FloatingBind
floats OrdList FloatingBind -> FloatingBind -> OrdList FloatingBind
forall a. OrdList a -> a -> OrdList a
`snocOL` FloatingBind
new_float)
where
check :: FloatingBind -> OkToSpec
check (FloatLet _) = OkToSpec
OkToSpec
check (FloatCase _ _ ok_for_spec :: Bool
ok_for_spec)
| Bool
ok_for_spec = OkToSpec
IfUnboxedOk
| Bool
otherwise = OkToSpec
NotOkToSpec
check FloatTick{} = OkToSpec
OkToSpec
unitFloat :: FloatingBind -> Floats
unitFloat :: FloatingBind -> Floats
unitFloat = Floats -> FloatingBind -> Floats
addFloat Floats
emptyFloats
appendFloats :: Floats -> Floats -> Floats
appendFloats :: Floats -> Floats -> Floats
appendFloats (Floats spec1 :: OkToSpec
spec1 floats1 :: OrdList FloatingBind
floats1) (Floats spec2 :: OkToSpec
spec2 floats2 :: OrdList FloatingBind
floats2)
= OkToSpec -> OrdList FloatingBind -> Floats
Floats (OkToSpec -> OkToSpec -> OkToSpec
combine OkToSpec
spec1 OkToSpec
spec2) (OrdList FloatingBind
floats1 OrdList FloatingBind
-> OrdList FloatingBind -> OrdList FloatingBind
forall a. OrdList a -> OrdList a -> OrdList a
`appOL` OrdList FloatingBind
floats2)
concatFloats :: [Floats] -> OrdList FloatingBind
concatFloats :: [Floats] -> OrdList FloatingBind
concatFloats = (Floats -> OrdList FloatingBind -> OrdList FloatingBind)
-> OrdList FloatingBind -> [Floats] -> OrdList FloatingBind
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\ (Floats _ bs1 :: OrdList FloatingBind
bs1) bs2 :: OrdList FloatingBind
bs2 -> OrdList FloatingBind
-> OrdList FloatingBind -> OrdList FloatingBind
forall a. OrdList a -> OrdList a -> OrdList a
appOL OrdList FloatingBind
bs1 OrdList FloatingBind
bs2) OrdList FloatingBind
forall a. OrdList a
nilOL
combine :: OkToSpec -> OkToSpec -> OkToSpec
combine :: OkToSpec -> OkToSpec -> OkToSpec
combine NotOkToSpec _ = OkToSpec
NotOkToSpec
combine _ NotOkToSpec = OkToSpec
NotOkToSpec
combine IfUnboxedOk _ = OkToSpec
IfUnboxedOk
combine _ IfUnboxedOk = OkToSpec
IfUnboxedOk
combine _ _ = OkToSpec
OkToSpec
deFloatTop :: Floats -> [CoreBind]
deFloatTop :: Floats -> CoreProgram
deFloatTop (Floats _ floats :: OrdList FloatingBind
floats)
= (FloatingBind -> CoreProgram -> CoreProgram)
-> CoreProgram -> OrdList FloatingBind -> CoreProgram
forall a b. (a -> b -> b) -> b -> OrdList a -> b
foldrOL FloatingBind -> CoreProgram -> CoreProgram
get [] OrdList FloatingBind
floats
where
get :: FloatingBind -> CoreProgram -> CoreProgram
get (FloatLet b :: CoreBind
b) bs :: CoreProgram
bs = CoreBind -> CoreBind
occurAnalyseRHSs CoreBind
b CoreBind -> CoreProgram -> CoreProgram
forall a. a -> [a] -> [a]
: CoreProgram
bs
get (FloatCase var :: Id
var body :: CoreExpr
body _) bs :: CoreProgram
bs =
CoreBind -> CoreBind
occurAnalyseRHSs (Id -> CoreExpr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec Id
var CoreExpr
body) CoreBind -> CoreProgram -> CoreProgram
forall a. a -> [a] -> [a]
: CoreProgram
bs
get b :: FloatingBind
b _ = String -> SDoc -> CoreProgram
forall a. HasCallStack => String -> SDoc -> a
pprPanic "corePrepPgm" (FloatingBind -> SDoc
forall a. Outputable a => a -> SDoc
ppr FloatingBind
b)
occurAnalyseRHSs :: CoreBind -> CoreBind
occurAnalyseRHSs (NonRec x :: Id
x e :: CoreExpr
e) = Id -> CoreExpr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec Id
x (CoreExpr -> CoreExpr
occurAnalyseExpr_NoBinderSwap CoreExpr
e)
occurAnalyseRHSs (Rec xes :: [(Id, CoreExpr)]
xes) = [(Id, CoreExpr)] -> CoreBind
forall b. [(b, Expr b)] -> Bind b
Rec [(Id
x, CoreExpr -> CoreExpr
occurAnalyseExpr_NoBinderSwap CoreExpr
e) | (x :: Id
x, e :: CoreExpr
e) <- [(Id, CoreExpr)]
xes]
canFloatFromNoCaf :: Platform -> Floats -> CpeRhs -> Maybe (Floats, CpeRhs)
canFloatFromNoCaf :: Platform -> Floats -> CoreExpr -> Maybe (Floats, CoreExpr)
canFloatFromNoCaf platform :: Platform
platform (Floats ok_to_spec :: OkToSpec
ok_to_spec fs :: OrdList FloatingBind
fs) rhs :: CoreExpr
rhs
| OkToSpec
OkToSpec <- OkToSpec
ok_to_spec
, Just (subst :: Subst
subst, fs' :: OrdList FloatingBind
fs') <- (Subst, OrdList FloatingBind)
-> [FloatingBind] -> Maybe (Subst, OrdList FloatingBind)
go (Subst
emptySubst, OrdList FloatingBind
forall a. OrdList a
nilOL) (OrdList FloatingBind -> [FloatingBind]
forall a. OrdList a -> [a]
fromOL OrdList FloatingBind
fs)
= (Floats, CoreExpr) -> Maybe (Floats, CoreExpr)
forall a. a -> Maybe a
Just (OkToSpec -> OrdList FloatingBind -> Floats
Floats OkToSpec
OkToSpec OrdList FloatingBind
fs', Subst -> CoreExpr -> CoreExpr
subst_expr Subst
subst CoreExpr
rhs)
| Bool
otherwise
= Maybe (Floats, CoreExpr)
forall a. Maybe a
Nothing
where
subst_expr :: Subst -> CoreExpr -> CoreExpr
subst_expr = SDoc -> Subst -> CoreExpr -> CoreExpr
substExpr (String -> SDoc
text "CorePrep")
go :: (Subst, OrdList FloatingBind) -> [FloatingBind]
-> Maybe (Subst, OrdList FloatingBind)
go :: (Subst, OrdList FloatingBind)
-> [FloatingBind] -> Maybe (Subst, OrdList FloatingBind)
go (subst :: Subst
subst, fbs_out :: OrdList FloatingBind
fbs_out) [] = (Subst, OrdList FloatingBind)
-> Maybe (Subst, OrdList FloatingBind)
forall a. a -> Maybe a
Just (Subst
subst, OrdList FloatingBind
fbs_out)
go (subst :: Subst
subst, fbs_out :: OrdList FloatingBind
fbs_out) (FloatLet (NonRec b :: Id
b r :: CoreExpr
r) : fbs_in :: [FloatingBind]
fbs_in)
| CoreExpr -> Bool
rhs_ok CoreExpr
r
= (Subst, OrdList FloatingBind)
-> [FloatingBind] -> Maybe (Subst, OrdList FloatingBind)
go (Subst
subst', OrdList FloatingBind
fbs_out OrdList FloatingBind -> FloatingBind -> OrdList FloatingBind
forall a. OrdList a -> a -> OrdList a
`snocOL` FloatingBind
new_fb) [FloatingBind]
fbs_in
where
(subst' :: Subst
subst', b' :: Id
b') = Subst -> Id -> (Subst, Id)
set_nocaf_bndr Subst
subst Id
b
new_fb :: FloatingBind
new_fb = CoreBind -> FloatingBind
FloatLet (Id -> CoreExpr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec Id
b' (Subst -> CoreExpr -> CoreExpr
subst_expr Subst
subst CoreExpr
r))
go (subst :: Subst
subst, fbs_out :: OrdList FloatingBind
fbs_out) (FloatLet (Rec prs :: [(Id, CoreExpr)]
prs) : fbs_in :: [FloatingBind]
fbs_in)
| (CoreExpr -> Bool) -> [CoreExpr] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all CoreExpr -> Bool
rhs_ok [CoreExpr]
rs
= (Subst, OrdList FloatingBind)
-> [FloatingBind] -> Maybe (Subst, OrdList FloatingBind)
go (Subst
subst', OrdList FloatingBind
fbs_out OrdList FloatingBind -> FloatingBind -> OrdList FloatingBind
forall a. OrdList a -> a -> OrdList a
`snocOL` FloatingBind
new_fb) [FloatingBind]
fbs_in
where
(bs :: [Id]
bs,rs :: [CoreExpr]
rs) = [(Id, CoreExpr)] -> ([Id], [CoreExpr])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Id, CoreExpr)]
prs
(subst' :: Subst
subst', bs' :: [Id]
bs') = (Subst -> Id -> (Subst, Id)) -> Subst -> [Id] -> (Subst, [Id])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL Subst -> Id -> (Subst, Id)
set_nocaf_bndr Subst
subst [Id]
bs
rs' :: [CoreExpr]
rs' = (CoreExpr -> CoreExpr) -> [CoreExpr] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map (Subst -> CoreExpr -> CoreExpr
subst_expr Subst
subst') [CoreExpr]
rs
new_fb :: FloatingBind
new_fb = CoreBind -> FloatingBind
FloatLet ([(Id, CoreExpr)] -> CoreBind
forall b. [(b, Expr b)] -> Bind b
Rec ([Id]
bs' [Id] -> [CoreExpr] -> [(Id, CoreExpr)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` [CoreExpr]
rs'))
go (subst :: Subst
subst, fbs_out :: OrdList FloatingBind
fbs_out) (ft :: FloatingBind
ft@FloatTick{} : fbs_in :: [FloatingBind]
fbs_in)
= (Subst, OrdList FloatingBind)
-> [FloatingBind] -> Maybe (Subst, OrdList FloatingBind)
go (Subst
subst, OrdList FloatingBind
fbs_out OrdList FloatingBind -> FloatingBind -> OrdList FloatingBind
forall a. OrdList a -> a -> OrdList a
`snocOL` FloatingBind
ft) [FloatingBind]
fbs_in
go _ _ = Maybe (Subst, OrdList FloatingBind)
forall a. Maybe a
Nothing
set_nocaf_bndr :: Subst -> Id -> (Subst, Id)
set_nocaf_bndr subst :: Subst
subst bndr :: Id
bndr
= (Subst -> Id -> CoreExpr -> Subst
extendIdSubst Subst
subst Id
bndr (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
bndr'), Id
bndr')
where
bndr' :: Id
bndr' = Id
bndr Id -> CafInfo -> Id
`setIdCafInfo` CafInfo
NoCafRefs
rhs_ok :: CoreExpr -> Bool
rhs_ok :: CoreExpr -> Bool
rhs_ok = Platform
-> (Name -> Bool)
-> (LitNumType -> Integer -> Maybe CoreExpr)
-> CoreExpr
-> Bool
rhsIsStatic Platform
platform (\_ -> Bool
False)
(\_nt :: LitNumType
_nt i :: Integer
i -> String -> SDoc -> Maybe CoreExpr
forall a. HasCallStack => String -> SDoc -> a
pprPanic "rhsIsStatic" (Integer -> SDoc
integer Integer
i))
wantFloatNested :: RecFlag -> Demand -> Bool -> Floats -> CpeRhs -> Bool
wantFloatNested :: RecFlag -> Demand -> Bool -> Floats -> CoreExpr -> Bool
wantFloatNested is_rec :: RecFlag
is_rec dmd :: Demand
dmd is_unlifted :: Bool
is_unlifted floats :: Floats
floats rhs :: CoreExpr
rhs
= Floats -> Bool
isEmptyFloats Floats
floats
Bool -> Bool -> Bool
|| Demand -> Bool
forall s u. JointDmd (Str s) (Use u) -> Bool
isStrictDmd Demand
dmd
Bool -> Bool -> Bool
|| Bool
is_unlifted
Bool -> Bool -> Bool
|| (RecFlag -> Floats -> Bool
allLazyNested RecFlag
is_rec Floats
floats Bool -> Bool -> Bool
&& CoreExpr -> Bool
exprIsHNF CoreExpr
rhs)
allLazyTop :: Floats -> Bool
allLazyTop :: Floats -> Bool
allLazyTop (Floats OkToSpec _) = Bool
True
allLazyTop _ = Bool
False
allLazyNested :: RecFlag -> Floats -> Bool
allLazyNested :: RecFlag -> Floats -> Bool
allLazyNested _ (Floats OkToSpec _) = Bool
True
allLazyNested _ (Floats NotOkToSpec _) = Bool
False
allLazyNested is_rec :: RecFlag
is_rec (Floats IfUnboxedOk _) = RecFlag -> Bool
isNonRec RecFlag
is_rec
data CorePrepEnv
= CPE { CorePrepEnv -> DynFlags
cpe_dynFlags :: DynFlags
, CorePrepEnv -> IdEnv CoreExpr
cpe_env :: IdEnv CoreExpr
, CorePrepEnv -> Id
cpe_mkIntegerId :: Id
, CorePrepEnv -> Id
cpe_mkNaturalId :: Id
, CorePrepEnv -> Maybe DataCon
cpe_integerSDataCon :: Maybe DataCon
, CorePrepEnv -> Maybe DataCon
cpe_naturalSDataCon :: Maybe DataCon
}
lookupMkIntegerName :: DynFlags -> HscEnv -> IO Id
lookupMkIntegerName :: DynFlags -> HscEnv -> IO Id
lookupMkIntegerName dflags :: DynFlags
dflags hsc_env :: HscEnv
hsc_env
= DynFlags -> IO Id -> IO Id
forall a. DynFlags -> IO a -> IO a
guardIntegerUse DynFlags
dflags (IO Id -> IO Id) -> IO Id -> IO Id
forall a b. (a -> b) -> a -> b
$ (TyThing -> Id) -> IO TyThing -> IO Id
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM TyThing -> Id
tyThingId (IO TyThing -> IO Id) -> IO TyThing -> IO Id
forall a b. (a -> b) -> a -> b
$
HscEnv -> Name -> IO TyThing
lookupGlobal HscEnv
hsc_env Name
mkIntegerName
lookupMkNaturalName :: DynFlags -> HscEnv -> IO Id
lookupMkNaturalName :: DynFlags -> HscEnv -> IO Id
lookupMkNaturalName dflags :: DynFlags
dflags hsc_env :: HscEnv
hsc_env
= DynFlags -> IO Id -> IO Id
forall a. DynFlags -> IO a -> IO a
guardNaturalUse DynFlags
dflags (IO Id -> IO Id) -> IO Id -> IO Id
forall a b. (a -> b) -> a -> b
$ (TyThing -> Id) -> IO TyThing -> IO Id
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM TyThing -> Id
tyThingId (IO TyThing -> IO Id) -> IO TyThing -> IO Id
forall a b. (a -> b) -> a -> b
$
HscEnv -> Name -> IO TyThing
lookupGlobal HscEnv
hsc_env Name
mkNaturalName
lookupIntegerSDataConName :: DynFlags -> HscEnv -> IO (Maybe DataCon)
lookupIntegerSDataConName :: DynFlags -> HscEnv -> IO (Maybe DataCon)
lookupIntegerSDataConName dflags :: DynFlags
dflags hsc_env :: HscEnv
hsc_env = case DynFlags -> IntegerLibrary
integerLibrary DynFlags
dflags of
IntegerGMP -> DynFlags -> IO (Maybe DataCon) -> IO (Maybe DataCon)
forall a. DynFlags -> IO a -> IO a
guardIntegerUse DynFlags
dflags (IO (Maybe DataCon) -> IO (Maybe DataCon))
-> IO (Maybe DataCon) -> IO (Maybe DataCon)
forall a b. (a -> b) -> a -> b
$ (TyThing -> Maybe DataCon) -> IO TyThing -> IO (Maybe DataCon)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (DataCon -> Maybe DataCon
forall a. a -> Maybe a
Just (DataCon -> Maybe DataCon)
-> (TyThing -> DataCon) -> TyThing -> Maybe DataCon
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyThing -> DataCon
tyThingDataCon) (IO TyThing -> IO (Maybe DataCon))
-> IO TyThing -> IO (Maybe DataCon)
forall a b. (a -> b) -> a -> b
$
HscEnv -> Name -> IO TyThing
lookupGlobal HscEnv
hsc_env Name
integerSDataConName
IntegerSimple -> Maybe DataCon -> IO (Maybe DataCon)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe DataCon
forall a. Maybe a
Nothing
lookupNaturalSDataConName :: DynFlags -> HscEnv -> IO (Maybe DataCon)
lookupNaturalSDataConName :: DynFlags -> HscEnv -> IO (Maybe DataCon)
lookupNaturalSDataConName dflags :: DynFlags
dflags hsc_env :: HscEnv
hsc_env = case DynFlags -> IntegerLibrary
integerLibrary DynFlags
dflags of
IntegerGMP -> DynFlags -> IO (Maybe DataCon) -> IO (Maybe DataCon)
forall a. DynFlags -> IO a -> IO a
guardNaturalUse DynFlags
dflags (IO (Maybe DataCon) -> IO (Maybe DataCon))
-> IO (Maybe DataCon) -> IO (Maybe DataCon)
forall a b. (a -> b) -> a -> b
$ (TyThing -> Maybe DataCon) -> IO TyThing -> IO (Maybe DataCon)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (DataCon -> Maybe DataCon
forall a. a -> Maybe a
Just (DataCon -> Maybe DataCon)
-> (TyThing -> DataCon) -> TyThing -> Maybe DataCon
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyThing -> DataCon
tyThingDataCon) (IO TyThing -> IO (Maybe DataCon))
-> IO TyThing -> IO (Maybe DataCon)
forall a b. (a -> b) -> a -> b
$
HscEnv -> Name -> IO TyThing
lookupGlobal HscEnv
hsc_env Name
naturalSDataConName
IntegerSimple -> Maybe DataCon -> IO (Maybe DataCon)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe DataCon
forall a. Maybe a
Nothing
guardIntegerUse :: DynFlags -> IO a -> IO a
guardIntegerUse :: DynFlags -> IO a -> IO a
guardIntegerUse dflags :: DynFlags
dflags act :: IO a
act
| DynFlags -> UnitId
thisPackage DynFlags
dflags UnitId -> UnitId -> Bool
forall a. Eq a => a -> a -> Bool
== UnitId
primUnitId
= a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> IO a) -> a -> IO a
forall a b. (a -> b) -> a -> b
$ String -> a
forall a. String -> a
panic "Can't use Integer in ghc-prim"
| DynFlags -> UnitId
thisPackage DynFlags
dflags UnitId -> UnitId -> Bool
forall a. Eq a => a -> a -> Bool
== UnitId
integerUnitId
= a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> IO a) -> a -> IO a
forall a b. (a -> b) -> a -> b
$ String -> a
forall a. String -> a
panic "Can't use Integer in integer-*"
| Bool
otherwise = IO a
act
guardNaturalUse :: DynFlags -> IO a -> IO a
guardNaturalUse :: DynFlags -> IO a -> IO a
guardNaturalUse dflags :: DynFlags
dflags act :: IO a
act
| DynFlags -> UnitId
thisPackage DynFlags
dflags UnitId -> UnitId -> Bool
forall a. Eq a => a -> a -> Bool
== UnitId
primUnitId
= a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> IO a) -> a -> IO a
forall a b. (a -> b) -> a -> b
$ String -> a
forall a. String -> a
panic "Can't use Natural in ghc-prim"
| DynFlags -> UnitId
thisPackage DynFlags
dflags UnitId -> UnitId -> Bool
forall a. Eq a => a -> a -> Bool
== UnitId
integerUnitId
= a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> IO a) -> a -> IO a
forall a b. (a -> b) -> a -> b
$ String -> a
forall a. String -> a
panic "Can't use Natural in integer-*"
| DynFlags -> UnitId
thisPackage DynFlags
dflags UnitId -> UnitId -> Bool
forall a. Eq a => a -> a -> Bool
== UnitId
baseUnitId
= a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> IO a) -> a -> IO a
forall a b. (a -> b) -> a -> b
$ String -> a
forall a. String -> a
panic "Can't use Natural in base"
| Bool
otherwise = IO a
act
mkInitialCorePrepEnv :: DynFlags -> HscEnv -> IO CorePrepEnv
mkInitialCorePrepEnv :: DynFlags -> HscEnv -> IO CorePrepEnv
mkInitialCorePrepEnv dflags :: DynFlags
dflags hsc_env :: HscEnv
hsc_env
= do Id
mkIntegerId <- DynFlags -> HscEnv -> IO Id
lookupMkIntegerName DynFlags
dflags HscEnv
hsc_env
Id
mkNaturalId <- DynFlags -> HscEnv -> IO Id
lookupMkNaturalName DynFlags
dflags HscEnv
hsc_env
Maybe DataCon
integerSDataCon <- DynFlags -> HscEnv -> IO (Maybe DataCon)
lookupIntegerSDataConName DynFlags
dflags HscEnv
hsc_env
Maybe DataCon
naturalSDataCon <- DynFlags -> HscEnv -> IO (Maybe DataCon)
lookupNaturalSDataConName DynFlags
dflags HscEnv
hsc_env
CorePrepEnv -> IO CorePrepEnv
forall (m :: * -> *) a. Monad m => a -> m a
return (CorePrepEnv -> IO CorePrepEnv) -> CorePrepEnv -> IO CorePrepEnv
forall a b. (a -> b) -> a -> b
$ CPE :: DynFlags
-> IdEnv CoreExpr
-> Id
-> Id
-> Maybe DataCon
-> Maybe DataCon
-> CorePrepEnv
CPE {
cpe_dynFlags :: DynFlags
cpe_dynFlags = DynFlags
dflags,
cpe_env :: IdEnv CoreExpr
cpe_env = IdEnv CoreExpr
forall a. VarEnv a
emptyVarEnv,
cpe_mkIntegerId :: Id
cpe_mkIntegerId = Id
mkIntegerId,
cpe_mkNaturalId :: Id
cpe_mkNaturalId = Id
mkNaturalId,
cpe_integerSDataCon :: Maybe DataCon
cpe_integerSDataCon = Maybe DataCon
integerSDataCon,
cpe_naturalSDataCon :: Maybe DataCon
cpe_naturalSDataCon = Maybe DataCon
naturalSDataCon
}
extendCorePrepEnv :: CorePrepEnv -> Id -> Id -> CorePrepEnv
extendCorePrepEnv :: CorePrepEnv -> Id -> Id -> CorePrepEnv
extendCorePrepEnv cpe :: CorePrepEnv
cpe id :: Id
id id' :: Id
id'
= CorePrepEnv
cpe { cpe_env :: IdEnv CoreExpr
cpe_env = IdEnv CoreExpr -> Id -> CoreExpr -> IdEnv CoreExpr
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv (CorePrepEnv -> IdEnv CoreExpr
cpe_env CorePrepEnv
cpe) Id
id (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
id') }
extendCorePrepEnvExpr :: CorePrepEnv -> Id -> CoreExpr -> CorePrepEnv
extendCorePrepEnvExpr :: CorePrepEnv -> Id -> CoreExpr -> CorePrepEnv
extendCorePrepEnvExpr cpe :: CorePrepEnv
cpe id :: Id
id expr :: CoreExpr
expr
= CorePrepEnv
cpe { cpe_env :: IdEnv CoreExpr
cpe_env = IdEnv CoreExpr -> Id -> CoreExpr -> IdEnv CoreExpr
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv (CorePrepEnv -> IdEnv CoreExpr
cpe_env CorePrepEnv
cpe) Id
id CoreExpr
expr }
extendCorePrepEnvList :: CorePrepEnv -> [(Id,Id)] -> CorePrepEnv
extendCorePrepEnvList :: CorePrepEnv -> [(Id, Id)] -> CorePrepEnv
extendCorePrepEnvList cpe :: CorePrepEnv
cpe prs :: [(Id, Id)]
prs
= CorePrepEnv
cpe { cpe_env :: IdEnv CoreExpr
cpe_env = IdEnv CoreExpr -> [(Id, CoreExpr)] -> IdEnv CoreExpr
forall a. VarEnv a -> [(Id, a)] -> VarEnv a
extendVarEnvList (CorePrepEnv -> IdEnv CoreExpr
cpe_env CorePrepEnv
cpe)
(((Id, Id) -> (Id, CoreExpr)) -> [(Id, Id)] -> [(Id, CoreExpr)]
forall a b. (a -> b) -> [a] -> [b]
map (\(id :: Id
id, id' :: Id
id') -> (Id
id, Id -> CoreExpr
forall b. Id -> Expr b
Var Id
id')) [(Id, Id)]
prs) }
lookupCorePrepEnv :: CorePrepEnv -> Id -> CoreExpr
lookupCorePrepEnv :: CorePrepEnv -> Id -> CoreExpr
lookupCorePrepEnv cpe :: CorePrepEnv
cpe id :: Id
id
= case IdEnv CoreExpr -> Id -> Maybe CoreExpr
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv (CorePrepEnv -> IdEnv CoreExpr
cpe_env CorePrepEnv
cpe) Id
id of
Nothing -> Id -> CoreExpr
forall b. Id -> Expr b
Var Id
id
Just exp :: CoreExpr
exp -> CoreExpr
exp
getMkIntegerId :: CorePrepEnv -> Id
getMkIntegerId :: CorePrepEnv -> Id
getMkIntegerId = CorePrepEnv -> Id
cpe_mkIntegerId
getMkNaturalId :: CorePrepEnv -> Id
getMkNaturalId :: CorePrepEnv -> Id
getMkNaturalId = CorePrepEnv -> Id
cpe_mkNaturalId
cpCloneBndrs :: CorePrepEnv -> [InVar] -> UniqSM (CorePrepEnv, [OutVar])
cpCloneBndrs :: CorePrepEnv -> [Id] -> UniqSM (CorePrepEnv, [Id])
cpCloneBndrs env :: CorePrepEnv
env bs :: [Id]
bs = (CorePrepEnv -> Id -> UniqSM (CorePrepEnv, Id))
-> CorePrepEnv -> [Id] -> UniqSM (CorePrepEnv, [Id])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM CorePrepEnv -> Id -> UniqSM (CorePrepEnv, Id)
cpCloneBndr CorePrepEnv
env [Id]
bs
cpCloneBndr :: CorePrepEnv -> InVar -> UniqSM (CorePrepEnv, OutVar)
cpCloneBndr :: CorePrepEnv -> Id -> UniqSM (CorePrepEnv, Id)
cpCloneBndr env :: CorePrepEnv
env bndr :: Id
bndr
| Bool -> Bool
not (Id -> Bool
isId Id
bndr)
= (CorePrepEnv, Id) -> UniqSM (CorePrepEnv, Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (CorePrepEnv
env, Id
bndr)
| Bool
otherwise
= do { Id
bndr' <- Id -> UniqSM Id
forall (m :: * -> *). MonadUnique m => Id -> m Id
clone_it Id
bndr
; let unfolding' :: Unfolding
unfolding' = Unfolding -> Unfolding
zapUnfolding (Id -> Unfolding
realIdUnfolding Id
bndr)
bndr'' :: Id
bndr'' = Id
bndr' Id -> Unfolding -> Id
`setIdUnfolding` Unfolding
unfolding'
Id -> RuleInfo -> Id
`setIdSpecialisation` RuleInfo
emptyRuleInfo
; (CorePrepEnv, Id) -> UniqSM (CorePrepEnv, Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (CorePrepEnv -> Id -> Id -> CorePrepEnv
extendCorePrepEnv CorePrepEnv
env Id
bndr Id
bndr'', Id
bndr'') }
where
clone_it :: Id -> m Id
clone_it bndr :: Id
bndr
| Id -> Bool
isLocalId Id
bndr, Bool -> Bool
not (Id -> Bool
isCoVar Id
bndr)
= do { Unique
uniq <- m Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM; Id -> m Id
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Unique -> Id
setVarUnique Id
bndr Unique
uniq) }
| Bool
otherwise
= Id -> m Id
forall (m :: * -> *) a. Monad m => a -> m a
return Id
bndr
fiddleCCall :: Id -> UniqSM Id
fiddleCCall :: Id -> UniqSM Id
fiddleCCall id :: Id
id
| Id -> Bool
isFCallId Id
id = (Id
id Id -> Unique -> Id
`setVarUnique`) (Unique -> Id) -> UniqSM Unique -> UniqSM Id
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UniqSM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
| Bool
otherwise = Id -> UniqSM Id
forall (m :: * -> *) a. Monad m => a -> m a
return Id
id
newVar :: Type -> UniqSM Id
newVar :: Type -> UniqSM Id
newVar ty :: Type
ty
= Type -> ()
seqType Type
ty () -> UniqSM Id -> UniqSM Id
forall a b. a -> b -> b
`seq` do
Unique
uniq <- UniqSM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
Id -> UniqSM Id
forall (m :: * -> *) a. Monad m => a -> m a
return (FastString -> Unique -> Type -> Id
mkSysLocalOrCoVar (String -> FastString
fsLit "sat") Unique
uniq Type
ty)
wrapTicks :: Floats -> CoreExpr -> (Floats, CoreExpr)
wrapTicks :: Floats -> CoreExpr -> (Floats, CoreExpr)
wrapTicks (Floats flag :: OkToSpec
flag floats0 :: OrdList FloatingBind
floats0) expr :: CoreExpr
expr =
(OkToSpec -> OrdList FloatingBind -> Floats
Floats OkToSpec
flag ([FloatingBind] -> OrdList FloatingBind
forall a. [a] -> OrdList a
toOL ([FloatingBind] -> OrdList FloatingBind)
-> [FloatingBind] -> OrdList FloatingBind
forall a b. (a -> b) -> a -> b
$ [FloatingBind] -> [FloatingBind]
forall a. [a] -> [a]
reverse [FloatingBind]
floats1), (Tickish Id -> CoreExpr -> CoreExpr)
-> CoreExpr -> [Tickish Id] -> CoreExpr
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tickish Id -> CoreExpr -> CoreExpr
mkTick CoreExpr
expr ([Tickish Id] -> [Tickish Id]
forall a. [a] -> [a]
reverse [Tickish Id]
ticks1))
where (floats1 :: [FloatingBind]
floats1, ticks1 :: [Tickish Id]
ticks1) = (([FloatingBind], [Tickish Id])
-> FloatingBind -> ([FloatingBind], [Tickish Id]))
-> ([FloatingBind], [Tickish Id])
-> OrdList FloatingBind
-> ([FloatingBind], [Tickish Id])
forall b a. (b -> a -> b) -> b -> OrdList a -> b
foldlOL ([FloatingBind], [Tickish Id])
-> FloatingBind -> ([FloatingBind], [Tickish Id])
go ([], []) (OrdList FloatingBind -> ([FloatingBind], [Tickish Id]))
-> OrdList FloatingBind -> ([FloatingBind], [Tickish Id])
forall a b. (a -> b) -> a -> b
$ OrdList FloatingBind
floats0
go :: ([FloatingBind], [Tickish Id])
-> FloatingBind -> ([FloatingBind], [Tickish Id])
go (floats :: [FloatingBind]
floats, ticks :: [Tickish Id]
ticks) (FloatTick t :: Tickish Id
t)
= ASSERT(tickishPlace t == PlaceNonLam)
([FloatingBind]
floats, if (Tickish Id -> Bool) -> [Tickish Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((Tickish Id -> Tickish Id -> Bool)
-> Tickish Id -> Tickish Id -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Tickish Id -> Tickish Id -> Bool
forall b. Eq b => Tickish b -> Tickish b -> Bool
tickishContains Tickish Id
t) [Tickish Id]
ticks
then [Tickish Id]
ticks else Tickish Id
tTickish Id -> [Tickish Id] -> [Tickish Id]
forall a. a -> [a] -> [a]
:[Tickish Id]
ticks)
go (floats :: [FloatingBind]
floats, ticks :: [Tickish Id]
ticks) f :: FloatingBind
f
= ((Tickish Id -> FloatingBind -> FloatingBind)
-> FloatingBind -> [Tickish Id] -> FloatingBind
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Tickish Id -> FloatingBind -> FloatingBind
wrap FloatingBind
f ([Tickish Id] -> [Tickish Id]
forall a. [a] -> [a]
reverse [Tickish Id]
ticks)FloatingBind -> [FloatingBind] -> [FloatingBind]
forall a. a -> [a] -> [a]
:[FloatingBind]
floats, [Tickish Id]
ticks)
wrap :: Tickish Id -> FloatingBind -> FloatingBind
wrap t :: Tickish Id
t (FloatLet bind :: CoreBind
bind) = CoreBind -> FloatingBind
FloatLet (Tickish Id -> CoreBind -> CoreBind
wrapBind Tickish Id
t CoreBind
bind)
wrap t :: Tickish Id
t (FloatCase b :: Id
b r :: CoreExpr
r ok :: Bool
ok) = Id -> CoreExpr -> Bool -> FloatingBind
FloatCase Id
b (Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
t CoreExpr
r) Bool
ok
wrap _ other :: FloatingBind
other = String -> SDoc -> FloatingBind
forall a. HasCallStack => String -> SDoc -> a
pprPanic "wrapTicks: unexpected float!"
(FloatingBind -> SDoc
forall a. Outputable a => a -> SDoc
ppr FloatingBind
other)
wrapBind :: Tickish Id -> CoreBind -> CoreBind
wrapBind t :: Tickish Id
t (NonRec binder :: Id
binder rhs :: CoreExpr
rhs) = Id -> CoreExpr -> CoreBind
forall b. b -> Expr b -> Bind b
NonRec Id
binder (Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
t CoreExpr
rhs)
wrapBind t :: Tickish Id
t (Rec pairs :: [(Id, CoreExpr)]
pairs) = [(Id, CoreExpr)] -> CoreBind
forall b. [(b, Expr b)] -> Bind b
Rec ((CoreExpr -> CoreExpr) -> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
forall b c a. (b -> c) -> [(a, b)] -> [(a, c)]
mapSnd (Tickish Id -> CoreExpr -> CoreExpr
mkTick Tickish Id
t) [(Id, CoreExpr)]
pairs)
collectCostCentres :: Module -> CoreProgram -> S.Set CostCentre
collectCostCentres :: Module -> CoreProgram -> Set CostCentre
collectCostCentres mod_name :: Module
mod_name
= (Set CostCentre -> CoreBind -> Set CostCentre)
-> Set CostCentre -> CoreProgram -> Set CostCentre
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Set CostCentre -> CoreBind -> Set CostCentre
go_bind Set CostCentre
forall a. Set a
S.empty
where
go :: Set CostCentre -> CoreExpr -> Set CostCentre
go cs :: Set CostCentre
cs e :: CoreExpr
e = case CoreExpr
e of
Var{} -> Set CostCentre
cs
Lit{} -> Set CostCentre
cs
App e1 :: CoreExpr
e1 e2 :: CoreExpr
e2 -> Set CostCentre -> CoreExpr -> Set CostCentre
go (Set CostCentre -> CoreExpr -> Set CostCentre
go Set CostCentre
cs CoreExpr
e1) CoreExpr
e2
Lam _ e :: CoreExpr
e -> Set CostCentre -> CoreExpr -> Set CostCentre
go Set CostCentre
cs CoreExpr
e
Let b :: CoreBind
b e :: CoreExpr
e -> Set CostCentre -> CoreExpr -> Set CostCentre
go (Set CostCentre -> CoreBind -> Set CostCentre
go_bind Set CostCentre
cs CoreBind
b) CoreExpr
e
Case scrt :: CoreExpr
scrt _ _ alts :: [Alt Id]
alts -> Set CostCentre -> [Alt Id] -> Set CostCentre
go_alts (Set CostCentre -> CoreExpr -> Set CostCentre
go Set CostCentre
cs CoreExpr
scrt) [Alt Id]
alts
Cast e :: CoreExpr
e _ -> Set CostCentre -> CoreExpr -> Set CostCentre
go Set CostCentre
cs CoreExpr
e
Tick (ProfNote cc :: CostCentre
cc _ _) e :: CoreExpr
e ->
Set CostCentre -> CoreExpr -> Set CostCentre
go (if CostCentre -> Module -> Bool
ccFromThisModule CostCentre
cc Module
mod_name then CostCentre -> Set CostCentre -> Set CostCentre
forall a. Ord a => a -> Set a -> Set a
S.insert CostCentre
cc Set CostCentre
cs else Set CostCentre
cs) CoreExpr
e
Tick _ e :: CoreExpr
e -> Set CostCentre -> CoreExpr -> Set CostCentre
go Set CostCentre
cs CoreExpr
e
Type{} -> Set CostCentre
cs
Coercion{} -> Set CostCentre
cs
go_alts :: Set CostCentre -> [Alt Id] -> Set CostCentre
go_alts = (Set CostCentre -> Alt Id -> Set CostCentre)
-> Set CostCentre -> [Alt Id] -> Set CostCentre
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\cs :: Set CostCentre
cs (_con :: AltCon
_con, _bndrs :: [Id]
_bndrs, e :: CoreExpr
e) -> Set CostCentre -> CoreExpr -> Set CostCentre
go Set CostCentre
cs CoreExpr
e)
go_bind :: S.Set CostCentre -> CoreBind -> S.Set CostCentre
go_bind :: Set CostCentre -> CoreBind -> Set CostCentre
go_bind cs :: Set CostCentre
cs (NonRec b :: Id
b e :: CoreExpr
e) =
Set CostCentre -> CoreExpr -> Set CostCentre
go (Set CostCentre
-> (CoreExpr -> Set CostCentre) -> Maybe CoreExpr -> Set CostCentre
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Set CostCentre
cs (Set CostCentre -> CoreExpr -> Set CostCentre
go Set CostCentre
cs) (Id -> Maybe CoreExpr
get_unf Id
b)) CoreExpr
e
go_bind cs :: Set CostCentre
cs (Rec bs :: [(Id, CoreExpr)]
bs) =
(Set CostCentre -> (Id, CoreExpr) -> Set CostCentre)
-> Set CostCentre -> [(Id, CoreExpr)] -> Set CostCentre
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\cs' :: Set CostCentre
cs' (b :: Id
b, e :: CoreExpr
e) -> Set CostCentre -> CoreExpr -> Set CostCentre
go (Set CostCentre
-> (CoreExpr -> Set CostCentre) -> Maybe CoreExpr -> Set CostCentre
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Set CostCentre
cs' (Set CostCentre -> CoreExpr -> Set CostCentre
go Set CostCentre
cs') (Id -> Maybe CoreExpr
get_unf Id
b)) CoreExpr
e) Set CostCentre
cs [(Id, CoreExpr)]
bs
get_unf :: Id -> Maybe CoreExpr
get_unf = Unfolding -> Maybe CoreExpr
maybeUnfoldingTemplate (Unfolding -> Maybe CoreExpr)
-> (Id -> Unfolding) -> Id -> Maybe CoreExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> Unfolding
realIdUnfolding