-core2core :: [CoreToDo] -- spec of what core-to-core passes to do
- -> FAST_STRING -- module name (profiling only)
- -> PprStyle -- printing style (for debugging only)
- -> UniqSupply -- a name supply
- -> [TyCon] -- local data tycons and tycon specialisations
- -> FiniteMap TyCon [(Bool, [Maybe Type])]
- -> [CoreBinding] -- input...
- -> IO
- ([CoreBinding], -- results: program, plus...
- IdEnv UnfoldingDetails, -- unfoldings to be exported from here
- SpecialiseData) -- specialisation data
-
-core2core core_todos module_name ppr_style us local_tycons tycon_specs binds
- = BSCC("Core2Core")
- if null core_todos then -- very rare, I suspect...
- -- well, we still must do some renumbering
- return (
- (substCoreBindings nullIdEnv nullTyVarEnv binds us,
- nullIdEnv,
- init_specdata)
- )
- else
- (if do_verbose_core2core then
- hPutStr stderr "VERBOSE CORE-TO-CORE:\n"
- else return ()) >>
-
- -- better do the main business
- foldl_mn do_core_pass
- (binds, us, nullIdEnv, init_specdata, zeroSimplCount)
- core_todos
- >>= \ (processed_binds, _, inline_env, spec_data, simpl_stats) ->
-
- (if opt_D_simplifier_stats
- then hPutStr stderr ("\nSimplifier Stats:\n")
- >>
- hPutStr stderr (showSimplCount simpl_stats)
- >>
- hPutStr stderr "\n"
- else return ()
- ) >>
-
- return (processed_binds, inline_env, spec_data)
- ESCC
- where
- init_specdata = initSpecData local_tycons tycon_specs
-
- do_verbose_core2core = opt_D_verbose_core2core
-
- lib_case_threshold -- ToDo: HACK HACK HACK : FIX ME FIX ME FIX ME
- -- Use 4x a known threshold
- = case opt_UnfoldingOverrideThreshold of
- Nothing -> 4 * uNFOLDING_USE_THRESHOLD
- Just xx -> 4 * xx
-
- -------------
- core_linter = if opt_DoCoreLinting
- then lintCoreBindings ppr_style
- else ( \ whodunnit spec_done binds -> binds )
-
- --------------
- do_core_pass info@(binds, us, inline_env, spec_data, simpl_stats) to_do
- = let
- (us1, us2) = splitUniqSupply us
- in
- case to_do of
- CoreDoSimplify simpl_sw_chkr
- -> BSCC("CoreSimplify")
- begin_pass ("Simplify" ++ if switchIsOn simpl_sw_chkr SimplDoFoldrBuild
- then " (foldr/build)" else "") >>
- case (simplifyPgm binds simpl_sw_chkr simpl_stats us1) of
- (p, it_cnt, simpl_stats2)
- -> end_pass False us2 p inline_env spec_data simpl_stats2
- ("Simplify (" ++ show it_cnt ++ ")"
- ++ if switchIsOn simpl_sw_chkr SimplDoFoldrBuild
- then " foldr/build" else "")
- ESCC
-
- CoreDoFoldrBuildWorkerWrapper
- -> BSCC("CoreDoFoldrBuildWorkerWrapper")
- begin_pass "FBWW" >>
- case (mkFoldrBuildWW us1 binds) of { binds2 ->
- end_pass False us2 binds2 inline_env spec_data simpl_stats "FBWW"
- } ESCC
-
- CoreDoFoldrBuildWWAnal
- -> BSCC("CoreDoFoldrBuildWWAnal")
- begin_pass "AnalFBWW" >>
- case (analFBWW binds) of { binds2 ->
- end_pass False us2 binds2 inline_env spec_data simpl_stats "AnalFBWW"
- } ESCC
-
- CoreLiberateCase
- -> BSCC("LiberateCase")
- begin_pass "LiberateCase" >>
- case (liberateCase lib_case_threshold binds) of { binds2 ->
- end_pass False us2 binds2 inline_env spec_data simpl_stats "LiberateCase"
- } ESCC
-
- CoreDoCalcInlinings1 -- avoid inlinings w/ cost-centres
- -> BSCC("CoreInlinings1")
- begin_pass "CalcInlinings" >>
- case (calcInlinings False inline_env binds) of { inline_env2 ->
- end_pass False us2 binds inline_env2 spec_data simpl_stats "CalcInlinings"
- } ESCC
-
- CoreDoCalcInlinings2 -- allow inlinings w/ cost-centres
- -> BSCC("CoreInlinings2")
- begin_pass "CalcInlinings" >>
- case (calcInlinings True inline_env binds) of { inline_env2 ->
- end_pass False us2 binds inline_env2 spec_data simpl_stats "CalcInlinings"
- } ESCC
-
- CoreDoFloatInwards
- -> BSCC("FloatInwards")
- begin_pass "FloatIn" >>
- case (floatInwards binds) of { binds2 ->
- end_pass False us2 binds2 inline_env spec_data simpl_stats "FloatIn"
- } ESCC
-
- CoreDoFullLaziness
- -> BSCC("CoreFloating")
- begin_pass "FloatOut" >>
- case (floatOutwards us1 binds) of { binds2 ->
- end_pass False us2 binds2 inline_env spec_data simpl_stats "FloatOut"
- } ESCC
-
- CoreDoStaticArgs
- -> BSCC("CoreStaticArgs")
- begin_pass "StaticArgs" >>
- case (doStaticArgs binds us1) of { binds2 ->
- end_pass False us2 binds2 inline_env spec_data simpl_stats "StaticArgs"
- -- Binds really should be dependency-analysed for static-
- -- arg transformation... Not to worry, they probably are.
- -- (I don't think it *dies* if they aren't [WDP 94/04/15])
- } ESCC
-
- CoreDoStrictness
- -> BSCC("CoreStranal")
- begin_pass "StrAnal" >>
- case (saWwTopBinds us1 binds) of { binds2 ->
- end_pass False us2 binds2 inline_env spec_data simpl_stats "StrAnal"
- } ESCC
-
- CoreDoSpecialising
- -> BSCC("Specialise")
- begin_pass "Specialise" >>
- case (specProgram us1 binds spec_data) of {
- (p, spec_data2@(SpecData _ spec_noerrs _ _ _
- spec_errs spec_warn spec_tyerrs)) ->
-
- -- if we got errors, we die straight away
- (if not spec_noerrs ||
- (opt_ShowImportSpecs && not (isEmptyBag spec_warn)) then
- hPutStr stderr (ppShow 1000 {-pprCols-}
- (pprSpecErrs module_name spec_errs spec_warn spec_tyerrs))
- >> hPutStr stderr "\n"
- else
- return ()) >>
-
- (if not spec_noerrs then -- Stop here if specialisation errors occured
- ghcExit 1
- else
- return ()) >>
-
- end_pass False us2 p inline_env spec_data2 simpl_stats "Specialise"
- }
- ESCC
-
- CoreDoDeforest
-#if OMIT_DEFORESTER
- -> error "ERROR: CoreDoDeforest: not built into compiler\n"
-#else
- -> BSCC("Deforestation")
- begin_pass "Deforestation" >>
- case (deforestProgram binds us1) of { binds2 ->
- end_pass False us2 binds2 inline_env spec_data simpl_stats "Deforestation"
- }
- ESCC
+core2core :: HscEnv
+ -> ModGuts
+ -> IO ModGuts
+
+core2core hsc_env guts
+ = do
+ let dflags = hsc_dflags hsc_env
+ core_todos
+ | Just todo <- dopt_CoreToDo dflags = todo
+ | otherwise = buildCoreToDo dflags
+
+ us <- mkSplitUniqSupply 's'
+ let (cp_us, ru_us) = splitUniqSupply us
+
+ -- COMPUTE THE RULE BASE TO USE
+ (imp_rule_base, guts') <- prepareRules hsc_env guts ru_us
+
+ -- DO THE BUSINESS
+ (stats, guts'') <- doCorePasses hsc_env cp_us
+ (zeroSimplCount dflags)
+ imp_rule_base guts' core_todos
+
+ dumpIfSet_dyn dflags Opt_D_dump_simpl_stats
+ "Grand total simplifier statistics"
+ (pprSimplCount stats)
+
+ return guts''
+
+
+simplifyExpr :: DynFlags -- includes spec of what core-to-core passes to do
+ -> CoreExpr
+ -> IO CoreExpr
+-- simplifyExpr is called by the driver to simplify an
+-- expression typed in at the interactive prompt
+simplifyExpr dflags expr
+ = do {
+ ; showPass dflags "Simplify"
+
+ ; us <- mkSplitUniqSupply 's'
+
+ ; let (expr', _counts) = initSmpl dflags us $
+ simplExprGently gentleSimplEnv expr
+
+ ; dumpIfSet_dyn dflags Opt_D_dump_simpl "Simplified expression"
+ (pprCoreExpr expr')
+
+ ; return expr'
+ }
+
+gentleSimplEnv :: SimplEnv
+gentleSimplEnv = mkSimplEnv SimplGently
+ (isAmongSimpl [])
+ emptyRuleBase
+
+doCorePasses :: HscEnv
+ -> UniqSupply -- uniques
+ -> SimplCount -- simplifier stats
+ -> RuleBase -- the main rule base
+ -> ModGuts -- local binds in (with rules attached)
+ -> [CoreToDo] -- which passes to do
+ -> IO (SimplCount, ModGuts)
+
+doCorePasses hsc_env us stats rb guts []
+ = return (stats, guts)
+
+doCorePasses hsc_env us stats rb guts (to_do : to_dos)
+ = do
+ let (us1, us2) = splitUniqSupply us
+ (stats1, rb1, guts1) <- doCorePass to_do hsc_env us1 rb guts
+ doCorePasses hsc_env us2 (stats `plusSimplCount` stats1) rb1 guts1 to_dos
+
+doCorePass (CoreDoSimplify mode sws) = _scc_ "Simplify" simplifyPgm mode sws
+doCorePass CoreCSE = _scc_ "CommonSubExpr" trBinds cseProgram
+doCorePass CoreLiberateCase = _scc_ "LiberateCase" trBinds liberateCase
+doCorePass CoreDoFloatInwards = _scc_ "FloatInwards" trBinds floatInwards
+doCorePass (CoreDoFloatOutwards f) = _scc_ "FloatOutwards" trBindsU (floatOutwards f)
+doCorePass CoreDoStaticArgs = _scc_ "StaticArgs" trBinds doStaticArgs
+doCorePass CoreDoStrictness = _scc_ "Stranal" trBinds dmdAnalPgm
+doCorePass CoreDoWorkerWrapper = _scc_ "WorkWrap" trBindsU wwTopBinds
+doCorePass CoreDoSpecialising = _scc_ "Specialise" trBindsU specProgram
+doCorePass CoreDoSpecConstr = _scc_ "SpecConstr" trBindsU specConstrProgram
+doCorePass CoreDoGlomBinds = trBinds glomBinds
+doCorePass CoreDoPrintCore = observe printCore
+doCorePass (CoreDoRuleCheck phase pat) = observe (ruleCheck phase pat)
+doCorePass CoreDoNothing = observe (\ _ _ -> return ())
+#ifdef OLD_STRICTNESS
+doCorePass CoreDoOldStrictness = _scc_ "OldStrictness" trBinds doOldStrictness