[GHC] #14737: Improve performance of Simplify.simplCast

GHC ghc-devs at haskell.org
Tue Apr 3 22:02:51 UTC 2018


#14737: Improve performance of Simplify.simplCast
-------------------------------------+-------------------------------------
        Reporter:  tdammers          |                Owner:  (none)
            Type:  bug               |               Status:  patch
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.2.2
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Compile-time      |  Unknown/Multiple
  performance bug                    |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #11735 #14683     |  Differential Rev(s):  Phab:D4385
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 >  Interestingly, the coercion optimizer will not work on InstCo ... (Refl
 ...).

 At first I disagreed.  The first equation for `opt_co4` is this
 {{{
 opt_co4 env sym rep r (InstCo co1 arg)
     -- forall over type...
   | Just (tv, kind_co, co_body) <- splitForAllCo_maybe co1
   = opt_co4_wrap (extendLiftingContext env tv
                     (arg' `mkCoherenceRightCo` mkSymCo kind_co))
                  sym rep r co_body
 }}}
 If `arg` is `Refl` then `kind_co` is also `Refl`, so `mkCoherenceRightCo`
 is a no-op.  So the argument to `extendLiftingContext` is `Refl`; and it
 looks like this
 {{{
 extendLiftingContext (LC subst env) tv (Refl _ ty)
   = LC (extendTvSubst subst tv ty) env
 }}}
 That is, it just extends the `TvSubst`.  And that looks exactly what
 happens in `mkInstCo`.  So I think that `opc_co4` does in fact do exactly
 the same.  But perhaps spotting a `Refl` argument would be a bit more
 direct?

 Meanwhile
 * I agree that `kind_co` should be substituted.  But how?  By calling
 `ope_co4` on it?  Or `opt_co3`?  I don't understand the hierarchy of
 `opt_co` functions.
 * I find that code for `extendLiftingContext` hard to grok.  In the `Refl`
 case we extend the `TvSubst`; otherwise we extend the `LiftCoEnv`.   Very
 mysterious.  I looked at it a bit, but got lost in the deeply cryptic
 `liftEnvSubst`.

 Returning to the main event, however, I agree we won't get an efficient
 substitution, because in the example in comment:13 the
 `splitForAllCo_maybe` will fail -- because `co1` is another `InstCo`!
 What we need, as usual, is to accumulate those arguments in a list; then
 in the middle we should find a stack of `ForAllCo`s; and we can extend the
 substitution as we pair them up.  Would that be right?   Perhaps that's
 why Tobias saw no improvement -- though I'm a bit surprised that it got a
 lot worse.


 >  opt_co4 uses splitForAllCo_maybe, which doesn't look for Refls. Perhaps
 it should.

 You mean that `Refl (forall a. ty)` can be regarded as a form of
 `ForAllCo`?  Especially since `mkForAllCo` goes to some trouble to build a
 `Refl` if it can.  So surely yes, `splitForAllCo_maybe` should split a
 `Refl (forall a.ty)`.

 > The only way InstCos can come into being is in the coercion optimizer.
 There is no call to mkInstCo beyond it. So perhaps we can take that into
 account when designing these functions.

 Not true: `pushCoTyArg` calls `mkInstCo`; that's where this entire
 conversation started!  And I don't know what it means to "take it into
 account"

 Things to do
 * Fix the missing substitution in `opt_co4`
 * Fix `splitForAllCo_maybe`
 * Fix `opt_co4` to behave well on deeply nsted `InstCos`
 Might you do these -- you are more likely to get them right than me.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14737#comment:16>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list