summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/NOTES156
-rw-r--r--compiler/Simon-log1260
-rw-r--r--compiler/coreSyn/CoreSubst.lhs17
-rw-r--r--compiler/simplCore/SimplCore.lhs1
-rw-r--r--compiler/stranal/WorkWrap.lhs4
-rw-r--r--compiler/typecheck/TcBinds.lhs66
-rw-r--r--compiler/typecheck/TcDeriv.lhs2
-rw-r--r--compiler/typecheck/TcInstDcls.lhs22
-rw-r--r--compiler/typecheck/TcRnDriver.lhs36
-rw-r--r--compiler/typecheck/TcRnMonad.lhs15
-rw-r--r--compiler/typecheck/TcTyClsDecls.lhs34
-rw-r--r--compiler/typecheck/TcUnify.lhs12
-rw-r--r--new_tc_notes181
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?)
-