diff options
| -rw-r--r-- | compiler/NOTES | 156 | ||||
| -rw-r--r-- | compiler/Simon-log | 1260 | ||||
| -rw-r--r-- | compiler/coreSyn/CoreSubst.lhs | 17 | ||||
| -rw-r--r-- | compiler/simplCore/SimplCore.lhs | 1 | ||||
| -rw-r--r-- | compiler/stranal/WorkWrap.lhs | 4 | ||||
| -rw-r--r-- | compiler/typecheck/TcBinds.lhs | 66 | ||||
| -rw-r--r-- | compiler/typecheck/TcDeriv.lhs | 2 | ||||
| -rw-r--r-- | compiler/typecheck/TcInstDcls.lhs | 22 | ||||
| -rw-r--r-- | compiler/typecheck/TcRnDriver.lhs | 36 | ||||
| -rw-r--r-- | compiler/typecheck/TcRnMonad.lhs | 15 | ||||
| -rw-r--r-- | compiler/typecheck/TcTyClsDecls.lhs | 34 | ||||
| -rw-r--r-- | compiler/typecheck/TcUnify.lhs | 12 | ||||
| -rw-r--r-- | new_tc_notes | 181 | 
13 files changed, 112 insertions, 1694 deletions
| diff --git a/compiler/NOTES b/compiler/NOTES deleted file mode 100644 index 645d27eaed..0000000000 --- a/compiler/NOTES +++ /dev/null @@ -1,156 +0,0 @@ -More type functions -~~~~~~~~~~~~~~~~~~~ -* Allow {tv = TYPE ty) as a non-rec binding in Core -* Use this to make equality constraints more uniform -* Can a Dict can contain an EqPred?   -  How does that differ from an EqInst? -* Make DictBinds into Core - -* In zonking, do we need to zonk the kinds of coercion variables? - -Type functions -~~~~~~~~~~~~~~ -* A Given inst should be a CoVar, not a coercion - -* finaliseEqInst should not need to call zonk - -* Why do we need fromGivenEqDict?  How could we construct 	 -	a Dict that had an EqPred? -	newDictBndr should make an EqInst directly - -* tc_co should be accessed only inside Inst - -* Inst.mkImplicTy needs a commment about filtering out EqInsts -  How *do* we deal with wanted equalities? - -* Inst.instType behaves inconsistently for EqInsts: it should -  return an EqPred, like the instType' hack in pprDictsTheta - -  Consequences: adjust the uses of instType in TcSimplify - -* tcDeref* functions are unused, except in tcGenericNormalizeFamInst, when -  we can equally well use TcMType.lookupTcTyVar - -* Coercion.mkEqPredCoI looks very peculiar. - - - - -------------------------- -*** 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? - - -------------------------------- -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 - - - - -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. diff --git a/compiler/Simon-log b/compiler/Simon-log deleted file mode 100644 index 3d2804d4bf..0000000000 --- a/compiler/Simon-log +++ /dev/null @@ -1,1260 +0,0 @@ -	------------------------------------ -	   GHCI hacking -	------------------------------------ - -* Don't forget to put deferred-type-decls back into RnIfaces - -* Do we want to record a package name in a .hi file? -  Does pi_mod have a ModuleName or a Module? - -	------------------------------------ -	   Mainly FunDeps (23 Jan 01) -	------------------------------------ - -This commit re-engineers the handling of functional dependencies. -A functional dependency is no longer an Inst; instead, the necessary -dependencies are snaffled out of their Class when necessary. - -As part of this exercise I found that I had to re-work how to do generalisation -in a binding group.  There is rather exhaustive documentation on the new Plan -at the top of TcSimplify. - -	****************** -	WARNING: I have compiled all the libraries with this new compiler -		 and all looks well, but I have not run many programs. -		 Things may break.  Let me know if so. -	****************** - -The main changes are these: - -1.  typecheck/TcBinds and TcSimplify have a lot of changes due to the  -    new generalisation and context reduction story.  There are extensive -    comments at the start of TcSimplify - -2.  typecheck/TcImprove is removed altogether.  Instead, improvement is  -    interleaved with context reduction (until a fixpoint is reached). -    All this is done in TcSimplify. - -3.  types/FunDeps has new exports -	* 'improve' does improvement, returning a list of equations -	* 'grow' and 'oclose' close a list of type variables wrt a set of -	  PredTypes, but in slightly different ways.  Comments in file. - -4.  I improved the way in which we check that main::IO t.  It's tidier now. - -In addition - -*   typecheck/TcMatches:  -	a) Tidy up, introducing a common function tcCheckExistentialPat - -	b) Improve the typechecking of parallel list comprehensions, -	   which wasn't quite right before.  (see comments with tcStmts) - -	WARNING: (b) is untested!  Jeff, you might want to check. - -*   Numerous other incidental changes in the typechecker - -*   Manuel found that rules don't fire well when you have partial applications -    from overloading.  For example, we may get - -	f a (d::Ord a) = let m_g = g a d -			 in -			 \y :: a -> ...(m_g (h y))... - -    The 'method' m_g doesn't get inlined because (g a d) might be a redex. -    Yet a rule that looks like  -		g a d (h y) = ... -    won't fire because that doesn't show up.  One way out would be to make -    the rule matcher a bit less paranoid about duplicating work, but instead -    I've added a flag -			-fno-method-sharing -    which controls whether we generate things like m_g in the first place. -    It's not clear that they are a win in the first place. - -    The flag is actually consulted in Inst.tcInstId - - - -	------------------------------------ -	   Mainly PredTypes (28 Sept 00) -	------------------------------------ - -Three things in this commit: - -	1.  Main thing: tidy up PredTypes -	2.  Move all Keys into PrelNames -	3.  Check for unboxed tuples in function args - -1. Tidy up PredTypes -~~~~~~~~~~~~~~~~~~~~ -The main thing in this commit is to modify the representation of Types -so that they are a (much) better for the qualified-type world.  This -should simplify Jeff's life as he proceeds with implicit parameters -and functional dependencies.  In particular, PredType, introduced by -Jeff, is now blessed and dignified with a place in TypeRep.lhs: - -	data PredType  = Class  Class [Type] -		       | IParam Name  Type - -Consider these examples: -	f :: (Eq a) => a -> Int -	g :: (?x :: Int -> Int) => a -> Int -	h :: (r\l) => {r} => {l::Int | r} - -Here the "Eq a" and "?x :: Int -> Int" and "r\l" are all called -*predicates*, and are represented by a PredType.  (We don't support -TREX records yet, but the setup is designed to expand to allow them.) - -In addition, Type gains an extra constructor: - -	data Type = .... | PredTy PredType - -so that PredType is injected directly into Type.  So the type -	p => t -is represented by -	PredType p `FunTy` t - -I have deleted the hackish IPNote stuff; predicates are dealt with entirely -through PredTys, not through NoteTy at all. - - -2.  Move Keys into PrelNames -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This is just a housekeeping operation. I've moved all the pre-assigned Uniques  -(aka Keys) from Unique.lhs into PrelNames.lhs.  I've also moved knowKeyRdrNames -from PrelInfo down into PrelNames.  This localises in PrelNames lots of stuff -about predefined names.  Previously one had to alter three files to add one, -now only one. - -3.  Unboxed tuples -~~~~~~~~~~~~~~~~~~ -Add a static check for unboxed tuple arguments.  E.g. -	data T = T (# Int, Int #) -is illegal - - - -	--------------------------------------- -	Update in place -	--------------------------------------- - --funfolding-update-in-place -Switching it on doesn't affect many programs, except these -sphere is because it makes a critical function (vecsub) more inlinable - -         sphere               66465k         -20.61% -          infer               13390k          +1.27% -        parstof                1461k          +1.18% -          fluid                3442k          +1.61% -           atom              177163k         +13.20% -           bspt                4837k          +4.85% -       cichelli               33546k          +2.69% -      typecheck              146023k          +1.47% - - -	--------------------------------------- -	Simon's tuning changes: early Sept 2000 -	--------------------------------------- - -Library changes -~~~~~~~~~~~~~~~ -* Eta expand PrelShow.showLitChar.  It's impossible to compile this well, -  and it makes a big difference to some programs (e.g. gen_regexps) - -* Make PrelList.concat into a good producer (in the foldr/build sense) - - -Flag changes -~~~~~~~~~~~~ -* Add -ddump-hi-diffs to print out changes in interface files.  Useful -  when watching what the compiler is doing - -* Add -funfolding-update-in-place to enable the experimental optimisation -  that makes the inliner a bit keener to inline if it's in the RHS of -  a thunk that might be updated in place.  Sometimes this is a bad idea -  (one example is in spectral/sphere; see notes in nofib/Simon-nofib-notes) - - -Tuning things -~~~~~~~~~~~~~ -* Fix a bug in SetLevels.lvlMFE.  (change ctxt_lvl to dest_level) -  I don't think this has any performance effect, but it saves making -  a redundant let-binding that is later eliminated. - -* Desugar.dsProgram and DsForeign -  Glom together all the bindings into a single Rec.  Previously the -  bindings generated by 'foreign' declarations were not glommed together, but -  this led to an infelicity (i.e. poorer code than necessary) in the modules -  that actually declare Float and Double (explained a bit more in Desugar.dsProgram) - -* OccurAnal.shortMeOut and IdInfo.shortableIdInfo -  Don't do the occurrence analyser's shorting out stuff for things which -  have rules.  Comments near IdInfo.shortableIdInfo. -  This is deeply boring, and mainly to do with making rules work well. -  Maybe rules should have phases attached too.... - -* CprAnalyse.addIdCprInfo -  Be a bit more willing to add CPR information to thunks;  -  in particular, if the strictness analyser has just discovered that this -  is a strict let, then the let-to-case transform will happen, and CPR is fine. -  This made a big difference to PrelBase.modInt, which had something like -	modInt = \ x -> let r = ... -> I# v in -			...body strict in r... -  r's RHS isn't a value yet; but modInt returns r in various branches, so -  if r doesn't have the CPR property then neither does modInt - -* MkId.mkDataConWrapId -  Arrange that vanilla constructors, like (:) and I#, get unfoldings that are -  just a simple variable $w:, $wI#.  This ensures they'll be inlined even into -  rules etc, which makes matching a bit more reliable.  The downside is that in -  situations like (map (:) xs), we'll end up with (map (\y ys. $w: y ys) xs. -  Which is tiresome but it doesn't happen much. - -* SaAbsInt.findStrictness  -  Deal with the case where a thing with no arguments is bottom.  This is Good. -  E.g.   module M where { foo = error "help" } -  Suppose we have in another module -	case M.foo of ... -  Then we'd like to do the case-of-error transform, without inlining foo. - - -Tidying up things -~~~~~~~~~~~~~~~~~ -* Reorganised Simplify.completeBinding (again). - -* Removed the is_bot field in CoreUnfolding (is_cheap is true if is_bot is!) -  This is just a tidy up - -* HsDecls and others -  Remove the NewCon constructor from ConDecl.  It just added code, and nothing else. -  And it led to a bug in MkIface, which though that a newtype decl was always changing! - -* IdInfo and many others -  Remove all vestiges of UpdateInfo (hasn't been used for years) - -		------------------------------ -		Join points 	Sept 2000 -		------------------------------ - -With Andrew Kennedy, I found out why a few of the join points introduced by -the simplifier end up as *not* let-no-escpaed.  Here's an example: - -f x y = case (pwr x b) == 1 of -	 False -> False -	 True -> pwr x c == 1 - -This compiles to: -  f = \ @ t w :: Integer -> -	  let { -	    $j :: (State# RealWorld -> Bool) -	    P -	    $j -	      = \ w1 :: (State# RealWorld) -> -		    case pwr w c of wild { -			S# i -> case i of wild1 { 1 -> $wTrue; __DEFAULT -> $wFalse }; -			J# s d1 -> -			    case cmpIntegerInt# s d1 1 of wild2 { -				0 -> $wTrue; __DEFAULT -> $wFalse -			    } -		    } -	  } in  -	    case pwr w b of wild { -		S# i -> -		    case i of wild1 { 1 -> $j realWorld#; __DEFAULT -> $wFalse }; -		J# s d1 -> -		    case cmpIntegerInt# s d1 1 of wild2 { -			0 -> $j realWorld#; __DEFAULT -> $wFalse -		    } -	    } - -Now consider - -	case (f x) of -	  True  -> False -	  False -> True - -Suppose f is inlined into this case.   No new join points are introduced, -because the alternatives are both small.  But the consumer -	case [.] of {True -> False; False -> True} -will move into the body of f, be duplicated 4 ways, and end up consuming -the result of the four outcomes at the body of f.  This yields: -	    $j :: (State# RealWorld -> Bool) -	    P -	    $j -	      = \ w1 :: (State# RealWorld) -> -		    case pwr w c of wild { -			S# i -> case i of wild1 { 1 -> $wTrue; __DEFAULT -> $wFalse }; -			J# s d1 -> -			    case cmpIntegerInt# s d1 1 of wild2 { -				0 -> $wTrue; __DEFAULT -> $wFalse -			    } -		    } -	  } in  -	    case pwr w b of wild { -		S# i -> -		    case i of wild1 { 1 -> case $j realWorld# of {T->F; F->T} -				    ; __DEFAULT -> $wTrue }; -		J# s d1 -> -		    case cmpIntegerInt# s d1 1 of wild2 { -			0 -> case $j realWorld# of {T->F; F->T} -			; __DEFAULT -> $wTrue -		    } -	    } - -And, voila, the join point $j isn't let-no-escaped any more.   -The point is that the consuming context can't "see inside" the join point. -It's a phase ordering thing.  If f is inlined before the join points  -are built in the first place, then all is well. - - - -	----------------------------- -	Sept 7 2000 -	----------------------------- - -* Make the simplifier's Stop continuation record whether the expression being -  simplified is the RHS of a thunk, or (say) the body of a lambda or case RHS. -  In the thunk case we want to be a bit keener about inlining if the type of -  the thunk is amenable to update in place. - -* SetLevels was being a bit too eager to float things to the top  -  level; e.g. _inline_me_ (\a -> e); here e got floated... -  Easily fixed by a change to ltMajLvl - -* Make CoreUnfold.calcUnfoldingGuidance a bit less keen to make case expressions -  seem small.  The original idea was to make inlined wrappers look small, so that -  when we inline a wrapper it doesn't make call site (much) bigger -  Otherwise we get nasty phase ordering stuff:  -		--	f x = g x x -		--	h y = ...(f e)... -  If we inline g's wrapper, f looks big, and doesn't get inlined -  into h; if we inline f first, while it looks small, then g's  -  wrapper will get inlined later anyway.  To avoid this nasty -  ordering difference, we make (case a of (x,y) -> ...),  -  *where a is one of the arguments* look free. - -  BUT	(a) It's too eager.  We don't want to inline a wrapper into a -	    context with no benefit.   -	    E.g.  \ x. f (x+x)   	o point in inlining (+) here! - -	(b) It's ineffective. Once g's wrapper is inlined, its case-expressions  -	    aren't scrutinising arguments any more - -  So I've rescinded this idea for now.  cases still look fairly small. - -* Fix interestingArg, which was being too liberal, and hence doing -  too much inlining. - -* Extended CoreUtils.exprIsCheap to make two more things cheap: -    - 	case (coerce x) of ... -    -   let x = y +# z -  This makes a bit more eta expansion happen.  It was provoked by -  a program of Marcin's. -   -* The simplifier used to glom together all the top-level bindings into -  a single Rec every time it was invoked.  The reason for this is explained -  in SimplCore.lhs, but for at least one simple program it meant that the -  simplifier never got around to unravelling the recursive group into  -  non-recursive pieces.  So I've put the glomming under explicit flag -  control with a -fglom-binds simplifier pass.   A side benefit is -  that because it happens less often, the (expensive) SCC algorithm -  runs less often. -   -* MkIface.ifaceBinds.   Make sure that we emit rules for things -  (like class operations) that don't get a top-level binding in the -  interface file.  Previously such rules were silently forgotten. - -* Move transformRhs to *after* simplification, which makes it a -  little easier to do, and means that the arity it computes is  -  readily available to completeBinding.  This gets much better -  arities. - -* Do coerce splitting in completeBinding. This gets good code for -	newtype CInt = CInt Int - -	test:: CInt -> Int -	test x = case x of -	      	   1 -> 2 -	      	   2 -> 4 -	      	   3 -> 8 -	      	   4 -> 16 -	      	   _ -> 0 - -* Modify the meaning of "arity" so that during compilation it means -  "if you apply this function to fewer args, it will do virtually  -  no work".   So, for example  -	f = coerce t (\x -> e) -  has arity at least 1.  When a function is exported, it's arity becomes -  the number of exposed, top-level lambdas, which is subtly different. -  But that's ok.   - -  I removed CoreUtils.exprArity altogether: it looked only at the exposed -  lambdas.  Instead, we use exprEtaExpandArity exclusively. - -  All of this makes I/O programs work much better. - - -	----------------------------- -	Sept 4 2000 -	----------------------------- - -* PrimRep, TysPrim.  Add PrimPtrRep as the representation for -  MVars and MutVars.  Previously they were given PtrRep, but that -  crashed dataReturnConvPrim!  Here's the program the killed it: -     data STRef s a = STRef (MutVar# s a) -     from (STRef x) = x -   -* Make the desugarer use string equality for string literal -  patterns longer than 1 character.  And put a specialised -  eqString into PrelBase, with a suitable specialisation rule. -  This makes a huge difference to the size of the code generated -  by deriving(Read) notably in Time.lhs - -	----------------------------- -	Marktoberdorf Commits (Aug 2000) -	----------------------------- - -1.  Tidy up the renaming story for "system binders", such as -dictionary functions, default methods, constructor workers etc.  These -are now documented in HsDecls.  The main effect of the change, apart -from tidying up, is to make the *type-checker* (instead of the -renamer) generate names for dict-funs and default-methods.  This is -good because Sergei's generic-class stuff generates new classes at -typecheck time. - - -2.  Fix the CSE pass so it does not require the no-shadowing invariant. -Keith discovered that the simplifier occasionally returns a result -with shadowing.  After much fiddling around (which has improved the -code in the simplifier a bit) I found that it is nearly impossible to -arrange that it really does do no-shadowing.  So I gave up and fixed -the CSE pass (which is the only one to rely on it) instead. - - -3. Fix a performance bug in the simplifier.  The change is in -SimplUtils.interestingArg.  It computes whether an argment should  -be considered "interesting"; if a function is applied to an interesting -argument, we are more likely to inline that function. -Consider this case -	let x = 3 in f x -The 'x' argument was considered "uninteresting" for a silly reason. -Since x only occurs once, it was unconditionally substituted, but -interestingArg didn't take account of that case.  Now it does. - -I also made interestingArg a bit more liberal.  Let's see if we -get too much inlining now. - - -4.  In the occurrence analyser, we were choosing a bad loop breaker. -Here's the comment that's now in OccurAnal.reOrderRec - -    score ((bndr, rhs), _, _) -	| exprIsTrivial rhs 	   = 3	-- Practically certain to be inlined -		-- Used to have also: && not (isExportedId bndr) -		-- But I found this sometimes cost an extra iteration when we have -		--	rec { d = (a,b); a = ...df...; b = ...df...; df = d } -		-- where df is the exported dictionary. Then df makes a really -		-- bad choice for loop breaker - -I also increased the score for bindings with a non-functional type, so that -dictionaries have a better chance of getting inlined early - - -5. Add a hash code to the InScopeSet (and make it properly abstract) -This should make uniqAway a lot more robust.  Simple experiments suggest -that uniqAway no longer gets into the long iteration chains that it used -to. - - -6.  Fix a bug in the inliner that made the simplifier tend to get into -a loop where it would keep iterating ("4 iterations, bailing out" message). -In SimplUtils.mkRhsTyLam we float bindings out past a big lambda, thus: -	x = /\ b -> let g = \x -> f x x -		    in E -becomes -	g* = /\a -> \x -> f x x -	x = /\ b -> let g = g* b in E -	 -It's essential that we don't simply inling g* back into the RHS of g, -else we will be back to square 1.  The inliner is meant not to do this -because there's no benefit to the inlining, but the size calculation -was a little off in CoreUnfold. - - -7.  In SetLevels we were bogus-ly building a Subst with an empty in-scope -set, so a WARNING popped up when compiling some modules.  (knights/ChessSetList -was the example that tickled it.)  Now in fact the warning wasn't an error, -but the Right Thing to do is to carry down a proper Subst in SetLevels, so -that is what I have now done.  It is very little more expensive. - - - -		~~~~~~~~~~~~ -		Apr/May 2000 -		~~~~~~~~~~~~ - -This is a pretty big commit!  It adds stuff I've been working on -over the last month or so.  DO NOT MERGE IT WITH 4.07! - -Recompilation checking -~~~~~~~~~~~~~~~~~~~~~~ -Substantial improvement in recompilation checking.  The version management -is now entirely internal to GHC.  ghc-iface.lprl is dead! - -The trick is to generate the new interface file in two steps: -  - first convert Types etc to HsTypes etc, and thereby  -	build a new ParsedIface -  - then compare against the parsed (but not renamed) version of the old -	interface file -Doing this meant adding code to convert *to* HsSyn things, and to  -compare HsSyn things for equality.  That is the main tedious bit. - -Another improvement is that we now track version info for  -fixities and rules, which was missing before. - - -Interface file reading -~~~~~~~~~~~~~~~~~~~~~~ -Make interface files reading more robust.   -  * If the old interface file is unreadable, don't fail. [bug fix] - -  * If the old interface file mentions interfaces  -    that are unreadable, don't fail. [bug fix] - -  * When we can't find the interface file,  -    print the directories we are looking in.  [feature] - - -Type signatures -~~~~~~~~~~~~~~~ -  * New flag -ddump-types to print type signatures - - -Type pruning -~~~~~~~~~~~~ -When importing  -	data T = T1 A | T2 B | T3 C -it seems excessive to import the types A, B, C as well, unless -the constructors T1, T2 etc are used.  A,B,C might be more types, -and importing them may mean reading more interfaces, and so on. - So the idea is that the renamer will just import the decl  -	data T -unless one of the constructors is used.  This turns out to be quite -easy to implement.  The downside is that we must make sure the -constructors are always available if they are really needed, so -I regard this as an experimental feature. - - -Elimininate ThinAir names -~~~~~~~~~~~~~~~~~~~~~~~~~ -Eliminate ThinAir.lhs and all its works.  It was always a hack, and now -the desugarer carries around an environment I think we can nuke ThinAir  -altogether. - -As part of this, I had to move all the Prelude RdrName defns from PrelInfo -to PrelMods --- so I renamed PrelMods as PrelNames. - -I also had to move the builtinRules so that they are injected by the renamer -(rather than appearing out of the blue in SimplCore).  This is if anything simpler. - -Miscellaneous -~~~~~~~~~~~~~ -* Tidy up the data types involved in Rules - -* Eliminate RnEnv.better_provenance; use Name.hasBetterProv instead - -* Add Unique.hasKey :: Uniquable a => a -> Unique -> Bool -  It's useful in a lot of places - -* Fix a bug in interface file parsing for __U[!] - - -======================================= -To-do -~~~~~ -* Try the effect of enhancing update in place with the CPR  -  idea in CoreUnfold.calcUnfoldingGuidance - -* Check with Simon M re srt on Lit - -* Make all primops return a data type so that we can't over-apply a primop -  This makes code gen simpler. Currently the only primops with a polymorphic -  return type are: -	raise# :: a -> b -	catch# :: a -> (b->a) -> a -	tagToEnum# :: Int -> a - -  Very strange code for PrelException.catchException!  What has STret got -  to do with it? - -* Liberate case - -* Missing w/w for coerce in go2 functions of fibToList' in fibheaps - -* Watch out for re-boxing in workers; sometimes it happens -  and then w/w is a Bad Thing - -* Only two uses of mkCompulsoryUnfolding -- try to nuke it - -* Note that mkDupAlt makes alts that have binders that -  are guaranteed to appear just once or not at all -	(a,b) -> j a -  Same for case binder, but that's harder to take into account. - -* max :: Int -> Int -> Int could be CPRd but isn't. - -* In mandel2 we do a little less well than 4.04 because we aren't  -  inlining point_colour, and that means we have to box up an argument -  before calling it.  [This was due to a bug in 4.04] -  There's also a great opportunity for liberateCase -  in check_radius, where it loops around with two lazy F# built each time - -* In PrelShow.itos' we find a thunk like: -	  tpl = case chrzh {(zpzh {(remIntzh {x{-aMf-} 10}) 48})} -		of tpl{-X1j-} __D P { __DEFAULT -> -		      PrelBase.Czh{-62,s-} {tpl{-X1j-}} -		} -  This is a pity.  The remInt# can't fail because the divisor isn't 0, -  so we could do the sum eagerly and allocate a charcter instead of a thunk. - -* It's good to do let-to-case before we wrap up.  Consider -  f b xs = let ys = partition isUpper xs -	       zs = case ys of (a,b) -> a -           in case b of -		True -> case ys of -			  (a,b) -> (zs,[]) -		False -> case ys of -			  (a,b) -> (zs ++ xs,[]) -  If we don't do let-to-case at all, we get 3 redundant case ys left. -  On the other hand we don't want to do it too early, because it -  prevents inlining into strict arg positions, which is important for  -  rules to work. - -* Strict dictionaries.   - -* INLINE functions are not always INLINEd, so it's sad to leave -  stuff in their bodies like constructors that havn't been inlined. - -* If let x = e in b is strict, then CPR can use the CPR info from x -  This bites in the mod method of Integral Int - -* Inline wrappers if they are the RHS of a let, so that update in place -  can happen? - -* Consider doing unboxing on strict constr args in a pattern match, -  as part of w/w.   - -* In spectral/expert/Search.ask there's a statically visible CSE. Catching this  -  depends almost entirely on chance, which is a pity. - -* Think about exprEtaExpandArity in WwLib.  Perhaps eliminate eta expand in simplify? -  Perhaps use even if no coerces etc, just eta expansion. (e.g. PrelArr.done) - -* In knights/KnightHeuristic, we don't find that possibleMoves is strict -  (with important knock-on effects) unless we apply rules before floating -  out the literal list [A,B,C...]. -  Similarly, in f_se (F_Cmp ...) in listcompr (but a smaller effect) - -* Floating can float the entire body of an INLINE thing out. -  e.g. PrelArr.done  -  This is sad, and a bit stupid. - -* In spectral/multiplier, we have  -    xor = lift21 forceBit f -      where f :: Bit -> Bit -> Bit -	    f 0 0 = 0 -	    f 0 1 = 1 -	    f 1 0 = 1 -	    f 1 1 = 0 -  Trouble is, f is CPR'd, and that means that instead of returning -  the constants I# 0, I# 1, it returns 0,1 and then boxes them. -  So allocation goes up.  I don't see a way around this. - -* spectral/hartel/parstof ends up saying -	case (unpackCString "x") of { c:cs -> ... } -  quite a bit.   We should spot these and behave accordingly. - -* Try a different hashing algorithms in hashUFM.  This might reduce long CSE lists -  as well as making uniqAway faster. - -* [I'm not sure this is really important in the end.] -  Don't float out partial applications in lvlMFE.  E.g. (in hPutStr defn of shoveString) -	\x -> case .. of  -		[] -> setBufWPtr a b -		... -  setBufWPtr has arity 3.  Floating it out is plain silly.  And in this particular -  case it's harmful, because it ends up preventing eta expansion on the \x. -  That in turn leads to a big extra cost in hPutStr. - -  *** Try not doing lvlMFE on the body of a lambda and case alternative *** - -* PrelNumExtra.lhs we get three copies of dropTrailing0s.  Too much inlining! -  drop0 has cost 21, but gets a discount of 6 (3 * #constrs) for its arg. -  With a keen-neess factor of 2, that makes a discount of 12.  Add two for -  the arguments and we get 21-12-2, which is just small enough to inline. -  But that is plainly stupid. - -  Add one for cases; and decrease discount for constructors. - -* IO.hGetContents still doesn't see that it is strict in the handle. -  Coerces still getting in the way. - -* Try not having really_interesting_cont (subsumed by changes in the  -	way guidance is calculated for inline things?) - -* Enumeration types in worker/wrapper for strictness analysis - -* This should be reported as an error: -	data T k = MkT (k Int#) - -* Bogus report of overlapped pattern for -	f (R {field = [c]}) = 1 -  	f (R {})	      = 2 -  This shows up for TyCon.tyConSingleDataCon_maybe - -*  > module Main( main ) where - -   > f :: String -> Int -   > f "=<" = 0 -   > f "="  = 0 -    -   > g :: [Char] -> Int -   > g ['=','<'] = 0 -   > g ['=']     = 0 -    -   > main = return () -    -   For ``f'' the following is reported. -    -   tmp.lhs:4:  -    Pattern match(es) are overlapped in the definition of function `f' -            "=" = ... - -   There are no complaints for definition for ``g''. - -* Without -O I don't think we need change the module version -  if the usages change; I forget why it changes even with -O - -* Record selectors for existential type; no good!  What to do? -  Record update doesn't make sense either. - -  Need to be careful when figuring out strictness, and when generating -  worker-wrapper split. - -  Also when deriving. - - -		Jan 2000 -		~~~~~~~~  - -A fairly big pile of work originally aimed at -removing the Con form of Core expression, and replacing it with simple -Lit form.  However, I wanted to make sure that the resulting thing -performed better than the original, so I ended up making an absolute -raft of other changes. - -Removing the Con form of Core expressions -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The big thing is that - -  For every constructor C there are now *two* Ids: - -	C is the constructor's *wrapper*. It evaluates and unboxes arguments -	before calling $wC.  It has a perfectly ordinary top-level defn  -	in the module defining the data type. - -	$wC is the constructor's *worker*.  It is like a primop that simply -	allocates and builds the constructor value.  Its arguments are the -	actual representation arguments of the constructor. - -  For every primop P there is *one* Id, its (curried) Id - -  Neither contructor worker Id nor the primop Id have a defminition anywhere. -  Instead they are saturated during the core-to-STG pass, and the code generator -  generates code for them directly. The STG language still has saturated  -  primops and constructor applications. - -* The Const type disappears, along with Const.lhs.  The literal part -  of Const.lhs reappears as Literal.lhs.  Much tidying up in here, -  to bring all the range checking into this one module. - -* I got rid of NoRep literals entirely.  They just seem to be too much trouble. - -* Because Con's don't exist any more, the funny C { args } syntax -  disappears from inteface files. - -* Every constructor, C, comes with a  - -  *wrapper*, called C, whose type is exactly what it looks like -	in the source program. It is an ordinary function, -	and it gets a top-level binding like any other function - -  *worker*, called $wC, which is the actual data constructor. -	Its type may be different to C, because: -		- useless dict args are dropped -		- strict args may be flattened -	It does not have a binding. - -  The worker is very like a primop, in that it has no binding, - - -Parsing -~~~~~~~ -* Result type signatures now work -	f :: Int -> Int = \x -> x -	-- The Int->Int is the type of f - -	g x y :: Int = x+y	 -	-- The Int is the type of the result of (g x y) - - -Recompilation checking and make -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* The .hi file for a modules is not touched if it doesn't change.  (It used to -  be touched regardless, forcing a chain of recompilations.)  The penalty for this -  is that we record exported things just as if they were mentioned in the body of -  the module.  And the penalty for that is that we may recompile a module when -  the only things that have changed are the things it is passing on without using. -  But it seems like a good trade. - -* -recomp is on by default - -Foreign declarations -~~~~~~~~~~~~~~~~~~~~ -* If you say -	foreign export zoo :: Int -> IO Int -  then you get a C produre called 'zoo', not 'zzoo' as before. -  I've also added a check that complains if you export (or import) a C -  procedure whose name isn't legal C. - - -Code generation and labels -~~~~~~~~~~~~~~~~~~~~~~~~~~ -* Now that constructor workers and wrappers have distinct names, there's -  no need to have a Foo_static_closure and a Foo_closure for constructor Foo. -  I nuked the entire StaticClosure story.  This has effects in some of -  the RTS headers (i.e. s/static_closure/closure/g) - - -Rules, constant folding -~~~~~~~~~~~~~~~~~~~~~~~ -* Constant folding becomes just another rewrite rule, attached to the Id for the -  PrimOp.   To achieve this, there's a new form of Rule, a BuiltinRule (see CoreSyn.lhs). -  The prelude rules are in prelude/PrelRules.lhs, while simplCore/ConFold.lhs has gone. - -* Appending of constant strings now works, using fold/build fusion, plus -  the rewrite rule -	unpack "foo" c (unpack "baz" c n)  =  unpack "foobaz" c n -  Implemented in PrelRules.lhs - -* The CCall primop is tidied up quite a bit.  There is now a data type CCall, -  defined in PrimOp, that packages up the info needed for a particular CCall. -  There is a new Id for each new ccall, with an big "occurrence name" -	{__ccall "foo" gc Int# -> Int#} -  In interface files, this is parsed as a single Id, which is what it is, really. - -Miscellaneous -~~~~~~~~~~~~~ -* There were numerous places where the host compiler's  -  minInt/maxInt was being used as the target machine's minInt/maxInt. -  I nuked all of these; everything is localised to inIntRange and inWordRange, -  in Literal.lhs - -* Desugaring record updates was broken: it didn't generate correct matches when -  used withe records with fancy unboxing etc.  It now uses matchWrapper. - -* Significant tidying up in codeGen/SMRep.lhs - -* Add __word, __word64, __int64 terminals to signal the obvious types  -  in interface files.  Add the ability to print word values in hex into  -  C code. - -* PrimOp.lhs is no longer part of a loop.  Remove PrimOp.hi-boot* - - -Types -~~~~~ -* isProductTyCon no longer returns False for recursive products, nor -  for unboxed products; you have to test for these separately.   -  There's no reason not to do CPR for recursive product types, for example. -  Ditto splitProductType_maybe. - -Simplification -~~~~~~~~~~~~~~~ -* New -fno-case-of-case flag for the simplifier.  We use this in the first run -  of the simplifier, where it helps to stop messing up expressions that  -  the (subsequent) full laziness pass would otherwise find float out. -  It's much more effective than previous half-baked hacks in inlining. - -  Actually, it turned out that there were three places in Simplify.lhs that -  needed to know use this flag. - -* Make the float-in pass push duplicatable bindings into the branches of -  a case expression, in the hope that we never have to allocate them. -  (see FloatIn.sepBindsByDropPoint) - -* Arrange that top-level bottoming Ids get a NOINLINE pragma -  This reduced gratuitous inlining of error messages. -  But arrange that such things still get w/w'd. - -* Arrange that a strict argument position is regarded as an 'interesting' -  context, so that if we see  -	foldr k z (g x) -  then we'll be inclined to inline g; this can expose a build. - -* There was a missing case in CoreUtils.exprEtaExpandArity that meant -  we were missing some obvious cases for eta expansion -  Also improve the code when handling applications. - -* Make record selectors (identifiable by their IdFlavour) into "cheap" operations. -	  [The change is a 2-liner in CoreUtils.exprIsCheap] -  This means that record selection may be inlined into function bodies, which -  greatly improves the arities of overloaded functions. - -* Make a cleaner job of inlining "lone variables".  There was some distributed -  cunning, but I've centralised it all now in SimplUtils.analyseCont, which -  analyses the context of a call to decide whether it is "interesting". - -* Don't specialise very small functions in Specialise.specDefn -  It's better to inline it.  Rather like the worker/wrapper case. - -* Be just a little more aggressive when floating out of let rhss. -  See comments with Simplify.wantToExpose -  A small change with an occasional big effect. - -* Make the inline-size computation think that  -	case x of I# x -> ... -  is *free*.   - - -CPR analysis -~~~~~~~~~~~~ -* Fix what was essentially a bug in CPR analysis.  Consider - -	letrec f x = let g y = let ... in f e1 -		     in -		     if ... then (a,b) else g x - -  g has the CPR property if f does; so when generating the final annotated -  RHS for f, we must use an envt in which f is bound to its final abstract -  value.  This wasn't happening.  Instead, f was given the CPR tag but g -  wasn't; but of course the w/w pass gives rotten results in that case!! -  (Because f's CPR-ness relied on g's.) - -  On they way I tidied up the code in CprAnalyse.  It's quite a bit shorter. - -  The fact that some data constructors return a constructed product shows -  up in their CPR info (MkId.mkDataConId) not in CprAnalyse.lhs - - - -Strictness analysis and worker/wrapper -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* BIG THING: pass in the demand to StrictAnal.saExpr.  This affects situations -  like -	f (let x = e1 in (x,x)) -  where f turns out to have strictness u(SS), say.  In this case we can -  mark x as demanded, and use a case expression for it. - -  The situation before is that we didn't "know" that there is the u(SS)  -  demand on the argument, so we simply computed that the body of the let  -  expression is lazy in x, and marked x as lazily-demanded.  Then even after -  f was w/w'd we got - -	let x = e1 in case (x,x) of (a,b) -> $wf a b - -  and hence - -	let x = e1 in $wf a b - -  I found a much more complicated situation in spectral/sphere/Main.shade, -  which improved quite a bit with this change. -  -* Moved the StrictnessInfo type from IdInfo to Demand.  It's the logical -  place for it, and helps avoid module loops - -* Do worker/wrapper for coerces even if the arity is zero.  Thus: -	stdout = coerce Handle (..blurg..) -  ==> -	wibble = (...blurg...) -	stdout = coerce Handle wibble -  This is good because I found places where we were saying  -	case coerce t stdout of { MVar a -> -	... -	case coerce t stdout of { MVar b ->  -	... -  and the redundant case wasn't getting eliminated because of the coerce. - - - -End December -~~~~~~~~~~~~ -* Fix a few renamer bugs - -* Substantially reorganise the Prelude to eliminate all orphan declarations. -  Details in PrelBase.lhs - -* Do a much better job of appending literal strings -   - remove NoRepStr -   - move unpackCString stuff to PrelBase -   - add BuiltinRules to the Rule type -   - add fold/build rules for literal strings - -   - -Week of Mon 25 Oct -~~~~~~~~~~~~~~~~~~ -* Fix a terrible bug in Simplify.mkDupableAlt; we were duplicating a small -  *InAlt*, but doing so invalidated occurrence info, which could lead to -  substantial code duplication. - -* Fix a bug in WwLib.mkWWcpr; I was generating CPR wrappers like -	I# (case x of ...) -  which is utterly wrong.  It should be  -	case x of ...(I# r) -  (The effect was to make functions stricter than they really are.) - -* Try doing no inlining at all in phase 0.  This noticeably improved -  spectral/fish (esp Main.hs I think), by improving floating. -  This single change has quite a large effect on some programs (allocation) - -  			Don't inline 	  Don't inline -			wrappers 	  anything   -			in phase 0	  in phase 0 -         awards                 113k          -7.08% -       cichelli               28962k          -3.12% -      wave4main               88089k        +130.45% -       fibheaps               31731k         +19.01% -           fish                8273k          -1.64% -      typecheck              148713k          +4.91% - -  But I found that fish worked much better if we inline *local* things -  in phase 0, but not *imported* things.   - -* Fix a terrible bug in Simplify.mkLamBndrZapper.  It was counting -  type args in one place, but not type binders, so it was sometimes -  inlining into unsaturated lambdas! - -* I found that there were some very bad loss-of-arity cases in PrelShow.   -  In particular, we had: - -	showl ""       = showChar '"' s -	showl ('"':xs) = showString "\\\"" . showl xs -	showl (x:xs)   = showLitChar x . showl xs - -  Trouble is, we get -	showl = \xs -> case xs of -			  ... -			  (x:xs) -> let f = showLitChar x -					g = showl xs -				    in \s -> f (g x) -  which is TERRIBLE.  We can't spot that showLitChar has arity 2 because -  it looks like this: - -	...other eqns... -        showLitChar c = showString ('\\' : asciiTab!!ord c) - -  notice that the (asciiTab!!orc c) is outside the \s, so GHC can't rewrite it to - -	showLitChar c =  \s -> showString ('\\' : asciiTab!!ord c) s - -  So I've changed PrelShow.showLitChar to use explicit \s.  Even then, showl -  doesn't work, because GHC can't see that showl xs can be pushed inside the \s. -  So I've put an explict \s there too.   - -	showl ""       s = showChar '"' s -	showl ('"':xs) s = showString "\\\"" (showl xs s) -	showl (x:xs)   s = showLitChar x (showl xs s) - -  Net result: imaginary/gen_regexps more than halves in allocation! - -  Turns out that the mkLamBndrZapper bug (above) meant that showl was -  erroneously inlining showLitChar x and showl xs, which is why this -  problem hasn't shown up before. -   -* Improve CSE a bit.  In ptic -	case h x of y -> ...(h x)... -  replaces (h x) by y. - -* Inline INLINE things very agressively, even though we get code duplication  -  thereby.  Reason: otherwise we sometimes call the original un-inlined INLINE -  defns, which have constructors etc still un-inlined in their RHSs.  The  -  improvement is dramatic for a few programs: - -      typecheck              150865k          -1.43% -      wave4main              114216k         -22.87% -          boyer               28793k          -7.86% -       cichelli               33786k         -14.28% -            ida               59505k          -1.79% -        rewrite               14665k          -4.91% -          sched               17641k          -4.22% - -  Code size increases by 10% which is not so good.  There must be a better way. -  Another bad thing showed up in fish/Main.hs.  Here we have -	(x1,y1) `vec_add` (x2,y2) = (x1+x2, y1+y2) -  which tends to get inlined.  But if we first inline (+), it looks big, -  so we don't inline it.  Sigh. - - -* Don't inline constructors in INLINE RHSs.  Ever.  Otherwise rules don't match. -  E.g. build - -* In ebnf2ps/Lexer.uncommentString, it would be a good idea to inline a constructor -  that occurs once in each branch of a case.  That way it doesn't get allocated -  in the branches that don't use it.  And in fact in this particular case -  something else good happens.  So CoreUnfold now does that. - -* Reverted to n_val_binders+2 in calcUnfoldingGuidance -  Otherwise wrappers are inlined even if there's no benefit. - - -Week of Mon 18 Oct -~~~~~~~~~~ -* Arrange that simplConArgs works in one less pass than before. -  This exposed a bug: a bogus call to completeBeta. - -* Add a top-level flag in CoreUnfolding, used in callSiteInline - -* Extend w/w to use etaExpandArity, so it does eta/coerce expansion - -* Don't float anything out of an INLINE. -  Don't float things to top level unless they also escape a value lambda. -	[see comments with SetLevels.lvlMFE -  Without at least one of these changes, I found that  -	{-# INLINE concat #-} -	concat = __inline (/\a -> foldr (++) []) -  was getting floated to -	concat = __inline( /\a -> lvl a ) -	lvl = ...inlined version of foldr... - -  Subsequently I found that not floating constants out of an INLINE -  gave really bad code like -	__inline (let x = e in \y -> ...) -  so I now let things float out of INLINE - -* Implement inline phases.   The meaning of the inline pragmas is -  described in CoreUnfold.lhs - -* Implement the "reverse-mapping" idea for CSE; actually it turned out to be easier -  to implement it in SetLevels, and may benefit full laziness too. - -Thurs 14 Oct -~~~~~~~~~~~~ -* It's a good idea to inline inRange. Consider - -	index (l,h) i = case inRange (l,h) i of -		  	  True ->  l+i -			  False -> error  -  inRange itself isn't strict in h, but if it't inlined then 'index' -  *does* become strict in h.  Interesting! - -* Big change to the way unfoldings and occurrence info is propagated in the simplifier -  The plan is described in Subst.lhs with the Subst type -  Occurrence info is now in a separate IdInfo field than user pragmas - -* I found that -	(coerce T (coerce S (\x.e))) y -  didn't simplify in one round. First we get to -	(\x.e) y -  and only then do the beta. Solution: cancel the coerces in the continuation - -* Amazingly, CoreUnfold wasn't counting the cost of a function an application. - -Early Oct -~~~~~~~~~ -* No commas between for-alls in RULES - -* Disable rules in initial simplifier run.  Otherwise full laziness -  doesn't get a chance to lift out a MFE before a rule (e.g. fusion) -  zaps it.  queens is a case in point - -* Improve float-out stuff significantly.  The big change is that if we have - -	\x -> ... /\a -> ...let p = ..a.. in let q = ...p... - -  where p's rhs doesn't x, we abstract a from p, so that we can get p past x. -  (We did that before.)  But we also substitute (p a) for p in q, and then -  we can do the same thing for q.  (We didn't do that, so q got stuck.) -  This is much better.  It involves doing a substitution "as we go" in SetLevels, -  though. - - -Weds 15 Sept -~~~~~~~~~~~~ -* exprIsDupable for an application (f e1 .. en) wasn't calling exprIsDupable -  on the arguments!!  So applications with few, but large, args were being dupliated. - -* sizeExpr on an application wasn't doing a nukeScrutDiscount on the arg of -  an application!!  So bogus discounts could accumulate from arguments! - -* Improve handling of INLINE pragmas in calcUnfoldingGuidance.  It was really -  wrong before - -* Substantially improve handling of coerces in worker/wrapper - -Tuesday 6 June -~~~~~~~~~~~~~~ -* Fix Kevin Atkinson's cant-find-instance bug.  Turns out that Rename.slurpSourceRefs -  needs to repeatedly call getImportedInstDecls, and then go back to slurping -  source-refs.  Comments with Rename.slurpSourceRefs. - -* Add a case to Simplify.mkDupableAlt for the quite-common case where there's -  a very simple alternative, in which case there's no point in creating a  -  join-point binding. - -* Fix CoreUtils.exprOkForSpeculation so that it returns True of (==# a# b#). -  This lack meant that  -	case ==# a# b# of { True -> x; False -> x } -  was not simplifying - -* Make float-out dump bindings at the top of a function argument, as -  at the top of a let(rec) rhs.  See notes with FloatOut.floatRhs - -* Make the ArgOf case of mkDupableAlt generate a OneShot lambda. -  This gave a noticeable boost to spectral/boyer2 - - -Monday 5 June -~~~~~~~~~~~~~ -Work, using IO.hPutStr as an example, to reduce the number of coerces. -The main idea is in WwLib.mkWWcoerce.  The gloss is that we must do -the w/w split even for small non-recursive things.  See notes with -WorkWrap.tryWw. - - -Friday 2 June -~~~~~~~~~~~~~ -Study why gen_regexps is slower than before.  Problem is in IO.writeLines, -in particular the local defn shoveString.  Two things are getting -in the way of arity expansion, which means we build far more function -closures than we should: -	shove = \ x -> let lvl = \s -> ... -		       in \s -> ... lvl ... - -The two things are: -	a) coerces -	b) full laziness floats - - -Solution to (a): add coerces to the worker/wrapper stuff. -See notes with WwLib.mkWWcoerce. - -This further complicated getWorkerId, so I finally bit the bullet and -make the workerInfo field of the IdInfo work properly, including -under substitutions.  Death to getWorkerId. - - - -Solution to (b): make all lambdas over realWorldStatePrimTy -into one-shot lambdas.  This is a GROSS HACK. - -* Also make the occurrence analyser aware of one-shot lambdas. - - -Thurs 1 June -~~~~~~~~~~~~ -Fix SetLevels so that it does not clone top-level bindings, but it -*does* clone bindings that are destined for the top level. - -The global invariant is that the top level bindings are always -unique, and never cloned. diff --git a/compiler/coreSyn/CoreSubst.lhs b/compiler/coreSyn/CoreSubst.lhs index 09f00c70b2..16173fb332 100644 --- a/compiler/coreSyn/CoreSubst.lhs +++ b/compiler/coreSyn/CoreSubst.lhs @@ -1197,16 +1197,15 @@ exprIsConApp_maybe id_unf expr                mk_arg e = mkApps e args          = dealWithCoercion co (con, substTys subst dfun_res_tys, map mk_arg ops) -        -- Look through unfoldings, but only cheap ones, because -        -- we are effectively duplicating the unfolding +        -- Look through unfoldings, but only arity-zero one;  +	-- if arity > 0 we are effectively inlining a function call, +	-- and that is the business of callSiteInline. +	-- In practice, without this test, most of the "hits" were +	-- CPR'd workers getting inlined back into their wrappers,          | Just rhs <- expandUnfolding_maybe unfolding -        = -- pprTrace "expanding" (ppr fun $$ ppr rhs) $ -          let in_scope' = extendInScopeSetSet in_scope (exprFreeVars rhs) -              res = go (Left in_scope') rhs cont -          in WARN( unfoldingArity unfolding > 0 && isJust res, -                   text "Interesting! exprIsConApp_maybe:"  -                   <+> ppr fun <+> ppr expr) -             res +        , unfoldingArity unfolding == 0  +        , let in_scope' = extendInScopeSetSet in_scope (exprFreeVars rhs) +        = go (Left in_scope') rhs cont          where            unfolding = id_unf fun diff --git a/compiler/simplCore/SimplCore.lhs b/compiler/simplCore/SimplCore.lhs index 1081ce0752..03ffb479db 100644 --- a/compiler/simplCore/SimplCore.lhs +++ b/compiler/simplCore/SimplCore.lhs @@ -885,6 +885,7 @@ hasShortableIdInfo :: Id -> Bool  hasShortableIdInfo id    =  isEmptySpecInfo (specInfo info)    && isDefaultInlinePragma (inlinePragInfo info) +  && not (isStableUnfolding (unfoldingInfo info))    where       info = idInfo id diff --git a/compiler/stranal/WorkWrap.lhs b/compiler/stranal/WorkWrap.lhs index 230c42808c..2c365887bc 100644 --- a/compiler/stranal/WorkWrap.lhs +++ b/compiler/stranal/WorkWrap.lhs @@ -296,8 +296,8 @@ checkSize :: Id -> CoreExpr  checkSize fn_id rhs thing_inside    | isStableUnfolding (realIdUnfolding fn_id)    = return [ (fn_id, rhs) ] -      -- See Note [Don't w/w INLINABLE things] -      -- and Note [Don't w/w INLINABLABLE things] +      -- See Note [Don't w/w INLINE things] +      -- and Note [Don't w/w INLINABLE things]        -- NB: use realIdUnfolding because we want to see the unfolding        --     even if it's a loop breaker! diff --git a/compiler/typecheck/TcBinds.lhs b/compiler/typecheck/TcBinds.lhs index 072f77c2f2..9f5257ad38 100644 --- a/compiler/typecheck/TcBinds.lhs +++ b/compiler/typecheck/TcBinds.lhs @@ -5,7 +5,7 @@  \section[TcBinds]{TcBinds}  \begin{code} -module TcBinds ( tcLocalBinds, tcTopBinds,  +module TcBinds ( tcLocalBinds, tcTopBinds, tcRecSelBinds,                   tcHsBootSigs, tcPolyBinds,                   PragFun, tcSpecPrags, tcVectDecls, mkPragFun,                    TcSigInfo(..), SigFun, mkSigFun, @@ -16,7 +16,7 @@ import {-# SOURCE #-} TcExpr  ( tcMonoExpr )  import DynFlags  import HsSyn - +import HscTypes( isHsBoot )  import TcRnMonad  import TcEnv  import TcUnify @@ -26,7 +26,6 @@ import TcPat  import TcMType  import TyCon  import TcType --- import Coercion  import TysPrim  import Id  import Var @@ -83,21 +82,37 @@ At the top-level the LIE is sure to contain nothing but constant  dictionaries, which we resolve at the module level.  \begin{code} -tcTopBinds :: HsValBinds Name  -           -> TcM ( LHsBinds TcId       -- Typechecked bindings -                  , [LTcSpecPrag]       -- SPECIALISE prags for imported Ids -                  , TcLclEnv)           -- Augmented environment - -        -- Note: returning the TcLclEnv is more than we really -        --       want.  The bit we care about is the local bindings -        --       and the free type variables thereof -tcTopBinds binds -  = do  { (ValBindsOut prs sigs, env) <- tcValBinds TopLevel binds getLclEnv -        ; let binds = foldr (unionBags . snd) emptyBag prs -        ; specs <- tcImpPrags sigs -        ; return (binds, specs, env) } +tcTopBinds :: HsValBinds Name -> TcM (TcGblEnv, TcLclEnv) +-- The TcGblEnv contains the new tcg_binds and tcg_spects +-- The TcLclEnv has an extended type envt for the new bindings +tcTopBinds (ValBindsOut binds sigs) +  = do  { tcg_env <- getGblEnv +        ; (binds', tcl_env) <- tcValBinds TopLevel binds sigs getLclEnv +        ; specs <- tcImpPrags sigs   -- SPECIALISE prags for imported Ids + +        ; let { tcg_env' = tcg_env { tcg_binds = foldr (unionBags . snd) +                                                       (tcg_binds tcg_env) +                                                       binds' +                                   , tcg_imp_specs = specs ++ tcg_imp_specs tcg_env } } + +        ; return (tcg_env', tcl_env) }          -- The top level bindings are flattened into a giant           -- implicitly-mutually-recursive LHsBinds +tcTopBinds (ValBindsIn {}) = panic "tcTopBinds" + +tcRecSelBinds :: HsValBinds Name -> TcM TcGblEnv +tcRecSelBinds (ValBindsOut binds sigs) +  = tcExtendGlobalValEnv [sel_id | L _ (IdSig sel_id) <- sigs] $ +    do { (rec_sel_binds, tcg_env) <- discardWarnings (tcValBinds TopLevel binds sigs getGblEnv) +       ; let tcg_env'  +              | isHsBoot (tcg_src tcg_env) = tcg_env +              | otherwise = tcg_env { tcg_binds = foldr (unionBags . snd) +                                                        (tcg_binds tcg_env) +                                                        rec_sel_binds } +              -- Do not add the code for record-selector bindings when  +              -- compiling hs-boot files +       ; return tcg_env' } +tcRecSelBinds (ValBindsIn {}) = panic "tcRecSelBinds"  tcHsBootSigs :: HsValBinds Name -> TcM [Id]  -- A hs-boot file has only one BindGroup, and it only has type @@ -125,9 +140,10 @@ tcLocalBinds EmptyLocalBinds thing_inside    = do  { thing <- thing_inside          ; return (EmptyLocalBinds, thing) } -tcLocalBinds (HsValBinds binds) thing_inside -  = do  { (binds', thing) <- tcValBinds NotTopLevel binds thing_inside -        ; return (HsValBinds binds', thing) } +tcLocalBinds (HsValBinds (ValBindsOut binds sigs)) thing_inside +  = do  { (binds', thing) <- tcValBinds NotTopLevel binds sigs thing_inside +        ; return (HsValBinds (ValBindsOut binds' sigs), thing) } +tcLocalBinds (HsValBinds (ValBindsIn {})) _ = panic "tcLocalBinds"  tcLocalBinds (HsIPBinds (IPBinds ip_binds _)) thing_inside    = do  { (given_ips, ip_binds') <- mapAndUnzipM (wrapLocSndM tc_ip_bind) ip_binds @@ -168,13 +184,11 @@ untouchable-range idea.  \begin{code}  tcValBinds :: TopLevelFlag  -           -> HsValBinds Name -> TcM thing -           -> TcM (HsValBinds TcId, thing)  - -tcValBinds _ (ValBindsIn binds _) _ -  = pprPanic "tcValBinds" (ppr binds) +           -> [(RecFlag, LHsBinds Name)] -> [LSig Name] +           -> TcM thing +           -> TcM ([(RecFlag, LHsBinds TcId)], thing)  -tcValBinds top_lvl (ValBindsOut binds sigs) thing_inside +tcValBinds top_lvl binds sigs thing_inside    = do  {       -- Typecheck the signature          ; let { prag_fn = mkPragFun sigs (foldr (unionBags . snd) emptyBag binds)                ; ty_sigs = filter isTypeLSig sigs @@ -193,7 +207,7 @@ tcValBinds top_lvl (ValBindsOut binds sigs) thing_inside                               tcBindGroups top_lvl sig_fn prag_fn                                             binds thing_inside -        ; return (ValBindsOut binds' sigs, thing) } +        ; return (binds', thing) }  ------------------------  tcBindGroups :: TopLevelFlag -> SigFun -> PragFun diff --git a/compiler/typecheck/TcDeriv.lhs b/compiler/typecheck/TcDeriv.lhs index db25c134d7..4fdb92fb29 100644 --- a/compiler/typecheck/TcDeriv.lhs +++ b/compiler/typecheck/TcDeriv.lhs @@ -337,7 +337,7 @@ tcDeriving tycl_decls inst_decls deriv_decls    ; let all_tycons = map ATyCon (bagToList newTyCons)    ; gbl_env <- tcExtendGlobalEnv all_tycons $ -               tcExtendGlobalEnv (concatMap implicitTyThings all_tycons) $ +               tcExtendGlobalEnvImplicit (concatMap implicitTyThings all_tycons) $                 tcExtendLocalFamInstEnv (map mkLocalFamInst (bagToList famInsts)) $                 tcExtendLocalInstEnv (map iSpec (bagToList inst_info)) getGblEnv diff --git a/compiler/typecheck/TcInstDcls.lhs b/compiler/typecheck/TcInstDcls.lhs index dbed0d3bfc..afcab3b022 100644 --- a/compiler/typecheck/TcInstDcls.lhs +++ b/compiler/typecheck/TcInstDcls.lhs @@ -52,7 +52,6 @@ import Bag  import BasicTypes  import DynFlags  import FastString -import HscTypes  import Id  import MkId  import Name @@ -380,20 +379,20 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls         ; let { (local_info,                  at_tycons_s)   = unzip local_info_tycons               ; at_idx_tycons   = concat at_tycons_s ++ idx_tycons -             ; implicit_things = concatMap implicitTyConThings at_idx_tycons -             ; aux_binds       = mkRecSelBinds at_idx_tycons  } +             ; at_things       = map ATyCon at_idx_tycons }                  -- (2) Add the tycons of indexed types and their implicit                  --     tythings to the global environment -       ; tcExtendGlobalEnvImplicit -             (map ATyCon at_idx_tycons ++ implicit_things) $ do { +       ; tcExtendGlobalEnvImplicit at_things $ do +       { tcg_env <- tcAddImplicits at_things +       ; setGblEnv tcg_env $                  -- Next, construct the instance environment so far, consisting                  -- of                  --   (a) local instance decls                  --   (b) local family instance decls -       ; addInsts local_info         $ +         addInsts local_info         $           addFamInsts at_idx_tycons   $ do {                  -- (3) Compute instances from "deriving" clauses; @@ -422,7 +421,7 @@ tcInstDecls1 tycl_decls inst_decls deriv_decls         ; return ( gbl_env                  , (bagToList deriv_inst_info) ++ local_info -                , aux_binds `plusHsValBinds` deriv_binds) +                , deriv_binds)      }}}    where      typInstCheck ty = is_cls (iSpec ty) `elem` typeableClassNames @@ -945,7 +944,8 @@ tcInstanceMethods dfun_id clas tyvars dfun_ev_vars inst_tys      tc_item (sel_id, dm_info)        = case findMethodBind (idName sel_id) binds of              Just user_bind -> tc_body sel_id standalone_deriv user_bind -            Nothing        -> tc_default sel_id dm_info +            Nothing        -> traceTc "tc_def" (ppr sel_id) >>  +                              tc_default sel_id dm_info      ----------------------      tc_body :: Id -> Bool -> LHsBind Name -> TcM (TcId, LHsBind Id) @@ -971,7 +971,8 @@ tcInstanceMethods dfun_id clas tyvars dfun_ev_vars inst_tys             ; tc_body sel_id False {- Not generated code? -} meth_bind }      tc_default sel_id NoDefMeth     -- No default method at all -      = do { warnMissingMethod sel_id +      = do { traceTc "tc_def: warn" (ppr sel_id) +           ; warnMissingMethod sel_id             ; (meth_id, _) <- mkMethIds clas tyvars dfun_ev_vars                                           inst_tys sel_id             ; return (meth_id, mkVarBind meth_id $ @@ -1002,7 +1003,7 @@ tcInstanceMethods dfun_id clas tyvars dfun_ev_vars inst_tys             ; dm_id <- tcLookupId dm_name             ; let dm_inline_prag = idInlinePragma dm_id                   rhs = HsWrap (mkWpEvVarApps [self_dict] <.> mkWpTyApps inst_tys) $ -                         HsVar dm_id +                       HsVar dm_id                   meth_bind = mkVarBind local_meth_id (L loc rhs)                   meth_id1 = meth_id `setInlinePragma` dm_inline_prag @@ -1163,6 +1164,7 @@ derivBindCtxt sel_id clas tys _bind  warnMissingMethod :: Id -> TcM ()  warnMissingMethod sel_id    = do { warn <- woptM Opt_WarnMissingMethods +       ; traceTc "warn" (ppr sel_id <+> ppr warn <+> ppr (not (startsWithUnderscore (getOccName sel_id))))         ; warnTc (warn  -- Warn only if -fwarn-missing-methods                   && not (startsWithUnderscore (getOccName sel_id)))                                          -- Don't warn about _foo methods diff --git a/compiler/typecheck/TcRnDriver.lhs b/compiler/typecheck/TcRnDriver.lhs index b383563311..fbdfa1b628 100644 --- a/compiler/typecheck/TcRnDriver.lhs +++ b/compiler/typecheck/TcRnDriver.lhs @@ -344,7 +344,7 @@ tcRnExtCore hsc_env (HsExtCore this_mod decls src_binds)  	-- any mutually recursive types are done right  	-- Just discard the auxiliary bindings; they are generated   	-- only for Haskell source code, and should already be in Core -   tcg_env <- tcTyAndClassDecls emptyModDetails rn_decls ; +   tcg_env   <- tcTyAndClassDecls emptyModDetails rn_decls ;     dep_files <- liftIO $ readIORef (tcg_dependent_files tcg_env) ;     setGblEnv tcg_env $ do { @@ -557,7 +557,6 @@ tcRnHsBootDecls decls  		-- Typecheck type/class decls  	; traceTc "Tc2" empty  	; tcg_env <- tcTyAndClassDecls emptyModDetails tycl_decls -        ; let aux_binds = mkRecSelBinds [tc | ATyCon tc <- nameEnvElts (tcg_type_env tcg_env)]  	; setGblEnv tcg_env    $ do {  		-- Typecheck instance decls @@ -580,18 +579,13 @@ tcRnHsBootDecls decls  		-- Make the final type-env  		-- Include the dfun_ids so that their type sigs  		-- are written into the interface file.  -		-- And similarly the aux_ids from aux_binds  	; let { type_env0 = tcg_type_env gbl_env  	      ; type_env1 = extendTypeEnvWithIds type_env0 val_ids  	      ; type_env2 = extendTypeEnvWithIds type_env1 dfun_ids  -	      ; type_env3 = extendTypeEnvWithIds type_env2 aux_ids   	      ; dfun_ids = map iDFunId inst_infos -	      ; aux_ids  = case aux_binds of -	      		     ValBindsOut _ sigs -> [id | L _ (IdSig id) <- sigs] -			     _		   	-> panic "tcRnHsBoodDecls"  	      } -	; setGlobalTypeEnv gbl_env type_env3 +	; setGlobalTypeEnv gbl_env type_env2     }}}     ; traceTc "boot" (ppr lie); return gbl_env } @@ -907,10 +901,7 @@ tcTopSrcDecls boot_details          traceTc "Tc2" empty ;  	tcg_env <- tcTyAndClassDecls boot_details tycl_decls ; -	let { aux_binds = mkRecSelBinds [tc | tc <- tcg_tcs tcg_env] } ; -		-- If there are any errors, tcTyAndClassDecls fails here - -	setGblEnv tcg_env	$ do { +	setGblEnv tcg_env       $ do {  		-- Source-language instances, including derivings,  		-- and import the supporting declarations @@ -932,16 +923,13 @@ tcTopSrcDecls boot_details  		-- Now GHC-generated derived bindings, generics, and selectors  		-- Do not generate warnings from compiler-generated code;  		-- hence the use of discardWarnings -	(tc_aux_binds,   specs1, tcl_env) <- discardWarnings (tcTopBinds aux_binds) ; -	(tc_deriv_binds, specs2, tcl_env) <- setLclTypeEnv tcl_env $  -			 	             discardWarnings (tcTopBinds deriv_binds) ; +	tc_envs <- discardWarnings (tcTopBinds deriv_binds) ; +        setEnvs tc_envs $ do {  		-- Value declarations next          traceTc "Tc5" empty ; -	(tc_val_binds, specs3, tcl_env) <- setLclTypeEnv tcl_env $ -			 	           tcTopBinds val_binds; - -        setLclTypeEnv tcl_env $ do {	-- Environment doesn't change now +	tc_envs@(tcg_env, tcl_env) <- tcTopBinds val_binds; +        setEnvs tc_envs $ do {	-- Environment doesn't change now                  -- Second pass over class and instance declarations,                   -- now using the kind-checked decls @@ -963,11 +951,7 @@ tcTopSrcDecls boot_details                  -- Wrap up          traceTc "Tc7a" empty ; -	tcg_env <- getGblEnv ; -	let { all_binds = tc_val_binds	 `unionBags` -			  tc_deriv_binds `unionBags` -			  tc_aux_binds   `unionBags` -			  inst_binds	 `unionBags` +	let { all_binds = inst_binds	 `unionBags`  			  foe_binds              ; sig_names = mkNameSet (collectHsValBinders val_binds)  @@ -976,8 +960,6 @@ tcTopSrcDecls boot_details                  -- Extend the GblEnv with the (as yet un-zonked)                   -- bindings, rules, foreign decls              ; tcg_env' = tcg_env { tcg_binds = tcg_binds tcg_env `unionBags` all_binds -                                 , tcg_imp_specs = tcg_imp_specs tcg_env ++ specs1 ++ specs2 ++ -                                                   specs3                                   , tcg_sigs  = tcg_sigs tcg_env `unionNameSets` sig_names                                   , tcg_rules = tcg_rules tcg_env ++ rules                                   , tcg_vects = tcg_vects tcg_env ++ vects @@ -985,7 +967,7 @@ tcTopSrcDecls boot_details                                   , tcg_fords = tcg_fords tcg_env ++ foe_decls ++ fi_decls } } ;          return (tcg_env', tcl_env) -    }}}}}} +    }}}}}}}  \end{code} diff --git a/compiler/typecheck/TcRnMonad.lhs b/compiler/typecheck/TcRnMonad.lhs index 845eaceb7b..c0a8817e31 100644 --- a/compiler/typecheck/TcRnMonad.lhs +++ b/compiler/typecheck/TcRnMonad.lhs @@ -611,10 +611,15 @@ discardWarnings :: TcRn a -> TcRn a  -- Ignore warnings inside the thing inside;  -- used to ignore-unused-variable warnings inside derived code  discardWarnings thing_inside -  = do  { errs_var <- newTcRef emptyMessages -        ; result <- setErrsVar errs_var thing_inside -        ; (_warns, errs) <- readTcRef errs_var -        ; addMessages (emptyBag, errs) +  = do  { errs_var <- getErrsVar +        ; (old_warns, _) <- readTcRef errs_var ; + +        ; result <- thing_inside + +        -- Revert warnings to old_warns +        ; (_new_warns, new_errs) <- readTcRef errs_var +        ; writeTcRef errs_var (old_warns, new_errs)  +          ; return result }  \end{code} @@ -627,7 +632,7 @@ discardWarnings thing_inside  \begin{code}  addReport :: Message -> Message -> TcRn () -addReport msg extra_info = do loc <- getSrcSpanM; addReportAt loc msg extra_info +addReport msg extra_info = do { traceTc "addr" msg; loc <- getSrcSpanM; addReportAt loc msg extra_info }  addReportAt :: SrcSpan -> Message -> Message -> TcRn ()  addReportAt loc msg extra_info diff --git a/compiler/typecheck/TcTyClsDecls.lhs b/compiler/typecheck/TcTyClsDecls.lhs index e23a181835..f91ccdf43d 100644 --- a/compiler/typecheck/TcTyClsDecls.lhs +++ b/compiler/typecheck/TcTyClsDecls.lhs @@ -14,7 +14,7 @@ TcTyClsDecls: Typecheck type and class declarations  -- for details  module TcTyClsDecls ( -	tcTyAndClassDecls, mkRecSelBinds, +	tcTyAndClassDecls, tcAddImplicits,  	-- Functions used by TcInstDcls to check   	-- data/type family instance declarations @@ -31,12 +31,13 @@ import BuildTyCl  import TcUnify  import TcRnMonad  import TcEnv +import TcBinds( tcRecSelBinds )  import TcTyDecls  import TcClassDcl  import TcHsType  import TcMType  import TcType -import TysWiredIn	( unitTy ) +import TysWiredIn( unitTy )  import Type  import Kind  import Class @@ -96,9 +97,9 @@ instantiate k to *.  \begin{code}  tcTyAndClassDecls :: ModDetails -                   -> [TyClGroup Name]       -- Mutually-recursive groups in dependency order -                   -> TcM (TcGblEnv)         -- Input env extended by types and classes -                                             -- and their implicit Ids,DataCons +                  -> [TyClGroup Name]   -- Mutually-recursive groups in dependency order +                  -> TcM TcGblEnv       -- Input env extended by types and classes +                                        -- and their implicit Ids,DataCons  -- Fails if there are any errors  tcTyAndClassDecls boot_details decls_s    = checkNoErrs $ do    -- The code recovers internally, but if anything gave rise to @@ -111,8 +112,8 @@ tcTyAndClassDecls boot_details decls_s      fold_env :: [TyClGroup Name] -> TcM TcGblEnv      fold_env [] = getGblEnv      fold_env (tyclds:tyclds_s) -      = do { env <- tcTyClGroup boot_details tyclds -           ; setGblEnv env $ fold_env tyclds_s } +      = do { tcg_env <- tcTyClGroup boot_details tyclds +           ; setGblEnv tcg_env $ fold_env tyclds_s }               -- remaining groups are typecheck in the extended global env  tcTyClGroup :: ModDetails -> TyClGroup Name -> TcM TcGblEnv @@ -154,11 +155,16 @@ tcTyClGroup boot_details tyclds             -- Step 4: Add the implicit things;             -- we want them in the environment because             -- they may be mentioned in interface files -       ; let implicit_things = concatMap implicitTyThings tyclss -             dm_ids          = mkDefaultMethodIds tyclss -       ; tcExtendGlobalEnvImplicit implicit_things $  -         tcExtendGlobalValEnv dm_ids $  -         getGblEnv } } +       ; tcExtendGlobalValEnv (mkDefaultMethodIds tyclss) $ +         tcAddImplicits tyclss } } + +tcAddImplicits :: [TyThing] -> TcM TcGblEnv +tcAddImplicits tyclss + = tcExtendGlobalEnvImplicit implicit_things $  +   tcRecSelBinds rec_sel_binds + where +   implicit_things = concatMap implicitTyThings tyclss +   rec_sel_binds   = mkRecSelBinds tyclss  zipRecTyClss :: TyClGroup Name               -> [TyThing]           -- Knot-tied @@ -1472,7 +1478,7 @@ must bring the default method Ids into scope first (so they can be seen  when typechecking the [d| .. |] quote, and typecheck them later.  \begin{code} -mkRecSelBinds :: [TyCon] -> HsValBinds Name +mkRecSelBinds :: [TyThing] -> HsValBinds Name  -- NB We produce *un-typechecked* bindings, rather like 'deriving'  --    This makes life easier, because the later type checking will add  --    all necessary type abstractions and applications @@ -1481,7 +1487,7 @@ mkRecSelBinds tycons    where      (sigs, binds) = unzip rec_sels      rec_sels = map mkRecSelBind [ (tc,fld)  -       	 	     	        | tc <- tycons +       	 	     	        | ATyCon tc <- tycons  				, fld <- tyConFields tc ]  mkRecSelBind :: (TyCon, FieldLabel) -> (LSig Name, LHsBinds Name) diff --git a/compiler/typecheck/TcUnify.lhs b/compiler/typecheck/TcUnify.lhs index e049a875f8..ca34ff7164 100644 --- a/compiler/typecheck/TcUnify.lhs +++ b/compiler/typecheck/TcUnify.lhs @@ -843,16 +843,22 @@ uUnfilledVars origin swapped tv1 details1 tv2 details2         ; sub_kind <- addErrCtxtM ctxt $ unifyKind k1 k2         ; case (sub_kind, details1, details2) of -           -- k1 <= k2, so update tv2 +           -- k1 < k2, so update tv2             (LT, _, MetaTv _ ref2) -> updateMeta tv2 ref2 ty1 -           -- k2 <= k1, so update tv1 + +           -- k2 < k1, so update tv1             (GT, MetaTv _ ref1, _) -> updateMeta tv1 ref1 ty2 + +	   -- k1 = k2, so we are free to update either way             (EQ, MetaTv i1 ref1, MetaTv i2 ref2)                  | nicer_to_update_tv1 i1 i2 -> updateMeta tv1 ref1 ty2                  | otherwise                 -> updateMeta tv2 ref2 ty1 +           (EQ, MetaTv _ ref1, _) -> updateMeta tv1 ref1 ty2 +           (EQ, _, MetaTv _ ref2) -> updateMeta tv2 ref2 ty1 +	   -- Can't do it in-place, so defer +	   -- This happens for skolems of all sorts             (_, _, _) -> unSwap swapped (uType_defer origin) ty1 ty2 }  -                        -- Defer for skolems of all sorts    where      k1       = tyVarKind tv1      k2       = tyVarKind tv2 diff --git a/new_tc_notes b/new_tc_notes deleted file mode 100644 index bf75f9b3ac..0000000000 --- a/new_tc_notes +++ /dev/null @@ -1,181 +0,0 @@ - -Notes on the new type constraint solver -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* 1/9/10: Consider -    {alpha} [b] (c~b) => (alpha ~ b) -  Then to maximise the chance of floating the equality out of -  the implication we'd like to orient the given as (b~c)  -  rather than (c~b). -     See test gadt-escape1, gadt13, gadt7 -  These tests pass because of approximateImplications - -* Equality superclasses are not getting the right instance decl -    indexed-types/should_compile/T2238: - -* Partial applications of data type families -    indexed-types/should_compile/DerivingNewType -   -Functional dependencies -~~~~~~~~~~~~~~~~~~~~~~~ -* indexed-types/Gentle - -RelaxedPolyRec by default -~~~~~~~~~~~~~~~~~~~~~~~~~ -* tcfail071 -* tcfail144 -* tcfail149, 150 - - ---------------------- -* 18/8/10: Fixed treatment of new work list from superclasses of wanteds.  -           TODO TODO: Revisit the desugarer to deal with equalities that  -           may mention recursive dictionaries.  - -* 12/8/10: Fixed proper kind checking for equalities and type family equalities. -  NOTE: Type synonyms stay unexpanded in canonical constraints. Is this correct? - -* 24/7/10: canonicalisation orients meta variables -           kind checking? -  see trySpontaneous: need to take care with orientation  - -* See newWantedSCWorkList: no adding superclass equalities -  for wanteds.  Seems ad hoc. - -* Happy genericTemplate notHappyAtAll needs a signature - -* time package needs signatures; I have put -XNoMonoLocalBinds in  -     validate-settings.mk for now - -Improve error message -~~~~~~~~~~~~~~~~~~~~~ -   FD1(normal)          <- DV: Failure to produce FD equality from *given* and top-level - -   FD2(normal)          <- DV: Failure to produce FC equality from two *givens* - -Unexpected failures: -~~~~~~~~~~~~~~~~~~~~~ -   PolyRec(normal,hpc,optasm)     <- DV: Actually works, but we have a warning  -                                     for -XRelaxedPolyRec deprecated flag -   T1470(normal,optc,hpc,optasm)    -   T2494(normal) -   T2494-2(normal,optc,hpc,optasm) -   T3108(normal,hpc,optasm)       <- DV: Actually works, but we have a warning for  -                                     deprecated flags -   T3391(normal,optc,hpc,optasm)   -   tc003(hpc) -   tc081(normal,optc,hpc,optasm)  <- DV: Let does not get generalized for  -                                         *single* variable binding -   tc089(normal,optc,hpc,optasm)        -   tc095(normal,optc,hpc,optasm) -   tc111(normal,optc,hpc,optasm) -   tc113(normal,optc,hpc,optasm)  Generalize top-level var binding -   tc127(normal,optc,hpc,optasm)  <- DV: Missing module Maybe in haskell98 package ...  -   tc132(normal,optc,hpc,optasm)  Generalize top-level var binding -   tc150(normal,optc,hpc,optasm)  Pattern signatures  -   tc159(normal,optc,hpc,optasm)  <- ILL FORMED EVIDENCE (related to newtype ... deriving)  -   tc162(normal) -   tc168(normal,optc,hpc,optasm)  <- DV: Actually works, don't know why its reported -   tc170(normal) -   tc175(normal,optc,hpc,optasm) -   tc189(normal,optc,hpc,optasm)  <- higher-rank ?  -   tc192(normal,optc,hpc,optasm)  <- loop in desugarer -   tc194(normal,optc,hpc,optasm)  <- polymorphic pattern signatures / higher-rank? -   tc211(normal,optc,hpc,optasm)  <- polymorphic pattern signatures / higher-rank? -   tc216(normal,optc,hpc,optasm)  <- ctx stack depth exceeded ...  -   tc217(normal,optc,hpc,optasm)   -   tc222(normal,optc,hpc,optasm) -   tc231(normal,optc,hpc,optasm) -   tc237(normal,optc,hpc,optasm) -   tc243(normal,optc,hpc,optasm)      <- DV: Actually works, Definition but no signature warning  -   tc244(normal,optc,hpc,optasm) - - -  - -ToDo -~~~~ -* zonking Coercions should use a function of a different name - -Basic setup -~~~~~~~~~~~ -   New modules     TcSimplify (old name, but all new code) -		   TcInteract -                   TcCanonical (defines the TcS monad too) -                   Constraints (both Wanted and Canonical) - -Existing modules   Coercion (defines operations over Coercions) -	 	   Kind -	 	   Type -		   TypeRep (the representation of types, kinds, coercions) - -   Dead modules	   TcTyFuns -		   TcSimplify-old.lhs (the old TcSimplify,  -			in repo just for reference) - - -Significant differences wrt the prototype -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* "Givens"  are simply evidence variables (EvVar) -  "Wanteds" are WantedConstraints -  See the Implication type in TcSolverTypes.lhs - -  There is no sum type combining given and wanted constraints - -* Wanted constraints are of three flavours (see data WantedConstraint) -	- evidenence variables: we can abstract over these -	- implications: we can't abstract over these -        - literal and method constraints; we can't abstract over these -		either, and they aren't implemented yet - -* We use a mutable group of bindings attached to each Inplication as the -  place to accumulate evidence for dictionaries and implicit parameters -  (It's also vital for equality superclasses.)  Each Impliciation has a -  TcEvBinds, defined in hsSyn/HsBinds.  The reference cell to accumulate -  bindings into is carried by the TcS solver monad; we need to fill in  -  evidence in the solver. - -* An evidence variable is -	- a dictionary -	- an implicit paramter -	- a coercion variable -  See newEvVar in Inst.lhs - -* The main Tc monad carries a set of untouchables -  The unifier ensures that they are not unified -  See Note [Unifying untouchables] - -* tcCheckExpr does deep-skol on expected type, and -  then calls tcExpr with (Check ty), where ty is deeply-skolemised - - -------------------- -Things to check later -------------------- -* Monomorphism restriction puts type variables in the top level env -  When generalising, we can't generalise over these ones (alas) -  Consider:  -    - Reject programs that fall under the monomorphism restriction -        (top-level monomorphic is rare) -    - Some hack to accept H98 programs - -* No orientation of tv~ty constraints; we don't need it - -Note [OpenSynTyCon app] -~~~~~~~~~~~~~~~~~~~~~~~ -Given - -  type family T a :: * -> * - -the two types (T () a) and (T () Int) must unify, even if there are -no type instances for T at all.  Should we just turn them into an -equality (T () a ~ T () Int)?  I don't think so.  We currently try to -eagerly unify everything we can before generating equalities; otherwise, -we could turn the unification of [Int] with [a] into an equality, too. - ------------------------- -We need to both 'unBox' and zonk deferred types.  We need to unBox as -functions, such as TcExpr.tcMonoExpr promise to fill boxes in the expected -type.  We need to zonk as the types go into the kind of the coercion variable -`cotv' and those are not zonked in Inst.zonkInst.  (Maybe it would be better -to zonk in zonInst instead.  Would that be sufficient?) - | 
