!OneBranch
!InterestingCxt
- | IAmALoopBreaker -- Used by the occurrence analyser to mark loop-breakers
- -- in a group of recursive definitions
+ | IAmALoopBreaker -- Note [LoopBreaker OccInfo]
!RulesOnly -- True <=> This is a weak or rules-only loop breaker
- -- See OccurAnal Note [Weak loop breakers]
+ -- See OccurAnal Note [Weak loop breakers]
type RulesOnly = Bool
\end{code}
+Note [LoopBreaker OccInfo]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+An OccInfo of (IAmLoopBreaker False) is used by the occurrence
+analyser in two ways:
+ (a) to mark loop-breakers in a group of recursive
+ definitions (hence the name)
+ (b) to mark binders that must not be inlined in this phase
+ (perhaps it has a NOINLINE pragma)
+Things with (IAmLoopBreaker False) do not get an unfolding
+pinned on to them, so they are completely opaque.
+
+See OccurAnal Note [Weak loop breakers] for (IAmLoopBreaker True).
+
\begin{code}
isNoOcc :: OccInfo -> Bool
but in addition it pins free-tyvar-info onto the Id's type,
where it can easily be found.
+Note [Free type variables]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+At one time we cached the free type variables of the type of an Id
+at the root of the type in a TyNote. The idea was to avoid repeating
+the free-type-variable calculation. But it turned out to slow down
+the compiler overall. I don't quite know why; perhaps finding free
+type variables of an Id isn't all that common whereas applying a
+substitution (which changes the free type variables) is more common.
+Anyway, we removed it in March 2008.
+
\begin{code}
mkLocalIdWithInfo :: Name -> Type -> IdInfo -> Id
mkLocalIdWithInfo name ty info = Var.mkLocalId name ty info
+ -- Note [Free type variables]
mkExportedLocalId :: Name -> Type -> Id
mkExportedLocalId name ty = Var.mkExportedLocalId name ty vanillaIdInfo
+ -- Note [Free type variables]
mkGlobalId :: GlobalIdDetails -> Name -> Type -> IdInfo -> Id
mkGlobalId details name ty info = Var.mkGlobalId details name ty info
tag_node :: UsageDetails -> Node Details -> (UsageDetails, Node Details)
-- (a) Tag the binders in the details with occ info
- -- (b) Mark the binder with OccInfo saying "no preInlineUnconditionally" if
- -- it is used in any rule (lhs or rhs) of the recursive group
+ -- (b) Mark the binder with "weak loop-breaker" OccInfo
+ -- saying "no preInlineUnconditionally" if it is used
+ -- in any rule (lhs or rhs) of the recursive group
-- See Note [Weak loop breakers]
tag_node usage (ND bndr rhs rhs_usage rhs_fvs, k, ks)
= (usage `delVarEnv` bndr, (ND bndr2 rhs rhs_usage rhs_fvs, k, ks))
| is_con_app rhs = 2 -- Data types help with cases
-- Note [conapp]
+-- If an Id is marked "never inline" then it makes a great loop breaker
+-- The only reason for not checking that here is that it is rare
+-- and I've never seen a situation where it makes a difference,
+-- so it probably isn't worth the time to test on every binder
+-- | isNeverActive (idInlinePragma bndr) = -10
+
| inlineCandidate bndr rhs = 1 -- Likely to be inlined
-- Note [Inline candidates]