From: simonpj@microsoft.com Date: Mon, 7 Dec 2009 08:04:42 +0000 (+0000) Subject: Comments only, about RULE plumbing X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=5c61fd637c1f3f47cddb523b33be95baa29716eb Comments only, about RULE plumbing --- diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs index 4568756..f424089 100644 --- a/compiler/main/HscTypes.lhs +++ b/compiler/main/HscTypes.lhs @@ -978,9 +978,7 @@ data ModGuts mg_insts :: ![Instance], -- ^ Class instances declared in this module mg_fam_insts :: ![FamInst], -- ^ Family instances declared in this module mg_rules :: ![CoreRule], -- ^ Before the core pipeline starts, contains - -- rules declared in this module. After the core - -- pipeline starts, it is changed to contain all - -- known rules for those things imported + -- See Note [Overall plumbing for rules] in Rules.lhs mg_binds :: ![CoreBind], -- ^ Bindings for this module mg_foreign :: !ForeignStubs, -- ^ Foreign exports declared in this module mg_warns :: !Warnings, -- ^ Warnings declared in the module diff --git a/compiler/main/TidyPgm.lhs b/compiler/main/TidyPgm.lhs index 6a9f0dd..eefdd2d 100644 --- a/compiler/main/TidyPgm.lhs +++ b/compiler/main/TidyPgm.lhs @@ -310,6 +310,8 @@ tidyProgram hsc_env (ModGuts { mg_module = mod, mg_exports = exports, binds implicit_binds imp_rules ; let { ext_rules = findExternalRules omit_prags binds imp_rules unfold_env } + -- Glom together imp_rules and rules currently attached to binders + -- Then pick just the ones we need to expose -- See Note [Which rules to expose] ; let { (tidy_env, tidy_binds) diff --git a/compiler/simplCore/SimplCore.lhs b/compiler/simplCore/SimplCore.lhs index 17132e5..f26575b 100644 --- a/compiler/simplCore/SimplCore.lhs +++ b/compiler/simplCore/SimplCore.lhs @@ -85,6 +85,7 @@ core2core hsc_env guts = do let (cp_us, ru_us) = splitUniqSupply us -- COMPUTE THE RULE BASE TO USE + -- See Note [Overall plumbing for rules] in Rules.lhs (hpt_rule_base, guts1) <- prepareRules hsc_env guts ru_us -- Get the module out of the current HscEnv so we can retrieve it from the monad. @@ -541,6 +542,7 @@ simplifyPgmIO mode switches hsc_env us hpt_rule_base (pprCoreBindings tagged_binds); -- Get any new rules, and extend the rule base + -- See Note [Overall plumbing for rules] in Rules.lhs -- We need to do this regularly, because simplification can -- poke on IdInfo thunks, which in turn brings in new rules -- behind the scenes. Otherwise there's a danger we'll simply diff --git a/compiler/specialise/Rules.lhs b/compiler/specialise/Rules.lhs index 90485d0..5bd22a1 100644 --- a/compiler/specialise/Rules.lhs +++ b/compiler/specialise/Rules.lhs @@ -57,6 +57,71 @@ import Data.List \end{code} +Note [Overall plumbing for rules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* The ModGuts initially contains mg_rules :: [CoreRule] of rules + declared in this module. During the core-to-core pipeline, + locally-declared rules for locally-declared Ids are attached to the + IdInfo for that Id, so the mg_rules field of ModGuts now only + contains locally-declared rules for *imported* Ids. TidyPgm restores + the original setup, so that the ModGuts again has *all* the + locally-declared rules. See Note [Attach rules to local ids] in + SimplCore + +* The HomePackageTable contains a ModDetails for each home package + module. Each contains md_rules :: [CoreRule] of rules declared in + that module. The HomePackageTable grows as ghc --make does its + up-sweep. In batch mode (ghc -c), the HPT is empty; all imported modules + are treated by the "external" route, discussed next, regardless of + which package they come from. + +* The ExternalPackageState has a single eps_rule_base :: RuleBase for + Ids in other packages. This RuleBase simply grow monotonically, as + ghc --make compiles one module after another. + + During simplification, interface files may get demand-loaded, + as the simplifier explores the unfoldings for Ids it has in + its hand. (Via an unsafePerformIO; the EPS is really a cache.) + That in turn may make the EPS rule-base grow. In contrast, the + HPT never grows in this way. + +* The result of all this is that during Core-to-Core optimisation + there are four sources of rules: + + (a) Rules in the IdInfo of the Id they are a rule for. These are + easy: fast to look up, and if you apply a substitution then + it'll be applied to the IdInfo as a matter of course. + + (b) Rules declared in this module for imported Ids, kept in the + ModGuts. If you do a substitution, you'd better apply the + substitution to these. There are seldom many of these. + + (c) Rules declared in the HomePackageTable. These never change. + + (d) Rules in the ExternalPackageTable. These can grow in response + to lazy demand-loading of interfaces. + +* At the moment (c) is carried in a reader-monad way by the CoreMonad. + The HomePackageTable doesn't have a single RuleBase because technically + we should only be able to "see" rules "below" this module; so we + generate a RuleBase for (c) by combing rules from all the modules + "below" us. That's whye we can't just select the home-package RuleBase + from HscEnv. + + [NB: we are inconsistent here. We should do the same for external + pacakges, but we don't. Same for type-class instances.] + +* So in the outer simplifier loop, we combine (b-d) into a single + RuleBase, reading + (b) from the ModGuts, + (c) from the CoreMonad, and + (d) from its mutable variable + [Of coures this means that we won't see new EPS rules that come in + during a single simplifier iteration, but that probably does not + matter.] + + %************************************************************************ %* * \subsection[specialisation-IdInfo]{Specialisation info about an @Id@}