-import SimplMonad ( zeroSimplCount, showSimplCount, SimplCount )
-import SimplPgm ( simplifyPgm )
-import Specialise
-import SpecUtils ( pprSpecErrs )
-import StrictAnal ( saWwTopBinds )
-import TyVar ( SYN_IE(TyVar), nullTyVarEnv, GenTyVar{-instance Eq-},
- nameTyVar
- )
-import Unique ( Unique{-instance Eq-}, Uniquable(..),
- integerTyConKey, ratioTyConKey,
- mkUnique, incrUnique,
- initTidyUniques
- )
-import UniqSupply ( UniqSupply, mkSplitUniqSupply,
- splitUniqSupply, getUnique
- )
-import UniqFM ( UniqFM, lookupUFM, addToUFM )
-import Usage ( SYN_IE(UVar), cloneUVar )
-import Util ( mapAccumL, assertPanic, panic{-ToDo:rm-}, pprTrace, pprPanic )
-import SrcLoc ( noSrcLoc )
-import Constants ( tARGET_MIN_INT, tARGET_MAX_INT )
-import Bag
-import Maybes
-
-\end{code}
-
-\begin{code}
-core2core :: [CoreToDo] -- spec of what core-to-core passes to do
- -> FAST_STRING -- module name (profiling 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 us local_tycons tycon_specs binds
- = -- 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 = tidyCorePgm module_name processed_binds
- in
- lintCoreBindings "TidyCorePgm" True final_binds >>
-
-
- -- Dump output
- dumpIfSet (opt_D_dump_simpl || opt_D_verbose_core2core)
- "Core transformations"
- (pprCoreBindings pprDumpStyle final_binds) >>
-
- -- Report statistics
- doIfSet opt_D_simplifier_stats
- (hPutStr stderr ("\nSimplifier Stats:\n") >>
- hPutStr stderr (showSimplCount simpl_stats) >>
- hPutStr stderr "\n") >>
-
- -- Return results
- return (final_binds, spec_data)
- where
- init_specdata = initSpecData local_tycons tycon_specs
-
- --------------
- 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 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 us2 binds2 spec_data simpl_stats "FBWW" }
-
- CoreDoFoldrBuildWWAnal
- -> _scc_ "CoreDoFoldrBuildWWAnal"
- begin_pass "AnalFBWW" >>
- case (analFBWW binds) of { binds2 ->
- end_pass us2 binds2 spec_data simpl_stats "AnalFBWW" }
-
- CoreLiberateCase
- -> _scc_ "LiberateCase"
- begin_pass "LiberateCase" >>
- case (liberateCase opt_LiberateCaseThreshold binds) of { binds2 ->
- end_pass us2 binds2 spec_data simpl_stats "LiberateCase" }
-
- CoreDoFloatInwards
- -> _scc_ "FloatInwards"
- begin_pass "FloatIn" >>
- case (floatInwards binds) of { binds2 ->
- end_pass us2 binds2 spec_data simpl_stats "FloatIn" }
-
- CoreDoFullLaziness
- -> _scc_ "CoreFloating"
- begin_pass "FloatOut" >>
- case (floatOutwards us1 binds) of { binds2 ->
- end_pass us2 binds2 spec_data simpl_stats "FloatOut" }
-
- CoreDoStaticArgs
- -> _scc_ "CoreStaticArgs"
- begin_pass "StaticArgs" >>
- case (doStaticArgs binds us1) of { binds2 ->
- end_pass 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 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
- doIfSet ((not spec_noerrs) ||
- (opt_ShowImportSpecs && not (isEmptyBag spec_warn)))
- (printErrs
- (pprSpecErrs module_name spec_errs spec_warn spec_tyerrs))
- >>
-
- doIfSet (not spec_noerrs) -- Stop here if specialisation errors occured
- (ghcExit 1) >>
-
- end_pass us2 p spec_data2 simpl_stats "Specialise"
- }
-
- CoreDoPrintCore -- print result of last pass
- -> dumpIfSet (not opt_D_verbose_core2core) "Print Core"
- (pprCoreBindings pprDumpStyle binds) >>
- return (binds, us1, spec_data, simpl_stats)
-
- -------------------------------------------------
-
- begin_pass what
- = if opt_D_show_passes
- then hPutStr stderr ("*** Core2Core: "++what++"\n")
- else return ()
-
- end_pass us2 binds2
- spec_data2@(SpecData spec_done _ _ _ _ _ _ _)
- simpl_stats2 what
- = -- Report verbosely, if required
- dumpIfSet opt_D_verbose_core2core what
- (pprCoreBindings pprDumpStyle binds2) >>
-
- lintCoreBindings what spec_done binds2 >>
-
- return
- (binds2, -- 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