[GHC] #12724: Be lazier about reducing type-function applications
GHC
ghc-devs at haskell.org
Mon Oct 17 21:01:39 UTC 2016
#12724: Be lazier about reducing type-function applications
-------------------------------------+-------------------------------------
Reporter: simonpj | Owner:
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: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by goldfire):
Here is the basic idea we had: keep `CFunEqCan`s in a lower-priority wing
of the work-list, and then solve them only when necessary.
When we see a type function application like `F 20` in a type, we
''flatten'' it to produce a flatten-unification-variable, fuv, and a
constraint `[W] F 20 ~ fuv`. It is this constraint that would be de-
prioritized. If the program can be type-checked without ever solving the
`CFunEqCan`, then we do not need to reduce the type function.
When a `CFunEqCan` comes up as the work item, we try to solve it only if
it is ''active''. An ''active'' `CFunEqCan` involves an fuv that:
1. Is an argument to the class in an inert class constraint, OR
2. Is an argument to the type family in an active `CFunEqCan`, OR
3. Is at the top level of an inert equality
If a `CFunEqCan` is not active (that is, if it's ''passive''), then just
throw it right into the inert set without trying to solve. The inert set
will have a new place to store passive `CFunEqCan`s; if it were to become
active (by one of the conditions above becoming satisfied), then it must
get kicked out.
We think that an efficient way of implementing this scheme is by reference
counting, essentially, where each fuv is mapped (in some data structure in
the `TcSEnv`) to a count of places where it is active. When the count
drops to zero, the associated `CFunEqCan` becomes passive. We would then
have to increment and decrement counters when adding to and kicking out
from the inert set.
Note that we have to be careful to making the refcount wibbles as
efficient as possible, because they will happen a lot. For example, we
can't just get the free variables of a constraint and then look for fuvs,
as that would allocate space to store the fv set. Instead, we must write a
new function that extracts only fuvs.
It remains to be seen if this will be a real performance improvement, as
there will be a cost everyone has to pay to speed up the type family case.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12724#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list