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

GHC ghc-devs at haskell.org
Tue Jan 30 07:41:18 UTC 2018


#14737: Improve performance of Simplify.simplCast
-------------------------------------+-------------------------------------
           Reporter:  tdammers       |             Owner:  (none)
               Type:  bug            |            Status:  new
           Priority:  normal         |         Milestone:
          Component:  Compiler       |           Version:  8.2.2
           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):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 Splitting off task 3 from #11735. When compiling
 [https://ghc.haskell.org/trac/ghc/attachment/ticket/14683/Grammar.hs],
 `simplCast` eats up more execution time than we think it should.

 From [https://ghc.haskell.org/trac/ghc/ticket/11735#comment:10]:

 > Something is clearly wrong with `Simplify.simplCast`.  I think I know
 what it is.  Given
 > {{{
 > (fun |> co) @t1 @t2 ... @tn
 > }}}
 >   we will call `pushCoTyArg` `n` times, and hence does `n` singleton
 substitutions, via the `n` calls to `piResultTy`.
 >
 >   Solution: gather up those type arguments (easy) and define
 > {{{
 > pushCoTyArgs :: Coercion -> [Type] -> Maybe ([Type], Coercion)
 > }}}

 And [https://ghc.haskell.org/trac/ghc/ticket/11735#comment:41]:

 > OK. I looked at `pushCoTyArg` and friends, and I have a very simple
 solution: just move the `isReflexiveCo` case in `addCoerce` (a local
 function within `Simplify.simplCast`) to the top. That should do it. Then
 `pushCoTyArg` is never called with a reflexive coercion, and so the
 `piResultTy` case won't happen.
 >
 > Now, `pushCoArgs` might still call `pushCoTyArg` with a reflexive
 coercion, but it can be taught not to as well: Have `pushCoArgs` return a
 `Maybe ([CoreArg], Maybe Coercion)` and `pushCoArg` return a `Maybe
 (CoreArg, Maybe Coercion)`. If the second return values are `Nothing`,
 that means that there is no cast (i.e., that the cast would have been
 reflexive). The only client of `pushCoArg(s)` is `exprIsConApp_maybe`,
 which simply omits a cast if `pushCoArgs` returns `Nothing`. Then, we
 never have to bother creating the reflexive coercions.
 >
 > This should be an easy win all around.

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


More information about the ghc-tickets mailing list