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 ... @tn
we will call
pushCoTyArg
n
times, and hence doesn
singleton substitutions, via then
calls 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
pushCoTyArg
and friends, and I have a very simple solution: just move theisReflexiveCo
case inaddCoerce
(a local function withinSimplify.simplCast
) to the top. That should do it. ThenpushCoTyArg
is never called with a reflexive coercion, and so thepiResultTy
case won't happen.Now,
pushCoArgs
might still callpushCoTyArg
with a reflexive coercion, but it can be taught not to as well: HavepushCoArgs
return aMaybe ([CoreArg], Maybe Coercion)
andpushCoArg
return 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 ifpushCoArgs
returnsNothing
. 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 |