- --------------
- do_core_pass info@(binds, us, 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 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 simpl_stats "FBWW" }
-
- CoreDoFoldrBuildWWAnal
- -> _scc_ "CoreDoFoldrBuildWWAnal"
- begin_pass "AnalFBWW" >>
- case (analFBWW binds) of { binds2 ->
- end_pass us2 binds2 simpl_stats "AnalFBWW" }
-
- CoreLiberateCase
- -> _scc_ "LiberateCase"
- begin_pass "LiberateCase" >>
- case (liberateCase opt_LiberateCaseThreshold binds) of { binds2 ->
- end_pass us2 binds2 simpl_stats "LiberateCase" }
-
- CoreDoFloatInwards
- -> _scc_ "FloatInwards"
- begin_pass "FloatIn" >>
- case (floatInwards binds) of { binds2 ->
- end_pass us2 binds2 simpl_stats "FloatIn" }
-
- CoreDoFullLaziness
- -> _scc_ "CoreFloating"
- begin_pass "FloatOut" >>
- case (floatOutwards us1 binds) of { binds2 ->
- end_pass us2 binds2 simpl_stats "FloatOut" }
-
- CoreDoStaticArgs
- -> _scc_ "CoreStaticArgs"
- begin_pass "StaticArgs" >>
- case (doStaticArgs binds us1) of { binds2 ->
- end_pass us2 binds2 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 simpl_stats "StrAnal" }
-
- CoreDoSpecialising
- -> _scc_ "Specialise"
- begin_pass "Specialise" >>
- case (specProgram us1 binds) of { p ->
- end_pass us2 p simpl_stats "Specialise"
- }
-
- CoreDoPrintCore -- print result of last pass
- -> dumpIfSet (not opt_D_verbose_core2core) "Print Core"
- (pprCoreBindings binds) >>
- return (binds, us1, simpl_stats)
-
- -------------------------------------------------
-
- begin_pass what
- = if opt_D_show_passes
- then hPutStr stderr ("*** Core2Core: "++what++"\n")
- else return ()
-
- end_pass us2 binds2
- simpl_stats2 what
- = -- Report verbosely, if required
- dumpIfSet opt_D_verbose_core2core what
- (pprCoreBindings binds2) >>
-
- lintCoreBindings what True {- spec_done -} binds2 >>
- -- The spec_done flag tells the linter to
- -- complain about unboxed let-bindings
- -- But we're not specialising unboxed types any more,
- -- so its irrelevant.
-
- return
- (binds2, -- processed binds, possibly run thru CoreLint
- us2, -- UniqSupply for the next guy
- 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
+ max_iterations = getSimplIntSwitch sw_chkr MaxSimplifierIterations
+ simpl_switch_is_on = switchIsOn sw_chkr
+
+ core_iter_dump binds | opt_D_verbose_core2core = pprCoreBindings binds
+ | otherwise = empty
+
+ iteration us iteration_no counts binds
+ = do {
+ -- Occurrence analysis
+ let { tagged_binds = _scc_ "OccAnal" occurAnalyseBinds simpl_switch_is_on binds };
+ dumpIfSet opt_D_dump_occur_anal "Occurrence analysis"
+ (pprCoreBindings tagged_binds);
+
+ -- Simplify
+ let { (binds', counts') = initSmpl sw_chkr us1 (simplTopBinds tagged_binds);
+ all_counts = counts `plusSimplCount` counts'
+ } ;
+
+ -- Stop if nothing happened; don't dump output
+ if isZeroSimplCount counts' then
+ return ("Simplifier reached fixed point", iteration_no, all_counts, binds')
+ else do {
+
+ -- Dump the result of this iteration
+ dumpIfSet opt_D_dump_simpl_iterations
+ ("Simplifier iteration " ++ show iteration_no
+ ++ " out of " ++ show max_iterations)
+ (vcat[pprSimplCount counts',
+ text "",
+ core_iter_dump binds']) ;
+
+ -- Stop if we've run out of iterations
+ if iteration_no == max_iterations then
+ do {
+ if max_iterations > 1 then
+ hPutStr stderr ("NOTE: Simplifier still going after " ++
+ show max_iterations ++
+ " iterations; bailing out.\n")
+ else return ();
+
+ return ("Simplifier baled out", iteration_no, all_counts, binds')
+ }
+
+ -- Else loop
+ else iteration us2 (iteration_no + 1) all_counts binds'
+ } }
+ where
+ (us1, us2) = splitUniqSupply us
+
+
+simplTopBinds [] = returnSmpl []
+simplTopBinds (bind1 : binds) = (simplBind bind1 $
+ simplTopBinds binds) `thenSmpl` \ (binds1', binds') ->
+ returnSmpl (binds1' ++ binds')