{-# LANGUAGE CPP #-}
module SimplCore ( core2core, simplifyExpr ) where
#include "HsVersions.h"
import GhcPrelude
import DynFlags
import CoreSyn
import HscTypes
import CSE              ( cseProgram )
import Rules            ( mkRuleBase, unionRuleBase,
                          extendRuleBaseList, ruleCheckProgram, addRuleInfo,
                          getRules )
import PprCore          ( pprCoreBindings, pprCoreExpr )
import OccurAnal        ( occurAnalysePgm, occurAnalyseExpr )
import IdInfo
import CoreStats        ( coreBindsSize, coreBindsStats, exprSize )
import CoreUtils        ( mkTicks, stripTicksTop )
import CoreLint         ( endPass, lintPassResult, dumpPassResult,
                          lintAnnots )
import Simplify         ( simplTopBinds, simplExpr, simplRules )
import SimplUtils       ( simplEnvForGHCi, activeRule, activeUnfolding )
import SimplEnv
import SimplMonad
import CoreMonad
import qualified ErrUtils as Err
import FloatIn          ( floatInwards )
import FloatOut         ( floatOutwards )
import FamInstEnv
import Id
import ErrUtils         ( withTiming, withTimingD )
import BasicTypes       ( CompilerPhase(..), isDefaultInlinePragma, defaultInlinePragma )
import VarSet
import VarEnv
import LiberateCase     ( liberateCase )
import SAT              ( doStaticArgs )
import Specialise       ( specProgram)
import SpecConstr       ( specConstrProgram)
import DmdAnal          ( dmdAnalProgram )
import CallArity        ( callArityAnalProgram )
import Exitify          ( exitifyProgram )
import WorkWrap         ( wwTopBinds )
import SrcLoc
import Util
import Module
import Plugins          ( withPlugins, installCoreToDos )
import DynamicLoading  
import UniqSupply       ( UniqSupply, mkSplitUniqSupply, splitUniqSupply )
import UniqFM
import Outputable
import Control.Monad
import qualified GHC.LanguageExtensions as LangExt
core2core :: HscEnv -> ModGuts -> IO ModGuts
core2core :: HscEnv -> ModGuts -> IO ModGuts
core2core HscEnv
hsc_env guts :: ModGuts
guts@(ModGuts { mg_module :: ModGuts -> Module
mg_module  = Module
mod
                                , mg_loc :: ModGuts -> SrcSpan
mg_loc     = SrcSpan
loc
                                , mg_deps :: ModGuts -> Dependencies
mg_deps    = Dependencies
deps
                                , mg_rdr_env :: ModGuts -> GlobalRdrEnv
mg_rdr_env = GlobalRdrEnv
rdr_env })
  = do { 
       ; let builtin_passes :: [CoreToDo]
builtin_passes = DynFlags -> [CoreToDo]
getCoreToDo DynFlags
dflags
             orph_mods :: ModuleSet
orph_mods = [Module] -> ModuleSet
mkModuleSet (Module
mod Module -> [Module] -> [Module]
forall a. a -> [a] -> [a]
: Dependencies -> [Module]
dep_orphs Dependencies
deps)
             uniq_mask :: Char
uniq_mask = Char
's'
       ;
       ; (ModGuts
guts2, SimplCount
stats) <- HscEnv
-> RuleBase
-> Char
-> Module
-> ModuleSet
-> PrintUnqualified
-> SrcSpan
-> CoreM ModGuts
-> IO (ModGuts, SimplCount)
forall a.
HscEnv
-> RuleBase
-> Char
-> Module
-> ModuleSet
-> PrintUnqualified
-> SrcSpan
-> CoreM a
-> IO (a, SimplCount)
runCoreM HscEnv
hsc_env RuleBase
hpt_rule_base Char
uniq_mask Module
mod
                                    ModuleSet
orph_mods PrintUnqualified
print_unqual SrcSpan
loc (CoreM ModGuts -> IO (ModGuts, SimplCount))
-> CoreM ModGuts -> IO (ModGuts, SimplCount)
forall a b. (a -> b) -> a -> b
$
                           do { HscEnv
hsc_env' <- CoreM HscEnv
getHscEnv
                              ; DynFlags
dflags' <- IO DynFlags -> CoreM DynFlags
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO DynFlags -> CoreM DynFlags) -> IO DynFlags -> CoreM DynFlags
forall a b. (a -> b) -> a -> b
$ HscEnv -> DynFlags -> IO DynFlags
initializePlugins HscEnv
hsc_env'
                                                      (HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env')
                              ; [CoreToDo]
all_passes <- DynFlags
-> PluginOperation CoreM [CoreToDo]
-> [CoreToDo]
-> CoreM [CoreToDo]
forall (m :: * -> *) a.
Monad m =>
DynFlags -> PluginOperation m a -> a -> m a
withPlugins DynFlags
dflags'
                                                PluginOperation CoreM [CoreToDo]
installCoreToDos
                                                [CoreToDo]
builtin_passes
                              ; [CoreToDo] -> ModGuts -> CoreM ModGuts
runCorePasses [CoreToDo]
all_passes ModGuts
guts }
       ; DynFlags -> DumpFlag -> String -> SDoc -> IO ()
Err.dumpIfSet_dyn DynFlags
dflags DumpFlag
Opt_D_dump_simpl_stats
             String
"Grand total simplifier statistics"
             (SimplCount -> SDoc
pprSimplCount SimplCount
stats)
       ; ModGuts -> IO ModGuts
forall (m :: * -> *) a. Monad m => a -> m a
return ModGuts
guts2 }
  where
    dflags :: DynFlags
dflags         = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
    home_pkg_rules :: [CoreRule]
home_pkg_rules = HscEnv -> [(ModuleName, IsBootInterface)] -> [CoreRule]
hptRules HscEnv
hsc_env (Dependencies -> [(ModuleName, IsBootInterface)]
dep_mods Dependencies
deps)
    hpt_rule_base :: RuleBase
hpt_rule_base  = [CoreRule] -> RuleBase
mkRuleBase [CoreRule]
home_pkg_rules
    print_unqual :: PrintUnqualified
print_unqual   = DynFlags -> GlobalRdrEnv -> PrintUnqualified
mkPrintUnqualified DynFlags
dflags GlobalRdrEnv
rdr_env
    
    
    
    
    
getCoreToDo :: DynFlags -> [CoreToDo]
getCoreToDo :: DynFlags -> [CoreToDo]
getCoreToDo DynFlags
dflags
  = [CoreToDo] -> [CoreToDo]
flatten_todos [CoreToDo]
core_todo
  where
    opt_level :: Int
opt_level     = DynFlags -> Int
optLevel           DynFlags
dflags
    phases :: Int
phases        = DynFlags -> Int
simplPhases        DynFlags
dflags
    max_iter :: Int
max_iter      = DynFlags -> Int
maxSimplIterations DynFlags
dflags
    rule_check :: Maybe String
rule_check    = DynFlags -> Maybe String
ruleCheck          DynFlags
dflags
    call_arity :: IsBootInterface
call_arity    = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_CallArity                    DynFlags
dflags
    exitification :: IsBootInterface
exitification = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_Exitification                DynFlags
dflags
    strictness :: IsBootInterface
strictness    = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_Strictness                   DynFlags
dflags
    full_laziness :: IsBootInterface
full_laziness = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_FullLaziness                 DynFlags
dflags
    do_specialise :: IsBootInterface
do_specialise = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_Specialise                   DynFlags
dflags
    do_float_in :: IsBootInterface
do_float_in   = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_FloatIn                      DynFlags
dflags
    cse :: IsBootInterface
cse           = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_CSE                          DynFlags
dflags
    spec_constr :: IsBootInterface
spec_constr   = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_SpecConstr                   DynFlags
dflags
    liberate_case :: IsBootInterface
liberate_case = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_LiberateCase                 DynFlags
dflags
    late_dmd_anal :: IsBootInterface
late_dmd_anal = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_LateDmdAnal                  DynFlags
dflags
    late_specialise :: IsBootInterface
late_specialise = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_LateSpecialise             DynFlags
dflags
    static_args :: IsBootInterface
static_args   = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_StaticArgumentTransformation DynFlags
dflags
    rules_on :: IsBootInterface
rules_on      = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_EnableRewriteRules           DynFlags
dflags
    eta_expand_on :: IsBootInterface
eta_expand_on = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_DoLambdaEtaExpansion         DynFlags
dflags
    ww_on :: IsBootInterface
ww_on         = GeneralFlag -> DynFlags -> IsBootInterface
gopt GeneralFlag
Opt_WorkerWrapper                DynFlags
dflags
    static_ptrs :: IsBootInterface
static_ptrs   = Extension -> DynFlags -> IsBootInterface
xopt Extension
LangExt.StaticPointers           DynFlags
dflags
    maybe_rule_check :: CompilerPhase -> CoreToDo
maybe_rule_check CompilerPhase
phase = Maybe String -> (String -> CoreToDo) -> CoreToDo
forall a. Maybe a -> (a -> CoreToDo) -> CoreToDo
runMaybe Maybe String
rule_check (CompilerPhase -> String -> CoreToDo
CoreDoRuleCheck CompilerPhase
phase)
    maybe_strictness_before :: Int -> CoreToDo
maybe_strictness_before Int
phase
      = IsBootInterface -> CoreToDo -> CoreToDo
runWhen (Int
phase Int -> [Int] -> IsBootInterface
forall (t :: * -> *) a.
(Foldable t, Eq a) =>
a -> t a -> IsBootInterface
`elem` DynFlags -> [Int]
strictnessBefore DynFlags
dflags) CoreToDo
CoreDoStrictness
    base_mode :: SimplMode
base_mode = SimplMode :: [String]
-> CompilerPhase
-> DynFlags
-> IsBootInterface
-> IsBootInterface
-> IsBootInterface
-> IsBootInterface
-> SimplMode
SimplMode { sm_phase :: CompilerPhase
sm_phase      = String -> CompilerPhase
forall a. String -> a
panic String
"base_mode"
                          , sm_names :: [String]
sm_names      = []
                          , sm_dflags :: DynFlags
sm_dflags     = DynFlags
dflags
                          , sm_rules :: IsBootInterface
sm_rules      = IsBootInterface
rules_on
                          , sm_eta_expand :: IsBootInterface
sm_eta_expand = IsBootInterface
eta_expand_on
                          , sm_inline :: IsBootInterface
sm_inline     = IsBootInterface
True
                          , sm_case_case :: IsBootInterface
sm_case_case  = IsBootInterface
True }
    simpl_phase :: Int -> [String] -> Int -> CoreToDo
simpl_phase Int
phase [String]
names Int
iter
      = [CoreToDo] -> CoreToDo
CoreDoPasses
      ([CoreToDo] -> CoreToDo) -> [CoreToDo] -> CoreToDo
forall a b. (a -> b) -> a -> b
$   [ Int -> CoreToDo
maybe_strictness_before Int
phase
          , Int -> SimplMode -> CoreToDo
CoreDoSimplify Int
iter
                (SimplMode
base_mode { sm_phase :: CompilerPhase
sm_phase = Int -> CompilerPhase
Phase Int
phase
                           , sm_names :: [String]
sm_names = [String]
names })
          , CompilerPhase -> CoreToDo
maybe_rule_check (Int -> CompilerPhase
Phase Int
phase) ]
    simpl_phases :: CoreToDo
simpl_phases = [CoreToDo] -> CoreToDo
CoreDoPasses [ Int -> [String] -> Int -> CoreToDo
simpl_phase Int
phase [String
"main"] Int
max_iter
                                | Int
phase <- [Int
phases, Int
phasesInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1 .. Int
1] ]
        
    simpl_gently :: CoreToDo
simpl_gently = Int -> SimplMode -> CoreToDo
CoreDoSimplify Int
max_iter
                       (SimplMode
base_mode { sm_phase :: CompilerPhase
sm_phase = CompilerPhase
InitialPhase
                                  , sm_names :: [String]
sm_names = [String
"Gentle"]
                                  , sm_rules :: IsBootInterface
sm_rules = IsBootInterface
rules_on   
                                  , sm_inline :: IsBootInterface
sm_inline = IsBootInterface
True
                                              
                                  , sm_case_case :: IsBootInterface
sm_case_case = IsBootInterface
False })
                          
                          
    strictness_pass :: [CoreToDo]
strictness_pass = if IsBootInterface
ww_on
                       then [CoreToDo
CoreDoStrictness,CoreToDo
CoreDoWorkerWrapper]
                       else [CoreToDo
CoreDoStrictness]
    
    demand_analyser :: CoreToDo
demand_analyser = ([CoreToDo] -> CoreToDo
CoreDoPasses (
                           [CoreToDo]
strictness_pass [CoreToDo] -> [CoreToDo] -> [CoreToDo]
forall a. [a] -> [a] -> [a]
++
                           [Int -> [String] -> Int -> CoreToDo
simpl_phase Int
0 [String
"post-worker-wrapper"] Int
max_iter]
                           ))
    
    
    static_ptrs_float_outwards :: CoreToDo
static_ptrs_float_outwards =
      IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
static_ptrs (CoreToDo -> CoreToDo) -> CoreToDo -> CoreToDo
forall a b. (a -> b) -> a -> b
$ [CoreToDo] -> CoreToDo
CoreDoPasses
        [ CoreToDo
simpl_gently 
                       
        , FloatOutSwitches -> CoreToDo
CoreDoFloatOutwards FloatOutSwitches :: Maybe Int
-> IsBootInterface
-> IsBootInterface
-> IsBootInterface
-> FloatOutSwitches
FloatOutSwitches
          { floatOutLambdas :: Maybe Int
floatOutLambdas   = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
0
          , floatOutConstants :: IsBootInterface
floatOutConstants = IsBootInterface
True
          , floatOutOverSatApps :: IsBootInterface
floatOutOverSatApps = IsBootInterface
False
          , floatToTopLevelOnly :: IsBootInterface
floatToTopLevelOnly = IsBootInterface
True
          }
        ]
    core_todo :: [CoreToDo]
core_todo =
     if Int
opt_level Int -> Int -> IsBootInterface
forall a. Eq a => a -> a -> IsBootInterface
== Int
0 then
       [ CoreToDo
static_ptrs_float_outwards,
         Int -> SimplMode -> CoreToDo
CoreDoSimplify Int
max_iter
             (SimplMode
base_mode { sm_phase :: CompilerPhase
sm_phase = Int -> CompilerPhase
Phase Int
0
                        , sm_names :: [String]
sm_names = [String
"Non-opt simplification"] })
       ]
     else  [
    
    
    
    
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
static_args ([CoreToDo] -> CoreToDo
CoreDoPasses [ CoreToDo
simpl_gently, CoreToDo
CoreDoStaticArgs ]),
        
        CoreToDo
simpl_gently,
        
        
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
do_specialise CoreToDo
CoreDoSpecialising,
        if IsBootInterface
full_laziness then
           FloatOutSwitches -> CoreToDo
CoreDoFloatOutwards FloatOutSwitches :: Maybe Int
-> IsBootInterface
-> IsBootInterface
-> IsBootInterface
-> FloatOutSwitches
FloatOutSwitches {
                                 floatOutLambdas :: Maybe Int
floatOutLambdas   = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
0,
                                 floatOutConstants :: IsBootInterface
floatOutConstants = IsBootInterface
True,
                                 floatOutOverSatApps :: IsBootInterface
floatOutOverSatApps = IsBootInterface
False,
                                 floatToTopLevelOnly :: IsBootInterface
floatToTopLevelOnly = IsBootInterface
False }
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
        else
           
           
           
           CoreToDo
static_ptrs_float_outwards,
        CoreToDo
simpl_phases,
                
                
                
                
                
                
                
                
                
        Int -> [String] -> Int -> CoreToDo
simpl_phase Int
0 [String
"main"] (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
max_iter Int
3),
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
do_float_in CoreToDo
CoreDoFloatInwards,
            
            
            
            
            
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
call_arity (CoreToDo -> CoreToDo) -> CoreToDo -> CoreToDo
forall a b. (a -> b) -> a -> b
$ [CoreToDo] -> CoreToDo
CoreDoPasses
            [ CoreToDo
CoreDoCallArity
            , Int -> [String] -> Int -> CoreToDo
simpl_phase Int
0 [String
"post-call-arity"] Int
max_iter
            ],
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
strictness CoreToDo
demand_analyser,
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
exitification CoreToDo
CoreDoExitify,
            
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
full_laziness (CoreToDo -> CoreToDo) -> CoreToDo -> CoreToDo
forall a b. (a -> b) -> a -> b
$
           FloatOutSwitches -> CoreToDo
CoreDoFloatOutwards FloatOutSwitches :: Maybe Int
-> IsBootInterface
-> IsBootInterface
-> IsBootInterface
-> FloatOutSwitches
FloatOutSwitches {
                                 floatOutLambdas :: Maybe Int
floatOutLambdas     = DynFlags -> Maybe Int
floatLamArgs DynFlags
dflags,
                                 floatOutConstants :: IsBootInterface
floatOutConstants   = IsBootInterface
True,
                                 floatOutOverSatApps :: IsBootInterface
floatOutOverSatApps = IsBootInterface
True,
                                 floatToTopLevelOnly :: IsBootInterface
floatToTopLevelOnly = IsBootInterface
False },
                
                
                
                
                
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
cse CoreToDo
CoreCSE,
                
                
                
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
do_float_in CoreToDo
CoreDoFloatInwards,
        CompilerPhase -> CoreToDo
maybe_rule_check (Int -> CompilerPhase
Phase Int
0),
                
                
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
liberate_case ([CoreToDo] -> CoreToDo
CoreDoPasses [
            CoreToDo
CoreLiberateCase,
            Int -> [String] -> Int -> CoreToDo
simpl_phase Int
0 [String
"post-liberate-case"] Int
max_iter
            ]),         
                        
                        
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
spec_constr CoreToDo
CoreDoSpecConstr,
        CompilerPhase -> CoreToDo
maybe_rule_check (Int -> CompilerPhase
Phase Int
0),
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
late_specialise
          ([CoreToDo] -> CoreToDo
CoreDoPasses [ CoreToDo
CoreDoSpecialising
                        , Int -> [String] -> Int -> CoreToDo
simpl_phase Int
0 [String
"post-late-spec"] Int
max_iter]),
        
        
        
        
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen ((IsBootInterface
liberate_case IsBootInterface -> IsBootInterface -> IsBootInterface
|| IsBootInterface
spec_constr) IsBootInterface -> IsBootInterface -> IsBootInterface
&& IsBootInterface
cse) CoreToDo
CoreCSE,
        
        Int -> [String] -> Int -> CoreToDo
simpl_phase Int
0 [String
"final"] Int
max_iter,
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen IsBootInterface
late_dmd_anal (CoreToDo -> CoreToDo) -> CoreToDo -> CoreToDo
forall a b. (a -> b) -> a -> b
$ [CoreToDo] -> CoreToDo
CoreDoPasses (
            [CoreToDo]
strictness_pass [CoreToDo] -> [CoreToDo] -> [CoreToDo]
forall a. [a] -> [a] -> [a]
++
            [Int -> [String] -> Int -> CoreToDo
simpl_phase Int
0 [String
"post-late-ww"] Int
max_iter]
          ),
        
        
        
        
        
        IsBootInterface -> CoreToDo -> CoreToDo
runWhen (IsBootInterface
strictness IsBootInterface -> IsBootInterface -> IsBootInterface
|| IsBootInterface
late_dmd_anal) CoreToDo
CoreDoStrictness,
        CompilerPhase -> CoreToDo
maybe_rule_check (Int -> CompilerPhase
Phase Int
0)
     ]
    
    flatten_todos :: [CoreToDo] -> [CoreToDo]
flatten_todos [] = []
    flatten_todos (CoreToDo
CoreDoNothing : [CoreToDo]
rest) = [CoreToDo] -> [CoreToDo]
flatten_todos [CoreToDo]
rest
    flatten_todos (CoreDoPasses [CoreToDo]
passes : [CoreToDo]
rest) =
      [CoreToDo] -> [CoreToDo]
flatten_todos [CoreToDo]
passes [CoreToDo] -> [CoreToDo] -> [CoreToDo]
forall a. [a] -> [a] -> [a]
++ [CoreToDo] -> [CoreToDo]
flatten_todos [CoreToDo]
rest
    flatten_todos (CoreToDo
todo : [CoreToDo]
rest) = CoreToDo
todo CoreToDo -> [CoreToDo] -> [CoreToDo]
forall a. a -> [a] -> [a]
: [CoreToDo] -> [CoreToDo]
flatten_todos [CoreToDo]
rest
runCorePasses :: [CoreToDo] -> ModGuts -> CoreM ModGuts
runCorePasses :: [CoreToDo] -> ModGuts -> CoreM ModGuts
runCorePasses [CoreToDo]
passes ModGuts
guts
  = (ModGuts -> CoreToDo -> CoreM ModGuts)
-> ModGuts -> [CoreToDo] -> CoreM ModGuts
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM ModGuts -> CoreToDo -> CoreM ModGuts
do_pass ModGuts
guts [CoreToDo]
passes
  where
    do_pass :: ModGuts -> CoreToDo -> CoreM ModGuts
do_pass ModGuts
guts CoreToDo
CoreDoNothing = ModGuts -> CoreM ModGuts
forall (m :: * -> *) a. Monad m => a -> m a
return ModGuts
guts
    do_pass ModGuts
guts (CoreDoPasses [CoreToDo]
ps) = [CoreToDo] -> ModGuts -> CoreM ModGuts
runCorePasses [CoreToDo]
ps ModGuts
guts
    do_pass ModGuts
guts CoreToDo
pass = do
       SDoc -> (ModGuts -> ()) -> CoreM ModGuts -> CoreM ModGuts
forall (m :: * -> *) a.
(MonadIO m, HasDynFlags m) =>
SDoc -> (a -> ()) -> m a -> m a
withTimingD (CoreToDo -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreToDo
pass SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
brackets (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
mod))
                   (() -> ModGuts -> ()
forall a b. a -> b -> a
const ()) (CoreM ModGuts -> CoreM ModGuts) -> CoreM ModGuts -> CoreM ModGuts
forall a b. (a -> b) -> a -> b
$ do
            { ModGuts
guts' <- SDoc -> (ModGuts -> CoreM ModGuts) -> ModGuts -> CoreM ModGuts
lintAnnots (CoreToDo -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreToDo
pass) (CoreToDo -> ModGuts -> CoreM ModGuts
doCorePass CoreToDo
pass) ModGuts
guts
            ; CoreToDo -> CoreProgram -> [CoreRule] -> CoreM ()
endPass CoreToDo
pass (ModGuts -> CoreProgram
mg_binds ModGuts
guts') (ModGuts -> [CoreRule]
mg_rules ModGuts
guts')
            ; ModGuts -> CoreM ModGuts
forall (m :: * -> *) a. Monad m => a -> m a
return ModGuts
guts' }
    mod :: Module
mod = ModGuts -> Module
mg_module ModGuts
guts
doCorePass :: CoreToDo -> ModGuts -> CoreM ModGuts
doCorePass :: CoreToDo -> ModGuts -> CoreM ModGuts
doCorePass pass :: CoreToDo
pass@(CoreDoSimplify {})  = {-# SCC "Simplify" #-}
                                       CoreToDo -> ModGuts -> CoreM ModGuts
simplifyPgm CoreToDo
pass
doCorePass CoreToDo
CoreCSE                   = {-# SCC "CommonSubExpr" #-}
                                       (CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
doPass CoreProgram -> CoreProgram
cseProgram
doCorePass CoreToDo
CoreLiberateCase          = {-# SCC "LiberateCase" #-}
                                       (DynFlags -> CoreProgram -> CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassD DynFlags -> CoreProgram -> CoreProgram
liberateCase
doCorePass CoreToDo
CoreDoFloatInwards        = {-# SCC "FloatInwards" #-}
                                       ModGuts -> CoreM ModGuts
floatInwards
doCorePass (CoreDoFloatOutwards FloatOutSwitches
f)   = {-# SCC "FloatOutwards" #-}
                                       (DynFlags -> UniqSupply -> CoreProgram -> IO CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDUM (FloatOutSwitches
-> DynFlags -> UniqSupply -> CoreProgram -> IO CoreProgram
floatOutwards FloatOutSwitches
f)
doCorePass CoreToDo
CoreDoStaticArgs          = {-# SCC "StaticArgs" #-}
                                       (UniqSupply -> CoreProgram -> CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassU UniqSupply -> CoreProgram -> CoreProgram
doStaticArgs
doCorePass CoreToDo
CoreDoCallArity           = {-# SCC "CallArity" #-}
                                       (DynFlags -> CoreProgram -> CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassD DynFlags -> CoreProgram -> CoreProgram
callArityAnalProgram
doCorePass CoreToDo
CoreDoExitify             = {-# SCC "Exitify" #-}
                                       (CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
doPass CoreProgram -> CoreProgram
exitifyProgram
doCorePass CoreToDo
CoreDoStrictness          = {-# SCC "NewStranal" #-}
                                       (DynFlags -> FamInstEnvs -> CoreProgram -> IO CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDFM DynFlags -> FamInstEnvs -> CoreProgram -> IO CoreProgram
dmdAnalProgram
doCorePass CoreToDo
CoreDoWorkerWrapper       = {-# SCC "WorkWrap" #-}
                                       (DynFlags
 -> FamInstEnvs -> UniqSupply -> CoreProgram -> CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDFU DynFlags -> FamInstEnvs -> UniqSupply -> CoreProgram -> CoreProgram
wwTopBinds
doCorePass CoreToDo
CoreDoSpecialising        = {-# SCC "Specialise" #-}
                                       ModGuts -> CoreM ModGuts
specProgram
doCorePass CoreToDo
CoreDoSpecConstr          = {-# SCC "SpecConstr" #-}
                                       ModGuts -> CoreM ModGuts
specConstrProgram
doCorePass CoreToDo
CoreDoPrintCore              = (DynFlags -> CoreProgram -> IO ()) -> ModGuts -> CoreM ModGuts
forall a.
(DynFlags -> CoreProgram -> IO a) -> ModGuts -> CoreM ModGuts
observe   DynFlags -> CoreProgram -> IO ()
printCore
doCorePass (CoreDoRuleCheck CompilerPhase
phase String
pat)  = CompilerPhase -> String -> ModGuts -> CoreM ModGuts
ruleCheckPass CompilerPhase
phase String
pat
doCorePass CoreToDo
CoreDoNothing                = ModGuts -> CoreM ModGuts
forall (m :: * -> *) a. Monad m => a -> m a
return
doCorePass (CoreDoPasses [CoreToDo]
passes)        = [CoreToDo] -> ModGuts -> CoreM ModGuts
runCorePasses [CoreToDo]
passes
doCorePass (CoreDoPluginPass String
_ ModGuts -> CoreM ModGuts
pass) = {-# SCC "Plugin" #-} ModGuts -> CoreM ModGuts
pass
doCorePass pass :: CoreToDo
pass@CoreToDo
CoreDesugar          = String -> SDoc -> ModGuts -> CoreM ModGuts
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"doCorePass" (CoreToDo -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreToDo
pass)
doCorePass pass :: CoreToDo
pass@CoreToDo
CoreDesugarOpt       = String -> SDoc -> ModGuts -> CoreM ModGuts
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"doCorePass" (CoreToDo -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreToDo
pass)
doCorePass pass :: CoreToDo
pass@CoreToDo
CoreTidy             = String -> SDoc -> ModGuts -> CoreM ModGuts
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"doCorePass" (CoreToDo -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreToDo
pass)
doCorePass pass :: CoreToDo
pass@CoreToDo
CorePrep             = String -> SDoc -> ModGuts -> CoreM ModGuts
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"doCorePass" (CoreToDo -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreToDo
pass)
doCorePass pass :: CoreToDo
pass@CoreToDo
CoreOccurAnal        = String -> SDoc -> ModGuts -> CoreM ModGuts
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"doCorePass" (CoreToDo -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreToDo
pass)
printCore :: DynFlags -> CoreProgram -> IO ()
printCore :: DynFlags -> CoreProgram -> IO ()
printCore DynFlags
dflags CoreProgram
binds
    = DynFlags -> IsBootInterface -> String -> SDoc -> IO ()
Err.dumpIfSet DynFlags
dflags IsBootInterface
True String
"Print Core" (CoreProgram -> SDoc
forall b. OutputableBndr b => [Bind b] -> SDoc
pprCoreBindings CoreProgram
binds)
ruleCheckPass :: CompilerPhase -> String -> ModGuts -> CoreM ModGuts
ruleCheckPass :: CompilerPhase -> String -> ModGuts -> CoreM ModGuts
ruleCheckPass CompilerPhase
current_phase String
pat ModGuts
guts =
    SDoc -> (ModGuts -> ()) -> CoreM ModGuts -> CoreM ModGuts
forall (m :: * -> *) a.
(MonadIO m, HasDynFlags m) =>
SDoc -> (a -> ()) -> m a -> m a
withTimingD (String -> SDoc
text String
"RuleCheck"SDoc -> SDoc -> SDoc
<+>SDoc -> SDoc
brackets (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Module -> SDoc) -> Module -> SDoc
forall a b. (a -> b) -> a -> b
$ ModGuts -> Module
mg_module ModGuts
guts))
                (() -> ModGuts -> ()
forall a b. a -> b -> a
const ()) (CoreM ModGuts -> CoreM ModGuts) -> CoreM ModGuts -> CoreM ModGuts
forall a b. (a -> b) -> a -> b
$ do
    { RuleBase
rb <- CoreM RuleBase
getRuleBase
    ; DynFlags
dflags <- CoreM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
    ; ModuleSet
vis_orphs <- CoreM ModuleSet
getVisibleOrphanMods
    ; let rule_fn :: Id -> [CoreRule]
rule_fn Id
fn = RuleEnv -> Id -> [CoreRule]
getRules (RuleBase -> ModuleSet -> RuleEnv
RuleEnv RuleBase
rb ModuleSet
vis_orphs) Id
fn
                        [CoreRule] -> [CoreRule] -> [CoreRule]
forall a. [a] -> [a] -> [a]
++ (ModGuts -> [CoreRule]
mg_rules ModGuts
guts)
    ; IO () -> CoreM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> CoreM ()) -> IO () -> CoreM ()
forall a b. (a -> b) -> a -> b
$ DynFlags
-> WarnReason -> Severity -> SrcSpan -> PprStyle -> SDoc -> IO ()
putLogMsg DynFlags
dflags WarnReason
NoReason Severity
Err.SevDump SrcSpan
noSrcSpan
                   (DynFlags -> PprStyle
defaultDumpStyle DynFlags
dflags)
                   (CompilerPhase
-> String -> (Id -> [CoreRule]) -> CoreProgram -> SDoc
ruleCheckProgram CompilerPhase
current_phase String
pat
                      Id -> [CoreRule]
rule_fn (ModGuts -> CoreProgram
mg_binds ModGuts
guts))
    ; ModGuts -> CoreM ModGuts
forall (m :: * -> *) a. Monad m => a -> m a
return ModGuts
guts }
doPassDUM :: (DynFlags -> UniqSupply -> CoreProgram -> IO CoreProgram) -> ModGuts -> CoreM ModGuts
doPassDUM :: (DynFlags -> UniqSupply -> CoreProgram -> IO CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDUM DynFlags -> UniqSupply -> CoreProgram -> IO CoreProgram
do_pass = (CoreProgram -> CoreM CoreProgram) -> ModGuts -> CoreM ModGuts
forall (m :: * -> *).
Monad m =>
(CoreProgram -> m CoreProgram) -> ModGuts -> m ModGuts
doPassM ((CoreProgram -> CoreM CoreProgram) -> ModGuts -> CoreM ModGuts)
-> (CoreProgram -> CoreM CoreProgram) -> ModGuts -> CoreM ModGuts
forall a b. (a -> b) -> a -> b
$ \CoreProgram
binds -> do
    DynFlags
dflags <- CoreM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
    UniqSupply
us     <- CoreM UniqSupply
forall (m :: * -> *). MonadUnique m => m UniqSupply
getUniqueSupplyM
    IO CoreProgram -> CoreM CoreProgram
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO CoreProgram -> CoreM CoreProgram)
-> IO CoreProgram -> CoreM CoreProgram
forall a b. (a -> b) -> a -> b
$ DynFlags -> UniqSupply -> CoreProgram -> IO CoreProgram
do_pass DynFlags
dflags UniqSupply
us CoreProgram
binds
doPassDM :: (DynFlags -> CoreProgram -> IO CoreProgram) -> ModGuts -> CoreM ModGuts
doPassDM :: (DynFlags -> CoreProgram -> IO CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDM DynFlags -> CoreProgram -> IO CoreProgram
do_pass = (DynFlags -> UniqSupply -> CoreProgram -> IO CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDUM (\DynFlags
dflags -> (CoreProgram -> IO CoreProgram)
-> UniqSupply -> CoreProgram -> IO CoreProgram
forall a b. a -> b -> a
const (DynFlags -> CoreProgram -> IO CoreProgram
do_pass DynFlags
dflags))
doPassD :: (DynFlags -> CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
doPassD :: (DynFlags -> CoreProgram -> CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassD DynFlags -> CoreProgram -> CoreProgram
do_pass = (DynFlags -> CoreProgram -> IO CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDM (\DynFlags
dflags -> CoreProgram -> IO CoreProgram
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreProgram -> IO CoreProgram)
-> (CoreProgram -> CoreProgram) -> CoreProgram -> IO CoreProgram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DynFlags -> CoreProgram -> CoreProgram
do_pass DynFlags
dflags)
doPassDU :: (DynFlags -> UniqSupply -> CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
doPassDU :: (DynFlags -> UniqSupply -> CoreProgram -> CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDU DynFlags -> UniqSupply -> CoreProgram -> CoreProgram
do_pass = (DynFlags -> UniqSupply -> CoreProgram -> IO CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDUM (\DynFlags
dflags UniqSupply
us -> CoreProgram -> IO CoreProgram
forall (m :: * -> *) a. Monad m => a -> m a
return (CoreProgram -> IO CoreProgram)
-> (CoreProgram -> CoreProgram) -> CoreProgram -> IO CoreProgram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DynFlags -> UniqSupply -> CoreProgram -> CoreProgram
do_pass DynFlags
dflags UniqSupply
us)
doPassU :: (UniqSupply -> CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
doPassU :: (UniqSupply -> CoreProgram -> CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassU UniqSupply -> CoreProgram -> CoreProgram
do_pass = (DynFlags -> UniqSupply -> CoreProgram -> CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDU ((UniqSupply -> CoreProgram -> CoreProgram)
-> DynFlags -> UniqSupply -> CoreProgram -> CoreProgram
forall a b. a -> b -> a
const UniqSupply -> CoreProgram -> CoreProgram
do_pass)
doPassDFM :: (DynFlags -> FamInstEnvs -> CoreProgram -> IO CoreProgram) -> ModGuts -> CoreM ModGuts
doPassDFM :: (DynFlags -> FamInstEnvs -> CoreProgram -> IO CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDFM DynFlags -> FamInstEnvs -> CoreProgram -> IO CoreProgram
do_pass ModGuts
guts = do
    DynFlags
dflags <- CoreM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
    PackageFamInstEnv
p_fam_env <- CoreM PackageFamInstEnv
getPackageFamInstEnv
    let fam_envs :: FamInstEnvs
fam_envs = (PackageFamInstEnv
p_fam_env, ModGuts -> PackageFamInstEnv
mg_fam_inst_env ModGuts
guts)
    (CoreProgram -> CoreM CoreProgram) -> ModGuts -> CoreM ModGuts
forall (m :: * -> *).
Monad m =>
(CoreProgram -> m CoreProgram) -> ModGuts -> m ModGuts
doPassM (IO CoreProgram -> CoreM CoreProgram
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO CoreProgram -> CoreM CoreProgram)
-> (CoreProgram -> IO CoreProgram)
-> CoreProgram
-> CoreM CoreProgram
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DynFlags -> FamInstEnvs -> CoreProgram -> IO CoreProgram
do_pass DynFlags
dflags FamInstEnvs
fam_envs) ModGuts
guts
doPassDFU :: (DynFlags -> FamInstEnvs -> UniqSupply -> CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
doPassDFU :: (DynFlags
 -> FamInstEnvs -> UniqSupply -> CoreProgram -> CoreProgram)
-> ModGuts -> CoreM ModGuts
doPassDFU DynFlags -> FamInstEnvs -> UniqSupply -> CoreProgram -> CoreProgram
do_pass ModGuts
guts = do
    DynFlags
dflags <- CoreM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
    UniqSupply
us     <- CoreM UniqSupply
forall (m :: * -> *). MonadUnique m => m UniqSupply
getUniqueSupplyM
    PackageFamInstEnv
p_fam_env <- CoreM PackageFamInstEnv
getPackageFamInstEnv
    let fam_envs :: FamInstEnvs
fam_envs = (PackageFamInstEnv
p_fam_env, ModGuts -> PackageFamInstEnv
mg_fam_inst_env ModGuts
guts)
    (CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
doPass (DynFlags -> FamInstEnvs -> UniqSupply -> CoreProgram -> CoreProgram
do_pass DynFlags
dflags FamInstEnvs
fam_envs UniqSupply
us) ModGuts
guts
doPassM :: Monad m => (CoreProgram -> m CoreProgram) -> ModGuts -> m ModGuts
doPassM :: (CoreProgram -> m CoreProgram) -> ModGuts -> m ModGuts
doPassM CoreProgram -> m CoreProgram
bind_f ModGuts
guts = do
    CoreProgram
binds' <- CoreProgram -> m CoreProgram
bind_f (ModGuts -> CoreProgram
mg_binds ModGuts
guts)
    ModGuts -> m ModGuts
forall (m :: * -> *) a. Monad m => a -> m a
return (ModGuts
guts { mg_binds :: CoreProgram
mg_binds = CoreProgram
binds' })
doPass :: (CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
doPass :: (CoreProgram -> CoreProgram) -> ModGuts -> CoreM ModGuts
doPass CoreProgram -> CoreProgram
bind_f ModGuts
guts = ModGuts -> CoreM ModGuts
forall (m :: * -> *) a. Monad m => a -> m a
return (ModGuts -> CoreM ModGuts) -> ModGuts -> CoreM ModGuts
forall a b. (a -> b) -> a -> b
$ ModGuts
guts { mg_binds :: CoreProgram
mg_binds = CoreProgram -> CoreProgram
bind_f (ModGuts -> CoreProgram
mg_binds ModGuts
guts) }
observe :: (DynFlags -> CoreProgram -> IO a) -> ModGuts -> CoreM ModGuts
observe :: (DynFlags -> CoreProgram -> IO a) -> ModGuts -> CoreM ModGuts
observe DynFlags -> CoreProgram -> IO a
do_pass = (CoreProgram -> CoreM CoreProgram) -> ModGuts -> CoreM ModGuts
forall (m :: * -> *).
Monad m =>
(CoreProgram -> m CoreProgram) -> ModGuts -> m ModGuts
doPassM ((CoreProgram -> CoreM CoreProgram) -> ModGuts -> CoreM ModGuts)
-> (CoreProgram -> CoreM CoreProgram) -> ModGuts -> CoreM ModGuts
forall a b. (a -> b) -> a -> b
$ \CoreProgram
binds -> do
    DynFlags
dflags <- CoreM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
    a
_ <- IO a -> CoreM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> CoreM a) -> IO a -> CoreM a
forall a b. (a -> b) -> a -> b
$ DynFlags -> CoreProgram -> IO a
do_pass DynFlags
dflags CoreProgram
binds
    CoreProgram -> CoreM CoreProgram
forall (m :: * -> *) a. Monad m => a -> m a
return CoreProgram
binds
simplifyExpr :: DynFlags 
             -> CoreExpr
             -> IO CoreExpr
simplifyExpr :: DynFlags -> CoreExpr -> IO CoreExpr
simplifyExpr DynFlags
dflags CoreExpr
expr
  = DynFlags -> SDoc -> (CoreExpr -> ()) -> IO CoreExpr -> IO CoreExpr
forall (m :: * -> *) a.
MonadIO m =>
DynFlags -> SDoc -> (a -> ()) -> m a -> m a
withTiming DynFlags
dflags (String -> SDoc
text String
"Simplify [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 Char
's'
        ; let sz :: Int
sz = CoreExpr -> Int
exprSize CoreExpr
expr
        ; (CoreExpr
expr', SimplCount
counts) <- DynFlags
-> RuleEnv
-> FamInstEnvs
-> UniqSupply
-> Int
-> SimplM CoreExpr
-> IO (CoreExpr, SimplCount)
forall a.
DynFlags
-> RuleEnv
-> FamInstEnvs
-> UniqSupply
-> Int
-> SimplM a
-> IO (a, SimplCount)
initSmpl DynFlags
dflags RuleEnv
emptyRuleEnv
                               FamInstEnvs
emptyFamInstEnvs UniqSupply
us Int
sz
                               (SimplEnv -> CoreExpr -> SimplM CoreExpr
simplExprGently (DynFlags -> SimplEnv
simplEnvForGHCi DynFlags
dflags) CoreExpr
expr)
        ; DynFlags -> IsBootInterface -> String -> SDoc -> IO ()
Err.dumpIfSet DynFlags
dflags (DumpFlag -> DynFlags -> IsBootInterface
dopt DumpFlag
Opt_D_dump_simpl_stats DynFlags
dflags)
                  String
"Simplifier statistics" (SimplCount -> SDoc
pprSimplCount SimplCount
counts)
        ; DynFlags -> DumpFlag -> String -> SDoc -> IO ()
Err.dumpIfSet_dyn DynFlags
dflags DumpFlag
Opt_D_dump_simpl String
"Simplified expression"
                        (CoreExpr -> SDoc
forall b. OutputableBndr b => Expr b -> SDoc
pprCoreExpr CoreExpr
expr')
        ; CoreExpr -> IO CoreExpr
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)
simplifyPgm :: CoreToDo -> ModGuts -> CoreM ModGuts
simplifyPgm :: CoreToDo -> ModGuts -> CoreM ModGuts
simplifyPgm CoreToDo
pass ModGuts
guts
  = do { HscEnv
hsc_env <- CoreM HscEnv
getHscEnv
       ; UniqSupply
us <- CoreM UniqSupply
forall (m :: * -> *). MonadUnique m => m UniqSupply
getUniqueSupplyM
       ; RuleBase
rb <- CoreM RuleBase
getRuleBase
       ; IO (SimplCount, ModGuts) -> CoreM ModGuts
forall a. IO (SimplCount, a) -> CoreM a
liftIOWithCount (IO (SimplCount, ModGuts) -> CoreM ModGuts)
-> IO (SimplCount, ModGuts) -> CoreM ModGuts
forall a b. (a -> b) -> a -> b
$
         CoreToDo
-> HscEnv
-> UniqSupply
-> RuleBase
-> ModGuts
-> IO (SimplCount, ModGuts)
simplifyPgmIO CoreToDo
pass HscEnv
hsc_env UniqSupply
us RuleBase
rb ModGuts
guts }
simplifyPgmIO :: CoreToDo
              -> HscEnv
              -> UniqSupply
              -> RuleBase
              -> ModGuts
              -> IO (SimplCount, ModGuts)  
simplifyPgmIO :: CoreToDo
-> HscEnv
-> UniqSupply
-> RuleBase
-> ModGuts
-> IO (SimplCount, ModGuts)
simplifyPgmIO pass :: CoreToDo
pass@(CoreDoSimplify Int
max_iterations SimplMode
mode)
              HscEnv
hsc_env UniqSupply
us RuleBase
hpt_rule_base
              guts :: ModGuts
guts@(ModGuts { mg_module :: ModGuts -> Module
mg_module = Module
this_mod
                            , mg_rdr_env :: ModGuts -> GlobalRdrEnv
mg_rdr_env = GlobalRdrEnv
rdr_env
                            , mg_deps :: ModGuts -> Dependencies
mg_deps = Dependencies
deps
                            , mg_binds :: ModGuts -> CoreProgram
mg_binds = CoreProgram
binds, mg_rules :: ModGuts -> [CoreRule]
mg_rules = [CoreRule]
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')
           <- UniqSupply
-> Int
-> [SimplCount]
-> CoreProgram
-> [CoreRule]
-> IO (String, Int, SimplCount, ModGuts)
do_iteration UniqSupply
us Int
1 [] CoreProgram
binds [CoreRule]
rules
        ; DynFlags -> IsBootInterface -> String -> SDoc -> IO ()
Err.dumpIfSet DynFlags
dflags (DumpFlag -> DynFlags -> IsBootInterface
dopt DumpFlag
Opt_D_verbose_core2core DynFlags
dflags IsBootInterface -> IsBootInterface -> IsBootInterface
&&
                                DumpFlag -> DynFlags -> IsBootInterface
dopt DumpFlag
Opt_D_dump_simpl_stats  DynFlags
dflags)
                  String
"Simplifier statistics for following pass"
                  ([SDoc] -> SDoc
vcat [String -> SDoc
text String
termination_msg SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"after" SDoc -> SDoc -> SDoc
<+> Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
it_count
                                              SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"iterations",
                         SDoc
blankLine,
                         SimplCount -> SDoc
pprSimplCount SimplCount
counts_out])
        ; (SimplCount, ModGuts) -> IO (SimplCount, ModGuts)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplCount
counts_out, ModGuts
guts')
    }
  where
    dflags :: DynFlags
dflags       = HscEnv -> DynFlags
hsc_dflags HscEnv
hsc_env
    print_unqual :: PrintUnqualified
print_unqual = DynFlags -> GlobalRdrEnv -> PrintUnqualified
mkPrintUnqualified DynFlags
dflags GlobalRdrEnv
rdr_env
    simpl_env :: SimplEnv
simpl_env    = SimplMode -> SimplEnv
mkSimplEnv SimplMode
mode
    active_rule :: Activation -> IsBootInterface
active_rule  = SimplMode -> Activation -> IsBootInterface
activeRule SimplMode
mode
    active_unf :: Id -> IsBootInterface
active_unf   = SimplMode -> Id -> IsBootInterface
activeUnfolding SimplMode
mode
    do_iteration :: UniqSupply
                 -> Int          
                 -> [SimplCount] 
                 -> CoreProgram  
                 -> [CoreRule]   
                 -> IO (String, Int, SimplCount, ModGuts)
    do_iteration :: UniqSupply
-> Int
-> [SimplCount]
-> CoreProgram
-> [CoreRule]
-> IO (String, Int, SimplCount, ModGuts)
do_iteration UniqSupply
us Int
iteration_no [SimplCount]
counts_so_far CoreProgram
binds [CoreRule]
rules
        
        
      | Int
iteration_no Int -> Int -> IsBootInterface
forall a. Ord a => a -> a -> IsBootInterface
> Int
max_iterations   
      = WARN( debugIsOn && (max_iterations > 2)
            , hang (text "Simplifier bailing out after" <+> int max_iterations
                    <+> text "iterations"
                    <+> (brackets $ hsep $ punctuate comma $
                         map (int . simplCountN) (reverse counts_so_far)))
                 2 (text "Size =" <+> ppr (coreBindsStats binds)))
                
                
        (String, Int, SimplCount, ModGuts)
-> IO (String, Int, SimplCount, ModGuts)
forall (m :: * -> *) a. Monad m => a -> m a
return ( String
"Simplifier baled out", Int
iteration_no Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
               , [SimplCount] -> SimplCount
totalise [SimplCount]
counts_so_far
               , ModGuts
guts { mg_binds :: CoreProgram
mg_binds = CoreProgram
binds, mg_rules :: [CoreRule]
mg_rules = [CoreRule]
rules } )
      
      
      | let sz :: Int
sz = CoreProgram -> Int
coreBindsSize CoreProgram
binds
      , () <- Int
sz Int -> () -> ()
`seq` ()     
      = do {
                
           let { tagged_binds :: CoreProgram
tagged_binds = {-# SCC "OccAnal" #-}
                     Module
-> (Id -> IsBootInterface)
-> (Activation -> IsBootInterface)
-> [CoreRule]
-> CoreProgram
-> CoreProgram
occurAnalysePgm Module
this_mod Id -> IsBootInterface
active_unf Activation -> IsBootInterface
active_rule [CoreRule]
rules
                                     CoreProgram
binds
               } ;
           DynFlags -> DumpFlag -> String -> SDoc -> IO ()
Err.dumpIfSet_dyn DynFlags
dflags DumpFlag
Opt_D_dump_occur_anal String
"Occurrence analysis"
                     (CoreProgram -> SDoc
forall b. OutputableBndr b => [Bind b] -> SDoc
pprCoreBindings CoreProgram
tagged_binds);
                
                
                
                
                
                
           ExternalPackageState
eps <- HscEnv -> IO ExternalPackageState
hscEPS HscEnv
hsc_env ;
           let  { rule_base1 :: RuleBase
rule_base1 = RuleBase -> RuleBase -> RuleBase
unionRuleBase RuleBase
hpt_rule_base (ExternalPackageState -> RuleBase
eps_rule_base ExternalPackageState
eps)
                ; rule_base2 :: RuleBase
rule_base2 = RuleBase -> [CoreRule] -> RuleBase
extendRuleBaseList RuleBase
rule_base1 [CoreRule]
rules
                ; fam_envs :: FamInstEnvs
fam_envs = (ExternalPackageState -> PackageFamInstEnv
eps_fam_inst_env ExternalPackageState
eps, PackageFamInstEnv
fam_inst_env)
                ; vis_orphs :: [Module]
vis_orphs = Module
this_mod Module -> [Module] -> [Module]
forall a. a -> [a] -> [a]
: Dependencies -> [Module]
dep_orphs Dependencies
deps } ;
                
           ((CoreProgram
binds1, [CoreRule]
rules1), SimplCount
counts1) <-
             DynFlags
-> RuleEnv
-> FamInstEnvs
-> UniqSupply
-> Int
-> SimplM (CoreProgram, [CoreRule])
-> IO ((CoreProgram, [CoreRule]), SimplCount)
forall a.
DynFlags
-> RuleEnv
-> FamInstEnvs
-> UniqSupply
-> Int
-> SimplM a
-> IO (a, SimplCount)
initSmpl DynFlags
dflags (RuleBase -> [Module] -> RuleEnv
mkRuleEnv RuleBase
rule_base2 [Module]
vis_orphs) FamInstEnvs
fam_envs UniqSupply
us1 Int
sz (SimplM (CoreProgram, [CoreRule])
 -> IO ((CoreProgram, [CoreRule]), SimplCount))
-> SimplM (CoreProgram, [CoreRule])
-> IO ((CoreProgram, [CoreRule]), SimplCount)
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
-> Maybe Id -> [CoreRule] -> MaybeJoinCont -> SimplM [CoreRule]
simplRules SimplEnv
env1 Maybe Id
forall a. Maybe a
Nothing [CoreRule]
rules MaybeJoinCont
forall a. Maybe a
Nothing
                  ; (CoreProgram, [CoreRule]) -> SimplM (CoreProgram, [CoreRule])
forall (m :: * -> *) a. Monad m => a -> m a
return (SimplFloats -> CoreProgram
getTopFloatBinds SimplFloats
floats, [CoreRule]
rules1) } ;
                
                
           if SimplCount -> IsBootInterface
isZeroSimplCount SimplCount
counts1 then
                (String, Int, SimplCount, ModGuts)
-> IO (String, Int, SimplCount, ModGuts)
forall (m :: * -> *) a. Monad m => a -> m a
return ( String
"Simplifier reached fixed point", Int
iteration_no
                       , [SimplCount] -> SimplCount
totalise (SimplCount
counts1 SimplCount -> [SimplCount] -> [SimplCount]
forall a. a -> [a] -> [a]
: [SimplCount]
counts_so_far)  
                       , ModGuts
guts { 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 } ;
                
           DynFlags
-> PrintUnqualified
-> Int
-> SimplCount
-> CoreProgram
-> [CoreRule]
-> IO ()
dump_end_iteration DynFlags
dflags PrintUnqualified
print_unqual Int
iteration_no SimplCount
counts1 CoreProgram
binds2 [CoreRule]
rules1 ;
           HscEnv -> CoreToDo -> CoreProgram -> IO ()
lintPassResult HscEnv
hsc_env CoreToDo
pass CoreProgram
binds2 ;
                
           UniqSupply
-> Int
-> [SimplCount]
-> CoreProgram
-> [CoreRule]
-> IO (String, Int, SimplCount, ModGuts)
do_iteration UniqSupply
us2 (Int
iteration_no Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (SimplCount
counts1SimplCount -> [SimplCount] -> [SimplCount]
forall a. a -> [a] -> [a]
:[SimplCount]
counts_so_far) CoreProgram
binds2 [CoreRule]
rules1
           } }
      | IsBootInterface
otherwise = String -> IO (String, Int, SimplCount, ModGuts)
forall a. String -> a
panic String
"do_iteration"
      where
        (UniqSupply
us1, UniqSupply
us2) = UniqSupply -> (UniqSupply, UniqSupply)
splitUniqSupply UniqSupply
us
        
        totalise :: [SimplCount] -> SimplCount
        totalise :: [SimplCount] -> SimplCount
totalise = (SimplCount -> SimplCount -> SimplCount)
-> SimplCount -> [SimplCount] -> SimplCount
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)
                         (DynFlags -> SimplCount
zeroSimplCount DynFlags
dflags)
simplifyPgmIO CoreToDo
_ HscEnv
_ UniqSupply
_ RuleBase
_ ModGuts
_ = String -> IO (SimplCount, ModGuts)
forall a. String -> a
panic String
"simplifyPgmIO"
dump_end_iteration :: DynFlags -> PrintUnqualified -> Int
                   -> SimplCount -> CoreProgram -> [CoreRule] -> IO ()
dump_end_iteration :: DynFlags
-> PrintUnqualified
-> Int
-> SimplCount
-> CoreProgram
-> [CoreRule]
-> IO ()
dump_end_iteration DynFlags
dflags PrintUnqualified
print_unqual Int
iteration_no SimplCount
counts CoreProgram
binds [CoreRule]
rules
  = DynFlags
-> PrintUnqualified
-> Maybe DumpFlag
-> SDoc
-> SDoc
-> CoreProgram
-> [CoreRule]
-> IO ()
dumpPassResult DynFlags
dflags PrintUnqualified
print_unqual Maybe DumpFlag
mb_flag SDoc
hdr SDoc
pp_counts CoreProgram
binds [CoreRule]
rules
  where
    mb_flag :: Maybe DumpFlag
mb_flag | DumpFlag -> DynFlags -> IsBootInterface
dopt DumpFlag
Opt_D_dump_simpl_iterations DynFlags
dflags = DumpFlag -> Maybe DumpFlag
forall a. a -> Maybe a
Just DumpFlag
Opt_D_dump_simpl_iterations
            | IsBootInterface
otherwise                               = Maybe DumpFlag
forall a. Maybe a
Nothing
            
    hdr :: SDoc
hdr = String -> SDoc
text String
"Simplifier iteration=" SDoc -> SDoc -> SDoc
<> Int -> SDoc
int Int
iteration_no
    pp_counts :: SDoc
pp_counts = [SDoc] -> SDoc
vcat [ String -> SDoc
text String
"---- Simplifier counts for" SDoc -> SDoc -> SDoc
<+> SDoc
hdr
                     , SimplCount -> SDoc
pprSimplCount SimplCount
counts
                     , String -> SDoc
text String
"---- End of simplifier counts for" SDoc -> SDoc -> SDoc
<+> SDoc
hdr ]
type IndEnv = IdEnv (Id, [Tickish Var]) 
shortOutIndirections :: CoreProgram -> CoreProgram
shortOutIndirections :: CoreProgram -> CoreProgram
shortOutIndirections CoreProgram
binds
  | VarEnv (Id, [Tickish Id]) -> IsBootInterface
forall a. VarEnv a -> IsBootInterface
isEmptyVarEnv VarEnv (Id, [Tickish Id])
ind_env = CoreProgram
binds
  | IsBootInterface
no_need_to_flatten    = CoreProgram
binds'                      
  | IsBootInterface
otherwise             = [[(Id, CoreExpr)] -> Bind Id
forall b. [(b, Expr b)] -> Bind b
Rec (CoreProgram -> [(Id, CoreExpr)]
forall b. [Bind b] -> [(b, Expr b)]
flattenBinds CoreProgram
binds')] 
  where
    ind_env :: VarEnv (Id, [Tickish Id])
ind_env            = CoreProgram -> VarEnv (Id, [Tickish Id])
makeIndEnv CoreProgram
binds
    
    exp_ids :: [Id]
exp_ids            = ((Id, [Tickish Id]) -> Id) -> [(Id, [Tickish Id])] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map (Id, [Tickish Id]) -> Id
forall a b. (a, b) -> a
fst ([(Id, [Tickish Id])] -> [Id]) -> [(Id, [Tickish Id])] -> [Id]
forall a b. (a -> b) -> a -> b
$ VarEnv (Id, [Tickish Id]) -> [(Id, [Tickish Id])]
forall elt. UniqFM elt -> [elt]
nonDetEltsUFM VarEnv (Id, [Tickish Id])
ind_env
      
      
      
    exp_id_set :: VarSet
exp_id_set         = [Id] -> VarSet
mkVarSet [Id]
exp_ids
    no_need_to_flatten :: IsBootInterface
no_need_to_flatten = (Id -> IsBootInterface) -> [Id] -> IsBootInterface
forall (t :: * -> *) a.
Foldable t =>
(a -> IsBootInterface) -> t a -> IsBootInterface
all ([CoreRule] -> IsBootInterface
forall (t :: * -> *) a. Foldable t => t a -> IsBootInterface
null ([CoreRule] -> IsBootInterface)
-> (Id -> [CoreRule]) -> Id -> IsBootInterface
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RuleInfo -> [CoreRule]
ruleInfoRules (RuleInfo -> [CoreRule]) -> (Id -> RuleInfo) -> Id -> [CoreRule]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> RuleInfo
idSpecialisation) [Id]
exp_ids
    binds' :: CoreProgram
binds'             = (Bind Id -> CoreProgram) -> CoreProgram -> CoreProgram
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) = [Id -> CoreExpr -> Bind Id
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)       = [[(Id, CoreExpr)] -> Bind Id
forall b. [(b, Expr b)] -> Bind b
Rec (((Id, CoreExpr) -> [(Id, CoreExpr)])
-> [(Id, CoreExpr)] -> [(Id, CoreExpr)]
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 -> IsBootInterface
`elemVarSet` VarSet
exp_id_set
        = []   
        | Just (Id
exp_id, [Tickish Id]
ticks) <- VarEnv (Id, [Tickish Id]) -> Id -> Maybe (Id, [Tickish Id])
forall a. VarEnv a -> Id -> Maybe a
lookupVarEnv VarEnv (Id, [Tickish Id])
ind_env Id
bndr
        , (Id
exp_id', Id
lcl_id') <- Id -> Id -> (Id, Id)
transferIdInfo Id
exp_id Id
bndr
        =      
               
          [ (Id
exp_id', [Tickish Id] -> CoreExpr -> CoreExpr
mkTicks [Tickish Id]
ticks CoreExpr
rhs),
            (Id
lcl_id', Id -> CoreExpr
forall b. Id -> Expr b
Var Id
exp_id') ]
        | IsBootInterface
otherwise
        = [(Id
bndr,CoreExpr
rhs)]
makeIndEnv :: [CoreBind] -> IndEnv
makeIndEnv :: CoreProgram -> VarEnv (Id, [Tickish Id])
makeIndEnv CoreProgram
binds
  = (VarEnv (Id, [Tickish Id]) -> Bind Id -> VarEnv (Id, [Tickish Id]))
-> VarEnv (Id, [Tickish Id])
-> CoreProgram
-> VarEnv (Id, [Tickish Id])
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' VarEnv (Id, [Tickish Id]) -> Bind Id -> VarEnv (Id, [Tickish Id])
add_bind VarEnv (Id, [Tickish Id])
forall a. VarEnv a
emptyVarEnv CoreProgram
binds
  where
    add_bind :: IndEnv -> CoreBind -> IndEnv
    add_bind :: VarEnv (Id, [Tickish Id]) -> Bind Id -> VarEnv (Id, [Tickish Id])
add_bind VarEnv (Id, [Tickish Id])
env (NonRec Id
exported_id CoreExpr
rhs) = VarEnv (Id, [Tickish Id])
-> (Id, CoreExpr) -> VarEnv (Id, [Tickish Id])
add_pair VarEnv (Id, [Tickish Id])
env (Id
exported_id, CoreExpr
rhs)
    add_bind VarEnv (Id, [Tickish Id])
env (Rec [(Id, CoreExpr)]
pairs)              = (VarEnv (Id, [Tickish Id])
 -> (Id, CoreExpr) -> VarEnv (Id, [Tickish Id]))
-> VarEnv (Id, [Tickish Id])
-> [(Id, CoreExpr)]
-> VarEnv (Id, [Tickish Id])
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' VarEnv (Id, [Tickish Id])
-> (Id, CoreExpr) -> VarEnv (Id, [Tickish Id])
add_pair VarEnv (Id, [Tickish Id])
env [(Id, CoreExpr)]
pairs
    add_pair :: IndEnv -> (Id,CoreExpr) -> IndEnv
    add_pair :: VarEnv (Id, [Tickish Id])
-> (Id, CoreExpr) -> VarEnv (Id, [Tickish Id])
add_pair VarEnv (Id, [Tickish Id])
env (Id
exported_id, CoreExpr
exported)
        | ([Tickish Id]
ticks, Var Id
local_id) <- (Tickish Id -> IsBootInterface)
-> CoreExpr -> ([Tickish Id], CoreExpr)
forall b.
(Tickish Id -> IsBootInterface) -> Expr b -> ([Tickish Id], Expr b)
stripTicksTop Tickish Id -> IsBootInterface
forall id. Tickish id -> IsBootInterface
tickishFloatable CoreExpr
exported
        , VarEnv (Id, [Tickish Id]) -> Id -> Id -> IsBootInterface
shortMeOut VarEnv (Id, [Tickish Id])
env Id
exported_id Id
local_id
        = VarEnv (Id, [Tickish Id])
-> Id -> (Id, [Tickish Id]) -> VarEnv (Id, [Tickish Id])
forall a. VarEnv a -> Id -> a -> VarEnv a
extendVarEnv VarEnv (Id, [Tickish Id])
env Id
local_id (Id
exported_id, [Tickish Id]
ticks)
    add_pair VarEnv (Id, [Tickish Id])
env (Id, CoreExpr)
_ = VarEnv (Id, [Tickish Id])
env
shortMeOut :: IndEnv -> Id -> Id -> Bool
shortMeOut :: VarEnv (Id, [Tickish Id]) -> Id -> Id -> IsBootInterface
shortMeOut VarEnv (Id, [Tickish Id])
ind_env Id
exported_id Id
local_id
  = if Id -> IsBootInterface
isExportedId Id
exported_id IsBootInterface -> IsBootInterface -> IsBootInterface
&&              
       Id -> IsBootInterface
isLocalId Id
local_id IsBootInterface -> IsBootInterface -> IsBootInterface
&&                    
                                                
                                                
       IsBootInterface -> IsBootInterface
not (Id -> IsBootInterface
isExportedId Id
local_id) IsBootInterface -> IsBootInterface -> IsBootInterface
&&           
                                                
       IsBootInterface -> IsBootInterface
not (Id
local_id Id -> VarEnv (Id, [Tickish Id]) -> IsBootInterface
forall a. Id -> VarEnv a -> IsBootInterface
`elemVarEnv` VarEnv (Id, [Tickish Id])
ind_env)      
    then
        if Id -> IsBootInterface
hasShortableIdInfo Id
exported_id
        then IsBootInterface
True       
        else WARN( True, text "Not shorting out:" <+> ppr exported_id )
             IsBootInterface
False
    else
        IsBootInterface
False
hasShortableIdInfo :: Id -> Bool
hasShortableIdInfo :: Id -> IsBootInterface
hasShortableIdInfo Id
id
  =  RuleInfo -> IsBootInterface
isEmptyRuleInfo (IdInfo -> RuleInfo
ruleInfo IdInfo
info)
  IsBootInterface -> IsBootInterface -> IsBootInterface
&& InlinePragma -> IsBootInterface
isDefaultInlinePragma (IdInfo -> InlinePragma
inlinePragInfo IdInfo
info)
  IsBootInterface -> IsBootInterface -> IsBootInterface
&& IsBootInterface -> IsBootInterface
not (Unfolding -> IsBootInterface
isStableUnfolding (IdInfo -> Unfolding
unfoldingInfo IdInfo
info))
  where
     info :: IdInfo
info = HasDebugCallStack => Id -> IdInfo
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
(IdInfo -> IdInfo) -> Id -> Id
modifyIdInfo IdInfo -> IdInfo
transfer Id
exported_id
    , Id
local_id Id -> InlinePragma -> Id
`setInlinePragma` InlinePragma
defaultInlinePragma )
  where
    local_info :: IdInfo
local_info = HasDebugCallStack => Id -> IdInfo
Id -> IdInfo
idInfo Id
local_id
    transfer :: IdInfo -> IdInfo
transfer IdInfo
exp_info = IdInfo
exp_info IdInfo -> StrictSig -> IdInfo
`setStrictnessInfo`    IdInfo -> StrictSig
strictnessInfo IdInfo
local_info
                                 IdInfo -> Unfolding -> IdInfo
`setUnfoldingInfo`     IdInfo -> Unfolding
unfoldingInfo 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)