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