[GHC] #11196: TypeInType performance regressions
GHC
ghc-devs at haskell.org
Wed Mar 23 16:20:51 UTC 2016
#11196: TypeInType performance regressions
-------------------------------------+-------------------------------------
Reporter: goldfire | Owner:
Type: bug | Status: new
Priority: high | Milestone: 8.0.2
Component: Compiler | Version: 7.11
Resolution: | Keywords: TypeInType
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by goldfire):
I had a thought while falling asleep last night about what may be causing
all of this.
Previously, `Type` had a constructor `FunTy :: Type -> Type -> Type`. Now,
the situation is more complex, with a `TyBinder`:
{{{#!hs
data Type = ... | ForAllTy TyBinder Type | ...
data TyBinder = Named TyVar VisibilityFlag | Anon Type
}}}
What was `FunTy arg res` is now `ForAllTy (Anon arg) res`. But this
refactoring means that we have an extra box for ''every'' function type.
And there are a lot of those. Chasing all of these boxes might mean that
everything goes just a bit slower... which is exactly what I've observed.
This refactoring was not forced by `TypeInType`, but Simon and I thought
it to be a good idea. It does simplify things in a bunch of places. It
could be undone -- somewhat labor-intensive, but not theoretically hard.
Even better would be to have unboxed and unpacked sums, which would allow
GHC to inline `TyBinder` into `Type`. It also might be possible to
simulate unboxed and unpacked sums through something like this:
{{{#!hs
data Type = ...
| ForAllTyNamed TyVar VisibilityFlag Type
| ForAllTyAnon Type Type
| ...
repSplitForAllTy :: Type -> Maybe (TyBinder, Type)
repSplitForAllTy (ForAllTyNamed tv vis ty) = Just (Named tv vis, ty)
repSplitForAllTy (ForAllTyAnon arg res) = Just (Anon arg, res)
repSplitForAllTy _ = Nothing
pattern ForAllTy :: TyBinder -> Type -> Type
pattern ForAllTy bndr ty <- (repSplitForAllTy -> Just (bndr, ty))
where
ForAllTy (Named tv vis) ty = ForAllTyNamed tv vis ty
ForAllTy (Anon arg) res = ForAllTyAnon arg res
}}}
With these definitions, it would seem you could use `ForAllTy` just as it
is done now. And my guess is that matching against, say `(ForAllTy (Anon
arg) res) -> ...`, as is done somewhat frequently, would induce GHC to
inline all of the splitting and matching (and allocation of the very-
temporary `TyBinder`). That would need to be tested. But perhaps this is
the answer to our woes.
If it's performant, this would also be a good recipe to disseminate to
people clamoring for unboxed, unpackable sums. With the forthcoming
support for pattern synonyms in TH (not for 8.0! but likely for 8.2), this
might even be possible to automate and implement unpacked sums in TH until
GHC can support them for real.
I won't be testing this anytime soon, sadly. Perhaps someone else can in
time for 8.0.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11196#comment:14>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list