summaryrefslogtreecommitdiff
path: root/compiler/simplCore/OccurAnal.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/simplCore/OccurAnal.hs')
-rw-r--r--compiler/simplCore/OccurAnal.hs20
1 files changed, 18 insertions, 2 deletions
diff --git a/compiler/simplCore/OccurAnal.hs b/compiler/simplCore/OccurAnal.hs
index b02ddc9540..52fa9d112c 100644
--- a/compiler/simplCore/OccurAnal.hs
+++ b/compiler/simplCore/OccurAnal.hs
@@ -56,10 +56,11 @@ Here's the externally-callable interface:
-}
occurAnalysePgm :: Module -- Used only in debug output
+ -> Bool
-> (Activation -> Bool)
-> [CoreRule] -> [CoreVect] -> VarSet
-> CoreProgram -> CoreProgram
-occurAnalysePgm this_mod active_rule imp_rules vects vectVars binds
+occurAnalysePgm this_mod remove_dead active_rule imp_rules vects vectVars binds
| isEmptyDetails final_usage
= occ_anald_binds
@@ -81,11 +82,16 @@ occurAnalysePgm this_mod active_rule imp_rules vects vectVars binds
initial_uds = addManyOccsSet emptyDetails
(rulesFreeVars imp_rules `unionVarSet`
vectsFreeVars vects `unionVarSet`
- vectVars)
+ vectVars `unionVarSet`
+ keepAliveVars)
-- The RULES and VECTORISE declarations keep things alive! (For VECTORISE declarations,
-- we only get them *until* the vectoriser runs. Afterwards, these dependencies are
-- reflected in 'vectors' — see Note [Vectorisation declarations and occurrences].)
+ -- Note [Do not delete dead code in the desugarer]
+ keepAliveVars | remove_dead = emptyVarSet
+ | otherwise = mkVarSet $ concatMap bindersOf binds
+
-- Note [Preventing loops due to imported functions rules]
imp_rule_edges = foldr (plusVarEnv_C unionVarSet) emptyVarEnv
[ mapVarEnv (const maps_to) (exprFreeIds arg `delVarSetList` ru_bndrs imp_rule)
@@ -2709,3 +2715,13 @@ andTailCallInfo :: TailCallInfo -> TailCallInfo -> TailCallInfo
andTailCallInfo info@(AlwaysTailCalled arity1) (AlwaysTailCalled arity2)
| arity1 == arity2 = info
andTailCallInfo _ _ = NoTailCallInfo
+
+-- Note [Do not delete dead code in the desugarer]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- GHC plugins rightly want to access code that is maybe not exported and thus
+-- “dead” from GHC's point of view. So we must not eliminate dead code before
+-- the first time a user plugin had a chance to run.
+--
+-- The desugarer runs the occurrence analyser; in that run we will add
+-- all binders to the “body” of the module, thus preventing them from being
+-- deleted or marked as dead.