[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / compiler / NOTES
index c64db1a..8607f90 100644 (file)
-cvs remove TcGRHSs.hi-boot TcGRHSs.hi-boot-5 TcGRHSs.lhs
-cvs remove pbinding.ugn
-cvs add grhsb.ugn gdexp.ugn
------------------------
+       New back end thoughts
 
+-----------------------------------------------------------------------------
+Codegen notes
 
-* CHECK that the things seek_liftable found are done in Core
+* jumps to ImpossibleBranch should be removed.
 
-* CHECK that there aren't too many indirections in STG
-       local = ...
-       global = local Int
+* Profiling:
+       - when updating a closure with an indirection to a function,
+         we should make a permanent indirection.
 
-Interface files
-~~~~~~~~~~~~~~~
-* Don't need to pin a kind on the type variable in a interface class decl,
-  because it'll be correctly re-inferred when we read it in.
+       - check that we're bumping the scc count appropriately
 
-* The double semicolon at the end of an interface-file signature is so that
-  the lexer can run through the pragmas very fast when -O isn't being used.
+* check perf & binary sizes against the HEAD
 
-* In export lists, T|(A,B) says that constructors A and B are exported, 
-  but not the type T.  Similarly for classes.  
-  We can't say T(T,A,B) and T(A,B) to export or not-export T respectively,
-  because the type T might have a constructor T.
+-----------------------------------------------------------------------------
+C backend notes
 
-===========================================================================
+* use STGCALL macros for foreign calls (doesn't look like volatile regs
+  are handled properly at the mo).
 
-               Nofib failures
-               ~~~~~~~~~~~~~~
+-----------------------------------------------------------------------------
+Cmm parser notes
 
-* spectral/hartel/wave4main, wang, spectral/simple, real/symalg
+* switches
 
-Bus error
+* need to cater for unexported procedures/info tables?
 
-* real/anna
+* 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).
 
-expected stdout not matched by reality
-*** big.sum.out        Thu Aug 22 14:37:05 1996
---- /tmp/runtest21900.1        Mon Jan 20 17:57:49 1997
-***************
-*** 1 ****
-! 12796    49
---- 1 ----
-! 63325 97
+-----------------------------------------------------------------------------
 
+* Move arg-descr from LFInfo to ClosureInfo? 
+  But: only needed for functions
 
-* /real/compress2
+* Move all of CgClosure.link_caf into NewCaf, and newDynCaf
 
-expected stderr not matched by reality
-Warning: missing newline at end of file /tmp/runtest14691.2
-*** /tmp/no_stderr14691        Thu Jan 23 14:33:29 1997
---- /tmp/runtest14691.2        Thu Jan 23 14:33:29 1997
-***************
-*** 0 ****
---- 1,2 ----
-+ 
-+ Fail: Prelude.Enum.Char.toEnum:out of range
+* If the case binder is dead, and the constr is nullary,
+  do we need to assign to Node?
 
 
-* real/ebnf2ps
-IOSupplement.hs: 43: value not in scope: getEnv
+-------------------------
+* Relation between separate type sigs and pattern type sigs
+f :: forall a. a->a
+f :: b->b = e   -- No: monomorphic
 
-       ...and...
-HappyParser.hs: 127: Couldn't match the type
-                        [HappyParser.Token'] against PrelBase.Int
-    Expected: HappyParser.HappyReduction
-    Inferred: PrelBase.Int -> HappyParser.Token' -> HappyParser.HappyState HappyParser.Token' ([HappyParser.HappyAbsSyn] -> [AbstractSyntax.Production]) -> PrelBase.Int -> PrelBase.Int -> o{-a1yN-} -> o{-a1yO-} -> [HappyParser.Token'] -> a{-a1yP-}
-    In an equation for function HappyParser.action_1:
-       HappyParser.action_1 _ = HappyParser.happyFail
+f :: forall a. a->a
+f :: forall a. a->a  -- OK
 
+f :: forall a. [a] -> [a]
+f :: forall b. b->b = e  ???
 
-* GHC_ONLY/bugs/andy_cherry
 
-DataTypes.lhs: 3: Could not find valid interface file for `GenUtils'
+-------------------------------
+NB: all floats are let-binds, but some non-rec lets
+    may be unlifted (with RHS ok-for-speculation)
 
-Need "make depend"
 
-* GHC_ONLY/bugs/lex
+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
 
-Pattern match fail in lex; must be producing empty or multi-valued result
+simpl (applied lambda)     ==> simplNonRecBind
+simpl (Let (NonRec ...) ..) ==> simplNonRecBind
 
-Aggravated by dreadful error messages:
-+ 
-+ Fail: In irrefutable pattern
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matching
-+ Fail: In pattern-matchingtoo many nested calls to `error'
+simpl (Let (Rec ...)    ..) ==> simplRecBind
 
+simplRecBind:
+  simplify binders (but not its IdInfo)
+  simplify the pairs one at a time
+       using simplRecPair
 
-* GHC_ONLY/bugs/jtod_circint
+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
 
-Main.hs: 12: No instance for: Signal.Signal (Signal.Stream Bit.Bit)
-    Main.hs: 12: at a use of an overloaded identifier: `Signal.one'
+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
+  
 
-instance-decl slurping is WRONG
+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..]
 
-* GHC_ONLY/arith005
+  - add unfolding [this is the only place we add an unfolding]
+    add arity
 
-ceiling doesn't work properly
 
---- 1,3 ----
-+ [1, 1, 2, 3, 4, 5, 0, -2, -3, -4, 1000013, 124, 101, 103, 1, 0, 17001, 0, 1, 4]
-+ [1, 1, 2, 3, 4, 5, 0, -2, -3, -4, 1000013, 124, 101, 103, 1, 0, 17001, 0, 1, 4]
-  [0, 0, 2, 3, 4, 5, -1, -2, -3, -4, 1000012, 124, 101, 103, 1, 0, 17000, 0, 1, 4]
-***************
-*** 2,5 ****
-  [0, 0, 2, 3, 4, 5, -1, -2, -3, -4, 1000012, 124, 101, 103, 1, 0, 17000, 0, 1, 4]
-- [0, 0, 2, 3, 4, 5, -1, -2, -3, -4, 1000012, 124, 101, 103, 1, 0, 17000, 0, 1, 4]
-- [0, 0, 2, 3, 4, 5, -1, -2, -3, -4, 1000012, 124, 101, 103, 1, 0, 17000, 0, 1, 4]
-  [0, 0, 1, 2, 3, 4, -1, -3, -4, -5, 1000012, 123, 100, 102, 0, -1, 17000, -1, 0, 3]
---- 4,5 ----
 
+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)
 
-* GHC_ONLY/bugs/lennart_array
+It's harder to make the rule match if we ANF-ise the constructor,
+or eta-expand the PAP:
 
-Wrong array semantics (but who cares?)
+       f (let { a = g x; b = h x } in (a,b))
+       g (\y. + x y)
 
-* GHC_ONLY/bugs/life_space_leak
+On the other hand if we see the let-defns
 
--n *** sum I got: 
-0 0
--n *** sum I expected: 
-02845  1350
+       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.