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

GHC ghc-devs at haskell.org
Thu Mar 29 07:51:08 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 tdammers):

 Preliminary result: digging into `simplCast` some deeper, one of the
 biggest contributors is the call to `isReflexiveCo`. By rewriting it from
 this:

 {{{
 isReflexiveCo = isJust . isReflexiveCo_maybe
 }}}

 ...to this:
 {{{
 isReflexiveCo (Refl {}) = True
 isReflexiveCo co = eqType ty1 ty2
   where Pair ty1 ty2 = coercionKind co
 }}}

 ...cuts execution time for compiling `Grammar.hs` down from 20 seconds to
 12.

 For reference, isReflexiveCo_maybe is defined as:
 {{{
 isReflexiveCo_maybe (Refl r ty) = Just (ty, r)
 isReflexiveCo_maybe co
   | ty1 `eqType` ty2
   = Just (ty1, r)
   | otherwise
   = Nothing
   where (Pair ty1 ty2, r) = coercionKindRole co
 }}}

 So we're really just replicating the logic here, with two differences that
 seem to improve performance drastically:

 - We skip calculating the role, using `coercionKind` rather than
 `coercionKindRole`.
 - Instead of `Maybe`, we use boolean logic directly, since we are not
 interested in the actual roles and types, we just want to know if there
 are any.

 In theory, neither of these should matter, because the expensive
 calculations should mostly just thunk up and never get evaluated, but we
 still see a huge improvement. So this could be due to one or more of the
 following:

 - We might evaluate more deeply into `coercionKindRole` than expected
 - The boolean logic might unbox and optimize into more efficient code
 requiring fewer allocations
 - `coercionKindRole` could have some unexpected inefficiencies compared to
 `coercionKind`
 - Writing it like this might lead to more beneficial inlining behavior

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


More information about the ghc-tickets mailing list