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))
16 import LambdaLift ( liftProgram )
17 import Name ( isLocallyDefined )
18 import UniqSet ( UniqSet(..), mapUniqSet )
19 import CostCentre ( CostCentre )
20 import SCCfinal ( stgMassageForProfiling )
21 import StgLint ( lintStgBindings )
22 import StgStats ( showStgStats )
23 import StgVarInfo ( setStgVarInfo )
24 import UpdAnal ( updateAnalyse )
26 import CmdLineOpts ( opt_SccGroup, --Not used:opt_EnsureSplittableC,
27 opt_StgDoLetNoEscapes, opt_D_verbose_stg2stg,
31 import Id ( nullIdEnv, lookupIdEnv, addOneToIdEnv,
32 growIdEnvList, isNullIdEnv, SYN_IE(IdEnv),
33 GenId{-instance Eq/Outputable -}, SYN_IE(Id)
35 import Maybes ( maybeToBool )
36 import PprType ( GenType{-instance Outputable-} )
37 import ErrUtils ( doIfSet )
38 import Outputable ( PprStyle, Outputable(..), printErrs, pprDumpStyle )
39 import Pretty ( Doc, ($$), vcat, text, ptext )
40 import UniqSupply ( splitUniqSupply, UniqSupply )
41 import Util ( mapAccumL, panic, assertPanic )
45 stg2stg :: [StgToDo] -- spec of what stg-to-stg passes to do
46 -> FAST_STRING -- module name (profiling only)
47 -> UniqSupply -- a name supply
48 -> [StgBinding] -- input...
50 ([StgBinding], -- output program...
51 ([CostCentre], -- local cost-centres that need to be decl'd
52 [CostCentre])) -- "extern" cost-centres
54 stg2stg stg_todos module_name us binds
55 = case (splitUniqSupply us) of { (us4now, us4later) ->
57 doIfSet do_verbose_stg2stg
58 (printErrs (text "VERBOSE STG-TO-STG:" $$
59 text "*** Core2Stg:" $$
60 vcat (map (ppr pprDumpStyle) (setStgVarInfo False binds)))) >>
62 -- Do the main business!
63 foldl_mn do_stg_pass (binds, us4now, ([],[])) stg_todos
64 >>= \ (processed_binds, _, cost_centres) ->
66 -- Do essential wind-up
68 {- Nuked for now SLPJ Dec 96
70 -- Essential wind-up: part (a), saturate RHSs
71 -- This must occur *after* elimIndirections, because elimIndirections
72 -- can change things' arities. Consider:
74 -- x_global = \a -> x_local a
75 -- Then elimIndirections will change the program to
77 -- and lo and behold x_global's arity has changed!
78 case (satStgRhs processed_binds us4later) of { saturated_binds ->
81 -- Essential wind-up: part (b), do setStgVarInfo. It has to
82 -- happen regardless, because the code generator uses its
85 -- Why does it have to happen last? Because earlier passes
86 -- may move things around, which would change the live-var
87 -- info. Also, setStgVarInfo decides about let-no-escape
88 -- things, which in turn do a better job if arities are
89 -- correct, which is done by satStgRhs.
92 return (setStgVarInfo do_let_no_escapes processed_binds, cost_centres)
95 do_let_no_escapes = opt_StgDoLetNoEscapes
96 do_verbose_stg2stg = opt_D_verbose_stg2stg
99 (do_unlocalising, unlocal_tag)
100 = case opt_EnsureSplittableC of
101 Just tag -> (True, _PK_ tag)
102 Nothing -> (False, panic "tag")
104 grp_name = case (opt_SccGroup) of
106 Nothing -> module_name -- default: module name
109 stg_linter = if False --LATER: opt_DoStgLinting (ToDo)
110 then lintStgBindings pprDumpStyle
111 else ( \ whodunnit binds -> binds )
113 -------------------------------------------
114 do_stg_pass (binds, us, ccs) to_do
116 (us1, us2) = splitUniqSupply us
119 StgDoStaticArgs -> panic "STG static argument transformation deleted"
121 StgDoUpdateAnalysis ->
122 ASSERT(null (fst ccs) && null (snd ccs))
124 -- NB We have to do setStgVarInfo first! (There's one
125 -- place free-var info is used) But no let-no-escapes,
126 -- because update analysis doesn't care.
127 end_pass us2 "UpdAnal" ccs (updateAnalyse (setStgVarInfo False binds))
130 trace (showStgStats binds)
131 end_pass us2 "StgStats" ccs binds
134 _scc_ "StgLambdaLift"
135 -- NB We have to do setStgVarInfo first!
137 binds3 = liftProgram module_name us1 (setStgVarInfo do_let_no_escapes binds)
139 end_pass us2 "LambdaLift" ccs binds3
141 StgDoMassageForProfiling ->
144 (collected_CCs, binds3)
145 = stgMassageForProfiling module_name grp_name us1 binds
147 end_pass us2 "ProfMassage" collected_CCs binds3
149 end_pass us2 what ccs binds2
150 = -- report verbosely, if required
151 (if do_verbose_stg2stg then
153 (($$) (text ("*** "++what++":"))
154 (vcat (map (ppr pprDumpStyle) binds2))
158 linted_binds = stg_linter what binds2
160 return (linted_binds, us2, ccs)
161 -- return: processed binds
162 -- UniqueSupply for the next guy to use
163 -- cost-centres to be declared/registered (specialised)
164 -- add to description of what's happened (reverse order)
166 -- here so it can be inlined...
167 foldl_mn f z [] = return z
168 foldl_mn f z (x:xs) = f z x >>= \ zz ->