[GHC] #10526: Overlapping instances, incoherence, and optimisation
GHC
ghc-devs at haskell.org
Mon Jun 15 09:22:09 UTC 2015
#10526: Overlapping instances, incoherence, and optimisation
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.10.1
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: None/Unknown | Unknown/Multiple
Blocked By: | Test Case:
Related Tickets: | Blocking:
| Differential Revisions:
-------------------------------------+-------------------------------------
Description changed by simonpj:
Old description:
> Segei Meshveliani reports that his `docon` library has rather unexpected
> behaviour with GHC 7.10. See [https://mail.haskell.org/pipermail
> /glasgow-haskell-users/2015-May/025916.html his email].
>
> The effect is that his test module `Main` has different runtime behaviour
> when compiling with and without `-O`. This sounds pretty bad.
>
> The reason is this:
> * He has overlapping instances for a class, say
> * `instance ... => C (T a)`, call it (A)
> * `instance C (T Int)`, call it (B)
> The actual situation is more complicated of course
>
> * The instances are defined in different modules.
>
> * In one module `Spec`
> * instance (B) is not visible
> * there is a function `f :: C a => a -> a`
> * `f` is called at type `T Int`.
> So GHC specialises `f`, to `f_spec :: T Int -> T Int`, and exports a
> RULE
> {{{
> RULE "SPEC" f = f_spec :: T Int -> T Int
> }}}
> The idea is that any other module that calls `f` at type `T Int` can
> simply re-use the specialised (and presumably much faster) version of
> `f`.
> `C (T Int)` but (B) is not visible, so GHC finds a solution using (A).
>
> * In another module, `Use`, which ''can'' see (B), we call `f` at type
> `T Int`. In the absence of the cross-module specialisation rule, or
> without `-O`, GHC would solve the constraint `C (T Int)`, this time using
> (B). But because of the rule, with `-O`, it re-uses `f_spec`. Result:
> different runtime behaviour.
>
> There is a more detailed discussion on
> [https://mail.haskell.org/pipermail/glasgow-haskell-
> users/2015-June/025970.html this thread].
>
> Files to reproduce.
New description:
Segei Meshveliani reports that his `docon` library has rather unexpected
behaviour with GHC 7.10. See [https://mail.haskell.org/pipermail/glasgow-
haskell-users/2015-May/025916.html his email].
The effect is that his test module `Main` has different runtime behaviour
when compiling with and without `-O`. This sounds pretty bad.
The reason is this:
* He has overlapping instances for a class, say
* `instance ... => C (T a)`, call it (A)
* `instance C (T Int)`, call it (B)
The actual situation is more complicated of course
* The instances are defined in different modules.
* In one module `Spec`
* instance (B) is not visible
* there is a function `f :: C a => a -> a`
* `f` is called at type `T Int`.
So GHC specialises `f`, to `f_spec :: T Int -> T Int`, and exports a RULE
{{{
RULE "SPEC" f = f_spec :: T Int -> T Int
}}}
The idea is that any other module that calls `f` at type `T Int` can
simply re-use the specialised (and presumably much faster) version of `f`.
But note that since (B) is not visible, so GHC finds a solution using (A),
and embodies that in `f_spec`.
* In another module, `Use`, which ''can'' see (B) and `Spec`, we call `f`
at type `T Int`. In the absence of the cross-module specialisation rule,
or without `-O`, GHC would solve the constraint `C (T Int)`, this time
using (B). But because of the rule, with `-O`, it re-uses `f_spec`.
Result: different runtime behaviour.
There is a more detailed discussion on [https://mail.haskell.org/pipermail
/glasgow-haskell-users/2015-June/025970.html this thread].
Files to reproduce.
--
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10526#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list