[GHC] #12791: Superclass methods could be more aggressively specialised.
GHC
ghc-devs at haskell.org
Wed Dec 7 20:21:02 UTC 2016
#12791: Superclass methods could be more aggressively specialised.
-------------------------------------+-------------------------------------
Reporter: mpickering | Owner: danharaj
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.0.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: #5835 | Differential Rev(s): Phab:D2714
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by danharaj):
#5835 is indeed related and my patch resolves it too.
However, my patch causes a regression in #10359.
The core has bad bits that all look similar to this:
{{{
main6
main6 =
\ ds ->
case ds of _ { Box ds1 ds2 ->
case ds1 main7 main_number ds2 of dt { D# ipv ->
Box
(\ @ dum $d(%,%) -> ds1 ($p1(%,%) $d(%,%), $p2(%,%) $d(%,%))) dt
}
}
}}}
The issue is caused by the fact that the `Box` constructor has a local
tuple constraint:
{{{#!hs
type Numerical a = (Fractional a, Real a)
data Box a = Box
{ func :: forall dum. (Numerical dum) => dum -> a -> a
, obj :: !a }
}}}
When code that unpacks `Box` and uses its local constraint to do some
stuff, the solver needs to produce the tuple constraint. A tuple
constraint is implemented as a class with its components as superclasses.
The solution with my current patch goes like:
{{{
runStage interact with inerts {
workitem = [W] $d(%,%) :: (Fractional num[sk],
Real num[sk]) (CDictCan(psc))
updSolvedSetTcs: [W] $d(%,%) :: (Fractional num[sk], Real num[sk])
newWantedEvVar/cache hit [G] $dFractional :: Fractional num[sk]
newWantedEvVar/cache hit [G] $dReal :: Real num[sk]
addTcEvBind
a2bg
[W] $d(%,%)
= C:(%,%) @[Fractional num[sk], Real num[sk]]
[$dFractional, $dReal]
end stage interact with inerts }
}}}
The old, unpatched solution goes like:
{{{
runStage interact with inerts {
workitem = [W] $d(%,%) :: (Fractional dum[sk],
Real dum[sk]) (CDictCan(psc))
addTcEvBind
a1Tk
[W] $d(%,%) = $d(%,%)
end stage interact with inerts }
}}}
The old solution just uses the tuple constraint we are given. The new
solution is trying to be too smart: It tries to solve from the top-level
instance and it can do so because the solver has decomposed the given
tuple constraint into given constraints of its components. So we end up
constructing a dictionary that is essentially the same as a given one.
Bad!
It's not clear to me how to exclude corner cases like this. It is
potentially possible that we *do* want to try to solve a tuple constraint
from instances because we might be able to find a more concrete solution
to one of its components. Is it possible to notice this inefficiency in a
core2core pass and resolve it then instead?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12791#comment:27>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list