2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1998
4 \section[IdInfo]{@IdInfos@: Non-essential information about @Ids@}
6 (And a pretty good illustration of quite a few things wrong with
18 exactArity, atLeastArity, unknownArity,
19 arityInfo, setArityInfo, ppArityInfo, arityLowerBound,
22 StrictnessInfo(..), -- Non-abstract
23 workerExists, mkStrictnessInfo,
24 noStrictnessInfo, strictnessInfo,
25 ppStrictnessInfo, setStrictnessInfo,
26 isBottomingStrictness, appIsBottom,
29 unfoldingInfo, setUnfoldingInfo,
32 demandInfo, setDemandInfo,
35 InlinePragInfo(..), OccInfo(..),
36 inlinePragInfo, setInlinePragInfo, notInsideLambda,
39 IdSpecEnv, specInfo, setSpecInfo,
42 UpdateInfo, UpdateSpec,
43 mkUpdateInfo, updateInfo, updateInfoMaybe, ppUpdateInfo, setUpdateInfo,
46 CafInfo(..), cafInfo, setCafInfo, ppCafInfo,
49 #include "HsVersions.h"
52 import {-# SOURCE #-} CoreUnfold ( Unfolding, noUnfolding )
53 import {-# SOURCE #-} CoreSyn ( CoreExpr )
55 import SpecEnv ( SpecEnv, emptySpecEnv )
56 import Demand ( Demand, isLazy, wwLazy, pprDemands )
60 An @IdInfo@ gives {\em optional} information about an @Id@. If
61 present it never lies, but it may not be present, in which case there
62 is always a conservative assumption which can be made.
64 Two @Id@s may have different info even though they have the same
65 @Unique@ (and are hence the same @Id@); for example, one might lack
66 the properties attached to the other.
68 The @IdInfo@ gives information about the value, or definition, of the
69 @Id@. It does {\em not} contain information about the @Id@'s usage
70 (except for @DemandInfo@? ToDo).
75 arityInfo :: ArityInfo, -- Its arity
76 demandInfo :: Demand, -- Whether or not it is definitely demanded
77 specInfo :: IdSpecEnv, -- Specialisations of this function which exist
78 strictnessInfo :: StrictnessInfo, -- Strictness properties
79 unfoldingInfo :: Unfolding, -- Its unfolding
80 updateInfo :: UpdateInfo, -- Which args should be updated
82 inlinePragInfo :: !InlinePragInfo -- Inline pragmas
89 setUpdateInfo ud info = info { updateInfo = ud }
90 setDemandInfo dd info = info { demandInfo = dd }
91 setStrictnessInfo st info = info { strictnessInfo = st }
92 setSpecInfo sp info = info { specInfo = sp }
93 setArityInfo ar info = info { arityInfo = ar }
94 setInlinePragInfo pr info = info { inlinePragInfo = pr }
95 setUnfoldingInfo uf info = info { unfoldingInfo = uf }
96 setCafInfo cf info = info { cafInfo = cf }
102 arityInfo = UnknownArity,
104 specInfo = emptySpecEnv,
105 strictnessInfo = NoStrictnessInfo,
106 unfoldingInfo = noUnfolding,
107 updateInfo = NoUpdateInfo,
108 cafInfo = MayHaveCafRefs,
109 inlinePragInfo = NoInlinePragInfo
114 ppIdInfo :: IdInfo -> SDoc
115 ppIdInfo (IdInfo {arityInfo,
124 ppArityInfo arityInfo,
125 ppUpdateInfo updateInfo,
126 ppStrictnessInfo strictnessInfo,
129 -- Inline pragma printed out with all binders; see PprCore.pprIdBndr
133 %************************************************************************
135 \subsection[arity-IdInfo]{Arity info about an @Id@}
137 %************************************************************************
139 For locally-defined Ids, the code generator maintains its own notion
140 of their arities; so it should not be asking... (but other things
141 besides the code-generator need arity info!)
145 = UnknownArity -- No idea
146 | ArityExactly Int -- Arity is exactly this
147 | ArityAtLeast Int -- Arity is this or greater
149 exactArity = ArityExactly
150 atLeastArity = ArityAtLeast
151 unknownArity = UnknownArity
153 arityLowerBound :: ArityInfo -> Int
154 arityLowerBound UnknownArity = 0
155 arityLowerBound (ArityAtLeast n) = n
156 arityLowerBound (ArityExactly n) = n
159 ppArityInfo UnknownArity = empty
160 ppArityInfo (ArityExactly arity) = hsep [ptext SLIT("__A"), int arity]
161 ppArityInfo (ArityAtLeast arity) = hsep [ptext SLIT("__AL"), int arity]
164 %************************************************************************
166 \subsection{Inline-pragma information}
168 %************************************************************************
174 | IAmASpecPragmaId -- Used for spec-pragma Ids; don't discard or inline
176 | IWantToBeINLINEd -- User INLINE pragma
177 | IMustNotBeINLINEd -- User NOINLINE pragma
179 | IAmALoopBreaker -- Used by the occurrence analyser to mark loop-breakers
180 -- in a group of recursive definitions
182 | ICanSafelyBeINLINEd -- Used by the occurrence analyser to mark things
183 -- that manifesly occur once, not inside SCCs,
184 -- not in constructor arguments
186 OccInfo -- Says whether the occurrence is inside a lambda
187 -- If so, must only substitute WHNFs
189 Bool -- False <=> occurs in more than one case branch
190 -- If so, there's a code-duplication issue
192 | IAmDead -- Marks unused variables. Sometimes useful for
193 -- lambda and case-bound variables.
195 | IMustBeINLINEd -- Absolutely must inline; used for PrimOps and
196 -- constructors only.
198 instance Outputable InlinePragInfo where
199 ppr NoInlinePragInfo = empty
200 ppr IMustBeINLINEd = ptext SLIT("__UU")
201 ppr IWantToBeINLINEd = ptext SLIT("__U")
202 ppr IMustNotBeINLINEd = ptext SLIT("__Unot")
203 ppr IAmALoopBreaker = ptext SLIT("__Ux")
204 ppr IAmDead = ptext SLIT("__Ud")
205 ppr (ICanSafelyBeINLINEd _ _) = ptext SLIT("__Us")
206 ppr IAmASpecPragmaId = ptext SLIT("__US")
208 instance Show InlinePragInfo where
209 showsPrec p prag = showsPrecSDoc p (ppr prag)
212 The @IMustNotBeDiscarded@ exists only to make Ids that are
213 on the *LHS* of bindings created by SPECIALISE pragmas;
215 The SpecPragmaId is never itself mentioned; it
216 exists solely so that the specialiser will find
217 the call to f, and make specialised version of it.
218 The SpecPragmaId binding is discarded by the specialiser
219 when it gathers up overloaded calls.
220 Meanwhile, it is not discarded as dead code.
224 = StrictOcc -- Occurs syntactically strictly;
225 -- i.e. in a function position or case scrutinee
227 | LazyOcc -- Not syntactically strict (*even* that of a strict function)
228 -- or in a case branch where there's more than one alternative
230 | InsideLam -- Inside a non-linear lambda (that is, a lambda which
231 -- is sure to be instantiated only once).
232 -- Substituting a redex for this occurrence is
233 -- dangerous because it might duplicate work.
235 instance Outputable OccInfo where
236 ppr StrictOcc = text "s"
238 ppr InsideLam = text "l"
241 notInsideLambda :: OccInfo -> Bool
242 notInsideLambda StrictOcc = True
243 notInsideLambda LazyOcc = True
244 notInsideLambda InsideLam = False
247 %************************************************************************
249 \subsection[specialisation-IdInfo]{Specialisation info about an @Id@}
251 %************************************************************************
253 A @IdSpecEnv@ holds details of an @Id@'s specialisations.
256 type IdSpecEnv = SpecEnv CoreExpr
259 For example, if \tr{f}'s @SpecEnv@ contains the mapping:
261 [List a, b] ===> (\d -> f' a b)
263 then when we find an application of f to matching types, we simply replace
264 it by the matching RHS:
266 f (List Int) Bool ===> (\d -> f' Int Bool)
268 All the stuff about how many dictionaries to discard, and what types
269 to apply the specialised function to, are handled by the fact that the
270 SpecEnv contains a template for the result of the specialisation.
272 There is one more exciting case, which is dealt with in exactly the same
273 way. If the specialised value is unboxed then it is lifted at its
274 definition site and unlifted at its uses. For example:
276 pi :: forall a. Num a => a
278 might have a specialisation
280 [Int#] ===> (case pi' of Lift pi# -> pi#)
282 where pi' :: Lift Int# is the specialised version of pi.
286 %************************************************************************
288 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
290 %************************************************************************
292 We specify the strictness of a function by giving information about
293 each of the ``wrapper's'' arguments (see the description about
294 worker/wrapper-style transformations in the PJ/Launchbury paper on
297 The list of @Demands@ specifies: (a)~the strictness properties
298 of a function's arguments; (b)~the {\em existence} of a ``worker''
299 version of the function; and (c)~the type signature of that worker (if
300 it exists); i.e. its calling convention.
306 | StrictnessInfo [Demand]
307 Bool -- True <=> the function diverges regardless of its arguments
308 -- Useful for "error" and other disguised variants thereof.
309 -- BUT NB: f = \x y. error "urk"
310 -- will have info SI [SS] True
311 -- but still (f) and (f 2) are not bot; only (f 3 2) is bot
313 Bool -- True <=> there is a worker. There might not be, even for a
314 -- strict function, because:
315 -- (a) the function might be small enough to inline,
316 -- so no need for w/w split
317 -- (b) the strictness info might be "SSS" or something, so no w/w split.
321 mkStrictnessInfo :: ([Demand], Bool) -> Bool -> StrictnessInfo
323 mkStrictnessInfo (xs, is_bot) has_wrkr
324 | all isLazy xs && not is_bot = NoStrictnessInfo -- Uninteresting
325 | otherwise = StrictnessInfo xs is_bot has_wrkr
327 noStrictnessInfo = NoStrictnessInfo
329 isBottomingStrictness (StrictnessInfo _ bot _) = bot
330 isBottomingStrictness NoStrictnessInfo = False
332 -- appIsBottom returns true if an application to n args would diverge
333 appIsBottom (StrictnessInfo ds bot _) n = bot && (n >= length ds)
334 appIsBottom NoStrictnessInfo n = False
336 ppStrictnessInfo NoStrictnessInfo = empty
337 ppStrictnessInfo (StrictnessInfo wrapper_args bot wrkr_maybe)
338 = hsep [ptext SLIT("__S"), pprDemands wrapper_args bot]
343 workerExists :: StrictnessInfo -> Bool
344 workerExists (StrictnessInfo _ _ worker_exists) = worker_exists
345 workerExists other = False
349 %************************************************************************
351 \subsection[update-IdInfo]{Update-analysis info about an @Id@}
353 %************************************************************************
358 | SomeUpdateInfo UpdateSpec
360 -- we need Eq/Ord to cross-chk update infos in interfaces
362 -- the form in which we pass update-analysis info between modules:
363 type UpdateSpec = [Int]
367 mkUpdateInfo = SomeUpdateInfo
369 updateInfoMaybe NoUpdateInfo = Nothing
370 updateInfoMaybe (SomeUpdateInfo []) = Nothing
371 updateInfoMaybe (SomeUpdateInfo u) = Just u
374 Text instance so that the update annotations can be read in.
377 ppUpdateInfo NoUpdateInfo = empty
378 ppUpdateInfo (SomeUpdateInfo []) = empty
379 ppUpdateInfo (SomeUpdateInfo spec) = (<>) (ptext SLIT("__U ")) (hcat (map int spec))
382 %************************************************************************
384 \subsection[CAF-IdInfo]{CAF-related information}
386 %************************************************************************
388 This information is used to build Static Reference Tables (see
389 simplStg/ComputeSRT.lhs).
393 = MayHaveCafRefs -- either:
394 -- (1) A function or static constructor
395 -- that refers to one or more CAFs,
396 -- (2) A real live CAF
398 | NoCafRefs -- A function or static constructor
399 -- that refers to no CAFs.
401 -- LATER: not sure how easy this is...
405 ppCafInfo NoCafRefs = ptext SLIT("__C")
406 ppCafInfo MayHaveCafRefs = empty