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
17 exactArity, atLeastArity, unknownArity,
18 arityInfo, setArityInfo, ppArityInfo, arityLowerBound,
21 StrictnessInfo(..), -- Non-abstract
23 noStrictnessInfo, strictnessInfo,
24 ppStrictnessInfo, setStrictnessInfo,
25 isBottomingStrictness, appIsBottom,
28 WorkerInfo, workerExists,
29 mkWorkerInfo, noWorkerInfo, workerInfo, setWorkerInfo,
33 unfoldingInfo, setUnfoldingInfo,
36 demandInfo, setDemandInfo,
39 InlinePragInfo(..), OccInfo(..),
40 inlinePragInfo, setInlinePragInfo, notInsideLambda,
43 IdSpecEnv, specInfo, setSpecInfo,
46 UpdateInfo, UpdateSpec,
47 mkUpdateInfo, updateInfo, updateInfoMaybe, ppUpdateInfo, setUpdateInfo,
50 CafInfo(..), cafInfo, setCafInfo, ppCafInfo,
52 -- Constructed Product Result Info
53 CprInfo(..), cprInfo, setCprInfo, ppCprInfo, noCprInfo
56 #include "HsVersions.h"
59 import {-# SOURCE #-} CoreUnfold ( Unfolding, noUnfolding )
60 import {-# SOURCE #-} CoreSyn ( CoreExpr )
63 import SpecEnv ( SpecEnv, emptySpecEnv )
64 import Demand ( Demand, isLazy, wwLazy, pprDemands )
67 import Maybe ( isJust )
71 An @IdInfo@ gives {\em optional} information about an @Id@. If
72 present it never lies, but it may not be present, in which case there
73 is always a conservative assumption which can be made.
75 Two @Id@s may have different info even though they have the same
76 @Unique@ (and are hence the same @Id@); for example, one might lack
77 the properties attached to the other.
79 The @IdInfo@ gives information about the value, or definition, of the
80 @Id@. It does {\em not} contain information about the @Id@'s usage
81 (except for @DemandInfo@? ToDo).
86 arityInfo :: ArityInfo, -- Its arity
87 demandInfo :: Demand, -- Whether or not it is definitely demanded
88 specInfo :: IdSpecEnv, -- Specialisations of this function which exist
89 strictnessInfo :: StrictnessInfo, -- Strictness properties
90 workerInfo :: WorkerInfo, -- Pointer to Worker Function
91 unfoldingInfo :: Unfolding, -- Its unfolding
92 updateInfo :: UpdateInfo, -- Which args should be updated
94 cprInfo :: CprInfo, -- Function always constructs a product result
95 inlinePragInfo :: !InlinePragInfo -- Inline pragmas
102 setUpdateInfo ud info = info { updateInfo = ud }
103 setDemandInfo dd info = info { demandInfo = dd }
104 setStrictnessInfo st info = info { strictnessInfo = st }
105 setWorkerInfo wk info = info { workerInfo = wk }
106 setSpecInfo sp info = info { specInfo = sp }
107 setArityInfo ar info = info { arityInfo = ar }
108 setInlinePragInfo pr info = info { inlinePragInfo = pr }
109 setUnfoldingInfo uf info = info { unfoldingInfo = uf }
110 setCafInfo cf info = info { cafInfo = cf }
111 setCprInfo cp info = info { cprInfo = cp }
117 arityInfo = UnknownArity,
119 specInfo = emptySpecEnv,
120 strictnessInfo = NoStrictnessInfo,
121 workerInfo = noWorkerInfo,
122 unfoldingInfo = noUnfolding,
123 updateInfo = NoUpdateInfo,
124 cafInfo = MayHaveCafRefs,
126 inlinePragInfo = NoInlinePragInfo
130 %************************************************************************
132 \subsection[arity-IdInfo]{Arity info about an @Id@}
134 %************************************************************************
136 For locally-defined Ids, the code generator maintains its own notion
137 of their arities; so it should not be asking... (but other things
138 besides the code-generator need arity info!)
142 = UnknownArity -- No idea
143 | ArityExactly Int -- Arity is exactly this
144 | ArityAtLeast Int -- Arity is this or greater
146 exactArity = ArityExactly
147 atLeastArity = ArityAtLeast
148 unknownArity = UnknownArity
150 arityLowerBound :: ArityInfo -> Int
151 arityLowerBound UnknownArity = 0
152 arityLowerBound (ArityAtLeast n) = n
153 arityLowerBound (ArityExactly n) = n
156 ppArityInfo UnknownArity = empty
157 ppArityInfo (ArityExactly arity) = hsep [ptext SLIT("__A"), int arity]
158 ppArityInfo (ArityAtLeast arity) = hsep [ptext SLIT("__AL"), int arity]
161 %************************************************************************
163 \subsection{Inline-pragma information}
165 %************************************************************************
171 | IAmASpecPragmaId -- Used for spec-pragma Ids; don't discard or inline
173 | IWantToBeINLINEd -- User INLINE pragma
174 | IMustNotBeINLINEd -- User NOINLINE pragma
176 | IAmALoopBreaker -- Used by the occurrence analyser to mark loop-breakers
177 -- in a group of recursive definitions
179 | ICanSafelyBeINLINEd -- Used by the occurrence analyser to mark things
180 -- that manifesly occur once, not inside SCCs,
181 -- not in constructor arguments
183 OccInfo -- Says whether the occurrence is inside a lambda
184 -- If so, must only substitute WHNFs
186 Bool -- False <=> occurs in more than one case branch
187 -- If so, there's a code-duplication issue
189 | IAmDead -- Marks unused variables. Sometimes useful for
190 -- lambda and case-bound variables.
192 | IMustBeINLINEd -- Absolutely must inline; used for PrimOps and
193 -- constructors only.
195 instance Outputable InlinePragInfo where
196 ppr NoInlinePragInfo = empty
197 ppr IMustBeINLINEd = ptext SLIT("__UU")
198 ppr IWantToBeINLINEd = ptext SLIT("__U")
199 ppr IMustNotBeINLINEd = ptext SLIT("__Unot")
200 ppr IAmALoopBreaker = ptext SLIT("__Ux")
201 ppr IAmDead = ptext SLIT("__Ud")
202 ppr (ICanSafelyBeINLINEd InsideLam _) = ptext SLIT("__Ul")
203 ppr (ICanSafelyBeINLINEd _ _) = ptext SLIT("__Us")
204 ppr IAmASpecPragmaId = ptext SLIT("__US")
206 instance Show InlinePragInfo where
207 showsPrec p prag = showsPrecSDoc p (ppr prag)
210 The @IMustNotBeDiscarded@ exists only to make Ids that are
211 on the *LHS* of bindings created by SPECIALISE pragmas;
213 The SpecPragmaId is never itself mentioned; it
214 exists solely so that the specialiser will find
215 the call to f, and make specialised version of it.
216 The SpecPragmaId binding is discarded by the specialiser
217 when it gathers up overloaded calls.
218 Meanwhile, it is not discarded as dead code.
222 = StrictOcc -- Occurs syntactically strictly;
223 -- i.e. in a function position or case scrutinee
225 | LazyOcc -- Not syntactically strict (*even* that of a strict function)
226 -- or in a case branch where there's more than one alternative
228 | InsideLam -- Inside a non-linear lambda (that is, a lambda which
229 -- is sure to be instantiated only once).
230 -- Substituting a redex for this occurrence is
231 -- dangerous because it might duplicate work.
233 instance Outputable OccInfo where
234 ppr StrictOcc = text "s"
236 ppr InsideLam = text "l"
239 notInsideLambda :: OccInfo -> Bool
240 notInsideLambda StrictOcc = True
241 notInsideLambda LazyOcc = True
242 notInsideLambda InsideLam = False
245 %************************************************************************
247 \subsection[specialisation-IdInfo]{Specialisation info about an @Id@}
249 %************************************************************************
251 A @IdSpecEnv@ holds details of an @Id@'s specialisations.
254 type IdSpecEnv = SpecEnv CoreExpr
257 For example, if \tr{f}'s @SpecEnv@ contains the mapping:
259 [List a, b] ===> (\d -> f' a b)
261 then when we find an application of f to matching types, we simply replace
262 it by the matching RHS:
264 f (List Int) Bool ===> (\d -> f' Int Bool)
266 All the stuff about how many dictionaries to discard, and what types
267 to apply the specialised function to, are handled by the fact that the
268 SpecEnv contains a template for the result of the specialisation.
270 There is one more exciting case, which is dealt with in exactly the same
271 way. If the specialised value is unboxed then it is lifted at its
272 definition site and unlifted at its uses. For example:
274 pi :: forall a. Num a => a
276 might have a specialisation
278 [Int#] ===> (case pi' of Lift pi# -> pi#)
280 where pi' :: Lift Int# is the specialised version of pi.
283 %************************************************************************
285 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
287 %************************************************************************
289 We specify the strictness of a function by giving information about
290 each of the ``wrapper's'' arguments (see the description about
291 worker/wrapper-style transformations in the PJ/Launchbury paper on
294 The list of @Demands@ specifies: (a)~the strictness properties of a
295 function's arguments; and (b)~the type signature of that worker (if it
296 exists); i.e. its calling convention.
298 Note that the existence of a worker function is now denoted by the Id's
305 | StrictnessInfo [Demand]
306 Bool -- True <=> the function diverges regardless of its arguments
307 -- Useful for "error" and other disguised variants thereof.
308 -- BUT NB: f = \x y. error "urk"
309 -- will have info SI [SS] True
310 -- but still (f) and (f 2) are not bot; only (f 3 2) is bot
314 mkStrictnessInfo :: ([Demand], Bool) -> StrictnessInfo
316 mkStrictnessInfo (xs, is_bot)
317 | all isLazy xs && not is_bot = NoStrictnessInfo -- Uninteresting
318 | otherwise = StrictnessInfo xs is_bot
320 noStrictnessInfo = NoStrictnessInfo
322 isBottomingStrictness (StrictnessInfo _ bot) = bot
323 isBottomingStrictness NoStrictnessInfo = False
325 -- appIsBottom returns true if an application to n args would diverge
326 appIsBottom (StrictnessInfo ds bot) n = bot && (n >= length ds)
327 appIsBottom NoStrictnessInfo n = False
329 ppStrictnessInfo NoStrictnessInfo = empty
330 ppStrictnessInfo (StrictnessInfo wrapper_args bot)
331 = hsep [ptext SLIT("__S"), pprDemands wrapper_args bot]
334 %************************************************************************
336 \subsection[worker-IdInfo]{Worker info about an @Id@}
338 %************************************************************************
340 If this Id has a worker then we store a reference to it. Worker
341 functions are generated by the worker/wrapper pass. This uses
342 information from the strictness and CPR analyses.
344 There might not be a worker, even for a strict function, because:
345 (a) the function might be small enough to inline, so no need
347 (b) the strictness info might be "SSS" or something, so no w/w split.
351 type WorkerInfo = Maybe Id
353 mkWorkerInfo :: Id -> WorkerInfo
354 mkWorkerInfo wk_id = Just wk_id
356 noWorkerInfo = Nothing
358 ppWorkerInfo Nothing = empty
359 ppWorkerInfo (Just wk_id) = ppr wk_id
361 workerExists :: Maybe Id -> Bool
362 workerExists = isJust
366 %************************************************************************
368 \subsection[update-IdInfo]{Update-analysis info about an @Id@}
370 %************************************************************************
375 | SomeUpdateInfo UpdateSpec
377 -- we need Eq/Ord to cross-chk update infos in interfaces
379 -- the form in which we pass update-analysis info between modules:
380 type UpdateSpec = [Int]
384 mkUpdateInfo = SomeUpdateInfo
386 updateInfoMaybe NoUpdateInfo = Nothing
387 updateInfoMaybe (SomeUpdateInfo []) = Nothing
388 updateInfoMaybe (SomeUpdateInfo u) = Just u
391 Text instance so that the update annotations can be read in.
394 ppUpdateInfo NoUpdateInfo = empty
395 ppUpdateInfo (SomeUpdateInfo []) = empty
396 ppUpdateInfo (SomeUpdateInfo spec) = (<>) (ptext SLIT("__U ")) (hcat (map int spec))
399 %************************************************************************
401 \subsection[CAF-IdInfo]{CAF-related information}
403 %************************************************************************
405 This information is used to build Static Reference Tables (see
406 simplStg/ComputeSRT.lhs).
410 = MayHaveCafRefs -- either:
411 -- (1) A function or static constructor
412 -- that refers to one or more CAFs,
413 -- (2) A real live CAF
415 | NoCafRefs -- A function or static constructor
416 -- that refers to no CAFs.
418 -- LATER: not sure how easy this is...
422 ppCafInfo NoCafRefs = ptext SLIT("__C")
423 ppCafInfo MayHaveCafRefs = empty
426 %************************************************************************
428 \subsection[cpr-IdInfo]{Constructed Product Result info about an @Id@}
430 %************************************************************************
432 If the @Id@ is a function then it may have CPR info. A CPR analysis
433 phase detects whether:
437 The function's return value has a product type, i.e. an algebraic type
438 with a single constructor. Examples of such types are tuples and boxed
441 The function always 'constructs' the value that it is returning. It
442 must do this on every path through, and it's OK if it calls another
443 function which constructs the result.
446 If this is the case then we store a template which tells us the
447 function has the CPR property and which components of the result are
456 -- e.g. const 5 == CPRInfo [NoCPRInfo]
463 -- CPRInfo [CPRInfo [NoCPRInfo],
464 -- CPRInfo [NoCprInfo,
465 -- CPRInfo [NoCPRInfo],
473 noCprInfo = NoCPRInfo
475 ppCprInfo NoCPRInfo = empty
476 ppCprInfo c@(CPRInfo _)
477 = hsep [ptext SLIT("__M"), ppCprInfo' c]
479 ppCprInfo' NoCPRInfo = char '-'
480 ppCprInfo' (CPRInfo args) = parens (hcat (map ppCprInfo' args))
482 instance Outputable CprInfo where
485 instance Show CprInfo where
486 showsPrec p c = showsPrecSDoc p (ppr c)