+tickUnfold :: Id -> SimplM ()
+tickUnfold id
+ = doTickSmpl f
+ where
+ f (SimplCount stuff (n_unf, unf1, unf2))
+ | n_unf >= maxUnfoldHistory = SimplCount new_stuff (1, [id], unf1)
+ | otherwise = SimplCount new_stuff (n_unf+1, id:unf1, unf2)
+ where
+ new_stuff = incTick UnfoldingDone ILIT(1) stuff
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsubsection{Command-line switches}
+%* *
+%************************************************************************
+
+\begin{code}
+getSwitchChecker :: SimplM SwitchChecker
+getSwitchChecker env us sc = (seChkr env, us, sc)
+
+getSimplIntSwitch :: SwitchChecker -> (Int-> SimplifierSwitch) -> Int
+getSimplIntSwitch chkr switch
+ = expectJust "getSimplIntSwitch" (intSwitchSet chkr switch)
+\end{code}
+
+
+@switchOffInlining@ is used to prepare the environment for simplifying
+the RHS of an Id that's marked with an INLINE pragma. It is going to
+be inlined wherever they are used, and then all the inlining will take
+effect. Meanwhile, there isn't much point in doing anything to the
+as-yet-un-INLINEd rhs. Furthremore, it's very important to switch off
+inlining! because
+ (a) not doing so will inline a worker straight back into its wrapper!
+
+and (b) Consider the following example
+ let f = \pq -> BIG
+ in
+ let g = \y -> f y y
+ {-# INLINE g #-}
+ in ...g...g...g...g...g...
+
+ Now, if that's the ONLY occurrence of f, it will be inlined inside g,
+ and thence copied multiple times when g is inlined.
+
+ Andy disagrees! Example:
+ all xs = foldr (&&) True xs
+ any p = all . map p {-# INLINE any #-}
+
+ Problem: any won't get deforested, and so if it's exported and
+ the importer doesn't use the inlining, (eg passes it as an arg)
+ then we won't get deforestation at all.
+ We havn't solved this problem yet!
+
+We prepare the envt by simply modifying the in_scope_env, which has all the
+unfolding info. At one point we did it by modifying the chkr so that
+it said "EssentialUnfoldingsOnly", but that prevented legitmate, and
+important, simplifications happening in the body of the RHS.
+
+6/98 update:
+
+We *don't* prevent inlining from happening for identifiers
+that are marked as IMustBeINLINEd. An example of where
+doing this is crucial is:
+
+ class Bar a => Foo a where
+ ...g....
+ {-# INLINE f #-}
+ f :: Foo a => a -> b
+ f x = ....Foo_sc1...
+
+If `f' needs to peer inside Foo's superclass, Bar, it refers
+to the appropriate super class selector, which is marked as
+must-inlineable. We don't generate any code for a superclass
+selector, so failing to inline it in the RHS of `f' will
+leave a reference to a non-existent id, with bad consequences.
+
+ALSO NOTE that we do all this by modifing the inline-pragma,
+not by zapping the unfolding. The latter may still be useful for
+knowing when something is evaluated.
+
+June 98 update: I've gone back to dealing with this by adding
+the EssentialUnfoldingsOnly switch. That doesn't stop essential
+unfoldings, nor inlineUnconditionally stuff; and the thing's going
+to be inlined at every call site anyway. Running over the whole
+environment seems like wild overkill.
+
+\begin{code}
+switchOffInlining :: SimplM a -> SimplM a
+switchOffInlining m env@(SimplEnv { seChkr = sw_chkr }) us sc
+ = m (env { seChkr = new_chkr }) us sc