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 %************************************************************************
185 | IMustNotBeINLINEd -- Used by the simplifier to prevent looping
186 -- on recursive definitions
188 | IMustBeINLINEd -- Absolutely must inline; used for PrimOps only
192 %************************************************************************
194 \subsection[specialisation-IdInfo]{Specialisation info about an @Id@}
196 %************************************************************************
198 A @IdSpecEnv@ holds details of an @Id@'s specialisations.
201 type IdSpecEnv = SpecEnv CoreExpr
204 For example, if \tr{f}'s @SpecEnv@ contains the mapping:
206 [List a, b] ===> (\d -> f' a b)
208 then when we find an application of f to matching types, we simply replace
209 it by the matching RHS:
211 f (List Int) Bool ===> (\d -> f' Int Bool)
213 All the stuff about how many dictionaries to discard, and what types
214 to apply the specialised function to, are handled by the fact that the
215 SpecEnv contains a template for the result of the specialisation.
217 There is one more exciting case, which is dealt with in exactly the same
218 way. If the specialised value is unboxed then it is lifted at its
219 definition site and unlifted at its uses. For example:
221 pi :: forall a. Num a => a
223 might have a specialisation
225 [Int#] ===> (case pi' of Lift pi# -> pi#)
227 where pi' :: Lift Int# is the specialised version of pi.
231 %************************************************************************
233 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
235 %************************************************************************
237 We specify the strictness of a function by giving information about
238 each of the ``wrapper's'' arguments (see the description about
239 worker/wrapper-style transformations in the PJ/Launchbury paper on
242 The list of @Demands@ specifies: (a)~the strictness properties
243 of a function's arguments; (b)~the {\em existence} of a ``worker''
244 version of the function; and (c)~the type signature of that worker (if
245 it exists); i.e. its calling convention.
251 | BottomGuaranteed -- This Id guarantees never to return;
252 -- it is bottom regardless of its arguments.
253 -- Useful for "error" and other disguised
256 | StrictnessInfo [Demand]
257 Bool -- True <=> there is a worker. There might not be, even for a
258 -- strict function, because:
259 -- (a) the function might be small enough to inline,
260 -- so no need for w/w split
261 -- (b) the strictness info might be "SSS" or something, so no w/w split.
263 -- Worker's Id, if applicable, and a list of the constructors
264 -- mentioned by the wrapper. This is necessary so that the
265 -- renamer can slurp them in. Without this info, the renamer doesn't
266 -- know which data types to slurp in concretely. Remember, for
267 -- strict things we don't put the unfolding in the interface file, to save space.
268 -- This constructor list allows the renamer to behave much as if the
269 -- unfolding *was* in the interface file.
273 mkStrictnessInfo :: [Demand] -> Bool -> StrictnessInfo
275 mkStrictnessInfo xs has_wrkr
276 | all is_lazy xs = NoStrictnessInfo -- Uninteresting
277 | otherwise = StrictnessInfo xs has_wrkr
279 is_lazy (WwLazy False) = True -- NB "Absent" args do *not* count!
280 is_lazy _ = False -- (as they imply a worker)
282 noStrictnessInfo = NoStrictnessInfo
283 mkBottomStrictnessInfo = BottomGuaranteed
285 bottomIsGuaranteed BottomGuaranteed = True
286 bottomIsGuaranteed other = False
288 ppStrictnessInfo NoStrictnessInfo = empty
289 ppStrictnessInfo BottomGuaranteed = ptext SLIT("_bot_")
291 ppStrictnessInfo (StrictnessInfo wrapper_args wrkr_maybe)
292 = hsep [ptext SLIT("_S_"), text (showList wrapper_args "")]
297 workerExists :: StrictnessInfo -> Bool
298 workerExists (StrictnessInfo _ worker_exists) = worker_exists
299 workerExists other = False
303 %************************************************************************
305 \subsection[demand-IdInfo]{Demand info about an @Id@}
307 %************************************************************************
309 Whether a value is certain to be demanded or not. (This is the
310 information that is computed by the ``front-end'' of the strictness
313 This information is only used within a module, it is not exported
319 | DemandedAsPer Demand
323 noDemandInfo = UnknownDemand
325 mkDemandInfo :: Demand -> DemandInfo
326 mkDemandInfo demand = DemandedAsPer demand
328 willBeDemanded :: DemandInfo -> Bool
329 willBeDemanded (DemandedAsPer demand) = isStrict demand
330 willBeDemanded _ = False
332 ppDemandInfo UnknownDemand = text "{-# L #-}"
333 ppDemandInfo (DemandedAsPer info) = hsep [text "{-#", text (showList [info] ""), text "#-}"]
337 %************************************************************************
339 \subsection[update-IdInfo]{Update-analysis info about an @Id@}
341 %************************************************************************
346 | SomeUpdateInfo UpdateSpec
348 -- we need Eq/Ord to cross-chk update infos in interfaces
350 -- the form in which we pass update-analysis info between modules:
351 type UpdateSpec = [Int]
355 mkUpdateInfo = SomeUpdateInfo
357 updateInfoMaybe NoUpdateInfo = Nothing
358 updateInfoMaybe (SomeUpdateInfo []) = Nothing
359 updateInfoMaybe (SomeUpdateInfo u) = Just u
362 Text instance so that the update annotations can be read in.
365 ppUpdateInfo NoUpdateInfo = empty
366 ppUpdateInfo (SomeUpdateInfo []) = empty
367 ppUpdateInfo (SomeUpdateInfo spec) = (<>) (ptext SLIT("_U_ ")) (hcat (map int spec))
370 %************************************************************************
372 \subsection[argUsage-IdInfo]{Argument Usage info about an @Id@}
374 %************************************************************************
379 | SomeArgUsageInfo ArgUsageType
381 data ArgUsage = ArgUsage Int -- number of arguments (is linear!)
384 type ArgUsageType = [ArgUsage] -- c_1 -> ... -> BLOB
388 mkArgUsageInfo [] = NoArgUsageInfo
389 mkArgUsageInfo au = SomeArgUsageInfo au
391 getArgUsage :: ArgUsageInfo -> ArgUsageType
392 getArgUsage NoArgUsageInfo = []
393 getArgUsage (SomeArgUsageInfo u) = u
398 ppArgUsageInfo NoArgUsageInfo = empty
399 ppArgUsageInfo (SomeArgUsageInfo aut) = (<>) (ptext SLIT("_L_ ")) (ppArgUsageType aut)
402 ppArgUsage (ArgUsage n) = int n
403 ppArgUsage (UnknownArgUsage) = char '-'
405 ppArgUsageType aut = hcat
407 hcat (punctuate comma (map ppArgUsage aut)),
412 %************************************************************************
414 \subsection[FBType-IdInfo]{Type of an expression through Foldr/build's eyes}
416 %************************************************************************
421 | SomeFBTypeInfo FBType
423 data FBType = FBType [FBConsum] FBProd deriving (Eq)
425 data FBConsum = FBGoodConsum | FBBadConsum deriving(Eq)
426 data FBProd = FBGoodProd | FBBadProd deriving(Eq)
430 mkFBTypeInfo = SomeFBTypeInfo
432 getFBType :: FBTypeInfo -> Maybe FBType
433 getFBType NoFBTypeInfo = Nothing
434 getFBType (SomeFBTypeInfo u) = Just u
438 ppFBTypeInfo NoFBTypeInfo = empty
439 ppFBTypeInfo (SomeFBTypeInfo (FBType cons prod))
440 = (<>) (ptext SLIT("_F_ ")) (ppFBType cons prod)
442 ppFBType cons prod = hcat
443 ([ char '"' ] ++ map ppCons cons ++ [ char '-', ppProd prod, char '"' ])
445 ppCons FBGoodConsum = char 'G'
446 ppCons FBBadConsum = char 'B'
447 ppProd FBGoodProd = char 'G'
448 ppProd FBBadProd = char 'B'