-\begin{code}
-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...
- SpecialiseData) -- specialisation data
-
-core2core core_todos module_name ppr_style us local_tycons tycon_specs binds
- = -- Print heading
- (if opt_D_verbose_core2core then
- hPutStr stderr "VERBOSE CORE-TO-CORE:\n"
- else return ()) >>
-
- -- Do the main business
- foldl_mn do_core_pass
- (binds, us, init_specdata, zeroSimplCount)
- core_todos
- >>= \ (processed_binds, us', spec_data, simpl_stats) ->
-
- -- Do the final tidy-up
- let
- final_binds = core_linter "TidyCorePgm" True $
- tidyCorePgm module_name processed_binds
- in
-
- -- Report statistics
- (if opt_D_simplifier_stats then
- hPutStr stderr ("\nSimplifier Stats:\n") >>
- hPutStr stderr (showSimplCount simpl_stats) >>
- hPutStr stderr "\n"
- else return ()) >>
-
- --
- return (final_binds, spec_data)
- where
- init_specdata = initSpecData local_tycons tycon_specs
-
- -------------
- core_linter what spec_done
- = if opt_DoCoreLinting
- then (if opt_D_show_passes then
- trace ("\n*** Core Lint result of " ++ what)
- else id
- )
- lintCoreBindings ppr_style what spec_done
- else id
-
- --------------
- do_core_pass info@(binds, us, spec_data, simpl_stats) to_do =
- case (splitUniqSupply us) of
- (us1,us2) ->
- case to_do of
- CoreDoSimplify simpl_sw_chkr
- -> _scc_ "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 spec_data simpl_stats2
- ("Simplify (" ++ show it_cnt ++ ")"
- ++ if switchIsOn simpl_sw_chkr SimplDoFoldrBuild
- then " foldr/build" else "")
-
- CoreDoFoldrBuildWorkerWrapper
- -> _scc_ "CoreDoFoldrBuildWorkerWrapper"
- begin_pass "FBWW" >>
- case (mkFoldrBuildWW us1 binds) of { binds2 ->
- end_pass False us2 binds2 spec_data simpl_stats "FBWW" }
-
- CoreDoFoldrBuildWWAnal
- -> _scc_ "CoreDoFoldrBuildWWAnal"
- begin_pass "AnalFBWW" >>
- case (analFBWW binds) of { binds2 ->
- end_pass False us2 binds2 spec_data simpl_stats "AnalFBWW" }
-
- CoreLiberateCase
- -> _scc_ "LiberateCase"
- begin_pass "LiberateCase" >>
- case (liberateCase opt_LiberateCaseThreshold binds) of { binds2 ->
- end_pass False us2 binds2 spec_data simpl_stats "LiberateCase" }
-
- CoreDoFloatInwards
- -> _scc_ "FloatInwards"
- begin_pass "FloatIn" >>
- case (floatInwards binds) of { binds2 ->
- end_pass False us2 binds2 spec_data simpl_stats "FloatIn" }
-
- CoreDoFullLaziness
- -> _scc_ "CoreFloating"
- begin_pass "FloatOut" >>
- case (floatOutwards us1 binds) of { binds2 ->
- end_pass False us2 binds2 spec_data simpl_stats "FloatOut" }
-
- CoreDoStaticArgs
- -> _scc_ "CoreStaticArgs"
- begin_pass "StaticArgs" >>
- case (doStaticArgs binds us1) of { binds2 ->
- end_pass False us2 binds2 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])
-
- CoreDoStrictness
- -> _scc_ "CoreStranal"
- begin_pass "StrAnal" >>
- case (saWwTopBinds us1 binds) of { binds2 ->
- end_pass False us2 binds2 spec_data simpl_stats "StrAnal" }
-
- CoreDoSpecialising
- -> _scc_ "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 (show
- (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 spec_data2 simpl_stats "Specialise"
- }
-
- CoreDoDeforest
-#if OMIT_DEFORESTER
- -> error "ERROR: CoreDoDeforest: not built into compiler\n"
-#else
- -> _scc_ "Deforestation"
- begin_pass "Deforestation" >>
- case (deforestProgram binds us1) of { binds2 ->
- end_pass False us2 binds2 spec_data simpl_stats "Deforestation" }
-#endif
-
- CoreDoPrintCore -- print result of last pass
- -> end_pass True us2 binds spec_data simpl_stats "Print"
-
- -------------------------------------------------
-
- begin_pass
- = if opt_D_show_passes
- then \ what -> hPutStr stderr ("*** Core2Core: "++what++"\n")
- else \ what -> return ()
-
- end_pass print us2 binds2
- spec_data2@(SpecData spec_done _ _ _ _ _ _ _)
- simpl_stats2 what
- = -- report verbosely, if required
- (if (opt_D_verbose_core2core && not print) ||
- (print && not opt_D_verbose_core2core)
- then
- hPutStr stderr ("\n*** "++what++":\n")
- >>
- hPutStr stderr (show
- (vcat (map (pprCoreBinding ppr_style) binds2)))
- >>
- hPutStr stderr "\n"
- else
- return ()) >>
- let
- linted_binds = core_linter what spec_done binds2
- in
- return
- (linted_binds, -- processed binds, possibly run thru CoreLint
- us2, -- UniqSupply for the next guy
- spec_data2, -- possibly-updated specialisation info
- simpl_stats2 -- accumulated simplifier stats
- )
-
--- here so it can be inlined...
-foldl_mn f z [] = return z
-foldl_mn f z (x:xs) = f z x >>= \ zz ->
- foldl_mn f zz xs
-\end{code}
-
-
-