1. 18 Jun, 2011 1 commit
    • dterei's avatar
      SafeHaskell: Transitively check safety when compiling a module. · 77d85a4a
      dterei authored
      While we previously checked the safety of safe imported modules we
      didn't do this check transitively. This can be a problem when we depend
      on a trustworthy module in a package that is no longer trusted, so we
      should fail compilation. We already stored in an interface file the
      transitive list of packages a module depends on. Now we extend that list
      to include a flag saying if we depend on that package being trusted as
  2. 03 Jun, 2011 1 commit
  3. 19 Apr, 2011 1 commit
    • Simon Peyton Jones's avatar
      This BIG PATCH contains most of the work for the New Coercion Representation · fdf86568
      Simon Peyton Jones authored
      See the paper "Practical aspects of evidence based compilation in System FC"
      * Coercion becomes a data type, distinct from Type
      * Coercions become value-level things, rather than type-level things,
        (although the value is zero bits wide, like the State token)
        A consequence is that a coerion abstraction increases the arity by 1
        (just like a dictionary abstraction)
      * There is a new constructor in CoreExpr, namely Coercion, to inject
        coercions into terms
  4. 12 Apr, 2011 1 commit
    • Simon Marlow's avatar
      Change the way module initialisation is done (#3252, #4417) · a52ff761
      Simon Marlow authored
      Previously the code generator generated small code fragments labelled
      with __stginit_M for each module M, and these performed whatever
      initialisation was necessary for that module and recursively invoked
      the initialisation functions for imported modules.  This appraoch had
       - FFI users had to call hs_add_root() to ensure the correct
         initialisation routines were called.  This is a non-standard,
         and ugly, API.
       - unless we were using -split-objs, the __stginit dependencies would
         entail linking the whole transitive closure of modules imported,
         whether they were actually used or not.  In an extreme case (#4387,
         #4417), a module from GHC might be imported for use in Template
         Haskell or an annotation, and that would force the whole of GHC to
         be needlessly linked into the final executable.
      So now instead we do our initialisation with C functions marked with
      __attribute__((constructor)), which are automatically invoked at
      program startup time (or DSO load-time).  The C initialisers are
      emitted into the stub.c file.  This means that every time we compile
      with -prof or -hpc, we now get a stub file, but thanks to #3687 that
      is now invisible to the user.
      There are some refactorings in the RTS (particularly for HPC) to
      handle the fact that initialisers now get run earlier than they did
      The __stginit symbols are still generated, and the hs_add_root()
      function still exists (but does nothing), for backwards compatibility.
  5. 31 Mar, 2011 1 commit
  6. 13 Dec, 2010 1 commit
    • simonpj@microsoft.com's avatar
      Fix recursive superclasses (again). Fixes Trac #4809. · a3bab050
      simonpj@microsoft.com authored
      This patch finally deals with the super-delicate question of
      superclases in possibly-recursive dictionaries.  The key idea
      is the DFun Superclass Invariant (see TcInstDcls):
           In the body of a DFun, every superclass argument to the
           returned dictionary is
             either   * one of the arguments of the DFun,
             or       * constant, bound at top level
      To establish the invariant, we add new "silent" superclass
      argument(s) to each dfun, so that the dfun does not do superclass
      selection internally.  There's a bit of hoo-ha to make sure that
      we don't print those silent arguments in error messages; a knock
      on effect was a change in interface-file format.
      A second change is that instead of the complex and fragile
      "self dictionary binding" in TcInstDcls and TcClassDcl,
      using the same mechanism for existential pattern bindings.
      See Note [Subtle interaction of recursion and overlap] in TcInstDcls
      and Note [Binding when looking up instances] in InstEnv.
      Main notes are here:
        * Note [Silent Superclass Arguments] in TcInstDcls,
          including the DFun Superclass Invariant
      Main code changes are:
        * The code for MkId.mkDictFunId and mkDictFunTy
        * DFunUnfoldings get a little more complicated;
          their arguments are a new type DFunArg (in CoreSyn)
        * No "self" argument in tcInstanceMethod
        * No special tcSimplifySuperClasss
        * No "dependents" argument to EvDFunApp
         It turns out that it's quite tricky to generate the right
         DFunUnfolding for a specialised dfun, when you use SPECIALISE
         INSTANCE.  For now I've just commented it out (in DsBinds) but
         that'll lose some optimisation, and I need to get back to
  7. 25 Oct, 2010 1 commit
  8. 21 Oct, 2010 1 commit
  9. 22 Sep, 2010 1 commit
    • simonpj@microsoft.com's avatar
      Fix an ASSERT failure with profiling · 9e6ca39b
      simonpj@microsoft.com authored
      The problem arose with this kind of thing
         x = (,) (scc "blah" Nothing)
      Then 'x' is marked NoCafRefs by CoreTidy, becuase it has 
      arity 1, and doesn't mention any caffy things.
      That in turns means that CorePrep must not float out the
      sat binding to give
        sat = scc "blah" Nothing
        x = (,) sat
      Rather we must generate
        x = \eta. let sat = scc "blah" Nothing 
                  in (,) sat eta
      URGH! This Caf stuff is such a mess.
  10. 18 Sep, 2010 1 commit
  11. 15 Sep, 2010 1 commit
  12. 13 Sep, 2010 1 commit
  13. 31 May, 2010 1 commit
    • simonpj@microsoft.com's avatar
      Robustify the treatement of DFunUnfolding · a90dc390
      simonpj@microsoft.com authored
      See Note [DFun unfoldings] in CoreSyn.  The issue here is that 
      you can't tell how many dictionary arguments a DFun needs just
      from looking at the Arity of the DFun Id: if the dictionary is
      represented by a newtype the arity might include the dictionary
      and value arguments of the (single) method.
      So we need to record the number of arguments need by the DFun
      in the DFunUnfolding itself.  Details in 
         Note [DFun unfoldings] in CoreSyn
  14. 06 May, 2010 1 commit
  15. 24 Dec, 2009 1 commit
  16. 21 Dec, 2009 1 commit
  17. 18 Dec, 2009 1 commit
    • simonpj@microsoft.com's avatar
      Always expose the unfolding of something with an InlineRule · 0c66cc56
      simonpj@microsoft.com authored
      Previously a bottoming function with a strictness wrapper 
      had a hidden inlining, and that was Very Bad, because in 
          f x = if ... then bot_fun x else x+1
      we really want to pass the *unboxed* x to bot_fun. This
      happens quite a bit in error handling code, eg for array
  18. 11 Dec, 2009 1 commit
    • simonpj@microsoft.com's avatar
      Bottom extraction: float out bottoming expressions to top level · b84ba676
      simonpj@microsoft.com authored
      The idea is to float out bottoming expressions to top level,
      abstracting them over any variables they mention, if necessary.  This
      is good because it makes functions smaller (and more likely to
      inline), by keeping error code out of line. 
      See Note [Bottoming floats] in SetLevels.
      On the way, this fixes the HPC failures for cg059 and friends.
      I've been meaning to do this for some time.  See Maessen's paper 1999
      "Bottom extraction: factoring error handling out of functional
      programs" (unpublished I think).
      Here are the nofib results:
              Program           Size    Allocs   Runtime   Elapsed
                  Min          +0.1%     -7.8%    -14.4%    -32.5%
                  Max          +0.5%     +0.2%     +1.6%    +13.8%
       Geometric Mean          +0.4%     -0.2%     -4.9%     -6.7%
      Module sizes
              -1 s.d.                -----           -2.6%
              +1 s.d.                -----           +2.3%
              Average                -----           -0.2%
      Compile times:
              -1 s.d.                -----          -11.4%
              +1 s.d.                -----           +4.3%
              Average                -----           -3.8%
      I'm think program sizes have crept up because the base library
      is bigger -- module sizes in nofib decrease very slightly.  In turn
      I think that may be because the floating generates a call where
      there was no call before.  Anyway I think it's acceptable.
      The main changes are:
      * SetLevels floats out things that exprBotStrictness_maybe 
        identifies as bottom.  Make sure to pin on the right 
        strictness info to the newly created Ids, so that the
        info ends up in interface files.
        Since FloatOut is run twice, we have to be careful that we
        don't treat the function created by the first float-out as
        a candidate for the second; this is what worthFloating does.
        See SetLevels Note [Bottoming floats]
                      Note [Bottoming floats: eta expansion]
      * Be careful not to inline top-level bottoming functions; this 
        would just undo what the floating transformation achieves.
        See CoreUnfold Note [Do not inline top-level bottoming functions
        Ensuring this requires a bit of extra plumbing, but nothing drastic..
      * Similarly pre/postInlineUnconditionally should be 
        careful not to re-inline top-level bottoming things!
        See SimplUtils Note [Top-level botomming Ids]
                       Note [Top level and postInlineUnconditionally]
  19. 07 Dec, 2009 1 commit
  20. 02 Dec, 2009 1 commit
    • simonpj@microsoft.com's avatar
      More work on the simplifier's inlining strategies · c86161c5
      simonpj@microsoft.com authored
      This patch collects a small raft of related changes
      * Arrange that during 
           (a) rule matching and 
           (b) uses of exprIsConApp_maybe
        we "look through" unfoldings only if they are active
        in the phase. Doing this for (a) required a bit of 
        extra plumbing in the rule matching code, but I think
        it's worth it.
        One wrinkle is that even if inlining is off (in the 'gentle'
        phase of simplification) during rule matching we want to
        "look through" things with inlinings.  
         See SimplUtils.activeUnfInRule.
        This fixes a long-standing bug, where things that were
        supposed to be (say) NOINLINE, could still be poked into
        via exprIsConApp_maybe. 
      * In the above cases, also check for (non-rule) loop breakers; 
        we never look through these.  This fixes a bug that could make
        the simplifier diverge (and did for Roman).  
        Test = simplCore/should_compile/dfun-loop
      * Try harder not to choose a DFun as a loop breaker. This is 
        just a small adjustment in the OccurAnal scoring function
      * In the scoring function in OccurAnal, look at the InlineRule
        unfolding (if there is one) not the actual RHS, beause the
        former is what'll be inlined.  
      * Make the application of any function to dictionary arguments
        CONLIKE.  Thus (f d1 d2) is CONLIKE.  
        Encapsulated in CoreUtils.isExpandableApp
        Reason: see Note [Expandable overloadings] in CoreUtils
      * Make case expressions seem slightly smaller in CoreUnfold.
        This reverses an unexpected consequences of charging for
      * Signficantly refactor the data type for Unfolding (again). 
        The result is much nicer.  
      * Add type synonym BasicTypes.CompilerPhase = Int
        and use it
      Many of the files touched by this patch are simply knock-on
      consequences of these two refactorings.
  21. 19 Nov, 2009 2 commits
    • simonpj@microsoft.com's avatar
      Remove the (very) old strictness analyser · 2662dbc5
      simonpj@microsoft.com authored
      I finally got tired of the #ifdef OLD_STRICTNESS stuff.  I had been
      keeping it around in the hope of doing old-to-new comparisions, but
      have failed to do so for many years, so I don't think it's going to
      happen.  This patch deletes the clutter.
    • simonpj@microsoft.com's avatar
      Implement -fexpose-all-unfoldings, and fix a non-termination bug · 6a944ae7
      simonpj@microsoft.com authored
      The -fexpose-all-unfoldings flag arranges to put unfoldings for *everything*
      in the interface file.  Of course,  this makes the file a lot bigger, but
      it also makes it complete, and that's great for supercompilation; or indeed
      any whole-program work.
        * Interface files need to record loop-breaker-hood.  (Previously,
          loop breakers were never exposed, so that info wasn't necessary.)
          Hence a small interface file format change. 
        * When inlining, must check loop-breaker-hood. (Previously, loop
          breakers didn't have an unfolding at all, so no need to check.)
        * Ditto in exprIsConApp_maybe.  Roman actually tripped this bug, 
          because a DFun, which had an unfolding, was also a loop breaker
        * TidyPgm.tidyIdInfo must be careful to preserve loop-breaker-hood
      So Id.idUnfolding checks for loop-breaker-hood and returns NoUnfolding
      if so. When you want the unfolding regardless of loop-breaker-hood, 
      use Id.realIdUnfolding.
      I have not documented the flag yet, because it's experimental.  Nor
      have I tested it thoroughly.  But with the flag off (the normal case)
      everything should work.
  22. 05 Nov, 2009 1 commit
  23. 03 Nov, 2009 1 commit
  24. 29 Oct, 2009 1 commit
    • simonpj@microsoft.com's avatar
      The Big INLINE Patch: totally reorganise way that INLINE pragmas work · 72462499
      simonpj@microsoft.com authored
      This patch has been a long time in gestation and has, as a
      result, accumulated some extra bits and bobs that are only
      loosely related.  I separated the bits that are easy to split
      off, but the rest comes as one big patch, I'm afraid.
      Note that:
       * It comes together with a patch to the 'base' library
       * Interface file formats change slightly, so you need to
         recompile all libraries
      The patch is mainly giant tidy-up, driven in part by the
      particular stresses of the Data Parallel Haskell project. I don't
      expect a big performance win for random programs.  Still, here are the
      nofib results, relative to the state of affairs without the patch
              Program           Size    Allocs   Runtime   Elapsed
                  Min         -12.7%    -14.5%    -17.5%    -17.8%
                  Max          +4.7%    +10.9%     +9.1%     +8.4%
       Geometric Mean          +0.9%     -0.1%     -5.6%     -7.3%
      The +10.9% allocation outlier is rewrite, which happens to have a
      very delicate optimisation opportunity involving an interaction
      of CSE and inlining (see nofib/Simon-nofib-notes). The fact that
      the 'before' case found the optimisation is somewhat accidental.
      Runtimes seem to go down, but I never kno wwhether to really trust
      this number.  Binary sizes wobble a bit, but nothing drastic.
      The Main Ideas are as follows.
      When you say 
            {-# INLINE f #-}
            f x = <rhs>
      you intend that calls (f e) are replaced by <rhs>[e/x] So we
      should capture (\x.<rhs>) in the Unfolding of 'f', and never meddle
      with it.  Meanwhile, we can optimise <rhs> to our heart's content,
      leaving the original unfolding intact in Unfolding of 'f'.
      So the representation of an Unfolding has changed quite a bit
      (see CoreSyn).  An INLINE pragma gives rise to an InlineRule 
      Moreover, it's only used when 'f' is applied to the
      specified number of arguments; that is, the number of argument on 
      the LHS of the '=' sign in the original source definition. 
      For example, (.) is now defined in the libraries like this
         {-# INLINE (.) #-}
         (.) f g = \x -> f (g x)
      so that it'll inline when applied to two arguments. If 'x' appeared
      on the left, thus
         (.) f g x = f (g x)
      it'd only inline when applied to three arguments.  This slightly-experimental
      change was requested by Roman, but it seems to make sense.
      Other associated changes
      * Moving the deck chairs in DsBinds, which processes the INLINE pragmas
      * In the old system an INLINE pragma made the RHS look like
         (Note InlineMe <rhs>)
        The Note switched off optimisation in <rhs>.  But it was quite
        fragile in corner cases. The new system is more robust, I believe.
        In any case, the InlineMe note has disappeared 
      * The workerInfo of an Id has also been combined into its Unfolding,
        so it's no longer a separate field of the IdInfo.
      * Many changes in CoreUnfold, esp in callSiteInline, which is the critical
        function that decides which function to inline.  Lots of comments added!
      * exprIsConApp_maybe has moved to CoreUnfold, since it's so strongly
        associated with "does this expression unfold to a constructor application".
        It can now do some limited beta reduction too, which Roman found 
        was an important.
      Instance declarations
      It's always been tricky to get the dfuns generated from instance
      declarations to work out well.  This is particularly important in 
      the Data Parallel Haskell project, and I'm now on my fourth attempt,
      more or less.
      There is a detailed description in TcInstDcls, particularly in
      Note [How instance declarations are translated].   Roughly speaking
      we now generate a top-level helper function for every method definition
      in an instance declaration, so that the dfun takes a particularly
      stylised form:
        dfun a d1 d2 = MkD (op1 a d1 d2) (op2 a d1 d2) ...etc...
      In fact, it's *so* stylised that we never need to unfold a dfun.
      Instead ClassOps have a special rewrite rule that allows us to
      short-cut dictionary selection.  Suppose dfun :: Ord a -> Ord [a]
                                                  d :: Ord a
          compare (dfun a d)  -->   compare_list a d 
      in one rewrite, without first inlining the 'compare' selector
      and the body of the dfun.
      To support this
      a) ClassOps have a BuiltInRule (see MkId.dictSelRule)
      b) DFuns have a special form of unfolding (CoreSyn.DFunUnfolding)
         which is exploited in CoreUnfold.exprIsConApp_maybe
      Implmenting all this required a root-and-branch rework of TcInstDcls
      and bits of TcClassDcl.
      Default methods
      If you give an INLINE pragma to a default method, it should be just
      as if you'd written out that code in each instance declaration, including
      the INLINE pragma.  I think that it now *is* so.  As a result, library
      code can be simpler; less duplication.
      The CONLIKE pragma
      In the DPH project, Roman found cases where he had
         p n k = let x = replicate n k
                 in ...(f x)...(g x)....
         {-# RULE f (replicate x) = f_rep x #-}
      Normally the RULE would not fire, because doing so involves 
      (in effect) duplicating the redex (replicate n k).  A new
      experimental modifier to the INLINE pragma, {-# INLINE CONLIKE
      replicate #-}, allows you to tell GHC to be prepared to duplicate
      a call of this function if it allows a RULE to fire.
      See Note [CONLIKE pragma] in BasicTypes
      Join points
      See Note [Case binders and join points] in Simplify
      Other refactoring
      * I moved endPass from CoreLint to CoreMonad, with associated jigglings
      * Better pretty-printing of Core
      * The top-level RULES (ones that are not rules for locally-defined things)
        are now substituted on every simplifier iteration.  I'm not sure how
        we got away without doing this before.  This entails a bit more plumbing
        in SimplCore.
      * The necessary stuff to serialise and deserialise the new
        info across interface files.
      * Something about bottoming floats in SetLevels
            Note [Bottoming floats]
      * substUnfolding has moved from SimplEnv to CoreSubs, where it belongs
              Program           Size    Allocs   Runtime   Elapsed
                 anna          +2.4%     -0.5%      0.16      0.17
                 ansi          +2.6%     -0.1%      0.00      0.00
                 atom          -3.8%     -0.0%     -1.0%     -2.5%
               awards          +3.0%     +0.7%      0.00      0.00
               banner          +3.3%     -0.0%      0.00      0.00
           bernouilli          +2.7%     +0.0%     -4.6%     -6.9%
                boyer          +2.6%     +0.0%      0.06      0.07
               boyer2          +4.4%     +0.2%      0.01      0.01
                 bspt          +3.2%     +9.6%      0.02      0.02
            cacheprof          +1.4%     -1.0%    -12.2%    -13.6%
             calendar          +2.7%     -1.7%      0.00      0.00
             cichelli          +3.7%     -0.0%      0.13      0.14
              circsim          +3.3%     +0.0%     -2.3%     -9.9%
             clausify          +2.7%     +0.0%      0.05      0.06
        comp_lab_zift          +2.6%     -0.3%     -7.2%     -7.9%
             compress          +3.3%     +0.0%     -8.5%     -9.6%
            compress2          +3.6%     +0.0%    -15.1%    -17.8%
          constraints          +2.7%     -0.6%    -10.0%    -10.7%
         cryptarithm1          +4.5%     +0.0%     -4.7%     -5.7%
         cryptarithm2          +4.3%    -14.5%      0.02      0.02
                  cse          +4.4%     -0.0%      0.00      0.00
                eliza          +2.8%     -0.1%      0.00      0.00
                event          +2.6%     -0.0%     -4.9%     -4.4%
               exp3_8          +2.8%     +0.0%     -4.5%     -9.5%
               expert          +2.7%     +0.3%      0.00      0.00
                  fem          -2.0%     +0.6%      0.04      0.04
                  fft          -6.0%     +1.8%      0.05      0.06
                 fft2          -4.8%     +2.7%      0.13      0.14
             fibheaps          +2.6%     -0.6%      0.05      0.05
                 fish          +4.1%     +0.0%      0.03      0.04
                fluid          -2.1%     -0.2%      0.01      0.01
               fulsom          -4.8%     +9.2%     +9.1%     +8.4%
               gamteb          -7.1%     -1.3%      0.10      0.11
                  gcd          +2.7%     +0.0%      0.05      0.05
          gen_regexps          +3.9%     -0.0%      0.00      0.00
               genfft          +2.7%     -0.1%      0.05      0.06
                   gg          -2.7%     -0.1%      0.02      0.02
                 grep          +3.2%     -0.0%      0.00      0.00
               hidden          -0.5%     +0.0%    -11.9%    -13.3%
                  hpg          -3.0%     -1.8%     +0.0%     -2.4%
                  ida          +2.6%     -1.2%      0.17     -9.0%
                infer          +1.7%     -0.8%      0.08      0.09
              integer          +2.5%     -0.0%     -2.6%     -2.2%
            integrate          -5.0%     +0.0%     -1.3%     -2.9%
              knights          +4.3%     -1.5%      0.01      0.01
                 lcss          +2.5%     -0.1%     -7.5%     -9.4%
                 life          +4.2%     +0.0%     -3.1%     -3.3%
                 lift          +2.4%     -3.2%      0.00      0.00
            listcompr          +4.0%     -1.6%      0.16      0.17
             listcopy          +4.0%     -1.4%      0.17      0.18
             maillist          +4.1%     +0.1%      0.09      0.14
               mandel          +2.9%     +0.0%      0.11      0.12
              mandel2          +4.7%     +0.0%      0.01      0.01
              minimax          +3.8%     -0.0%      0.00      0.00
              mkhprog          +3.2%     -4.2%      0.00      0.00
           multiplier          +2.5%     -0.4%     +0.7%     -1.3%
             nucleic2          -9.3%     +0.0%      0.10      0.10
                 para          +2.9%     +0.1%     -0.7%     -1.2%
            paraffins         -10.4%     +0.0%      0.20     -1.9%
               parser          +3.1%     -0.0%      0.05      0.05
              parstof          +1.9%     -0.0%      0.00      0.01
                  pic          -2.8%     -0.8%      0.01      0.02
                power          +2.1%     +0.1%     -8.5%     -9.0%
               pretty         -12.7%     +0.1%      0.00      0.00
               primes          +2.8%     +0.0%      0.11      0.11
            primetest          +2.5%     -0.0%     -2.1%     -3.1%
               prolog          +3.2%     -7.2%      0.00      0.00
               puzzle          +4.1%     +0.0%     -3.5%     -8.0%
               queens          +2.8%     +0.0%      0.03      0.03
              reptile          +2.2%     -2.2%      0.02      0.02
              rewrite          +3.1%    +10.9%      0.03      0.03
                 rfib          -5.2%     +0.2%      0.03      0.03
                  rsa          +2.6%     +0.0%      0.05      0.06
                  scc          +4.6%     +0.4%      0.00      0.00
                sched          +2.7%     +0.1%      0.03      0.03
                  scs          -2.6%     -0.9%     -9.6%    -11.6%
               simple          -4.0%     +0.4%    -14.6%    -14.9%
                solid          -5.6%     -0.6%     -9.3%    -14.3%
              sorting          +3.8%     +0.0%      0.00      0.00
               sphere          -3.6%     +8.5%      0.15      0.16
               symalg          -1.3%     +0.2%      0.03      0.03
                  tak          +2.7%     +0.0%      0.02      0.02
            transform          +2.0%     -2.9%     -8.0%     -8.8%
             treejoin          +3.1%     +0.0%    -17.5%    -17.8%
            typecheck          +2.9%     -0.3%     -4.6%     -6.6%
              veritas          +3.9%     -0.3%      0.00      0.00
                 wang          -6.2%     +0.0%      0.18     -9.8%
            wave4main         -10.3%     +2.6%     -2.1%     -2.3%
         wheel-sieve1          +2.7%     -0.0%     +0.3%     -0.6%
         wheel-sieve2          +2.7%     +0.0%     -3.7%     -7.5%
                 x2n1          -4.1%     +0.1%      0.03      0.04
                  Min         -12.7%    -14.5%    -17.5%    -17.8%
                  Max          +4.7%    +10.9%     +9.1%     +8.4%
       Geometric Mean          +0.9%     -0.1%     -5.6%     -7.3%
  25. 17 Oct, 2009 1 commit
  26. 15 Oct, 2009 1 commit
  27. 14 Oct, 2009 1 commit
  28. 29 Sep, 2009 1 commit
    • Simon Marlow's avatar
      Fix some missing unfoldings (foldr in particular!) · c475d44b
      Simon Marlow authored
      The changes I made to the tidier recently introduced a serious
      regression: the unfoldings for bindings in a recursive group were
      sometimes lost, because we were looking at Id occurrences rather than
      Id binders, and the occurrences of recursive Ids do not necessarily
      have unfoldings attached.
  29. 03 Aug, 2009 1 commit
  30. 28 Jul, 2009 1 commit
    • Simon Marlow's avatar
      Be a bit more sensible about choosing external OccNames · 4fa65a12
      Simon Marlow authored
      Instead of chr_$wchr, we now just get $wchr.  In general, when an
      OccName is system-generated, we leave it out of the final external
      name, preferring to use the name of the exported parent instead (which
      is necessarily a user-written name).
      Names should be no less deterministic, but should be shorter and more
  31. 23 Jul, 2009 2 commits
  32. 20 Jul, 2009 1 commit
    • Simon Marlow's avatar
      Choose external names more predictably · fa9f1e20
      Simon Marlow authored
      Now, for a compiler-generated binding "x", if "x" is referred to by
      the exported "f", then it will be named "f_x" rather than something
      like "x23".  This means that hopefully
        - compilation will more often product the same results given the
          same input (the choice of names is not dependent on the
          non-deterministic order of bindings within the compiler).
        - less recompilation will be necessary after making changes
        - navigating Core might be a bit easier.
      unfortunately, compilation with -O still does not consistently produce
      the same ABI.  The simplifier sometimes does different things,
      Names will be longer, but I can't see a way around that.
  33. 07 Jul, 2009 1 commit
  34. 18 Mar, 2009 1 commit
    • simonpj@microsoft.com's avatar
      Add the notion of "constructor-like" Ids for rule-matching · 4bc25e8c
      simonpj@microsoft.com authored
      This patch adds an optional CONLIKE modifier to INLINE/NOINLINE pragmas, 
         {-# NOINLINE CONLIKE [1] f #-}
      The effect is to allow applications of 'f' to be expanded in a potential
      rule match.  Example
        {-# RULE "r/f" forall v. r (f v) = f (v+1) #-}
      Consider the term
           let x = f v in ..x...x...(r x)...
      Normally the (r x) would not match the rule, because GHC would be scared
      about duplicating the redex (f v). However the CONLIKE modifier says to
      treat 'f' like a constructor in this situation, and "look through" the
      unfolding for x.  So (r x) fires, yielding (f (v+1)).
      The main changes are:
        - Syntax
        - The inlinePragInfo field of an IdInfo has a RuleMatchInfo
          component, which records whether or not the Id is CONLIKE.
          Of course, this needs to be serialised in interface files too.
        - The occurrence analyser (OccAnal) and simplifier (Simplify) treat
          CONLIKE thing like constructors, by ANF-ing them
        - New function coreUtils.exprIsExpandable is like exprIsCheap, but
          additionally spots applications of CONLIKE functions
        - A CoreUnfolding has a field that caches exprIsExpandable
        - The rule matcher consults this field.  See 
          Note [Expanding variables] in Rules.lhs.
      On the way I fixed a lurking variable bug in the way variables are
      expanded.  See Note [Do not expand locally-bound variables] in
      Rule.lhs.  I also did a bit of reformatting and refactoring in
      Rules.lhs, so the module has more lines changed than are really
  35. 30 Jan, 2009 1 commit
  36. 13 Jan, 2009 1 commit
    • simonpj@microsoft.com's avatar
      Rewrite CorePrep and improve eta expansion · 62eeda5a
      simonpj@microsoft.com authored
      This patch does two main things
      a) Rewrite most of CorePrep to be much easier to understand (I hope!).
         The invariants established by CorePrep are now written out, and
         the code is more perspicuous.  It is surpringly hard to get right,
         and the old code had become quite incomprehensible.
      b) Rewrite the eta-expander so that it does a bit of simplifying
         on-the-fly, and thereby guarantees to maintain the CorePrep
         invariants.  This make it much easier to use from CorePrep, and
         is a generally good thing anyway.
      A couple of pieces of re-structuring:
      *  I moved the eta-expander and arity analysis stuff into a new
         module coreSyn/CoreArity.
         Max will find that the type CoreArity.EtaInfo looks strangely 
      *  I moved a bunch of comments from Simplify to OccurAnal; that's
         why it looks as though there's a lot of lines changed in those
      On the way I fixed various things
        - Function arguments are eta expanded
             f (map g)  ===>  let s = \x. map g x in f s
        - Trac #2368
      The result is a modest performance gain, I think mainly due
      to the first of these changes:
              Program           Size    Allocs   Runtime   Elapsed
                  Min          -1.0%    -17.4%    -19.1%    -46.4%
                  Max          +0.3%     +0.5%     +5.4%    +53.8%
       Geometric Mean          -0.1%     -0.3%     -7.0%    -10.2%
  37. 02 Jan, 2009 1 commit
    • simonpj@microsoft.com's avatar
      Make record selectors into ordinary functions · 9ffadf21
      simonpj@microsoft.com authored
      This biggish patch addresses Trac #2670.  The main effect is to make
      record selectors into ordinary functions, whose unfoldings appear in
      interface files, in contrast to their previous existence as magic
      "implicit Ids".  This means that the usual machinery of optimisation,
      analysis, and inlining applies to them, which was failing before when
      the selector was somewhat complicated.  (Which it can be when
      strictness annotations, unboxing annotations, and GADTs are involved.)
      The change involves the following points
      * Changes in Var.lhs to the representation of Var.  Now a LocalId can
        have an IdDetails as well as a GlobalId.  In particular, the
        information that an Id is a record selector is kept in the
        IdDetails.  While compiling the current module, the record selector
        *must* be a LocalId, so that it participates properly in compilation
        (free variables etc).
        This led me to change the (hidden) representation of Var, so that there
        is now only one constructor for Id, not two.
      * The IdDetails is persisted into interface files, so that an
        importing module can see which Ids are records selectors.
      * In TcTyClDecls, we generate the record-selector bindings in renamed,
        but not typechecked form.  In this way, we can get the typechecker
        to add all the types and so on, which is jolly helpful especially
        when GADTs or type families are involved.  Just like derived
        instance declarations.
        This is the big new chunk of 180 lines of code (much of which is
        commentary).  A call to the same function, mkAuxBinds, is needed in
        TcInstDcls for associated types.
      * The typechecker therefore has to pin the correct IdDetails on to 
        the record selector, when it typechecks it.  There was a neat way
        to do this, by adding a new sort of signature to HsBinds.Sig, namely
        IdSig.  This contains an Id (with the correct Name, Type, and IdDetails);
        the type checker uses it as the binder for the final binding.  This
        worked out rather easily.
      * Record selectors are no longer "implicit ids", which entails changes to
        (These three functions must agree.)
      * MkId.mkRecordSelectorId is deleted entirely, some 300+ lines (incl
        comments) of very error prone code.  Happy days.
      * A TyCon no longer contains the list of record selectors: 
        algTcSelIds is gone
      The renamer is unaffected, including the way that import and export of
      record selectors is handled.
      Other small things
      * IfaceSyn.ifaceDeclSubBndrs had a fragile test for whether a data
        constructor had a wrapper.  I've replaced that with an explicit flag
        in the interface file. More robust I hope.
      * I renamed isIdVar to isId, which touched a few otherwise-unrelated files.
  38. 16 Dec, 2008 1 commit
    • Simon Marlow's avatar
      Rollback INLINE patches · e79c9ce0
      Simon Marlow authored
      rolling back:
      Fri Dec  5 16:54:00 GMT 2008  simonpj@microsoft.com
        * Completely new treatment of INLINE pragmas (big patch)
        This is a major patch, which changes the way INLINE pragmas work.
        Although lots of files are touched, the net is only +21 lines of
        code -- and I bet that most of those are comments!
        HEADS UP: interface file format has changed, so you'll need to
        recompile everything.
        There is not much effect on overall performance for nofib, 
        probably because those programs don't make heavy use of INLINE pragmas.
                Program           Size    Allocs   Runtime   Elapsed
                    Min         -11.3%     -6.9%     -9.2%     -8.2%
                    Max          -0.1%     +4.6%     +7.5%     +8.9%
         Geometric Mean          -2.2%     -0.2%     -1.0%     -0.8%
        (The +4.6% for on allocs is cichelli; see other patch relating to
        The old INLINE system
        The old system worked like this. A function with an INLINE pragam
        got a right-hand side which looked like
             f = __inline_me__ (\xy. e)
        The __inline_me__ part was an InlineNote, and was treated specially
        in various ways.  Notably, the simplifier didn't inline inside an
        __inline_me__ note.  
        As a result, the code for f itself was pretty crappy. That matters
        if you say (map f xs), because then you execute the code for f,
        rather than inlining a copy at the call site.
        The new story: InlineRules
        The new system removes the InlineMe Note altogether.  Instead there
        is a new constructor InlineRule in CoreSyn.Unfolding.  This is a 
        bit like a RULE, in that it remembers the template to be inlined inside
        the InlineRule.  No simplification or inlining is done on an InlineRule,
        just like RULEs.  
        An Id can have an InlineRule *or* a CoreUnfolding (since these are two
        constructors from Unfolding). The simplifier treats them differently:
          - An InlineRule is has the substitution applied (like RULES) but 
            is otherwise left undisturbed.
          - A CoreUnfolding is updated with the new RHS of the definition,
            on each iteration of the simplifier.
        An InlineRule fires regardless of size, but *only* when the function
        is applied to enough arguments.  The "arity" of the rule is specified
        (by the programmer) as the number of args on the LHS of the "=".  So
        it makes a difference whether you say
          	{-# INLINE f #-}
        	f x = \y -> e     or     f x y = e
        This is one of the big new features that InlineRule gives us, and it
        is one that Roman really wanted.
        In contrast, a CoreUnfolding can fire when it is applied to fewer
        args than than the function has lambdas, provided the result is small
        Consequential stuff
        * A 'wrapper' no longer has a WrapperInfo in the IdInfo.  Instead,
          the InlineRule has a field identifying wrappers.
        * Of course, IfaceSyn and interface serialisation changes appropriately.
        * Making implication constraints inline nicely was a bit fiddly. In
          the end I added a var_inline field to HsBInd.VarBind, which is why
          this patch affects the type checker slightly
        * I made some changes to the way in which eta expansion happens in
          CorePrep, mainly to ensure that *arguments* that become let-bound
          are also eta-expanded.  I'm still not too happy with the clarity
          and robustness fo the result.
        * We now complain if the programmer gives an INLINE pragma for
          a recursive function (prevsiously we just ignored it).  Reason for
          change: we don't want an InlineRule on a LoopBreaker, because then
          we'd have to check for loop-breaker-hood at occurrence sites (which
          isn't currenlty done).  Some tests need changing as a result.
        This patch has been in my tree for quite a while, so there are
        probably some other minor changes.
          M ./compiler/basicTypes/Id.lhs -11
          M ./compiler/basicTypes/IdInfo.lhs -82
          M ./compiler/basicTypes/MkId.lhs -2 +2
          M ./compiler/coreSyn/CoreFVs.lhs -2 +25
          M ./compiler/coreSyn/CoreLint.lhs -5 +1
          M ./compiler/coreSyn/CorePrep.lhs -59 +53
          M ./compiler/coreSyn/CoreSubst.lhs -22 +31
          M ./compiler/coreSyn/CoreSyn.lhs -66 +92
          M ./compiler/coreSyn/CoreUnfold.lhs -112 +112
          M ./compiler/coreSyn/CoreUtils.lhs -185 +184
          M ./compiler/coreSyn/MkExternalCore.lhs -1
          M ./compiler/coreSyn/PprCore.lhs -4 +40
          M ./compiler/deSugar/DsBinds.lhs -70 +118
          M ./compiler/deSugar/DsForeign.lhs -2 +4
          M ./compiler/deSugar/DsMeta.hs -4 +3
          M ./compiler/hsSyn/HsBinds.lhs -3 +3
          M ./compiler/hsSyn/HsUtils.lhs -2 +7
          M ./compiler/iface/BinIface.hs -11 +25
          M ./compiler/iface/IfaceSyn.lhs -13 +21
          M ./compiler/iface/MkIface.lhs -24 +19
          M ./compiler/iface/TcIface.lhs -29 +23
          M ./compiler/main/TidyPgm.lhs -55 +49
          M ./compiler/parser/ParserCore.y -5 +6
          M ./compiler/simplCore/CSE.lhs -2 +1
          M ./compiler/simplCore/FloatIn.lhs -6 +1
          M ./compiler/simplCore/FloatOut.lhs -23
          M ./compiler/simplCore/OccurAnal.lhs -36 +5
          M ./compiler/simplCore/SetLevels.lhs -59 +54
          M ./compiler/simplCore/SimplCore.lhs -48 +52
          M ./compiler/simplCore/SimplEnv.lhs -26 +22
          M ./compiler/simplCore/SimplUtils.lhs -28 +4
          M ./compiler/simplCore/Simplify.lhs -91 +109
          M ./compiler/specialise/Specialise.lhs -15 +18
          M ./compiler/stranal/WorkWrap.lhs -14 +11
          M ./compiler/stranal/WwLib.lhs -2 +2
          M ./compiler/typecheck/Inst.lhs -1 +3
          M ./compiler/typecheck/TcBinds.lhs -17 +27
          M ./compiler/typecheck/TcClassDcl.lhs -1 +2
          M ./compiler/typecheck/TcExpr.lhs -4 +6
          M ./compiler/typecheck/TcForeign.lhs -1 +1
          M ./compiler/typecheck/TcGenDeriv.lhs -14 +13
          M ./compiler/typecheck/TcHsSyn.lhs -3 +2
          M ./compiler/typecheck/TcInstDcls.lhs -5 +4
          M ./compiler/typecheck/TcRnDriver.lhs -2 +11
          M ./compiler/typecheck/TcSimplify.lhs -10 +17
          M ./compiler/vectorise/VectType.hs +7
      Mon Dec  8 12:43:10 GMT 2008  simonpj@microsoft.com
        * White space only
          M ./compiler/simplCore/Simplify.lhs -2
      Mon Dec  8 12:48:40 GMT 2008  simonpj@microsoft.com
        * Move simpleOptExpr from CoreUnfold to CoreSubst
          M ./compiler/coreSyn/CoreSubst.lhs -1 +87
          M ./compiler/coreSyn/CoreUnfold.lhs -72 +1
      Mon Dec  8 17:30:18 GMT 2008  simonpj@microsoft.com
        * Use CoreSubst.simpleOptExpr in place of the ad-hoc simpleSubst (reduces code too)
          M ./compiler/deSugar/DsBinds.lhs -50 +16
      Tue Dec  9 17:03:02 GMT 2008  simonpj@microsoft.com
        * Fix Trac #2861: bogus eta expansion
        Urghlhl!  I "tided up" the treatment of the "state hack" in CoreUtils, but
        missed an unexpected interaction with the way that a bottoming function
        simply swallows excess arguments.  There's a long
             Note [State hack and bottoming functions]
        to explain (which accounts for most of the new lines of code).
          M ./compiler/coreSyn/CoreUtils.lhs -16 +53
      Mon Dec 15 10:02:21 GMT 2008  Simon Marlow <marlowsd@gmail.com>
        * Revert CorePrep part of "Completely new treatment of INLINE pragmas..."
        The original patch said:
        * I made some changes to the way in which eta expansion happens in
          CorePrep, mainly to ensure that *arguments* that become let-bound
          are also eta-expanded.  I'm still not too happy with the clarity
          and robustness fo the result.
        Unfortunately this change apparently broke some invariants that were
        relied on elsewhere, and in particular lead to panics when compiling
        with profiling on.
        Will re-investigate in the new year.
          M ./compiler/coreSyn/CorePrep.lhs -53 +58
          M ./configure.ac -1 +1
      Mon Dec 15 12:28:51 GMT 2008  Simon Marlow <marlowsd@gmail.com>
        * revert accidental change to configure.ac
          M ./configure.ac -1 +1