{-# LANGUAGE CPP #-}
module GHC.Core.Opt.Simplify
( SimplifyExprOpts(..), SimplifyOpts(..)
, simplifyExpr, simplifyPgm
) where
import GHC.Prelude
import GHC.Driver.Flags
import GHC.Core
import GHC.Core.Rules
import GHC.Core.Ppr ( pprCoreBindings, pprCoreExpr )
import GHC.Core.Opt.OccurAnal ( occurAnalysePgm, occurAnalyseExpr )
import GHC.Core.Stats ( coreBindsSize, coreBindsStats, exprSize )
import GHC.Core.Utils ( mkTicks, stripTicksTop )
import GHC.Core.Lint ( LintPassResultConfig, dumpPassResult, lintPassResult )
import GHC.Core.Opt.Simplify.Iteration ( simplTopBinds, simplExpr, simplImpRules )
import GHC.Core.Opt.Simplify.Utils ( activeRule, activeUnfolding )
import GHC.Core.Opt.Simplify.Env
import GHC.Core.Opt.Simplify.Monad
import GHC.Core.Opt.Stats ( simplCountN )
import GHC.Core.FamInstEnv
import GHC.Utils.Error ( withTiming )
import GHC.Utils.Logger as Logger
import GHC.Utils.Outputable
import GHC.Utils.Constants (debugIsOn)
import GHC.Unit.Env ( UnitEnv, ueEPS )
import GHC.Unit.External
import GHC.Unit.Module.ModGuts
import GHC.Types.Id
import GHC.Types.Id.Info
import GHC.Types.Basic
import GHC.Types.Var.Set
import GHC.Types.Var.Env
import GHC.Types.Tickish
import GHC.Types.Unique.FM
import Control.Monad
import Data.Foldable ( for_ )
#if __GLASGOW_HASKELL__ <= 810
import GHC.Utils.Panic ( panic )
#endif
data SimplifyExprOpts = SimplifyExprOpts
{ SimplifyExprOpts -> [FamInst]
se_fam_inst :: ![FamInst]
, SimplifyExprOpts -> SimplMode
se_mode :: !SimplMode
, SimplifyExprOpts -> TopEnvConfig
se_top_env_cfg :: !TopEnvConfig
}
simplifyExpr :: Logger
-> ExternalUnitCache
-> SimplifyExprOpts
-> CoreExpr
-> IO CoreExpr
simplifyExpr :: Logger
-> ExternalUnitCache -> SimplifyExprOpts -> CoreExpr -> IO CoreExpr
simplifyExpr Logger
logger ExternalUnitCache
euc SimplifyExprOpts
opts CoreExpr
expr
= forall (m :: * -> *) a.
MonadIO m =>
Logger -> SDoc -> (a -> ()) -> m a -> m a
withTiming Logger
logger (forall doc. IsLine doc => String -> doc
text String
"Simplify [expr]") (forall a b. a -> b -> a
const ()) forall a b. (a -> b) -> a -> b
$
do { ExternalPackageState
eps <- ExternalUnitCache -> IO ExternalPackageState
eucEPS ExternalUnitCache
euc ;
; let fam_envs :: (PackageFamInstEnv, PackageFamInstEnv)
fam_envs = ( ExternalPackageState -> PackageFamInstEnv
eps_fam_inst_env ExternalPackageState
eps
, PackageFamInstEnv -> [FamInst] -> PackageFamInstEnv
extendFamInstEnvList PackageFamInstEnv
emptyFamInstEnv forall a b. (a -> b) -> a -> b
$ SimplifyExprOpts -> [FamInst]
se_fam_inst SimplifyExprOpts
opts
)
simpl_env :: SimplEnv
simpl_env = SimplMode -> (PackageFamInstEnv, PackageFamInstEnv) -> SimplEnv
mkSimplEnv (SimplifyExprOpts -> SimplMode
se_mode SimplifyExprOpts
opts) (PackageFamInstEnv, PackageFamInstEnv)
fam_envs
top_env_cfg :: TopEnvConfig
top_env_cfg = SimplifyExprOpts -> TopEnvConfig
se_top_env_cfg SimplifyExprOpts
opts
read_eps_rules :: IO PackageRuleBase
read_eps_rules = ExternalPackageState -> PackageRuleBase
eps_rule_base forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ExternalUnitCache -> IO ExternalPackageState
eucEPS ExternalUnitCache
euc
read_ruleenv :: IO RuleEnv
read_ruleenv = RuleEnv -> PackageRuleBase -> RuleEnv
updExternalPackageRules RuleEnv
emptyRuleEnv forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO PackageRuleBase
read_eps_rules
; let sz :: Int
sz = CoreExpr -> Int
exprSize CoreExpr
expr
; (CoreExpr
expr', SimplCount
counts) <- forall a.
Logger
-> IO RuleEnv
-> TopEnvConfig
-> Int
-> SimplM a
-> IO (a, SimplCount)
initSmpl Logger
logger IO RuleEnv
read_ruleenv TopEnvConfig
top_env_cfg Int
sz forall a b. (a -> b) -> a -> b
$
SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExprGently SimplEnv
simpl_env CoreExpr
expr
; Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
Logger.putDumpFileMaybe Logger
logger DumpFlag
Opt_D_dump_simpl_stats
String
"Simplifier statistics" DumpFormat
FormatText (SimplCount -> SDoc
pprSimplCount SimplCount
counts)
; Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
Logger.putDumpFileMaybe Logger
logger DumpFlag
Opt_D_dump_simpl String
"Simplified expression"
DumpFormat
FormatCore
(forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr CoreExpr
expr')
; forall (m :: * -> *) a. Monad m => a -> m a
return CoreExpr
expr'
}
simplExprGently :: SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExprGently :: SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExprGently SimplEnv
env CoreExpr
expr = do
CoreExpr
expr1 <- SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
env (CoreExpr -> CoreExpr
occurAnalyseExpr CoreExpr
expr)
SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExpr SimplEnv
env (CoreExpr -> CoreExpr
occurAnalyseExpr CoreExpr
expr1)
data SimplifyOpts = SimplifyOpts
{ SimplifyOpts -> Bool
so_dump_core_sizes :: !Bool
, SimplifyOpts -> Int
so_iterations :: !Int
, SimplifyOpts -> SimplMode
so_mode :: !SimplMode
, SimplifyOpts -> Maybe LintPassResultConfig
so_pass_result_cfg :: !(Maybe LintPassResultConfig)
, SimplifyOpts -> PackageRuleBase
so_hpt_rules :: !RuleBase
, SimplifyOpts -> TopEnvConfig
so_top_env_cfg :: !TopEnvConfig
}
simplifyPgm :: Logger
-> UnitEnv
-> NamePprCtx
-> SimplifyOpts
-> ModGuts
-> IO (SimplCount, ModGuts)
simplifyPgm :: Logger
-> UnitEnv
-> NamePprCtx
-> SimplifyOpts
-> ModGuts
-> IO (SimplCount, ModGuts)
simplifyPgm Logger
logger UnitEnv
unit_env NamePprCtx
name_ppr_ctx SimplifyOpts
opts
guts :: ModGuts
guts@(ModGuts { mg_module :: ModGuts -> Module
mg_module = Module
this_mod
, mg_binds :: ModGuts -> CoreProgram
mg_binds = CoreProgram
binds, mg_rules :: ModGuts -> [CoreRule]
mg_rules = [CoreRule]
local_rules
, mg_fam_inst_env :: ModGuts -> PackageFamInstEnv
mg_fam_inst_env = PackageFamInstEnv
fam_inst_env })
= do { (String
termination_msg, Int
it_count, SimplCount
counts_out, ModGuts
guts')
<- Int
-> [SimplCount]
-> CoreProgram
-> [CoreRule]
-> IO (String, Int, SimplCount, ModGuts)
do_iteration Int
1 [] CoreProgram
binds [CoreRule]
local_rules
; forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Logger -> DumpFlag -> Bool
logHasDumpFlag Logger
logger DumpFlag
Opt_D_verbose_core2core
Bool -> Bool -> Bool
&& Logger -> DumpFlag -> Bool
logHasDumpFlag Logger
logger DumpFlag
Opt_D_dump_simpl_stats) forall a b. (a -> b) -> a -> b
$
Logger -> String -> SDoc -> IO ()
logDumpMsg Logger
logger
String
"Simplifier statistics for following pass"
(forall doc. IsDoc doc => [doc] -> doc
vcat [forall doc. IsLine doc => String -> doc
text String
termination_msg forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => String -> doc
text String
"after" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr Int
it_count
forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => String -> doc
text String
"iterations",
SDoc
blankLine,
SimplCount -> SDoc
pprSimplCount SimplCount
counts_out])
; forall (m :: * -> *) a. Monad m => a -> m a
return (SimplCount
counts_out, ModGuts
guts')
}
where
dump_core_sizes :: Bool
dump_core_sizes = SimplifyOpts -> Bool
so_dump_core_sizes SimplifyOpts
opts
mode :: SimplMode
mode = SimplifyOpts -> SimplMode
so_mode SimplifyOpts
opts
max_iterations :: Int
max_iterations = SimplifyOpts -> Int
so_iterations SimplifyOpts
opts
top_env_cfg :: TopEnvConfig
top_env_cfg = SimplifyOpts -> TopEnvConfig
so_top_env_cfg SimplifyOpts
opts
active_rule :: Activation -> Bool
active_rule = SimplMode -> Activation -> Bool
activeRule SimplMode
mode
active_unf :: Id -> Bool
active_unf = SimplMode -> Id -> Bool
activeUnfolding SimplMode
mode
!guts_no_binds :: ModGuts
guts_no_binds = ModGuts
guts { mg_binds :: CoreProgram
mg_binds = [], mg_rules :: [CoreRule]
mg_rules = [] }
hpt_rule_env :: RuleEnv
hpt_rule_env :: RuleEnv
hpt_rule_env = ModGuts -> PackageRuleBase -> PackageRuleBase -> RuleEnv
mkRuleEnv ModGuts
guts PackageRuleBase
emptyRuleBase (SimplifyOpts -> PackageRuleBase
so_hpt_rules SimplifyOpts
opts)
do_iteration :: Int
-> [SimplCount]
-> CoreProgram
-> [CoreRule]
-> IO (String, Int, SimplCount, ModGuts)
do_iteration :: Int
-> [SimplCount]
-> CoreProgram
-> [CoreRule]
-> IO (String, Int, SimplCount, ModGuts)
do_iteration Int
iteration_no [SimplCount]
counts_so_far CoreProgram
binds [CoreRule]
local_rules
| Int
iteration_no forall a. Ord a => a -> a -> Bool
> Int
max_iterations
= forall a. HasCallStack => Bool -> String -> SDoc -> a -> a
warnPprTrace (Bool
debugIsOn Bool -> Bool -> Bool
&& (Int
max_iterations forall a. Ord a => a -> a -> Bool
> Int
2))
String
"Simplifier bailing out"
( SDoc -> Int -> SDoc -> SDoc
hang (forall a. Outputable a => a -> SDoc
ppr Module
this_mod forall doc. IsLine doc => doc -> doc -> doc
<> forall doc. IsLine doc => String -> doc
text String
", after"
forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => Int -> doc
int Int
max_iterations forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => String -> doc
text String
"iterations"
forall doc. IsLine doc => doc -> doc -> doc
<+> (forall doc. IsLine doc => doc -> doc
brackets forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => [doc] -> doc
hsep forall a b. (a -> b) -> a -> b
$ forall doc. IsLine doc => doc -> [doc] -> [doc]
punctuate forall doc. IsLine doc => doc
comma forall a b. (a -> b) -> a -> b
$
forall a b. (a -> b) -> [a] -> [b]
map (forall doc. IsLine doc => Int -> doc
int forall b c a. (b -> c) -> (a -> b) -> a -> c
. SimplCount -> Int
simplCountN) (forall a. [a] -> [a]
reverse [SimplCount]
counts_so_far)))
Int
2 (forall doc. IsLine doc => String -> doc
text String
"Size =" forall doc. IsLine doc => doc -> doc -> doc
<+> forall a. Outputable a => a -> SDoc
ppr (CoreProgram -> CoreStats
coreBindsStats CoreProgram
binds))) forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) a. Monad m => a -> m a
return ( String
"Simplifier baled out", Int
iteration_no forall a. Num a => a -> a -> a
- Int
1
, [SimplCount] -> SimplCount
totalise [SimplCount]
counts_so_far
, ModGuts
guts_no_binds { mg_binds :: CoreProgram
mg_binds = CoreProgram
binds, mg_rules :: [CoreRule]
mg_rules = [CoreRule]
local_rules } )
| let sz :: Int
sz = CoreProgram -> Int
coreBindsSize CoreProgram
binds
, () <- Int
sz seq :: forall a b. a -> b -> b
`seq` ()
= do {
let { tagged_binds :: CoreProgram
tagged_binds = {-# SCC "OccAnal" #-}
Module
-> (Id -> Bool)
-> (Activation -> Bool)
-> [CoreRule]
-> CoreProgram
-> CoreProgram
occurAnalysePgm Module
this_mod Id -> Bool
active_unf Activation -> Bool
active_rule
[CoreRule]
local_rules CoreProgram
binds
} ;
Logger -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
Logger.putDumpFileMaybe Logger
logger DumpFlag
Opt_D_dump_occur_anal String
"Occurrence analysis"
DumpFormat
FormatCore
(forall b. OutputableBndr b => [Bind b] -> SDoc
pprCoreBindings CoreProgram
tagged_binds);
ExternalPackageState
eps <- UnitEnv -> IO ExternalPackageState
ueEPS UnitEnv
unit_env ;
let {
; !base_rule_env :: RuleEnv
base_rule_env = RuleEnv -> [CoreRule] -> RuleEnv
updLocalRules RuleEnv
hpt_rule_env [CoreRule]
local_rules
; read_eps_rules :: IO PackageRuleBase
; read_eps_rules :: IO PackageRuleBase
read_eps_rules = ExternalPackageState -> PackageRuleBase
eps_rule_base forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> UnitEnv -> IO ExternalPackageState
ueEPS UnitEnv
unit_env
; read_rule_env :: IO RuleEnv
; read_rule_env :: IO RuleEnv
read_rule_env = RuleEnv -> PackageRuleBase -> RuleEnv
updExternalPackageRules RuleEnv
base_rule_env forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO PackageRuleBase
read_eps_rules
; fam_envs :: (PackageFamInstEnv, PackageFamInstEnv)
fam_envs = (ExternalPackageState -> PackageFamInstEnv
eps_fam_inst_env ExternalPackageState
eps, PackageFamInstEnv
fam_inst_env)
; simpl_env :: SimplEnv
simpl_env = SimplMode -> (PackageFamInstEnv, PackageFamInstEnv) -> SimplEnv
mkSimplEnv SimplMode
mode (PackageFamInstEnv, PackageFamInstEnv)
fam_envs } ;
((CoreProgram
binds1, [CoreRule]
rules1), SimplCount
counts1) <-
forall a.
Logger
-> IO RuleEnv
-> TopEnvConfig
-> Int
-> SimplM a
-> IO (a, SimplCount)
initSmpl Logger
logger IO RuleEnv
read_rule_env TopEnvConfig
top_env_cfg Int
sz forall a b. (a -> b) -> a -> b
$
do { (SimplFloats
floats, SimplEnv
env1) <- {-# SCC "SimplTopBinds" #-}
SimplEnv -> CoreProgram -> SimplM (SimplFloats, SimplEnv)
simplTopBinds SimplEnv
simpl_env CoreProgram
tagged_binds
; [CoreRule]
rules1 <- SimplEnv -> [CoreRule] -> SimplM [CoreRule]
simplImpRules SimplEnv
env1 [CoreRule]
local_rules
; forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats -> CoreProgram
getTopFloatBinds SimplFloats
floats, [CoreRule]
rules1) } ;
if SimplCount -> Bool
isZeroSimplCount SimplCount
counts1 then
forall (m :: * -> *) a. Monad m => a -> m a
return ( String
"Simplifier reached fixed point", Int
iteration_no
, [SimplCount] -> SimplCount
totalise (SimplCount
counts1 forall a. a -> [a] -> [a]
: [SimplCount]
counts_so_far)
, ModGuts
guts_no_binds { mg_binds :: CoreProgram
mg_binds = CoreProgram
binds1, mg_rules :: [CoreRule]
mg_rules = [CoreRule]
rules1 } )
else do {
let { binds2 :: CoreProgram
binds2 = {-# SCC "ZapInd" #-} CoreProgram -> CoreProgram
shortOutIndirections CoreProgram
binds1 } ;
Logger
-> Bool
-> NamePprCtx
-> Int
-> SimplCount
-> CoreProgram
-> [CoreRule]
-> IO ()
dump_end_iteration Logger
logger Bool
dump_core_sizes NamePprCtx
name_ppr_ctx Int
iteration_no SimplCount
counts1 CoreProgram
binds2 [CoreRule]
rules1 ;
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (SimplifyOpts -> Maybe LintPassResultConfig
so_pass_result_cfg SimplifyOpts
opts) forall a b. (a -> b) -> a -> b
$ \LintPassResultConfig
pass_result_cfg ->
Logger -> LintPassResultConfig -> CoreProgram -> IO ()
lintPassResult Logger
logger LintPassResultConfig
pass_result_cfg CoreProgram
binds2 ;
Int
-> [SimplCount]
-> CoreProgram
-> [CoreRule]
-> IO (String, Int, SimplCount, ModGuts)
do_iteration (Int
iteration_no forall a. Num a => a -> a -> a
+ Int
1) (SimplCount
counts1forall a. a -> [a] -> [a]
:[SimplCount]
counts_so_far) CoreProgram
binds2 [CoreRule]
rules1
} }
#if __GLASGOW_HASKELL__ <= 810
| otherwise = panic "do_iteration"
#endif
where
totalise :: [SimplCount] -> SimplCount
totalise :: [SimplCount] -> SimplCount
totalise = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\SimplCount
c SimplCount
acc -> SimplCount
acc SimplCount -> SimplCount -> SimplCount
`plusSimplCount` SimplCount
c)
(Bool -> SimplCount
zeroSimplCount forall a b. (a -> b) -> a -> b
$ Logger -> DumpFlag -> Bool
logHasDumpFlag Logger
logger DumpFlag
Opt_D_dump_simpl_stats)
dump_end_iteration :: Logger -> Bool -> NamePprCtx -> Int
-> SimplCount -> CoreProgram -> [CoreRule] -> IO ()
dump_end_iteration :: Logger
-> Bool
-> NamePprCtx
-> Int
-> SimplCount
-> CoreProgram
-> [CoreRule]
-> IO ()
dump_end_iteration Logger
logger Bool
dump_core_sizes NamePprCtx
name_ppr_ctx Int
iteration_no SimplCount
counts CoreProgram
binds [CoreRule]
rules
= Logger
-> Bool
-> NamePprCtx
-> Maybe DumpFlag
-> String
-> SDoc
-> CoreProgram
-> [CoreRule]
-> IO ()
dumpPassResult Logger
logger Bool
dump_core_sizes NamePprCtx
name_ppr_ctx Maybe DumpFlag
mb_flag String
hdr SDoc
pp_counts CoreProgram
binds [CoreRule]
rules
where
mb_flag :: Maybe DumpFlag
mb_flag | Logger -> DumpFlag -> Bool
logHasDumpFlag Logger
logger DumpFlag
Opt_D_dump_simpl_iterations = forall a. a -> Maybe a
Just DumpFlag
Opt_D_dump_simpl_iterations
| Bool
otherwise = forall a. Maybe a
Nothing
hdr :: String
hdr = String
"Simplifier iteration=" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show Int
iteration_no
pp_counts :: SDoc
pp_counts = forall doc. IsDoc doc => [doc] -> doc
vcat [ forall doc. IsLine doc => String -> doc
text String
"---- Simplifier counts for" forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => String -> doc
text String
hdr
, SimplCount -> SDoc
pprSimplCount SimplCount
counts
, forall doc. IsLine doc => String -> doc
text String
"---- End of simplifier counts for" forall doc. IsLine doc => doc -> doc -> doc
<+> forall doc. IsLine doc => String -> doc
text String
hdr ]
type IndEnv = IdEnv (Id, [CoreTickish])
shortOutIndirections :: CoreProgram -> CoreProgram
shortOutIndirections :: CoreProgram -> CoreProgram
shortOutIndirections CoreProgram
binds
| forall a. VarEnv a -> Bool
isEmptyVarEnv IndEnv
ind_env = CoreProgram
binds
| Bool
no_need_to_flatten = CoreProgram
binds'
| Bool
otherwise = [forall b. [(b, Expr b)] -> Bind b
Rec (forall b. [Bind b] -> [(b, Expr b)]
flattenBinds CoreProgram
binds')]
where
ind_env :: IndEnv
ind_env = CoreProgram -> IndEnv
makeIndEnv CoreProgram
binds
exp_ids :: [Id]
exp_ids = forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall key elt. UniqFM key elt -> [elt]
nonDetEltsUFM IndEnv
ind_env
exp_id_set :: VarSet
exp_id_set = [Id] -> VarSet
mkVarSet [Id]
exp_ids
no_need_to_flatten :: Bool
no_need_to_flatten = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall b c a. (b -> c) -> (a -> b) -> a -> c
. RuleInfo -> [CoreRule]
ruleInfoRules forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> RuleInfo
idSpecialisation) [Id]
exp_ids
binds' :: CoreProgram
binds' = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Bind Id -> CoreProgram
zap CoreProgram
binds
zap :: Bind Id -> CoreProgram
zap (NonRec Id
bndr CoreExpr
rhs) = [forall b. b -> Expr b -> Bind b
NonRec Id
b CoreExpr
r | (Id
b,CoreExpr
r) <- (Id, CoreExpr) -> [(Id, CoreExpr)]
zapPair (Id
bndr,CoreExpr
rhs)]
zap (Rec [(Id, CoreExpr)]
pairs) = [forall b. [(b, Expr b)] -> Bind b
Rec (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Id, CoreExpr) -> [(Id, CoreExpr)]
zapPair [(Id, CoreExpr)]
pairs)]
zapPair :: (Id, CoreExpr) -> [(Id, CoreExpr)]
zapPair (Id
bndr, CoreExpr
rhs)
| Id
bndr Id -> VarSet -> Bool
`elemVarSet` VarSet
exp_id_set
= []
| Just (Id
exp_id, [CoreTickish]
ticks) <- forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv IndEnv
ind_env Id
bndr
, (Id
exp_id', Id
lcl_id') <- Id -> Id -> (Id, Id)
transferIdInfo Id
exp_id Id
bndr
=
[ (Id
exp_id', [CoreTickish] -> CoreExpr -> CoreExpr
mkTicks [CoreTickish]
ticks CoreExpr
rhs),
(Id
lcl_id', forall b. Id -> Expr b
Var Id
exp_id') ]
| Bool
otherwise
= [(Id
bndr,CoreExpr
rhs)]
makeIndEnv :: [CoreBind] -> IndEnv
makeIndEnv :: CoreProgram -> IndEnv
makeIndEnv CoreProgram
binds
= forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' IndEnv -> Bind Id -> IndEnv
add_bind forall a. VarEnv a
emptyVarEnv CoreProgram
binds
where
add_bind :: IndEnv -> CoreBind -> IndEnv
add_bind :: IndEnv -> Bind Id -> IndEnv
add_bind IndEnv
env (NonRec Id
exported_id CoreExpr
rhs) = IndEnv -> (Id, CoreExpr) -> IndEnv
add_pair IndEnv
env (Id
exported_id, CoreExpr
rhs)
add_bind IndEnv
env (Rec [(Id, CoreExpr)]
pairs) = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' IndEnv -> (Id, CoreExpr) -> IndEnv
add_pair IndEnv
env [(Id, CoreExpr)]
pairs
add_pair :: IndEnv -> (Id,CoreExpr) -> IndEnv
add_pair :: IndEnv -> (Id, CoreExpr) -> IndEnv
add_pair IndEnv
env (Id
exported_id, CoreExpr
exported)
| ([CoreTickish]
ticks, Var Id
local_id) <- forall b.
(CoreTickish -> Bool) -> Expr b -> ([CoreTickish], Expr b)
stripTicksTop forall (pass :: TickishPass). GenTickish pass -> Bool
tickishFloatable CoreExpr
exported
, IndEnv -> Id -> Id -> Bool
shortMeOut IndEnv
env Id
exported_id Id
local_id
= forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv IndEnv
env Id
local_id (Id
exported_id, [CoreTickish]
ticks)
add_pair IndEnv
env (Id, CoreExpr)
_ = IndEnv
env
shortMeOut :: IndEnv -> Id -> Id -> Bool
shortMeOut :: IndEnv -> Id -> Id -> Bool
shortMeOut IndEnv
ind_env Id
exported_id Id
local_id
= if Id -> Bool
isExportedId Id
exported_id Bool -> Bool -> Bool
&&
Id -> Bool
isLocalId Id
local_id Bool -> Bool -> Bool
&&
Bool -> Bool
not (Id -> Bool
isExportedId Id
local_id) Bool -> Bool -> Bool
&&
Bool -> Bool
not (Id
local_id forall a. Id -> VarEnv a -> Bool
`elemVarEnv` IndEnv
ind_env)
then
if Id -> Bool
hasShortableIdInfo Id
exported_id
then Bool
True
else forall a. HasCallStack => Bool -> String -> SDoc -> a -> a
warnPprTrace Bool
True String
"Not shorting out" (forall a. Outputable a => a -> SDoc
ppr Id
exported_id) Bool
False
else
Bool
False
hasShortableIdInfo :: Id -> Bool
hasShortableIdInfo :: Id -> Bool
hasShortableIdInfo Id
id
= RuleInfo -> Bool
isEmptyRuleInfo (IdInfo -> RuleInfo
ruleInfo IdInfo
info)
Bool -> Bool -> Bool
&& InlinePragma -> Bool
isDefaultInlinePragma (IdInfo -> InlinePragma
inlinePragInfo IdInfo
info)
Bool -> Bool -> Bool
&& Bool -> Bool
not (Unfolding -> Bool
isStableUnfolding (IdInfo -> Unfolding
realUnfoldingInfo IdInfo
info))
where
info :: IdInfo
info = HasDebugCallStack => Id -> IdInfo
idInfo Id
id
transferIdInfo :: Id -> Id -> (Id, Id)
transferIdInfo :: Id -> Id -> (Id, Id)
transferIdInfo Id
exported_id Id
local_id
= ( HasDebugCallStack => (IdInfo -> IdInfo) -> Id -> Id
modifyIdInfo IdInfo -> IdInfo
transfer Id
exported_id
, HasDebugCallStack => (IdInfo -> IdInfo) -> Id -> Id
modifyIdInfo IdInfo -> IdInfo
zap_info Id
local_id )
where
local_info :: IdInfo
local_info = HasDebugCallStack => Id -> IdInfo
idInfo Id
local_id
transfer :: IdInfo -> IdInfo
transfer IdInfo
exp_info = IdInfo
exp_info IdInfo -> DmdSig -> IdInfo
`setDmdSigInfo` IdInfo -> DmdSig
dmdSigInfo IdInfo
local_info
IdInfo -> CprSig -> IdInfo
`setCprSigInfo` IdInfo -> CprSig
cprSigInfo IdInfo
local_info
IdInfo -> Unfolding -> IdInfo
`setUnfoldingInfo` IdInfo -> Unfolding
realUnfoldingInfo IdInfo
local_info
IdInfo -> InlinePragma -> IdInfo
`setInlinePragInfo` IdInfo -> InlinePragma
inlinePragInfo IdInfo
local_info
IdInfo -> RuleInfo -> IdInfo
`setRuleInfo` RuleInfo -> RuleInfo -> RuleInfo
addRuleInfo (IdInfo -> RuleInfo
ruleInfo IdInfo
exp_info) RuleInfo
new_info
new_info :: RuleInfo
new_info = Name -> RuleInfo -> RuleInfo
setRuleInfoHead (Id -> Name
idName Id
exported_id)
(IdInfo -> RuleInfo
ruleInfo IdInfo
local_info)
zap_info :: IdInfo -> IdInfo
zap_info IdInfo
lcl_info = IdInfo
lcl_info IdInfo -> InlinePragma -> IdInfo
`setInlinePragInfo` InlinePragma
defaultInlinePragma
IdInfo -> Unfolding -> IdInfo
`setUnfoldingInfo` Unfolding
noUnfolding