Check whether the main function is actually exported (#414)
[ghc-hetmet.git] / compiler / specialise / Rules.lhs
index 0cf7a44..cc5054a 100644 (file)
@@ -22,9 +22,9 @@ module Rules (
        addIdSpecialisations, 
        
        -- * Misc. CoreRule helpers
-        rulesOfBinds, getRules, pprRulesForUser,
+        rulesOfBinds, getRules, pprRulesForUser, expandId,
         
-        lookupRule, mkLocalRule, roughTopNames
+        lookupRule, mkRule, mkLocalRule, roughTopNames
     ) where
 
 #include "HsVersions.h"
@@ -96,11 +96,18 @@ mkLocalRule :: RuleName -> Activation
            -> Name -> [CoreBndr] -> [CoreExpr] -> CoreExpr -> CoreRule
 -- ^ Used to make 'CoreRule' for an 'Id' defined in the module being 
 -- compiled. See also 'CoreSyn.CoreRule'
-mkLocalRule name act fn bndrs args rhs
+mkLocalRule = mkRule True
+
+mkRule :: Bool -> RuleName -> Activation 
+       -> Name -> [CoreBndr] -> [CoreExpr] -> CoreExpr -> CoreRule
+-- ^ Used to make 'CoreRule' for an 'Id' defined in the module being 
+-- compiled. See also 'CoreSyn.CoreRule'
+mkRule is_local name act fn bndrs args rhs
   = Rule { ru_name = name, ru_fn = fn, ru_act = act,
           ru_bndrs = bndrs, ru_args = args,
-          ru_rhs = rhs, ru_rough = roughTopNames args,
-          ru_local = True }
+          ru_rhs = occurAnalyseExpr rhs, 
+          ru_rough = roughTopNames args,
+          ru_local = is_local }
 
 --------------
 roughTopNames :: [CoreExpr] -> [Maybe Name]
@@ -192,18 +199,32 @@ rulesOfBinds :: [CoreBind] -> [CoreRule]
 rulesOfBinds binds = concatMap (concatMap idCoreRules . bindersOf) binds
 
 getRules :: RuleBase -> Id -> [CoreRule]
-       -- The rules for an Id come from two places:
-       --      (a) the ones it is born with (idCoreRules fn)
-       --      (b) rules added in subsequent modules (extra_rules)
-       -- PrimOps, for example, are born with a bunch of rules under (a)
+-- See Note [Where rules are found]
 getRules rule_base fn
-  | isLocalId fn  = idCoreRules fn
-  | otherwise     = WARN( not (isPrimOpId fn) && notNull (idCoreRules fn), 
-                         ppr fn <+> ppr (idCoreRules fn) )
-                   idCoreRules fn ++ (lookupNameEnv rule_base (idName fn) `orElse` [])
-       -- Only PrimOpIds have rules inside themselves, and perhaps more besides
+  = idCoreRules fn ++ imp_rules
+  where
+    imp_rules = lookupNameEnv rule_base (idName fn) `orElse` []
 \end{code}
 
+Note [Where rules are found]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The rules for an Id come from two places:
+  (a) the ones it is born with, stored inside the Id iself (idCoreRules fn),
+  (b) rules added in other modules, stored in the global RuleBase (imp_rules)
+
+It's tempting to think that 
+     - LocalIds have only (a)
+     - non-LocalIds have only (b)
+
+but that isn't quite right:
+
+     - PrimOps and ClassOps are born with a bunch of rules inside the Id,
+       even when they are imported
+
+     - The rules in PrelRules.builtinRules should be active even
+       in the module defining the Id (when it's a LocalId), but 
+       the rules are kept in the global RuleBase
+
 
 %************************************************************************
 %*                                                                     *
@@ -355,6 +376,7 @@ matchRule :: (Activation -> Bool) -> InScopeSet
 
 matchRule _is_active _in_scope args _rough_args
          (BuiltinRule { ru_try = match_fn })
+-- Built-in rules can't be switched off, it seems
   = case match_fn args of
        Just expr -> Just expr
        Nothing   -> Nothing
@@ -488,9 +510,10 @@ match menv subst (Var v1) e2
   | Just subst <- match_var menv subst v1 e2
   = Just subst
 
-match menv subst e1 (Note _ e2)
-  = match menv subst e1 e2
-       -- See Note [Notes in RULE matching]
+match menv subst (Note _ e1) e2 = match menv subst e1 e2
+match menv subst e1 (Note _ e2) = match menv subst e1 e2
+      -- Ignore notes in both template and thing to be matched
+      -- See Note [Notes in RULE matching]
 
 match menv subst e1 (Var v2)      -- Note [Expanding variables]
   | not (locallyBoundR rn_env v2) -- Note [Do not expand locally-bound variables]
@@ -566,7 +589,7 @@ match menv subst (Cast e1 co1) (Cast e2 co2)
        ; match menv subst1 e1 e2 }
 
 -- Everything else fails
-match _ _ _e1 _e2 = -- pprTrace "Failing at" ((text "e1:" <+> ppr e1) $$ (text "e2:" <+> ppr e2)) $ 
+match _ _ _e1 _e2 = -- pprTrace "Failing at" ((text "e1:" <+> ppr _e1) $$ (text "e2:" <+> ppr _e2)) $ 
                         Nothing
 
 ------------------------------------------
@@ -684,11 +707,11 @@ Hence, (a) the guard (not (isLocallyBoundR v2))
 
 Note [Notes in RULE matching]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Look through Notes.  In particular, we don't want to
-be confused by InlineMe notes.  Maybe we should be more
-careful about profiling notes, but for now I'm just
-riding roughshod over them.  
-See Note [Notes in call patterns] in SpecConstr
+Look through Notes in both template and expression being matched.  In
+particular, we don't want to be confused by InlineMe notes.  Maybe we
+should be more careful about profiling notes, but for now I'm just
+riding roughshod over them.  cf Note [Notes in call patterns] in
+SpecConstr
 
 Note [Matching lets]
 ~~~~~~~~~~~~~~~~~~~~