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
22 workerExists, mkStrictnessInfo,
23 noStrictnessInfo, strictnessInfo,
24 ppStrictnessInfo, setStrictnessInfo,
25 isBottomingStrictness, appIsBottom,
28 unfoldingInfo, setUnfoldingInfo,
31 demandInfo, setDemandInfo,
34 InlinePragInfo(..), OccInfo(..),
35 inlinePragInfo, setInlinePragInfo, notInsideLambda,
38 IdSpecEnv, specInfo, setSpecInfo,
41 UpdateInfo, UpdateSpec,
42 mkUpdateInfo, updateInfo, updateInfoMaybe, ppUpdateInfo, setUpdateInfo,
45 CafInfo(..), cafInfo, setCafInfo, ppCafInfo,
48 #include "HsVersions.h"
51 import {-# SOURCE #-} CoreUnfold ( Unfolding, noUnfolding )
52 import {-# SOURCE #-} CoreSyn ( CoreExpr )
54 import SpecEnv ( SpecEnv, emptySpecEnv )
55 import Demand ( Demand, isLazy, wwLazy, pprDemands )
59 An @IdInfo@ gives {\em optional} information about an @Id@. If
60 present it never lies, but it may not be present, in which case there
61 is always a conservative assumption which can be made.
63 Two @Id@s may have different info even though they have the same
64 @Unique@ (and are hence the same @Id@); for example, one might lack
65 the properties attached to the other.
67 The @IdInfo@ gives information about the value, or definition, of the
68 @Id@. It does {\em not} contain information about the @Id@'s usage
69 (except for @DemandInfo@? ToDo).
74 arityInfo :: ArityInfo, -- Its arity
75 demandInfo :: Demand, -- Whether or not it is definitely demanded
76 specInfo :: IdSpecEnv, -- Specialisations of this function which exist
77 strictnessInfo :: StrictnessInfo, -- Strictness properties
78 unfoldingInfo :: Unfolding, -- Its unfolding
79 updateInfo :: UpdateInfo, -- Which args should be updated
81 inlinePragInfo :: !InlinePragInfo -- Inline pragmas
88 setUpdateInfo ud info = info { updateInfo = ud }
89 setDemandInfo dd info = info { demandInfo = dd }
90 setStrictnessInfo st info = info { strictnessInfo = st }
91 setSpecInfo sp info = info { specInfo = sp }
92 setArityInfo ar info = info { arityInfo = ar }
93 setInlinePragInfo pr info = info { inlinePragInfo = pr }
94 setUnfoldingInfo uf info = info { unfoldingInfo = uf }
95 setCafInfo cf info = info { cafInfo = cf }
101 arityInfo = UnknownArity,
103 specInfo = emptySpecEnv,
104 strictnessInfo = NoStrictnessInfo,
105 unfoldingInfo = noUnfolding,
106 updateInfo = NoUpdateInfo,
107 cafInfo = MayHaveCafRefs,
108 inlinePragInfo = NoInlinePragInfo
112 %************************************************************************
114 \subsection[arity-IdInfo]{Arity info about an @Id@}
116 %************************************************************************
118 For locally-defined Ids, the code generator maintains its own notion
119 of their arities; so it should not be asking... (but other things
120 besides the code-generator need arity info!)
124 = UnknownArity -- No idea
125 | ArityExactly Int -- Arity is exactly this
126 | ArityAtLeast Int -- Arity is this or greater
128 exactArity = ArityExactly
129 atLeastArity = ArityAtLeast
130 unknownArity = UnknownArity
132 arityLowerBound :: ArityInfo -> Int
133 arityLowerBound UnknownArity = 0
134 arityLowerBound (ArityAtLeast n) = n
135 arityLowerBound (ArityExactly n) = n
138 ppArityInfo UnknownArity = empty
139 ppArityInfo (ArityExactly arity) = hsep [ptext SLIT("__A"), int arity]
140 ppArityInfo (ArityAtLeast arity) = hsep [ptext SLIT("__AL"), int arity]
143 %************************************************************************
145 \subsection{Inline-pragma information}
147 %************************************************************************
153 | IAmASpecPragmaId -- Used for spec-pragma Ids; don't discard or inline
155 | IWantToBeINLINEd -- User INLINE pragma
156 | IMustNotBeINLINEd -- User NOINLINE pragma
158 | IAmALoopBreaker -- Used by the occurrence analyser to mark loop-breakers
159 -- in a group of recursive definitions
161 | ICanSafelyBeINLINEd -- Used by the occurrence analyser to mark things
162 -- that manifesly occur once, not inside SCCs,
163 -- not in constructor arguments
165 OccInfo -- Says whether the occurrence is inside a lambda
166 -- If so, must only substitute WHNFs
168 Bool -- False <=> occurs in more than one case branch
169 -- If so, there's a code-duplication issue
171 | IAmDead -- Marks unused variables. Sometimes useful for
172 -- lambda and case-bound variables.
174 | IMustBeINLINEd -- Absolutely must inline; used for PrimOps and
175 -- constructors only.
177 instance Outputable InlinePragInfo where
178 ppr NoInlinePragInfo = empty
179 ppr IMustBeINLINEd = ptext SLIT("__UU")
180 ppr IWantToBeINLINEd = ptext SLIT("__U")
181 ppr IMustNotBeINLINEd = ptext SLIT("__Unot")
182 ppr IAmALoopBreaker = ptext SLIT("__Ux")
183 ppr IAmDead = ptext SLIT("__Ud")
184 ppr (ICanSafelyBeINLINEd _ _) = ptext SLIT("__Us")
185 ppr IAmASpecPragmaId = ptext SLIT("__US")
187 instance Show InlinePragInfo where
188 showsPrec p prag = showsPrecSDoc p (ppr prag)
191 The @IMustNotBeDiscarded@ exists only to make Ids that are
192 on the *LHS* of bindings created by SPECIALISE pragmas;
194 The SpecPragmaId is never itself mentioned; it
195 exists solely so that the specialiser will find
196 the call to f, and make specialised version of it.
197 The SpecPragmaId binding is discarded by the specialiser
198 when it gathers up overloaded calls.
199 Meanwhile, it is not discarded as dead code.
203 = StrictOcc -- Occurs syntactically strictly;
204 -- i.e. in a function position or case scrutinee
206 | LazyOcc -- Not syntactically strict (*even* that of a strict function)
207 -- or in a case branch where there's more than one alternative
209 | InsideLam -- Inside a non-linear lambda (that is, a lambda which
210 -- is sure to be instantiated only once).
211 -- Substituting a redex for this occurrence is
212 -- dangerous because it might duplicate work.
214 instance Outputable OccInfo where
215 ppr StrictOcc = text "s"
217 ppr InsideLam = text "l"
220 notInsideLambda :: OccInfo -> Bool
221 notInsideLambda StrictOcc = True
222 notInsideLambda LazyOcc = True
223 notInsideLambda InsideLam = False
226 %************************************************************************
228 \subsection[specialisation-IdInfo]{Specialisation info about an @Id@}
230 %************************************************************************
232 A @IdSpecEnv@ holds details of an @Id@'s specialisations.
235 type IdSpecEnv = SpecEnv CoreExpr
238 For example, if \tr{f}'s @SpecEnv@ contains the mapping:
240 [List a, b] ===> (\d -> f' a b)
242 then when we find an application of f to matching types, we simply replace
243 it by the matching RHS:
245 f (List Int) Bool ===> (\d -> f' Int Bool)
247 All the stuff about how many dictionaries to discard, and what types
248 to apply the specialised function to, are handled by the fact that the
249 SpecEnv contains a template for the result of the specialisation.
251 There is one more exciting case, which is dealt with in exactly the same
252 way. If the specialised value is unboxed then it is lifted at its
253 definition site and unlifted at its uses. For example:
255 pi :: forall a. Num a => a
257 might have a specialisation
259 [Int#] ===> (case pi' of Lift pi# -> pi#)
261 where pi' :: Lift Int# is the specialised version of pi.
264 %************************************************************************
266 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
268 %************************************************************************
270 We specify the strictness of a function by giving information about
271 each of the ``wrapper's'' arguments (see the description about
272 worker/wrapper-style transformations in the PJ/Launchbury paper on
275 The list of @Demands@ specifies: (a)~the strictness properties
276 of a function's arguments; (b)~the {\em existence} of a ``worker''
277 version of the function; and (c)~the type signature of that worker (if
278 it exists); i.e. its calling convention.
284 | StrictnessInfo [Demand]
285 Bool -- True <=> the function diverges regardless of its arguments
286 -- Useful for "error" and other disguised variants thereof.
287 -- BUT NB: f = \x y. error "urk"
288 -- will have info SI [SS] True
289 -- but still (f) and (f 2) are not bot; only (f 3 2) is bot
291 Bool -- True <=> there is a worker. There might not be, even for a
292 -- strict function, because:
293 -- (a) the function might be small enough to inline,
294 -- so no need for w/w split
295 -- (b) the strictness info might be "SSS" or something, so no w/w split.
299 mkStrictnessInfo :: ([Demand], Bool) -> Bool -> StrictnessInfo
301 mkStrictnessInfo (xs, is_bot) has_wrkr
302 | all isLazy xs && not is_bot = NoStrictnessInfo -- Uninteresting
303 | otherwise = StrictnessInfo xs is_bot has_wrkr
305 noStrictnessInfo = NoStrictnessInfo
307 isBottomingStrictness (StrictnessInfo _ bot _) = bot
308 isBottomingStrictness NoStrictnessInfo = False
310 -- appIsBottom returns true if an application to n args would diverge
311 appIsBottom (StrictnessInfo ds bot _) n = bot && (n >= length ds)
312 appIsBottom NoStrictnessInfo n = False
314 ppStrictnessInfo NoStrictnessInfo = empty
315 ppStrictnessInfo (StrictnessInfo wrapper_args bot wrkr_maybe)
316 = hsep [ptext SLIT("__S"), pprDemands wrapper_args bot]
321 workerExists :: StrictnessInfo -> Bool
322 workerExists (StrictnessInfo _ _ worker_exists) = worker_exists
323 workerExists other = False
327 %************************************************************************
329 \subsection[update-IdInfo]{Update-analysis info about an @Id@}
331 %************************************************************************
336 | SomeUpdateInfo UpdateSpec
338 -- we need Eq/Ord to cross-chk update infos in interfaces
340 -- the form in which we pass update-analysis info between modules:
341 type UpdateSpec = [Int]
345 mkUpdateInfo = SomeUpdateInfo
347 updateInfoMaybe NoUpdateInfo = Nothing
348 updateInfoMaybe (SomeUpdateInfo []) = Nothing
349 updateInfoMaybe (SomeUpdateInfo u) = Just u
352 Text instance so that the update annotations can be read in.
355 ppUpdateInfo NoUpdateInfo = empty
356 ppUpdateInfo (SomeUpdateInfo []) = empty
357 ppUpdateInfo (SomeUpdateInfo spec) = (<>) (ptext SLIT("__U ")) (hcat (map int spec))
360 %************************************************************************
362 \subsection[CAF-IdInfo]{CAF-related information}
364 %************************************************************************
366 This information is used to build Static Reference Tables (see
367 simplStg/ComputeSRT.lhs).
371 = MayHaveCafRefs -- either:
372 -- (1) A function or static constructor
373 -- that refers to one or more CAFs,
374 -- (2) A real live CAF
376 | NoCafRefs -- A function or static constructor
377 -- that refers to no CAFs.
379 -- LATER: not sure how easy this is...
383 ppCafInfo NoCafRefs = ptext SLIT("__C")
384 ppCafInfo MayHaveCafRefs = empty