1. 23 Sep, 2003 1 commit
    • simonpj's avatar
      [project @ 2003-09-23 15:29:02 by simonpj] · 6d493299
      simonpj authored
               Much grunting about let-floating
      We want to avoid putting bindings between the '=' of a defn and a '\':
      	let { f = let ... in \y-> ... } in ...
      Reason: float-in often follows float-out, and it may then add yte
      more bindings there, some of which may be strict.  But f may by
      not be marked as not-demanded (for other reasons: see the call to
      zapDemandInfo in Simplify.completeLazyBind); and now the strict binding
      may not be able to float out again.  (Well, it triggers the ASSERT in
      So this commit adds FloatOut.floatNonRecRhs (to complement floatRhs) which
      is a big more vigorous about floating out.
      But that in turn showed up a pile of gore to do with unlifted bindings.
      We can't have them showing up at top level.  After thrashing in the swamp
      for a while, I eventually arranged that
      	let x# = e in b
      (where x# has an unlifted type) is treated exactly like
      	case e of x# -> b
      That is, it is never floated.  Yes, we lose opportunities to float some
      (very cheap!  unlifted let-bindings are always cheap) out of a lambda,
      but we're missing much bigger opportunities already.  For example:
      	\x -> f (h y)
      where h :: Int -> Int# is expensive. We'd like to float the (h y) outside
      the \x, but we don't because it's unboxed.  Possible solution: box it.
      Anyway, that's for the future.
  2. 13 Sep, 2002 1 commit
    • simonpj's avatar
      [project @ 2002-09-13 15:02:25 by simonpj] · 9af77fa4
      simonpj authored
      	Make Template Haskell into the HEAD
      This massive commit transfers to the HEAD all the stuff that
      Simon and Tim have been doing on Template Haskell.  The
      meta-haskell-branch is no more!
      WARNING: make sure that you
        * Update your links if you are using link trees.
          Some modules have been added, some have gone away.
        * Do 'make clean' in all library trees.
          The interface file format has changed, and you can
          get strange panics (sadly) if GHC tries to read old interface files:
          e.g.  ghc-5.05: panic! (the `impossible' happened, GHC version 5.05):
      	  Binary.get(TyClDecl): ForeignType
        * You need to recompile the rts too; Linker.c has changed
      However the libraries are almost unaltered; just a tiny change in
      Base, and to the exports in Prelude.
      NOTE: so far as TH itself is concerned, expression splices work
      fine, but declaration splices are not complete.
      		The main change
      The main structural change: renaming and typechecking have to be
      interleaved, because we can't rename stuff after a declaration splice
      until after we've typechecked the stuff before (and the splice
      * Combine the renamer and typecheker monads into one
      	(TcRnMonad, TcRnTypes)
        These two replace TcMonad and RnMonad
      * Give them a single 'driver' (TcRnDriver).  This driver
        replaces TcModule.lhs and Rename.lhs
      * The haskell-src library package has a module
        which defines the Haskell data type seen by the TH programmer.
      * New modules:
      	hsSyn/Convert.hs 	converts THSyntax -> HsSyn
      	deSugar/DsMeta.hs 	converts HsSyn -> THSyntax
      * New module typecheck/TcSplice type-checks Template Haskell splices.
      		Linking stuff
      * ByteCodeLink has been split into
      	ByteCodeLink	(which links)
      	ByteCodeAsm	(which assembles)
      * New module ghci/ObjLink is the object-code linker.
      * compMan/CmLink is removed entirely (was out of place)
        Ditto CmTypes (which was tiny)
      * Linker.c initialises the linker when it is first used (no need to call
        initLinker any more).  Template Haskell makes it harder to know when
        and whether to initialise the linker.
      	Gathering the LIE in the type checker
      * Instead of explicitly gathering constraints in the LIE
      	tcExpr :: RenamedExpr -> TcM (TypecheckedExpr, LIE)
        we now dump the constraints into a mutable varabiable carried
        by the monad, so we get
      	tcExpr :: RenamedExpr -> TcM TypecheckedExpr
        Much less clutter in the code, and more efficient too.
        (Originally suggested by Mark Shields.)
      		Remove "SysNames"
      Because the renamer and the type checker were entirely separate,
      we had to carry some rather tiresome implicit binders (or "SysNames")
      along inside some of the HsDecl data structures.  They were both
      tiresome and fragile.
      Now that the typechecker and renamer are more intimately coupled,
      we can eliminate SysNames (well, mostly... default methods still
      carry something similar).
      		Clean up HsPat
      One big clean up is this: instead of having two HsPat types (InPat and
      OutPat), they are now combined into one.  This is more consistent with
      the way that HsExpr etc is handled; there are some 'Out' constructors
      for the type checker output.
      	HsPat.InPat	--> HsPat.Pat
      	HsPat.OutPat	--> HsPat.Pat
      	No 'pat' type parameter in HsExpr, HsBinds, etc
      	Constructor patterns are nicer now: they use
      	for the three cases of constructor patterns:
      		prefix, infix, and record-bindings
      	The *same* data type HsConDetails is used in the type
      	declaration of the data type (HsDecls.TyData)
      Lots of associated clean-up operations here and there.  Less code.
      Everything is wonderful.
  3. 29 Jul, 2002 1 commit
    • simonmar's avatar
      [project @ 2002-07-29 10:50:43 by simonmar] · 5bca7237
      simonmar authored
      Type variables created by the typechecker didn't have the correct
      NameSpace: they were in the Var namespace rather than the TyVar
      namespace, which can lead to strange warnings about quantified type
      variables being not mentioned in the type when DEBUG is on.
      	- added mkSystemNameEncoded for use when the string
      	  is already encoded (saves re-encoding the string every
      	- added mkSystemTvNameEncoded for making a type variable
      	  name, as above
      	- use mkSystemTvNameEncoded when making type variables
      	- add mkSysLocalUnencoded for the (rare) case when
      	  the string needs encoding
      	- use mkSystemTvNameEncoded rather than mkSystemName for
      	  making type variables
      	- use mkSysLocalUnencoded since the names generated here
      	  need encoding.
  4. 29 Apr, 2002 1 commit
    • simonmar's avatar
      [project @ 2002-04-29 14:03:38 by simonmar] · b085ee40
      simonmar authored
      FastString cleanup, stage 1.
      The FastString type is no longer a mixture of hashed strings and
      literal strings, it contains hashed strings only with O(1) comparison
      (except for UnicodeStr, but that will also go away in due course).  To
      create a literal instance of FastString, use FSLIT("..").
      By far the most common use of the old literal version of FastString
      was in the pattern
      	  ptext SLIT("...")
      this combination still works, although it doesn't go via FastString
      any more.  The next stage will be to remove the need to use this
      special combination at all, using a RULE.
      To convert a FastString into an SDoc, now use 'ftext' instead of
      I've also removed all the FAST_STRING related macros from HsVersions.h
      except for SLIT and FSLIT, just use the relevant functions from
      FastString instead.
  5. 04 Jan, 2002 1 commit
    • simonpj's avatar
      [project @ 2002-01-04 11:35:22 by simonpj] · 6346938c
      simonpj authored
      	Be a bit less gung ho about let-floating
      Sometimes it's a bad idea to float cheap expressions
      outwards, even if they escape a value lambda.
      	  -- Even if it escapes a value lambda, we only
      	  -- float if it's not cheap (unless it'll get all the
      	  -- way to the top).  I've seen cases where we
      	  -- float dozens of tiny free expressions, which cost
      	  -- more to allocate than to evaluate.
      	  -- NB: exprIsCheap is also true of bottom expressions, which
      	  --     is good; we don't want to share them
      	  -- It's only Really Bad to float a cheap expression out of a
      	  -- strict context, because that builds a thunk that otherwise
      	  -- would never be built.  So another alternative would be to
      	  -- add
      	  -- 	|| (strict_ctxt && not (exprIsBottom expr))
      	  -- to the condition above. We should really try this out.
      The relevant function is lvlMFE, which has been subject to a lot
      of fiddling over the years.  Probably this isn't the last time.
      This all actually showed up when I was compiling IA.lhs from Ian Lynagh.
  6. 14 Dec, 2001 1 commit
    • simonpj's avatar
      [project @ 2001-12-14 17:24:03 by simonpj] · 5f087cf4
      simonpj authored
      	Performance tuning things
      I did some nofib tests, and fixed a number of performance problems.
      1.  Things were getting floated to top level, and that prevented
      some useful fusion happening.
      	y = build g
      	x = foldr k z y
      Fixed by arranging that we only get really keen on floating to top
      level in the second run of the let-float-out pass.
      2.  Some fettling up on the let-floater itself.  It had some parameters
      that weren't even being used!  And it was stupidly floating things out
      of a one-shot lambda, and the float-in pass didn't float them back in.
      I think I fixed both of these problems.
      3.  The eta-reducer was not eta-reducing (/\a -> g a) to g.  In general
      it has to be a bit careful because "seq" means that (\x -> g x) is
      not in general the same as g ---- but it *is* the same for a type lambda.
      This turned out to be important in rule matching, where the foldr/build
      rule was not firing because the LHS of the rule looked like
      	foldr k z (/\ a -> g a) = ...
      which never matched!  Result, no fusion to speak of!
      4.  The simplifier was a bit too gung ho about inlining used-once
      things bound to constructor args.  The comment is with Simplify.simplNonRecX.
  7. 12 Dec, 2001 1 commit
  8. 11 Dec, 2001 2 commits
    • simonpj's avatar
      [project @ 2001-12-11 17:51:33 by simonpj] · da70405e
      simonpj authored
      More inline/floating fixes; sigh
    • simonpj's avatar
      [project @ 2001-12-11 12:20:22 by simonpj] · 0de57732
      simonpj authored
      	Don't float out of INLINE blocks
      We never want to float stuff out of an INLINE right hand
      side.  This has been a long-standing thorn, and I managed
      to dislodge it yesterday (hence Lint errors).  Fixed again,
      more robustly this time (I hope).
  9. 10 Dec, 2001 1 commit
    • simonpj's avatar
      [project @ 2001-12-10 12:26:10 by simonpj] · 7953d080
      simonpj authored
      	Don't do CPR w/w for constants
      We don't want to do a CPR split for a constant
      function.  So if the worker will get no (value) args,
      we disable the CPR transformation.
      This infelicity exposed a buglet in the full laziness
      transformation; we were floating an expression outside
      an InlineMe context.   I've take the blunderbuss approach
      now, of effectively disabling full laziness inside an
      InlineMe.  Seems reasonable.
  10. 01 Nov, 2001 1 commit
    • simonpj's avatar
      [project @ 2001-11-01 13:20:05 by simonpj] · 51666a19
      simonpj authored
      	Fix a unboxed-binding bug in SpecConstr
      	[HEAD only]
      This fixes a rather obscure bug in the constructor
      specialiser discovered by Ralf Hinze.  It was
      generating a specialised version of the function
      with no arguments --- and the function returned an
      unboxed type.
      Solution: same as for worker-wrapper; add a dummy
      Several files are affected because I added
      CoreUtils.mkPiTypes, as a useful helper function.
  11. 26 Sep, 2001 1 commit
    • simonpj's avatar
      [project @ 2001-09-26 16:19:28 by simonpj] · 6858f7c1
      simonpj authored
      		Simon's big commit
      	[ These files seem to have been left out for some reason ]
      This commit, which I don't think I can sensibly do piecemeal, consists
      of the things I've been doing recently, mainly directed at making
      Manuel, George, and Marcin happier with RULES.
      Reogranise the simplifier
      1. The simplifier's environment is now an explicit parameter.  This
      makes it a bit easier to figure out where it is going.
      2. Constructor arguments can now be arbitrary expressions, except
      when the application is the RHS of a let(rec).  This makes it much
      easier to match rules like
      	    "foo"  f (h x, g y) = f' x y
      In the simplifier, it's Simplify.mkAtomicArgs that ANF-ises a
      constructor application where necessary.  In the occurrence analyser,
      there's a new piece of context info (OccEncl) to say whether a
      constructor app is in a place where it should be in ANF.  (Unless
      it knows this it'll give occurrence info which will inline the
      argument back into the constructor app.)
      3. I'm experimenting with doing the "float-past big lambda" transformation
      in the full laziness pass, rather than mixed in with the simplifier (was
      4.  Arrange that
      	case (coerce (S,T) (x,y)) of ...
      will simplify.  Previous it didn't.
      A local change to CoreUtils.exprIsConApp_maybe.
      5. Do a better job in CoreUtils.exprEtaExpandArity when there's an
      error function in one branch.
      Phase numbers, RULES, and INLINE pragmas
      1.  Phase numbers decrease from N towards zero (instead of increasing).
      This makes it easier to add new earlier phases, which is what users want
      to do.
      2.  RULES get their own phase number, N, and are disabled in phases before N.
      e.g. 	{-# RULES "foo" [2] forall x y.  f (x,y) = f' x y #-}
      Note the [2], which says "only active in phase 2 and later".
      3.  INLINE and NOINLINE pragmas have a phase number to.  This is now treated
      in just the same way as the phase number on RULE; that is, the Id is not inlined
      in phases earlier than N.  In phase N and later the Id *may* be inlined, and
      here is where INLINE and NOINLINE differ: INLNE makes the RHS look small, so
      as soon as it *may* be inlined it probably *will* be inlined.
      The syntax of the phase number on an INLINE/NOINLINE pragma has changed to be
      like the RULES case (i.e. in square brackets).  This should also make sure
      you examine all such phase numbers; many will need to change now the numbering
      is reversed.
      Inlining Ids is no longer affected at all by whether the Id appears on the
      LHS of a rule.  Now it's up to the programmer to put a suitable INLINE/NOINLINE
      pragma to stop it being inlined too early.
      Implementation notes:
      *  A new data type, BasicTypes.Activation says when a rule or inline pragma
      is active.   Functions isAlwaysActive, isNeverActive, isActive, do the
      obvious thing (all in BasicTypes).
      * Slight change in the SimplifierSwitch data type, which led to a lot of
      simplifier-specific code moving from CmdLineOpts to SimplMonad; a Good Thing.
      * The InlinePragma in the IdInfo of an Id is now simply an Activation saying
      when the Id can be inlined.  (It used to be a rather bizarre pair of a
      Bool and a (Maybe Phase), so this is much much easier to understand.)
      * The simplifier has a "mode" environment switch, replacing the old
      black list.  Unfortunately the data type decl has to be in
      CmdLineOpts, because it's an argument to the CoreDoSimplify switch
          data SimplifierMode = SimplGently | SimplPhase Int
      Here "gently" means "no rules, no inlining".   All the crucial
      inlining decisions are now collected together in SimplMonad
      (preInlineUnconditionally, postInlineUnconditionally, activeInline,
      1.  Only dictionary *functions* are made INLINE, not dictionaries that
      have no parameters.  (This inline-dictionary-function thing is Marcin's
      idea and I'm still not sure whether it's a good idea.  But it's definitely
      a Bad Idea when there are no arguments.)
      2.  Be prepared to specialise an INLINE function: an easy fix in
      But there is still a problem, which is that the INLINE wins
      at the call site, so we don't use the specialised version anyway.
      I'm still unsure whether it makes sense to SPECIALISE something
      you want to INLINE.
      Random smaller things
      * builtinRules (there was only one, but may be more) in PrelRules are now
        incorporated.   They were being ignored before...
      * OrdList.foldOL -->  OrdList.foldrOL, OrdList.foldlOL
      * Some tidying up of the tidyOpenTyVar, tidyTyVar functions.  I've
        forgotten exactly what!
  12. 18 May, 2001 1 commit
    • simonpj's avatar
      [project @ 2001-05-18 08:46:18 by simonpj] · b4775e5e
      simonpj authored
      	Get unbox-strict-fields right
      The problem was that when a library was compiled *without* -funbox-strict-fields,
      and the main program was compiled *with* that flag, we were wrongly treating
      the fields of imported data types as unboxed.
      To fix this I added an extra constructor to StrictnessMark to express whether
      the "!" annotation came from an interface file (don't fiddle) or a source
      file (decide whether to unbox).
      On the way I tided things up:
      * StrictnessMark moves to Demand.lhs, and doesn't have the extra DataCon
        fields that kept it in DataCon before.
      * HsDecls.BangType has one constructor, not three, with a StrictnessMark field.
      * DataCon keeps track of its strictness signature (dcRepStrictness), but not
        its "user strict marks" (which were never used)
      * All the functions, like getUniquesDs, that used to take an Int saying how
        many uniques to allocate, now return an infinite list. This saves arguments
        and hassle.  But it involved touching quite a few files.
      * rebuildConArgs takes a list of Uniques to use as its unique supply.  This
        means I could combine DsUtils.rebuildConArgs with MkId.rebuildConArgs
        (hooray; the main point of the previous change)
      I also tidied up one or two error messages
  13. 19 Mar, 2001 1 commit
    • simonpj's avatar
      [project @ 2001-03-19 16:22:51 by simonpj] · a7dff32d
      simonpj authored
      	Be more careful about floating out from  INLINE pragmas
      Given this:
      	x = __inline__ (f (g y))
      we were floating the (g y) out as a MFE, thus:
      	lvl = g y
      	x = __inline__ (f lvl)
      This is bad.  The (g y) redex gets outside the __inline__ envelope, 
      and may never get inlined. 
      The solution involved a bit of fiddling in SetLevels.
  14. 07 Mar, 2001 1 commit
  15. 01 Mar, 2001 1 commit
    • simonpj's avatar
      [project @ 2001-03-01 17:10:06 by simonpj] · 09518039
      simonpj authored
      Improve IdInfo substitution
      To get rules to work nicely, we need to make rules for recursive functions
      active in the RHS of the very recursive function itself.  This can be
      done nicely: the change is to move the calls to simplIdInfo in Simplify
      to an earlier place.
      The second thing is that when doing simple expression substitution
      in a rule (which we do during simplification for rules attached to an Id)
      we were zapping the occurrence info carefully pinned on the rule binders
      when the rule was put into the Id's rules.  This in turn meant that
      the simplifer ran more iterations than necessary when rules were fired.
      (Andrew Tolmach discovered this.)
      So I tidied up the interface to Subst a little.  The relevant functions
      that have changed are
      	simplBndr, simplBndrs, simplLetId, simplIdInfo,
      	substAndCloneId, substAndCloneIds, substAndCloneRecIds,
      There are consequential changes in other modules, but it compiles
      at least the whole standard libraries happily, and the codegen tests,
      so I'm reasonably confident in it.  But watch out for new strange
  16. 24 Nov, 2000 1 commit
  17. 14 Nov, 2000 1 commit
  18. 14 Sep, 2000 1 commit
    • simonpj's avatar
      [project @ 2000-09-14 13:46:39 by simonpj] · cae34044
      simonpj authored
      	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)
  19. 07 Sep, 2000 1 commit
    • simonpj's avatar
      [project @ 2000-09-07 16:32:23 by simonpj] · 4e6d5798
      simonpj authored
      A list of simplifier-related stuff, triggered
      	by looking at GHC's performance.
      	I don't guarantee that this lot will lead to
      	a uniform improvement over 4.08, but it it should
      	be a bit better.  More work probably required.
      * 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.
      * 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.
      * 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
      * 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.
  20. 01 Aug, 2000 1 commit
    • simonpj's avatar
      [project @ 2000-08-01 09:08:25 by simonpj] · fe69f3c1
      simonpj authored
      Simon's Marktoberdorf Commits
      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
      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
      	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.
  21. 18 Jul, 2000 1 commit
  22. 17 Jul, 2000 1 commit
    • keithw's avatar
      [project @ 2000-07-17 14:33:49 by keithw] · 613ddab2
      keithw authored
      Fix bug in SetLevels that meant an occurrence of a non-cloned binder,
      where the non-cloned binder shadowed a cloned binder, resulted in
      the occurrence incorrectly being substituted with the clone of the
      *outer* binder.  Curious that this never got tickled before!
  23. 14 Jul, 2000 1 commit
    • simonpj's avatar
      [project @ 2000-07-14 08:17:36 by simonpj] · 77a8c0db
      simonpj authored
      This commit completely re-does the kind-inference mechanism.
      Previously it was inter-wound with type inference, but that was
      always hard to understand, and it finally broke when we started
      checking for ambiguity when type-checking a type signature (details
      So now kind inference is more clearly separated, so that it never
      takes place at the same time as type inference.  The biggest change
      is in TcTyClsDecls, which does the kind inference for a group of
      type and class declarations.  It now contains comments to explain
      how it all works.
      There are also comments in TypeRep which describes the slightly
      tricky way in which we deal with the fact that kind 'type' (written
      '*') actually has 'boxed type' and 'unboxed type' as sub-kinds.
      The whole thing is a bit of a hack, because we don't really have 
      sub-kinding, but it's less of a hack than before.
      A lot of general tidying up happened at the same time.
      In particular, I removed some dead code here and there
  24. 11 Jul, 2000 1 commit
  25. 13 Jun, 2000 1 commit
  26. 25 May, 2000 1 commit
    • simonpj's avatar
      [project @ 2000-05-25 12:41:14 by simonpj] · 495ef8bd
      simonpj authored
      		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!
      Interface file formats have changed a little; you'll need
      to make clean before remaking.
      						Simon PJ
      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
      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.
      * 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[!]
  27. 24 May, 2000 1 commit
    • simonpj's avatar
      [project @ 2000-05-24 11:39:48 by simonpj] · 6e04c7e8
      simonpj authored
      MERGE 4.07
      * When float outwards (full laziness) remember to
        switch off the demand flag.  Else we wrongly
        can transform
      	\x -> let y __D = (...) in y+x
      	let y __D = (...)
      	in \x -> y+x
        In the latter, y is not necessarily demanded;
        it depends whether the function is called.  We
        should switch off the demand flag.
        The fix is right at the bottom in SetLevels.subst_id_info
  28. 24 Mar, 2000 1 commit
    • simonpj's avatar
      [project @ 2000-03-24 17:49:29 by simonpj] · 6c872fff
      simonpj authored
      a) Small wibbles to do with inlining and floating
      b) Implement Ralf's request, so that one can write
      	type F = forall a. a -> a
      	f :: Int -> F
      	f = ...
         The for-alls inside F are hoisted out to the top of
         the type signature for f.  This applies uniformly to
         all user-written types
  29. 23 Mar, 2000 1 commit
    • simonpj's avatar
      [project @ 2000-03-23 17:45:17 by simonpj] · 111cee3f
      simonpj authored
      This utterly gigantic commit is what I've been up to in background
      mode in the last couple of months.  Originally the main goal
      was to get rid of Con (staturated constant applications)
      in the CoreExpr type, but one thing led to another, and I kept
      postponing actually committing.   Sorry.
      	Simon, 23 March 2000
      I've tested it pretty thoroughly, but doubtless things will break.
      Here are the highlights
      * Con is gone; the CoreExpr type is simpler
      * NoRepLits have gone
      * Better usage info in interface files => less recompilation
      * Result type signatures work
      * CCall primop is tidied up
      * Constant folding now done by Rules
      * Lots of hackery in the simplifier
      * Improvements in CPR and strictness analysis
      Many bug fixes including
      * Sergey's DoCon compiles OK; no loop in the strictness analyser
      * Volker Wysk's programs don't crash the CPR analyser
      I have not done much on measuring compilation times and binary sizes;
      they could have got worse.  I think performance has got significantly
      better, though, in most cases.
      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.
      	Its type may be different to C, because:
      		- useless dict args are dropped
      		- strict args may be flattened
        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.
      * 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.
      * 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*
      * 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.
      * 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
      		     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
      	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.
  30. 01 Nov, 1999 1 commit
    • simonpj's avatar
      [project @ 1999-11-01 17:09:54 by simonpj] · 30b5ebe4
      simonpj authored
      A regrettably-gigantic commit that puts in place what Simon PJ
      has been up to for the last month or so, on and off.
      The basic idea was to restore unfoldings to *occurrences* of
      variables without introducing a space leak.  I wanted to make
      sure things improved relative to 4.04, and that proved depressingly
      hard.  On the way I discovered several quite serious bugs in the
      Here's a summary of what's gone on.
      * No commas between for-alls in RULES.  This makes the for-alls have
        the same syntax as in types.
      * 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
      * Implement inline phases.   The meaning of the inline pragmas is
        described in CoreUnfold.lhs.  You can say things like
      	{#- INLINE 2 build #-}
        to mean "inline build in phase 2"
      * 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 the "reverse-mapping" idea for CSE; actually it turned out to be easier
        to implement it in SetLevels, and may benefit full laziness too.
      * 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.
      * 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,
  31. 17 Sep, 1999 1 commit
    • simonpj's avatar
      [project @ 1999-09-17 09:15:22 by simonpj] · 731f53de
      simonpj authored
      This bunch of commits represents work in progress on inlining and
      worker/wrapper stuff.
      Currently, I think it makes the compiler slightly worse than 4.04, for
      reasons I don't yet understand.  But it means that Simon and I can
      both peer at what is going on.
      * Substantially improve handling of coerces in worker/wrapper
      * 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
  32. 14 Jul, 1999 1 commit
    • simonpj's avatar
      [project @ 1999-07-14 14:40:20 by simonpj] · 4e7d56fd
      simonpj authored
      Main things:
      * Add splitProductType_maybe to DataCon.lhs, with type
      	:: Type 			-- A product type, perhaps
      	-> Maybe (TyCon, 		-- The type constructor
      		  [Type],		-- Type args of the tycon
      		  DataCon,		-- The data constructor
      		  [Type])		-- Its *representation* arg types
        Then use it in many places (e.g. worker-wrapper places) instead
        of a pile of junk
      * Clean up various uses of dataConArgTys, which were plain wrong because
        they weren't passed the existential type arguments.  Most of these calls
        are eliminated by using splitProductType_maybe above.  I hope I correctly
        squashed the others. This fixes a bug that Meurig's programs showed up.
          module FailGHC (killSustainer) where
          import Weak
          import IOExts
          data Sustainer = forall a . Sustainer (IORef (Maybe a)) (IO ())
          killSustainer :: Sustainer -> IO ()
          killSustainer (Sustainer _ act) = act
        The above program used to kill the compiler.
      * A fairly concerted attack on the Dreaded Space Leak.
      	- Add Type.seqType, CoreSyn.seqExpr, CoreSyn.seqRules
      	- Add some seq'ing when building Ids and IdInfos
      		These reduce the space usage a lot
      	- Add CoreSyn.coreBindsSize, which is pretty strict in the program,
      		and call it when we have -dshow-passes.
      	- Do not put the inlining in an Id that is being plugged into
      		the result-expression of the simplifier.  This cures
      		a the 'wedge' in the space profile for reasons I don't understand fully
        Together, these things reduce the max space usage when compiling PrelNum from
        17M to about 7Mbytes.
        I think there are now *too many* seqs, and they waste work, but I don't have
        time to find which ones.
        Furthermore, we aren't done. For some reason, some of the stuff allocated by
        the simplifier makes it through all during code generation and I don't see why.
        There's a should-be-unnecessary call to coreBindsSize in Main.main which
        zaps some, but not all of this space.
        -dshow-passes reduces space usage a bit, but I don't think it should really.
        All the measurements were made on a compiler compiled with profiling by
        GHC 3.03.    I hope they carry over to other builds!
      * One trivial thing: changed all variables 'label' to 'lbl', becuase the
        former is a keyword with -fglagow-exts in GHC 3.03 (which I was compiling with).
        Something similar in StringBuffer.
  33. 06 Jul, 1999 1 commit
    • simonpj's avatar
      [project @ 1999-07-06 16:45:31 by simonpj] · 9d38678e
      simonpj authored
      All Simon's recent tuning changes.  Rough summary follows:
      * 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
      * Reduce the number of coerces, using worker/wrapper stuff.
        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
      * 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.  Kevin Glynn will be happy.
      * Make all lambdas over realWorldStatePrimTy
        into one-shot lambdas.  This is a GROSS HACK.
      * Also make the occurrence analyser aware of one-shot lambdas.
      * Make various Prelude things into INLINE, so that foldr doesn't
        get inlined in their body, so that the caller gets the benefit
        of fusion.  Notably in PrelArr.lhs.
  34. 28 Jun, 1999 1 commit
    • simonpj's avatar
      [project @ 1999-06-28 16:35:56 by simonpj] · b01ae32e
      simonpj authored
      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.
  35. 22 Jun, 1999 1 commit
  36. 26 May, 1999 1 commit
  37. 18 May, 1999 1 commit
  38. 11 May, 1999 1 commit
    • keithw's avatar
      [project @ 1999-05-11 16:37:29 by keithw] · d133b73a
      keithw authored
      (this is number 4 of 9 commits to be applied together)
        The major purpose of this commit is to introduce usage information
        and usage analysis into the compiler, per the paper _Once Upon a
        Polymorphic Type_ (Keith Wansbrough and Simon Peyton Jones, POPL'99,
        and Glasgow TR-1998-19).
        Usage information has been added to types, in the form of a new kind
        of NoteTy: (UsgNote UsageAnn(UsOnce|UsMany|UsVar UVar)).  Usages
        print as __o (once), __m (many, usually omitted), or (not in
        interface files) __uvxxxx.  Usage annotations should only appear at
        certain places in a type (see the paper).  The `default' annotation
        is __m, and so an omitted annotation implies __m.  Utility functions
        for handling usage annotations are provided in Type.
        If the compiler is built with -DUSMANY (a flag intended for use in
        debugging by KSW only), __m are *required* and may not be omitted.
        The major constraint is that type arguments (eg to mkAppTy) must be
        unannotated on top.  To maintain this invariant, many functions
        required the insertion of Type.unUsgTy (removing annot from top of a
        type) or UsageSPUtils.unannotTy (removing all annotations from a
        type).  A function returning usage-annotated types for primops has
        been added to PrimOp.
        A new kind of Note, (TermUsg UsageAnn), has been added to annotate
        Terms.  This note is *not* printed in interface files, and for the
        present does not escape the internals of the usage inference engine.
  39. 18 Dec, 1998 1 commit
    • simonpj's avatar
      [project @ 1998-12-18 17:40:31 by simonpj] · 7e602b0a
      simonpj authored
      Another big commit from Simon.  Actually, the last one
      didn't all go into the main trunk; because of a CVS glitch it
      ended up in the wrong branch.
      So this commit includes:
      * Scoped type variables
      * Warnings for unused variables should work now (they didn't before)
      * Simplifier improvements:
      	- Much better treatment of strict arguments
      	- Better treatment of bottoming Ids
      	- No need for w/w split for fns that are merely strict
      	- Fewer iterations needed, I hope
      * Less gratuitous renaming in interface files and abs C
      * OccName is a separate module, and is an abstract data type
      I think the whole Prelude and Exts libraries compile correctly.
      Something isn't quite right about typechecking existentials though.