+++ /dev/null
-
--------------------------
-*** unexpected failure for jtod_circint(opt)
-
-
- New back end thoughts
-
------------------------------------------------------------------------------
-Codegen notes
-
-* jumps to ImpossibleBranch should be removed.
-
-* Profiling:
- - when updating a closure with an indirection to a function,
- we should make a permanent indirection.
-
- - check that we're bumping the scc count appropriately
-
-* check perf & binary sizes against the HEAD
-
------------------------------------------------------------------------------
-C backend notes
-
-* use STGCALL macros for foreign calls (doesn't look like volatile regs
- are handled properly at the mo).
-
------------------------------------------------------------------------------
-Cmm parser notes
-
-* switches
-
-* need to cater for unexported procedures/info tables?
-
-* We should be able to get rid of entry labels, use info labels only.
- - we need a %ENTRY_LBL(info_lbl) macro, so that instead of
- JMP_(foo_entry) we can write jump %ENTRY_LBL(foo_info).
-
------------------------------------------------------------------------------
-
-* Move arg-descr from LFInfo to ClosureInfo?
- But: only needed for functions
-
-* Move all of CgClosure.link_caf into NewCaf, and newDynCaf
-
-* If the case binder is dead, and the constr is nullary,
- do we need to assign to Node?
-
-
--------------------------
-* Relation between separate type sigs and pattern type sigs
-f :: forall a. a->a
-f :: b->b = e -- No: monomorphic
-
-f :: forall a. a->a
-f :: forall a. a->a -- OK
-
-f :: forall a. [a] -> [a]
-f :: forall b. b->b = e ???
-
-
--------------------------------
-NB: all floats are let-binds, but some non-rec lets
- may be unlifted (with RHS ok-for-speculation)
-
-
-simplArg: [use strictness]
- [used for non-top-lvl non-rec RHS or function arg]
- if strict-type || demanded
- simplStrictExpr
- else
- simplExpr ---> (floats,expr)
- float all the floats if exposes constr app, return expr
-
-simpl (applied lambda) ==> simplNonRecBind
-simpl (Let (NonRec ...) ..) ==> simplNonRecBind
-
-simpl (Let (Rec ...) ..) ==> simplRecBind
-
-simplRecBind:
- simplify binders (but not its IdInfo)
- simplify the pairs one at a time
- using simplRecPair
-
-simplNonRecBind: [was simplBeta]
- [used for non-top-lvl non-rec bindings]
- - check for PreInlineUnconditionally
- - simplify binder, including its IdInfo
- - simplArg
- - if strict-type
- addCaseBind [which makes a let if ok-for-spec]
- else
- completeLazyBind
-
-simplLazyBind: [binder already simplified, but not its IdInfo]
- [used for both rec and top-lvl non-rec]
- [must not be strict/unboxed; case not allowed]
- - check for PreInlineUnconditionally
- - substituteIdInfo and add result to in-scope
- [so that rules are available in rec rhs]
- - simplExpr --> (floats,expr)
- - float: lifted floats only
- if exposes constructor or pap (even if non-triv args)
- or if top level
- - completeLazyBind
-
-
-completeLazyBind: [given a simplified RHS]
- [used for both rec and non-rec bindings, top level and not]
- - try discarding dead
- - try PostInlineUnconditionally
- - let-bind coerce arg and repeat
- - try rhs tylam (float)
- - try eta expand (float) [not if any float is unlifted && (non-spec || top_lvl || rec)]
- - let-bind constructor args [not if any float is ..as above..]
-
- - add unfolding [this is the only place we add an unfolding]
- add arity
-
-
-
-Right hand sides and arguments
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-In many ways we want to treat
- (a) the right hand side of a let(rec), and
- (b) a function argument
-in the same way. But not always! In particular, we would
-like to leave these arguments exactly as they are, so they
-will match a RULE more easily.
-
- f (g x, h x)
- g (+ x)
-
-It's harder to make the rule match if we ANF-ise the constructor,
-or eta-expand the PAP:
-
- f (let { a = g x; b = h x } in (a,b))
- g (\y. + x y)
-
-On the other hand if we see the let-defns
-
- p = (g x, h x)
- q = + x
-
-then we *do* want to ANF-ise and eta-expand, so that p and q
-can be safely inlined.
-
-Even floating lets out is a bit dubious. For let RHS's we float lets
-out if that exposes a value, so that the value can be inlined more vigorously.
-For example
-
- r = let x = e in (x,x)
-
-Here, if we float the let out we'll expose a nice constructor. We did experiments
-that showed this to be a generally good thing. But it was a bad thing to float
-lets out unconditionally, because that meant they got allocated more often.
-
-For function arguments, there's less reason to expose a constructor (it won't
-get inlined). Just possibly it might make a rule match, but I'm pretty skeptical.
-So for the moment we don't float lets out of function arguments either.
-
-
-Eta expansion
-~~~~~~~~~~~~~~
-For eta expansion, we want to catch things like
-
- case e of (a,b) -> \x -> case a of (p,q) -> \y -> r
-
-If the \x was on the RHS of a let, we'd eta expand to bring the two
-lambdas together. And in general that's a good thing to do. Perhaps
-we should eta expand wherever we find a (value) lambda? Then the eta
-expansion at a let RHS can concentrate solely on the PAP case.