2 % (c) The GRASP/AQUA Project, Glasgow University, 1993-1996
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,
23 noDemandInfo, mkDemandInfo, demandInfo, ppDemandInfo, setDemandInfo, willBeDemanded,
24 Demand(..), -- Non-abstract
27 StrictnessInfo(..), -- Non-abstract
29 mkStrictnessInfo, mkBottomStrictnessInfo, noStrictnessInfo, bottomIsGuaranteed,
30 strictnessInfo, ppStrictnessInfo, setStrictnessInfo,
33 unfoldingInfo, setUnfoldingInfo,
37 inlinePragInfo, setInlinePragInfo,
40 IdSpecEnv, specInfo, setSpecInfo,
43 UpdateInfo, UpdateSpec,
44 mkUpdateInfo, updateInfo, updateInfoMaybe, ppUpdateInfo, setUpdateInfo,
47 ArgUsageInfo, ArgUsage(..), ArgUsageType,
48 mkArgUsageInfo, argUsageInfo, setArgUsageInfo, getArgUsage,
51 FBTypeInfo, FBType(..), FBConsum(..), FBProd(..),
52 fbTypeInfo, ppFBTypeInfo, setFBTypeInfo, mkFBTypeInfo, getFBType
55 #include "HsVersions.h"
58 import {-# SOURCE #-} CoreUnfold ( Unfolding, noUnfolding )
59 import {-# SOURCE #-} CoreSyn ( CoreExpr )
61 -- for mkdependHS, CoreSyn.hi-boot refers to it:
62 import BinderInfo ( BinderInfo )
64 import SpecEnv ( SpecEnv, emptySpecEnv )
65 import BasicTypes ( NewOrData )
73 An @IdInfo@ gives {\em optional} information about an @Id@. If
74 present it never lies, but it may not be present, in which case there
75 is always a conservative assumption which can be made.
77 Two @Id@s may have different info even though they have the same
78 @Unique@ (and are hence the same @Id@); for example, one might lack
79 the properties attached to the other.
81 The @IdInfo@ gives information about the value, or definition, of the
82 @Id@. It does {\em not} contain information about the @Id@'s usage
83 (except for @DemandInfo@? ToDo).
88 arityInfo :: ArityInfo, -- Its arity
90 demandInfo :: DemandInfo, -- Whether or not it is definitely demanded
92 specInfo :: IdSpecEnv, -- Specialisations of this function which exist
94 strictnessInfo :: StrictnessInfo, -- Strictness properties
96 unfoldingInfo :: Unfolding, -- Its unfolding; for locally-defined
97 -- things, this can *only* be NoUnfolding
99 updateInfo :: UpdateInfo, -- Which args should be updated
101 argUsageInfo :: ArgUsageInfo, -- how this Id uses its arguments
103 fbTypeInfo :: FBTypeInfo, -- the Foldr/Build W/W property of this function.
105 inlinePragInfo :: InlinePragInfo -- Inline pragmas
112 setFBTypeInfo fb info = info { fbTypeInfo = fb }
113 setArgUsageInfo au info = info { argUsageInfo = au }
114 setUpdateInfo ud info = info { updateInfo = ud }
115 setDemandInfo dd info = info { demandInfo = dd }
116 setStrictnessInfo st info = info { strictnessInfo = st }
117 setSpecInfo sp info = info { specInfo = sp }
118 setArityInfo ar info = info { arityInfo = ar }
119 setInlinePragInfo pr info = info { inlinePragInfo = pr }
120 setUnfoldingInfo uf info = info { unfoldingInfo = uf }
126 arityInfo = UnknownArity,
127 demandInfo = UnknownDemand,
128 specInfo = emptySpecEnv,
129 strictnessInfo = NoStrictnessInfo,
130 unfoldingInfo = noUnfolding,
131 updateInfo = NoUpdateInfo,
132 argUsageInfo = NoArgUsageInfo,
133 fbTypeInfo = NoFBTypeInfo,
134 inlinePragInfo = NoPragmaInfo
139 ppIdInfo :: Bool -- True <=> print specialisations, please
143 ppIdInfo specs_please (IdInfo {arityInfo, updateInfo, strictnessInfo, demandInfo})
145 ppArityInfo arityInfo,
146 ppUpdateInfo updateInfo,
147 ppStrictnessInfo strictnessInfo,
148 ppDemandInfo demandInfo
152 %************************************************************************
154 \subsection[arity-IdInfo]{Arity info about an @Id@}
156 %************************************************************************
160 = UnknownArity -- No idea
161 | ArityExactly Int -- Arity is exactly this
162 | ArityAtLeast Int -- Arity is this or greater
164 exactArity = ArityExactly
165 atLeastArity = ArityAtLeast
166 unknownArity = UnknownArity
168 ppArityInfo UnknownArity = empty
169 ppArityInfo (ArityExactly arity) = hsep [ptext SLIT("_A_"), int arity]
170 ppArityInfo (ArityAtLeast arity) = hsep [ptext SLIT("_A>_"), int arity]
173 %************************************************************************
175 \subsection{Inline-pragma information}
177 %************************************************************************
183 | IWantToBeINLINEd -- user requests that we inline this
185 | IDontWantToBeINLINEd -- user requests that we don't inline this
187 | IMustNotBeINLINEd -- Used by the simplifier to prevent looping
188 -- on recursive definitions
190 | IMustBeINLINEd -- Absolutely must inline; used for PrimOps only
194 %************************************************************************
196 \subsection[specialisation-IdInfo]{Specialisation info about an @Id@}
198 %************************************************************************
200 A @IdSpecEnv@ holds details of an @Id@'s specialisations.
203 type IdSpecEnv = SpecEnv CoreExpr
206 For example, if \tr{f}'s @SpecEnv@ contains the mapping:
208 [List a, b] ===> (\d -> f' a b)
210 then when we find an application of f to matching types, we simply replace
211 it by the matching RHS:
213 f (List Int) Bool ===> (\d -> f' Int Bool)
215 All the stuff about how many dictionaries to discard, and what types
216 to apply the specialised function to, are handled by the fact that the
217 SpecEnv contains a template for the result of the specialisation.
219 There is one more exciting case, which is dealt with in exactly the same
220 way. If the specialised value is unboxed then it is lifted at its
221 definition site and unlifted at its uses. For example:
223 pi :: forall a. Num a => a
225 might have a specialisation
227 [Int#] ===> (case pi' of Lift pi# -> pi#)
229 where pi' :: Lift Int# is the specialised version of pi.
233 %************************************************************************
235 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
237 %************************************************************************
239 We specify the strictness of a function by giving information about
240 each of the ``wrapper's'' arguments (see the description about
241 worker/wrapper-style transformations in the PJ/Launchbury paper on
244 The list of @Demands@ specifies: (a)~the strictness properties
245 of a function's arguments; (b)~the {\em existence} of a ``worker''
246 version of the function; and (c)~the type signature of that worker (if
247 it exists); i.e. its calling convention.
253 | BottomGuaranteed -- This Id guarantees never to return;
254 -- it is bottom regardless of its arguments.
255 -- Useful for "error" and other disguised
258 | StrictnessInfo [Demand]
259 Bool -- True <=> there is a worker. There might not be, even for a
260 -- strict function, because:
261 -- (a) the function might be small enough to inline,
262 -- so no need for w/w split
263 -- (b) the strictness info might be "SSS" or something, so no w/w split.
265 -- Worker's Id, if applicable, and a list of the constructors
266 -- mentioned by the wrapper. This is necessary so that the
267 -- renamer can slurp them in. Without this info, the renamer doesn't
268 -- know which data types to slurp in concretely. Remember, for
269 -- strict things we don't put the unfolding in the interface file, to save space.
270 -- This constructor list allows the renamer to behave much as if the
271 -- unfolding *was* in the interface file.
275 mkStrictnessInfo :: [Demand] -> Bool -> StrictnessInfo
277 mkStrictnessInfo xs has_wrkr
278 | all is_lazy xs = NoStrictnessInfo -- Uninteresting
279 | otherwise = StrictnessInfo xs has_wrkr
281 is_lazy (WwLazy False) = True -- NB "Absent" args do *not* count!
282 is_lazy _ = False -- (as they imply a worker)
284 noStrictnessInfo = NoStrictnessInfo
285 mkBottomStrictnessInfo = BottomGuaranteed
287 bottomIsGuaranteed BottomGuaranteed = True
288 bottomIsGuaranteed other = False
290 ppStrictnessInfo NoStrictnessInfo = empty
291 ppStrictnessInfo BottomGuaranteed = ptext SLIT("_bot_")
293 ppStrictnessInfo (StrictnessInfo wrapper_args wrkr_maybe)
294 = hsep [ptext SLIT("_S_"), text (showList wrapper_args "")]
299 workerExists :: StrictnessInfo -> Bool
300 workerExists (StrictnessInfo _ worker_exists) = worker_exists
301 workerExists other = False
305 %************************************************************************
307 \subsection[demand-IdInfo]{Demand info about an @Id@}
309 %************************************************************************
311 Whether a value is certain to be demanded or not. (This is the
312 information that is computed by the ``front-end'' of the strictness
315 This information is only used within a module, it is not exported
321 | DemandedAsPer Demand
325 noDemandInfo = UnknownDemand
327 mkDemandInfo :: Demand -> DemandInfo
328 mkDemandInfo demand = DemandedAsPer demand
330 willBeDemanded :: DemandInfo -> Bool
331 willBeDemanded (DemandedAsPer demand) = isStrict demand
332 willBeDemanded _ = False
334 ppDemandInfo UnknownDemand = text "{-# L #-}"
335 ppDemandInfo (DemandedAsPer info) = hsep [text "{-#", text (showList [info] ""), text "#-}"]
339 %************************************************************************
341 \subsection[update-IdInfo]{Update-analysis info about an @Id@}
343 %************************************************************************
348 | SomeUpdateInfo UpdateSpec
350 -- we need Eq/Ord to cross-chk update infos in interfaces
352 -- the form in which we pass update-analysis info between modules:
353 type UpdateSpec = [Int]
357 mkUpdateInfo = SomeUpdateInfo
359 updateInfoMaybe NoUpdateInfo = Nothing
360 updateInfoMaybe (SomeUpdateInfo []) = Nothing
361 updateInfoMaybe (SomeUpdateInfo u) = Just u
364 Text instance so that the update annotations can be read in.
367 ppUpdateInfo NoUpdateInfo = empty
368 ppUpdateInfo (SomeUpdateInfo []) = empty
369 ppUpdateInfo (SomeUpdateInfo spec) = (<>) (ptext SLIT("_U_ ")) (hcat (map int spec))
372 %************************************************************************
374 \subsection[argUsage-IdInfo]{Argument Usage info about an @Id@}
376 %************************************************************************
381 | SomeArgUsageInfo ArgUsageType
383 data ArgUsage = ArgUsage Int -- number of arguments (is linear!)
386 type ArgUsageType = [ArgUsage] -- c_1 -> ... -> BLOB
390 mkArgUsageInfo [] = NoArgUsageInfo
391 mkArgUsageInfo au = SomeArgUsageInfo au
393 getArgUsage :: ArgUsageInfo -> ArgUsageType
394 getArgUsage NoArgUsageInfo = []
395 getArgUsage (SomeArgUsageInfo u) = u
400 ppArgUsageInfo NoArgUsageInfo = empty
401 ppArgUsageInfo (SomeArgUsageInfo aut) = (<>) (ptext SLIT("_L_ ")) (ppArgUsageType aut)
404 ppArgUsage (ArgUsage n) = int n
405 ppArgUsage (UnknownArgUsage) = char '-'
407 ppArgUsageType aut = hcat
409 hcat (punctuate comma (map ppArgUsage aut)),
414 %************************************************************************
416 \subsection[FBType-IdInfo]{Type of an expression through Foldr/build's eyes}
418 %************************************************************************
423 | SomeFBTypeInfo FBType
425 data FBType = FBType [FBConsum] FBProd deriving (Eq)
427 data FBConsum = FBGoodConsum | FBBadConsum deriving(Eq)
428 data FBProd = FBGoodProd | FBBadProd deriving(Eq)
432 mkFBTypeInfo = SomeFBTypeInfo
434 getFBType :: FBTypeInfo -> Maybe FBType
435 getFBType NoFBTypeInfo = Nothing
436 getFBType (SomeFBTypeInfo u) = Just u
440 ppFBTypeInfo NoFBTypeInfo = empty
441 ppFBTypeInfo (SomeFBTypeInfo (FBType cons prod))
442 = (<>) (ptext SLIT("_F_ ")) (ppFBType cons prod)
444 ppFBType cons prod = hcat
445 ([ char '"' ] ++ map ppCons cons ++ [ char '-', ppProd prod, char '"' ])
447 ppCons FBGoodConsum = char 'G'
448 ppCons FBBadConsum = char 'B'
449 ppProd FBGoodProd = char 'G'
450 ppProd FBBadProd = char 'B'