[project @ 2004-11-18 00:56:18 by igloo]
[ghc-hetmet.git] / ghc / compiler / NOTES
1 *** unexpected failure for jtod_circint(opt)
2
3
4         New back end thoughts
5
6 -----------------------------------------------------------------------------
7 Codegen notes
8
9 * jumps to ImpossibleBranch should be removed.
10
11 * Profiling:
12         - when updating a closure with an indirection to a function,
13           we should make a permanent indirection.
14
15         - check that we're bumping the scc count appropriately
16
17 * check perf & binary sizes against the HEAD
18
19 -----------------------------------------------------------------------------
20 C backend notes
21
22 * use STGCALL macros for foreign calls (doesn't look like volatile regs
23   are handled properly at the mo).
24
25 -----------------------------------------------------------------------------
26 Cmm parser notes
27
28 * switches
29
30 * need to cater for unexported procedures/info tables?
31
32 * We should be able to get rid of entry labels, use info labels only.
33   - we need a %ENTRY_LBL(info_lbl) macro, so that instead of
34      JMP_(foo_entry) we can write jump %ENTRY_LBL(foo_info).
35
36 -----------------------------------------------------------------------------
37
38 * Move arg-descr from LFInfo to ClosureInfo? 
39   But: only needed for functions
40
41 * Move all of CgClosure.link_caf into NewCaf, and newDynCaf
42
43 * If the case binder is dead, and the constr is nullary,
44   do we need to assign to Node?
45
46
47 -------------------------
48 * Relation between separate type sigs and pattern type sigs
49 f :: forall a. a->a
50 f :: b->b = e   -- No: monomorphic
51
52 f :: forall a. a->a
53 f :: forall a. a->a  -- OK
54
55 f :: forall a. [a] -> [a]
56 f :: forall b. b->b = e  ???
57
58
59 -------------------------------
60 NB: all floats are let-binds, but some non-rec lets
61     may be unlifted (with RHS ok-for-speculation)
62
63
64 simplArg:  [use strictness]
65            [used for non-top-lvl non-rec RHS or function arg]
66   if strict-type || demanded
67         simplStrictExpr
68   else
69         simplExpr ---> (floats,expr)
70         float all the floats if exposes constr app, return expr
71
72 simpl (applied lambda)      ==> simplNonRecBind
73 simpl (Let (NonRec ...) ..) ==> simplNonRecBind
74
75 simpl (Let (Rec ...)    ..) ==> simplRecBind
76
77 simplRecBind:
78   simplify binders (but not its IdInfo)
79   simplify the pairs one at a time
80         using simplRecPair
81
82 simplNonRecBind:        [was simplBeta]
83         [used for non-top-lvl non-rec bindings]
84   - check for PreInlineUnconditionally
85   - simplify binder, including its IdInfo
86   - simplArg
87   - if strict-type 
88         addCaseBind [which makes a let if ok-for-spec]
89     else
90         completeLazyBind
91
92 simplLazyBind:  [binder already simplified, but not its IdInfo]
93                 [used for both rec and top-lvl non-rec]
94                 [must not be strict/unboxed; case not allowed]
95   - check for PreInlineUnconditionally
96   - substituteIdInfo and add result to in-scope 
97         [so that rules are available in rec rhs]
98   - simplExpr --> (floats,expr)
99   - float: lifted floats only
100         if exposes constructor or pap (even if non-triv args)
101         or if top level
102   - completeLazyBind
103   
104
105 completeLazyBind:       [given a simplified RHS]
106         [used for both rec and non-rec bindings, top level and not]
107   - try discarding dead
108   - try PostInlineUnconditionally
109   - let-bind coerce arg and repeat
110   - try rhs tylam (float)
111   - try eta expand (float)    [not if any float is unlifted && (non-spec || top_lvl || rec)]
112   - let-bind constructor args [not if any float is ..as above..]
113
114   - add unfolding [this is the only place we add an unfolding]
115     add arity
116
117
118
119 Right hand sides and arguments
120 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
121 In many ways we want to treat 
122         (a) the right hand side of a let(rec), and 
123         (b) a function argument
124 in the same way.  But not always!  In particular, we would
125 like to leave these arguments exactly as they are, so they
126 will match a RULE more easily.
127         
128         f (g x, h x)    
129         g (+ x)
130
131 It's harder to make the rule match if we ANF-ise the constructor,
132 or eta-expand the PAP:
133
134         f (let { a = g x; b = h x } in (a,b))
135         g (\y. + x y)
136
137 On the other hand if we see the let-defns
138
139         p = (g x, h x)
140         q = + x
141
142 then we *do* want to ANF-ise and eta-expand, so that p and q
143 can be safely inlined.   
144
145 Even floating lets out is a bit dubious.  For let RHS's we float lets
146 out if that exposes a value, so that the value can be inlined more vigorously.
147 For example
148
149         r = let x = e in (x,x)
150
151 Here, if we float the let out we'll expose a nice constructor. We did experiments
152 that showed this to be a generally good thing.  But it was a bad thing to float
153 lets out unconditionally, because that meant they got allocated more often.
154
155 For function arguments, there's less reason to expose a constructor (it won't
156 get inlined).  Just possibly it might make a rule match, but I'm pretty skeptical.
157 So for the moment we don't float lets out of function arguments either.
158
159
160 Eta expansion
161 ~~~~~~~~~~~~~~
162 For eta expansion, we want to catch things like
163
164         case e of (a,b) -> \x -> case a of (p,q) -> \y -> r
165
166 If the \x was on the RHS of a let, we'd eta expand to bring the two
167 lambdas together.  And in general that's a good thing to do.  Perhaps
168 we should eta expand wherever we find a (value) lambda?  Then the eta
169 expansion at a let RHS can concentrate solely on the PAP case.