2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1995
4 \section[SimplStg]{Driver for simplifying @STG@ programs}
7 #include "HsVersions.h"
9 module SimplStg ( stg2stg ) where
12 IMPORT_1_3(IO(hPutStr,stderr))
17 import LambdaLift ( liftProgram )
18 import Name ( isLocallyDefined )
19 import SCCfinal ( stgMassageForProfiling )
20 import SatStgRhs ( satStgRhs )
21 import StgLint ( lintStgBindings )
22 import StgStats ( showStgStats )
23 import StgVarInfo ( setStgVarInfo )
24 import UpdAnal ( updateAnalyse )
26 import CmdLineOpts ( opt_EnsureSplittableC, opt_SccGroup,
27 opt_StgDoLetNoEscapes, opt_D_verbose_stg2stg,
30 import Id ( nullIdEnv, lookupIdEnv, addOneToIdEnv,
31 growIdEnvList, isNullIdEnv, SYN_IE(IdEnv),
32 GenId{-instance Eq/Outputable -}
34 import Maybes ( maybeToBool )
35 import PprType ( GenType{-instance Outputable-} )
36 import Pretty ( ppShow, ppAbove, ppAboves, ppStr )
37 import UniqSupply ( splitUniqSupply )
38 import Util ( mapAccumL, panic, assertPanic )
43 stg2stg :: [StgToDo] -- spec of what stg-to-stg passes to do
44 -> FAST_STRING -- module name (profiling only)
45 -> PprStyle -- printing style (for debugging only)
46 -> UniqSupply -- a name supply
47 -> [StgBinding] -- input...
49 ([StgBinding], -- output program...
50 ([CostCentre], -- local cost-centres that need to be decl'd
51 [CostCentre])) -- "extern" cost-centres
53 stg2stg stg_todos module_name ppr_style us binds
54 = case (splitUniqSupply us) of { (us4now, us4later) ->
56 (if do_verbose_stg2stg then
57 hPutStr stderr "VERBOSE STG-TO-STG:\n" >>
58 hPutStr stderr (ppShow 1000
59 (ppAbove (ppStr ("*** Core2Stg:"))
60 (ppAboves (map (ppr ppr_style) (setStgVarInfo False binds)))
64 -- Do the main business!
65 foldl_mn do_stg_pass (binds, us4now, ([],[])) stg_todos
66 >>= \ (processed_binds, _, cost_centres) ->
68 -- Do essential wind-up
70 {- Nuked for now SLPJ Dec 96
71 -- Essential wind-up: part (a), saturate RHSs
72 -- This must occur *after* elimIndirections, because elimIndirections
73 -- can change things' arities. Consider:
75 -- x_global = \a -> x_local a
76 -- Then elimIndirections will change the program to
78 -- and lo and behold x_global's arity has changed!
80 case (satStgRhs processed_binds us4later) of { saturated_binds ->
83 -- Essential wind-up: part (b), do setStgVarInfo. It has to
84 -- happen regardless, because the code generator uses its
87 -- Why does it have to happen last? Because earlier passes
88 -- may move things around, which would change the live-var
89 -- info. Also, setStgVarInfo decides about let-no-escape
90 -- things, which in turn do a better job if arities are
91 -- correct, which is done by satStgRhs.
94 {- Done in Core now. Nuke soon. SLPJ Nov 96
96 -- ToDo: provide proper flag control!
98 = if not do_unlocalising
100 else snd (unlocaliseStgBinds unlocal_tag nullIdEnv no_ind_binds)
104 return (setStgVarInfo do_let_no_escapes processed_binds, cost_centres)
107 do_let_no_escapes = opt_StgDoLetNoEscapes
108 do_verbose_stg2stg = opt_D_verbose_stg2stg
110 grp_name = case (opt_SccGroup) of
112 Nothing -> module_name -- default: module name
115 stg_linter = if False -- LATER: switch_is_on DoCoreLinting -- ToDo: DoStgLinting flag
116 then lintStgBindings ppr_style
117 else ( \ whodunnit binds -> binds )
119 -------------------------------------------
120 do_stg_pass (binds, us, ccs) to_do
122 (us1, us2) = splitUniqSupply us
125 StgDoStaticArgs -> panic "STG static argument transformation deleted"
127 StgDoUpdateAnalysis ->
128 ASSERT(null (fst ccs) && null (snd ccs))
130 -- NB We have to do setStgVarInfo first! (There's one
131 -- place free-var info is used) But no let-no-escapes,
132 -- because update analysis doesn't care.
133 end_pass us2 "UpdAnal" ccs (updateAnalyse (setStgVarInfo False binds))
136 trace (showStgStats binds)
137 end_pass us2 "StgStats" ccs binds
140 _scc_ "StgLambdaLift"
141 -- NB We have to do setStgVarInfo first!
143 binds3 = liftProgram us1 (setStgVarInfo do_let_no_escapes binds)
145 end_pass us2 "LambdaLift" ccs binds3
147 StgDoMassageForProfiling ->
150 (collected_CCs, binds3)
151 = stgMassageForProfiling module_name grp_name us1 binds
153 end_pass us2 "ProfMassage" collected_CCs binds3
155 end_pass us2 what ccs binds2
156 = -- report verbosely, if required
157 (if do_verbose_stg2stg then
158 hPutStr stderr (ppShow 1000
159 (ppAbove (ppStr ("*** "++what++":"))
160 (ppAboves (map (ppr ppr_style) binds2))
164 linted_binds = stg_linter what binds2
166 return (linted_binds, us2, ccs)
167 -- return: processed binds
168 -- UniqueSupply for the next guy to use
169 -- cost-centres to be declared/registered (specialised)
170 -- add to description of what's happened (reverse order)
172 -- here so it can be inlined...
173 foldl_mn f z [] = return z
174 foldl_mn f z (x:xs) = f z x >>= \ zz ->