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 = a,
127 -- Inline pragma printed out with all binders; see PprCore.pprIdBndr
131 %************************************************************************
133 \subsection[arity-IdInfo]{Arity info about an @Id@}
135 %************************************************************************
137 For locally-defined Ids, the code generator maintains its own notion
138 of their arities; so it should not be asking... (but other things
139 besides the code-generator need arity info!)
143 = UnknownArity -- No idea
144 | ArityExactly Int -- Arity is exactly this
145 | ArityAtLeast Int -- Arity is this or greater
147 exactArity = ArityExactly
148 atLeastArity = ArityAtLeast
149 unknownArity = UnknownArity
151 arityLowerBound :: ArityInfo -> Int
152 arityLowerBound UnknownArity = 0
153 arityLowerBound (ArityAtLeast n) = n
154 arityLowerBound (ArityExactly n) = n
157 ppArityInfo UnknownArity = empty
158 ppArityInfo (ArityExactly arity) = hsep [ptext SLIT("__A"), int arity]
159 ppArityInfo (ArityAtLeast arity) = hsep [ptext SLIT("__AL"), int arity]
162 %************************************************************************
164 \subsection{Inline-pragma information}
166 %************************************************************************
172 | IAmASpecPragmaId -- Used for spec-pragma Ids; don't discard or inline
174 | IWantToBeINLINEd -- User INLINE pragma
175 | IMustNotBeINLINEd -- User NOINLINE pragma
177 | IAmALoopBreaker -- Used by the occurrence analyser to mark loop-breakers
178 -- in a group of recursive definitions
180 | ICanSafelyBeINLINEd -- Used by the occurrence analyser to mark things
181 -- that manifesly occur once, not inside SCCs,
182 -- not in constructor arguments
184 OccInfo -- Says whether the occurrence is inside a lambda
185 -- If so, must only substitute WHNFs
187 Bool -- False <=> occurs in more than one case branch
188 -- If so, there's a code-duplication issue
190 | IAmDead -- Marks unused variables. Sometimes useful for
191 -- lambda and case-bound variables.
193 | IMustBeINLINEd -- Absolutely must inline; used for PrimOps and
194 -- constructors only.
196 instance Outputable InlinePragInfo where
197 ppr NoInlinePragInfo = empty
198 ppr IMustBeINLINEd = ptext SLIT("__UU")
199 ppr IWantToBeINLINEd = ptext SLIT("__U")
200 ppr IMustNotBeINLINEd = ptext SLIT("__Unot")
201 ppr IAmALoopBreaker = ptext SLIT("__Ux")
202 ppr IAmDead = ptext SLIT("__Ud")
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.
284 %************************************************************************
286 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
288 %************************************************************************
290 We specify the strictness of a function by giving information about
291 each of the ``wrapper's'' arguments (see the description about
292 worker/wrapper-style transformations in the PJ/Launchbury paper on
295 The list of @Demands@ specifies: (a)~the strictness properties
296 of a function's arguments; (b)~the {\em existence} of a ``worker''
297 version of the function; and (c)~the type signature of that worker (if
298 it exists); i.e. its calling convention.
304 | StrictnessInfo [Demand]
305 Bool -- True <=> the function diverges regardless of its arguments
306 -- Useful for "error" and other disguised variants thereof.
307 -- BUT NB: f = \x y. error "urk"
308 -- will have info SI [SS] True
309 -- but still (f) and (f 2) are not bot; only (f 3 2) is bot
311 Bool -- True <=> there is a worker. There might not be, even for a
312 -- strict function, because:
313 -- (a) the function might be small enough to inline,
314 -- so no need for w/w split
315 -- (b) the strictness info might be "SSS" or something, so no w/w split.
319 mkStrictnessInfo :: ([Demand], Bool) -> Bool -> StrictnessInfo
321 mkStrictnessInfo (xs, is_bot) has_wrkr
322 | all isLazy xs && not is_bot = NoStrictnessInfo -- Uninteresting
323 | otherwise = StrictnessInfo xs is_bot has_wrkr
325 noStrictnessInfo = NoStrictnessInfo
327 isBottomingStrictness (StrictnessInfo _ bot _) = bot
328 isBottomingStrictness NoStrictnessInfo = False
330 -- appIsBottom returns true if an application to n args would diverge
331 appIsBottom (StrictnessInfo ds bot _) n = bot && (n >= length ds)
332 appIsBottom NoStrictnessInfo n = False
334 ppStrictnessInfo NoStrictnessInfo = empty
335 ppStrictnessInfo (StrictnessInfo wrapper_args bot wrkr_maybe)
336 = hsep [ptext SLIT("__S"), pprDemands wrapper_args bot]
341 workerExists :: StrictnessInfo -> Bool
342 workerExists (StrictnessInfo _ _ worker_exists) = worker_exists
343 workerExists other = False
347 %************************************************************************
349 \subsection[update-IdInfo]{Update-analysis info about an @Id@}
351 %************************************************************************
356 | SomeUpdateInfo UpdateSpec
358 -- we need Eq/Ord to cross-chk update infos in interfaces
360 -- the form in which we pass update-analysis info between modules:
361 type UpdateSpec = [Int]
365 mkUpdateInfo = SomeUpdateInfo
367 updateInfoMaybe NoUpdateInfo = Nothing
368 updateInfoMaybe (SomeUpdateInfo []) = Nothing
369 updateInfoMaybe (SomeUpdateInfo u) = Just u
372 Text instance so that the update annotations can be read in.
375 ppUpdateInfo NoUpdateInfo = empty
376 ppUpdateInfo (SomeUpdateInfo []) = empty
377 ppUpdateInfo (SomeUpdateInfo spec) = (<>) (ptext SLIT("__U ")) (hcat (map int spec))
380 %************************************************************************
382 \subsection[CAF-IdInfo]{CAF-related information}
384 %************************************************************************
386 This information is used to build Static Reference Tables (see
387 simplStg/ComputeSRT.lhs).
391 = MayHaveCafRefs -- either:
392 -- (1) A function or static constructor
393 -- that refers to one or more CAFs,
394 -- (2) A real live CAF
396 | NoCafRefs -- A function or static constructor
397 -- that refers to no CAFs.
399 -- LATER: not sure how easy this is...
403 ppCafInfo NoCafRefs = ptext SLIT("__C")
404 ppCafInfo MayHaveCafRefs = empty