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
15 applySubstToIdInfo, apply_to_IdInfo, -- not for general use, please
18 exactArity, atLeastArity, unknownArity,
19 arityInfo, addArityInfo, ppArityInfo,
22 noDemandInfo, mkDemandInfo, demandInfo, ppDemandInfo, addDemandInfo, willBeDemanded,
24 StrictnessInfo(..), -- Non-abstract
25 Demand(..), NewOrData, -- Non-abstract
28 mkStrictnessInfo, mkBottomStrictnessInfo, noStrictnessInfo, bottomIsGuaranteed,
29 strictnessInfo, ppStrictnessInfo, addStrictnessInfo,
31 unfoldInfo, addUnfoldInfo,
33 IdSpecEnv, specInfo, addSpecInfo,
35 UpdateInfo, UpdateSpec,
36 mkUpdateInfo, updateInfo, updateInfoMaybe, ppUpdateInfo, addUpdateInfo,
38 ArgUsageInfo, ArgUsage(..), ArgUsageType,
39 mkArgUsageInfo, argUsageInfo, addArgUsageInfo, getArgUsage,
41 FBTypeInfo, FBType(..), FBConsum(..), FBProd(..),
42 fbTypeInfo, ppFBTypeInfo, addFBTypeInfo, mkFBTypeInfo, getFBType
45 #include "HsVersions.h"
48 import {-# SOURCE #-} CoreUnfold ( Unfolding, noUnfolding )
49 import {-# SOURCE #-} CoreSyn ( SimplifiableCoreExpr )
50 -- for mkdependHS, CoreSyn.hi-boot refers to it:
51 import BinderInfo ( BinderInfo )
53 import SpecEnv ( SpecEnv, emptySpecEnv, isEmptySpecEnv )
54 import BasicTypes ( NewOrData )
62 An @IdInfo@ gives {\em optional} information about an @Id@. If
63 present it never lies, but it may not be present, in which case there
64 is always a conservative assumption which can be made.
66 Two @Id@s may have different info even though they have the same
67 @Unique@ (and are hence the same @Id@); for example, one might lack
68 the properties attached to the other.
70 The @IdInfo@ gives information about the value, or definition, of the
71 @Id@. It does {\em not} contain information about the @Id@'s usage
72 (except for @DemandInfo@? ToDo).
77 ArityInfo -- Its arity
79 DemandInfo -- Whether or not it is definitely
82 IdSpecEnv -- Specialisations of this function which exist
84 StrictnessInfo -- Strictness properties
86 Unfolding -- Its unfolding; for locally-defined
87 -- things, this can *only* be NoUnfolding
89 UpdateInfo -- Which args should be updated
91 ArgUsageInfo -- how this Id uses its arguments
93 FBTypeInfo -- the Foldr/Build W/W property of this function.
97 noIdInfo = IdInfo UnknownArity UnknownDemand emptySpecEnv NoStrictnessInfo noUnfolding
98 NoUpdateInfo NoArgUsageInfo NoFBTypeInfo
101 Simply turgid. But BE CAREFUL: don't @apply_to_Id@ if that @Id@
102 will in turn @apply_to_IdInfo@ of the self-same @IdInfo@. (A very
103 nasty loop, friends...)
105 apply_to_IdInfo ty_fn idinfo@(IdInfo arity demand spec strictness unfold
106 update arg_usage fb_ww)
107 | isEmptySpecEnv spec
110 = panic "IdInfo:apply_to_IdInfo"
113 Variant of the same thing for the typechecker.
115 applySubstToIdInfo s0 (IdInfo arity demand spec strictness unfold
116 update arg_usage fb_ww)
117 = panic "IdInfo:applySubstToIdInfo"
121 ppIdInfo :: Bool -- True <=> print specialisations, please
125 ppIdInfo specs_please
126 (IdInfo arity demand specenv strictness unfold update arg_usage fbtype)
128 -- order is important!:
132 ppStrictnessInfo strictness,
135 then empty -- ToDo -- sty (not (isDataCon for_this_id))
136 -- better_id_fn inline_env (mEnvToList specenv)
139 -- DemandInfo needn't be printed since it has no effect on interfaces
145 %************************************************************************
147 \subsection[arity-IdInfo]{Arity info about an @Id@}
149 %************************************************************************
153 = UnknownArity -- No idea
154 | ArityExactly Int -- Arity is exactly this
155 | ArityAtLeast Int -- Arity is this or greater
159 exactArity = ArityExactly
160 atLeastArity = ArityAtLeast
161 unknownArity = UnknownArity
163 arityInfo (IdInfo arity _ _ _ _ _ _ _) = arity
165 addArityInfo (IdInfo _ a b c d e f g) arity = IdInfo arity a b c d e f g
167 ppArityInfo UnknownArity = empty
168 ppArityInfo (ArityExactly arity) = hsep [ptext SLIT("_A_"), int arity]
169 ppArityInfo (ArityAtLeast arity) = hsep [ptext SLIT("_A>_"), int arity]
172 %************************************************************************
174 \subsection[demand-IdInfo]{Demand info about an @Id@}
176 %************************************************************************
178 Whether a value is certain to be demanded or not. (This is the
179 information that is computed by the ``front-end'' of the strictness
182 This information is only used within a module, it is not exported
188 | DemandedAsPer Demand
192 noDemandInfo = UnknownDemand
194 mkDemandInfo :: Demand -> DemandInfo
195 mkDemandInfo demand = DemandedAsPer demand
197 willBeDemanded :: DemandInfo -> Bool
198 willBeDemanded (DemandedAsPer demand) = isStrict demand
199 willBeDemanded _ = False
203 demandInfo (IdInfo _ demand _ _ _ _ _ _) = demand
205 addDemandInfo (IdInfo a _ c d e f g h) demand = IdInfo a demand c d e f g h
207 ppDemandInfo UnknownDemand = text "{-# L #-}"
208 ppDemandInfo (DemandedAsPer info) = hsep [text "{-#", text (showList [info] ""), text "#-}"]
211 %************************************************************************
213 \subsection[specialisation-IdInfo]{Specialisation info about an @Id@}
215 %************************************************************************
217 A @IdSpecEnv@ holds details of an @Id@'s specialisations.
220 type IdSpecEnv = SpecEnv SimplifiableCoreExpr
223 For example, if \tr{f}'s @SpecEnv@ contains the mapping:
225 [List a, b] ===> (\d -> f' a b)
227 then when we find an application of f to matching types, we simply replace
228 it by the matching RHS:
230 f (List Int) Bool ===> (\d -> f' Int Bool)
232 All the stuff about how many dictionaries to discard, and what types
233 to apply the specialised function to, are handled by the fact that the
234 SpecEnv contains a template for the result of the specialisation.
236 There is one more exciting case, which is dealt with in exactly the same
237 way. If the specialised value is unboxed then it is lifted at its
238 definition site and unlifted at its uses. For example:
240 pi :: forall a. Num a => a
242 might have a specialisation
244 [Int#] ===> (case pi' of Lift pi# -> pi#)
246 where pi' :: Lift Int# is the specialised version of pi.
250 specInfo :: IdInfo -> IdSpecEnv
251 specInfo (IdInfo _ _ spec _ _ _ _ _) = spec
253 addSpecInfo id_info spec | isEmptySpecEnv spec = id_info
254 addSpecInfo (IdInfo a b _ d e f g h) spec = IdInfo a b spec d e f g h
258 %************************************************************************
260 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
262 %************************************************************************
264 We specify the strictness of a function by giving information about
265 each of the ``wrapper's'' arguments (see the description about
266 worker/wrapper-style transformations in the PJ/Launchbury paper on
269 The list of @Demands@ specifies: (a)~the strictness properties
270 of a function's arguments; (b)~the {\em existence} of a ``worker''
271 version of the function; and (c)~the type signature of that worker (if
272 it exists); i.e. its calling convention.
278 | BottomGuaranteed -- This Id guarantees never to return;
279 -- it is bottom regardless of its arguments.
280 -- Useful for "error" and other disguised
283 | StrictnessInfo [Demand]
284 Bool -- True <=> there is a worker. There might not be, even for a
285 -- strict function, because:
286 -- (a) the function might be small enough to inline,
287 -- so no need for w/w split
288 -- (b) the strictness info might be "SSS" or something, so no w/w split.
290 -- Worker's Id, if applicable, and a list of the constructors
291 -- mentioned by the wrapper. This is necessary so that the
292 -- renamer can slurp them in. Without this info, the renamer doesn't
293 -- know which data types to slurp in concretely. Remember, for
294 -- strict things we don't put the unfolding in the interface file, to save space.
295 -- This constructor list allows the renamer to behave much as if the
296 -- unfolding *was* in the interface file.
300 mkStrictnessInfo :: [Demand] -> Bool -> StrictnessInfo
302 mkStrictnessInfo xs has_wrkr
303 | all is_lazy xs = NoStrictnessInfo -- Uninteresting
304 | otherwise = StrictnessInfo xs has_wrkr
306 is_lazy (WwLazy False) = True -- NB "Absent" args do *not* count!
307 is_lazy _ = False -- (as they imply a worker)
309 noStrictnessInfo = NoStrictnessInfo
310 mkBottomStrictnessInfo = BottomGuaranteed
312 bottomIsGuaranteed BottomGuaranteed = True
313 bottomIsGuaranteed other = False
315 strictnessInfo (IdInfo _ _ _ strict _ _ _ _) = strict
317 addStrictnessInfo id_info NoStrictnessInfo = id_info
318 addStrictnessInfo (IdInfo a b d _ e f g h) strict = IdInfo a b d strict e f g h
320 ppStrictnessInfo NoStrictnessInfo = empty
321 ppStrictnessInfo BottomGuaranteed = ptext SLIT("_bot_")
323 ppStrictnessInfo (StrictnessInfo wrapper_args wrkr_maybe)
324 = hsep [ptext SLIT("_S_"), text (showList wrapper_args "")]
329 workerExists :: StrictnessInfo -> Bool
330 workerExists (StrictnessInfo _ worker_exists) = worker_exists
331 workerExists other = False
335 %************************************************************************
337 \subsection[unfolding-IdInfo]{Unfolding info about an @Id@}
339 %************************************************************************
342 unfoldInfo (IdInfo _ _ _ _ unfolding _ _ _) = unfolding
344 addUnfoldInfo (IdInfo a b d e _ f g h) uf = IdInfo a b d e uf f g h
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 instance Read UpdateInfo where
376 readsPrec p s | null s = panic "IdInfo: empty update pragma?!"
377 | otherwise = [(SomeUpdateInfo (map ok_digit s),"")]
379 ok_digit c | c >= '0' && c <= '2' = ord c - ord '0'
380 | otherwise = panic "IdInfo: not a digit while reading update pragma"
382 updateInfo (IdInfo _ _ _ _ _ update _ _) = update
384 addUpdateInfo id_info NoUpdateInfo = id_info
385 addUpdateInfo (IdInfo a b d e f _ g h) upd_info = IdInfo a b d e f upd_info g h
387 ppUpdateInfo NoUpdateInfo = empty
388 ppUpdateInfo (SomeUpdateInfo []) = empty
389 ppUpdateInfo (SomeUpdateInfo spec) = (<>) (ptext SLIT("_U_ ")) (hcat (map int spec))
392 %************************************************************************
394 \subsection[argUsage-IdInfo]{Argument Usage info about an @Id@}
396 %************************************************************************
401 | SomeArgUsageInfo ArgUsageType
402 -- ??? deriving (Eq, Ord)
404 data ArgUsage = ArgUsage Int -- number of arguments (is linear!)
406 type ArgUsageType = [ArgUsage] -- c_1 -> ... -> BLOB
410 mkArgUsageInfo [] = NoArgUsageInfo
411 mkArgUsageInfo au = SomeArgUsageInfo au
413 getArgUsage :: ArgUsageInfo -> ArgUsageType
414 getArgUsage NoArgUsageInfo = []
415 getArgUsage (SomeArgUsageInfo u) = u
419 argUsageInfo (IdInfo _ _ _ _ _ _ au _) = au
421 addArgUsageInfo id_info NoArgUsageInfo = id_info
422 addArgUsageInfo (IdInfo a b d e f g _ h) au_info = IdInfo a b d e f g au_info h
425 ppArgUsageInfo NoArgUsageInfo = empty
426 ppArgUsageInfo (SomeArgUsageInfo aut) = (<>) (ptext SLIT("_L_ ")) (ppArgUsageType aut)
429 ppArgUsage (ArgUsage n) = int n
430 ppArgUsage (UnknownArgUsage) = char '-'
432 ppArgUsageType aut = hcat
434 hcat (punctuate comma (map ppArgUsage aut)),
438 %************************************************************************
440 \subsection[FBType-IdInfo]{Type of an expression through Foldr/build's eyes}
442 %************************************************************************
447 | SomeFBTypeInfo FBType
449 data FBType = FBType [FBConsum] FBProd deriving (Eq)
451 data FBConsum = FBGoodConsum | FBBadConsum deriving(Eq)
452 data FBProd = FBGoodProd | FBBadProd deriving(Eq)
456 mkFBTypeInfo = SomeFBTypeInfo
458 getFBType :: FBTypeInfo -> Maybe FBType
459 getFBType NoFBTypeInfo = Nothing
460 getFBType (SomeFBTypeInfo u) = Just u
464 fbTypeInfo (IdInfo _ _ _ _ _ _ _ fb) = fb
466 addFBTypeInfo id_info NoFBTypeInfo = id_info
467 addFBTypeInfo (IdInfo a b d e f g h _) fb_info = IdInfo a b d e f g h fb_info
469 ppFBTypeInfo NoFBTypeInfo = empty
470 ppFBTypeInfo (SomeFBTypeInfo (FBType cons prod))
471 = (<>) (ptext SLIT("_F_ ")) (ppFBType cons prod)
473 ppFBType cons prod = hcat
474 ([ char '"' ] ++ map ppCons cons ++ [ char '-', ppProd prod, char '"' ])
476 ppCons FBGoodConsum = char 'G'
477 ppCons FBBadConsum = char 'B'
478 ppProd FBGoodProd = char 'G'
479 ppProd FBBadProd = char 'B'