Improve performance of Simplify.simplCast
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 ... @tnwe will call
pushCoTyArgntimes, and hence doesnsingleton substitutions, via thencalls topiResultTy.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
pushCoTyArgand friends, and I have a very simple solution: just move theisReflexiveCocase inaddCoerce(a local function withinSimplify.simplCast) to the top. That should do it. ThenpushCoTyArgis never called with a reflexive coercion, and so thepiResultTycase won't happen.Now,
pushCoArgsmight still callpushCoTyArgwith a reflexive coercion, but it can be taught not to as well: HavepushCoArgsreturn aMaybe ([CoreArg], Maybe Coercion)andpushCoArgreturn aMaybe (CoreArg, Maybe Coercion). If the second return values areNothing, that means that there is no cast (i.e., that the cast would have been reflexive). The only client ofpushCoArg(s)isexprIsConApp_maybe, which simply omits a cast ifpushCoArgsreturnsNothing. Then, we never have to bother creating the reflexive coercions.This should be an easy win all around.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.2.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | goldfire, simonpj, tdammers |
| Operating system | |
| Architecture |