[GHC] #15019: Fix performance regressions from #14737

GHC ghc-devs at haskell.org
Wed Apr 25 06:27:00 UTC 2018


#15019: Fix performance regressions from #14737
-------------------------------------+-------------------------------------
        Reporter:  tdammers          |                Owner:  tdammers
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:  8.6.1
       Component:  Compiler          |              Version:
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Compile-time      |  Unknown/Multiple
  performance bug                    |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #14737            |  Differential Rev(s):  phab:D4568
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by tdammers):

 Replying to [comment:5 simonpj]:
 > Eh? The code you give doesn't look like a coercion.  It looks like a
 type, or a pair of types.  I must be misunderstanding.

 Sorry about that, didn't realize that this was misleading without the
 relevant context.

 So we have this code here:

 {{{
 pushCoTyArg co ty
   | isReflCo co
   = Just (ty, Nothing)

   -- The following is inefficient - don't do `eqType` here, the coercion
   -- optimizer will take care of it. See Trac #14737.
   | tyL `eqType` tyR
   = pprTrace "eqType fired: " (ppr (tyL, tyR)) $ -- <- this is where we're
 doing the trace logging
     Just (ty, Nothing)

   | isForAllTy tyL
   = ASSERT2( isForAllTy tyR, ppr co $$ ppr ty )
     Just (ty `mkCastTy` mkSymCo co1, Just co2)

   | otherwise
   = Nothing
   where
     Pair tyL tyR = coercionKind co
        -- co :: tyL ~ tyR
        -- tyL = forall (a1 :: k1). ty1
        -- tyR = forall (a2 :: k2). ty2
 }}}

 So the two types we see in this log are `tyL` and `tyR`, calculated using
 `coercionKind co`. And our goal is to find a drop-in replacement for
 `isReflCo` that detects most of the coercions that hit the `eqType` guard
 right now, but is significantly cheaper than `eqType` (and `coercionKind`
 / `coercionKindRole`).

 It may become less confusing if we dump the actual coercion too:

 {{{
 pushCoTyArg co ty
   | isReflCo co
   = Just (ty, Nothing)

   -- The following is inefficient - don't do `eqType` here, the coercion
   -- optimizer will take care of it. See Trac #14737.
   | tyL `eqType` tyR
   = pprTrace "eqType fired: " (ppr (co, tyL, tyR)) $
     Just (ty, Nothing)
 }}}

 This gives us output like the following:
 {{{
 eqType fired:
   (Sym (N:GQuu[0] <K1 R Bool>_N) ; N:GQuu[0] <K1 R Bool>_N,
    forall a. K1 R Bool a -> [String] -> [String],
    forall a. K1 R Bool a -> [String] -> [String])
 }}}

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


More information about the ghc-tickets mailing list