Changes between Version 19 and Version 20 of Commentary/Compiler/RecompilationAvoidance


Ignore:
Timestamp:
Dec 2, 2010 12:21:53 PM (5 years ago)
Author:
simonmar
Comment:

change description of instances following fix for #4469

Legend:

Unmodified
Added
Removed
Modified
  • Commentary/Compiler/RecompilationAvoidance

    v19 v20  
    434434depends on, and hence will trigger recompilation. 
    435435 
    436 This is perfectly safe, but implementing it exactly as described above 
    437 would lead to unnecessary recompilation.  For example 
     436In fact, we don't need to include the instance itself when fingerprinting C or T, it is enough to include the DFun (dictionary function) Id, since the type of this Id includes the form of the instance.  Furthermore, we ''must'' include the DFun anway, because we must have a dependency on the dictionary and its methods, just in case they are inlined in a client module.  A DFun looks something like this: 
     437 
     438{{{ 
     439c3e94597bf9a532e094067b08c216493 
     440  $fEqBool :: GHC.Base.Eq GHC.Bool.Bool 
     441    {- HasNoCafRefs Strictness: m 
     442       Unfolding: (GHC.Base.:DEq @ GHC.Bool.Bool GHC.Base.==2 
     443       GHC.Base.$s$dm/=1) 
     444}}} 
     445 
     446Making a type or class depend on its instances can cause a lot of recompilation when an instance changes.  For example: 
    438447 
    439448{{{ 
     
    444453}}} 
    445454 
    446 now the instance `C T` will be attached to `T`.  But we really don't 
    447 want to include `C`'s fingerprint in `T`'s fingerprint, because that would 
    448 register an unnecessary dependency of `T` on `C`: every time `C` 
    449 changed, we'd recompile anything that depended on `T`.  The dependency 
    450 is unnecessary, because we know anything that needs the instance will 
    451 already depend on both `C` and `T`. 
    452  
    453 So instead of creating a fingerprint that depends on the instance 
    454 declaration and everything it mentions, we fingerprint ''just the 
    455 declaration itself''.  This works by fingerprinting each name in the 
    456 declaration as its literal string, rather than the fingerprint of the 
    457 name. 
    458  
    459 But what about the ''contents'' of the instance declaration?  With 
    460 optimisation on, the compiler may inline instances and their methods, 
    461 so if an instance changes we need to trigger recompilation for any 
    462 module that actually used the previous version of the instance.  This 
    463 works as follows.  An instance declaration looks like this 
    464  
    465 {{{ 
    466 instance GHC.Base.Eq [GHC.Bool.Bool] = GHC.Base.$f10 
    467 }}} 
    468  
    469 Here `GHC.Base.$f10` is the "dictionary function", i.e. the value 
    470 representing this dictionary.  `GHC.Base.$f10` has a declaration of 
    471 its own, in the same interface, complete with a fingerprint. 
    472  
    473 {{{ 
    474 c3e94597bf9a532e094067b08c216493 
    475   $f10 :: GHC.Base.Eq GHC.Bool.Bool 
    476     {- HasNoCafRefs Strictness: m 
    477        Unfolding: (GHC.Base.:DEq @ GHC.Bool.Bool GHC.Base.==2 
    478        GHC.Base.$s$dm/=1) 
    479 }}} 
    480  
    481 So we ensure that any module that used this instance registers the 
    482 fingerprint of `GHC.Base.$f10` in its usages (this is the single 
    483 exception to the rule that the usages only contains names that are 
    484 explicitly mentioned in the source file). 
     455now the DFun for the instance `C T` will be attached to `T`, and so `T`'s fingerprint will change when anything about the instance changes, including `C` itself.  So there is now have a dependency of `T` on `C`, which can cause a lot of recompilation whenever `C` changes.  Modules using `T` who do not care about `C` will still be recompiled. 
     456 
     457This seems like it would cause a lot of unnecessary recompilation.  Indeed, in GHC 7.0.1 and earlier we tried to optimise this case, by breaking the dependency of `T` on `C` and tracking usages of DFuns directly - whenever a DFun was used, the typechecker would record the fact, and a usage on the DFun would be recorded in the interface file.  Unfortunately, there's a bug in this plan (see #4469).  When we're using `make`, we only recompile a module when any of the interfaces that it directly imports have changed; but a DFun dependency can refer to any module, not just the directly imported ones.  Instead, we have to ensure that if an instance related to a particular type or class has changed, then the fingerprint on either the type or class changes, which is what the current plan does.  It would be nice to optimise this in a safe way, and maybe in the future we will be able to do that. 
    485458 
    486459=== Orphans ===