-
-
-%************************************************************************
-%* *
-\subsection{Black-listing}
-%* *
-%************************************************************************
-
-Inlining is controlled by the "Inline phase" number, which is set
-by the per-simplification-pass '-finline-phase' flag.
-
-For optimisation we use phase 1,2 and nothing (i.e. no -finline-phase flag)
-in that order. The meanings of these are determined by the @blackListed@ function
-here.
-
-The final simplification doesn't have a phase number.
-
-Pragmas
-~~~~~~~
- Pragma Black list if
-
-(least black listing, most inlining)
- INLINE n foo phase is Just p *and* p<n *and* foo appears on LHS of rule
- INLINE foo phase is Just p *and* foo appears on LHS of rule
- NOINLINE n foo phase is Just p *and* (p<n *or* foo appears on LHS of rule)
- NOINLINE foo always
-(most black listing, least inlining)
-
-\begin{code}
-blackListed :: IdSet -- Used in transformation rules
- -> Maybe Int -- Inline phase
- -> Id -> Bool -- True <=> blacklisted
-
--- The blackListed function sees whether a variable should *not* be
--- inlined because of the inline phase we are in. This is the sole
--- place that the inline phase number is looked at.
-
-blackListed rule_vars Nothing -- Last phase
- = \v -> isNeverInlinePrag (idInlinePragma v)
-
-blackListed rule_vars (Just phase)
- = \v -> normal_case rule_vars phase v
-
-normal_case rule_vars phase v
- = case idInlinePragma v of
- NoInlinePragInfo -> has_rules
-
- IMustNotBeINLINEd from_INLINE Nothing
- | from_INLINE -> has_rules -- Black list until final phase
- | otherwise -> True -- Always blacklisted
-
- IMustNotBeINLINEd from_INLINE (Just threshold)
- | from_INLINE -> (phase < threshold && has_rules)
- | otherwise -> (phase < threshold || has_rules)
- where
- has_rules = v `elemVarSet` rule_vars
- || not (isEmptyCoreRules (idSpecialisation v))
-\end{code}
-
-
-SLPJ 95/04: Why @runST@ must be inlined very late:
-\begin{verbatim}
-f x =
- runST ( \ s -> let
- (a, s') = newArray# 100 [] s
- (_, s'') = fill_in_array_or_something a x s'
- in
- freezeArray# a s'' )
-\end{verbatim}
-If we inline @runST@, we'll get:
-\begin{verbatim}
-f x = let
- (a, s') = newArray# 100 [] realWorld#{-NB-}
- (_, s'') = fill_in_array_or_something a x s'
- in
- freezeArray# a s''
-\end{verbatim}
-And now the @newArray#@ binding can be floated to become a CAF, which
-is totally and utterly wrong:
-\begin{verbatim}
-f = let
- (a, s') = newArray# 100 [] realWorld#{-NB-} -- YIKES!!!
- in
- \ x ->
- let (_, s'') = fill_in_array_or_something a x s' in
- freezeArray# a s''
-\end{verbatim}
-All calls to @f@ will share a {\em single} array!
-
-Yet we do want to inline runST sometime, so we can avoid
-needless code. Solution: black list it until the last moment.
-