GHC Trac Home
GHC Git Repos
Working on GHC
Mailing Lists & IRC
The GHC Team
All Feature Req's
Tickets I Created
Patches for review
New Feature Req
side by side
lines around each change
Show the changes in full context
White space changes
Jul 23, 2009 1:22:20 PM (
(Correctly triggering recompilation when packages change was one of the things we fixed when implementing fingerprints, see #1372).
== Interface stability ==
For recompilation avoidance to be really effective, we need to ensure that fingerprints do not change unnecessarily. That is, if a module is modified, it should be the case that the only fingerprints that change are related to the parts of the module that were modified. This may seem obvious, but it's surprisingly easy to get wrong. Here are some of the ways we got it wrong in the past, and some ways we still get it wrong.
* Prior to GHC 6.12, dictionary functions were named something like `M.$f23`, where `M` is the module defining the instance, and the number `23` was generated by simply assigning numbers to the dictionary functions defined by `M` sequentially. This is a problem for recompilation avoidance, because now removing or adding an instance in `M` will change the numbering, and force recompilation of anything that depends on any instance in `M`. Worse, the numbers are assigned non-deterministically, so simply recompiling `M` without changing its code could change the fingerprints. In GHC 6.12 we changed it so that dictionary functions are named after the class and type(s) of the instance, e.g. `M.$fOrdInteger`.
* compiler-generated bindings used to be numbered in the same way, non-deterministically. The non-determinism arises because Uniques are assigned by the compiler non-deterministically. Well, they are deterministic but not in a way that you can sensibly control, because it depends on the order in which interface bindings are read, etc. Internal mappings use Uniques as the key, so asking for the elements of a mapping gives a non-deterministic ordering. The list of bindings emitted by the simplifier, although in dependency order, can vary non-deterministically within the constraints of the dependencies. So if we number the compiler-generated bindings sequentially, the result will be a non-deterministic ABI.
In GHC 6.12 we changed this so that compiler-generated bindings are given names of the form `f_x`, where `f` is the name of the exported Id that refers to the binding. If there are multiple `f_x`s, then they are disambiguated with an integer suffix, but the numbers are assigned deterministically, by traversing the definition of `f` in depth-first left-to-right order to find references. See `TidyPgm.chooseExternalIds`.
* There are still some cases where an interface can change without changing the source code. Here are the ones I know about
* The `spec_ids` (specialised Ids) attached to an Id have a non-deterministic ordering
* CSE can give different results depending on the order in which the bindings are considered, and since the ordering is
non-deterministic, the result of CSE is also non-deterministic. e.g. in `x = z; y = z; z = 3`, where `y` and `x` are
exported, we can end up with either `x = y; y = 3` or `y = x; x = 3`.