Comments only, about RULE plumbing
authorsimonpj@microsoft.com <unknown>
Mon, 7 Dec 2009 08:04:42 +0000 (08:04 +0000)
committersimonpj@microsoft.com <unknown>
Mon, 7 Dec 2009 08:04:42 +0000 (08:04 +0000)
compiler/main/HscTypes.lhs
compiler/main/TidyPgm.lhs
compiler/simplCore/SimplCore.lhs
compiler/specialise/Rules.lhs

index 4568756..f424089 100644 (file)
@@ -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 
        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
        mg_binds     :: ![CoreBind],     -- ^ Bindings for this module
        mg_foreign   :: !ForeignStubs,   -- ^ Foreign exports declared in this module
        mg_warns     :: !Warnings,       -- ^ Warnings declared in the module
index 6a9f0dd..eefdd2d 100644 (file)
@@ -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 }
                                    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)
                -- See Note [Which rules to expose]
 
        ; let { (tidy_env, tidy_binds)
index 17132e5..f26575b 100644 (file)
@@ -85,6 +85,7 @@ core2core hsc_env guts = do
     let (cp_us, ru_us) = splitUniqSupply us
 
     -- COMPUTE THE RULE BASE TO USE
     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.
     (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
                     (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
                -- 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
index 90485d0..5bd22a1 100644 (file)
@@ -57,6 +57,71 @@ import Data.List
 \end{code}
 
 
 \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@}
 %************************************************************************
 %*                                                                     *
 \subsection[specialisation-IdInfo]{Specialisation info about an @Id@}