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 )
51 import SpecEnv ( SpecEnv, emptySpecEnv, isEmptySpecEnv )
52 import BasicTypes ( NewOrData )
55 import Maybes ( firstJust )
57 import Unique ( pprUnique )
58 import Util ( mapAccumL )
60 ord = fromEnum :: Char -> Int
61 showTypeCategory = panic "IdInfo.showTypeCategory"
64 An @IdInfo@ gives {\em optional} information about an @Id@. If
65 present it never lies, but it may not be present, in which case there
66 is always a conservative assumption which can be made.
68 Two @Id@s may have different info even though they have the same
69 @Unique@ (and are hence the same @Id@); for example, one might lack
70 the properties attached to the other.
72 The @IdInfo@ gives information about the value, or definition, of the
73 @Id@. It does {\em not} contain information about the @Id@'s usage
74 (except for @DemandInfo@? ToDo).
79 ArityInfo -- Its arity
81 DemandInfo -- Whether or not it is definitely
84 IdSpecEnv -- Specialisations of this function which exist
86 StrictnessInfo -- Strictness properties
88 Unfolding -- Its unfolding; for locally-defined
89 -- things, this can *only* be NoUnfolding
91 UpdateInfo -- Which args should be updated
93 ArgUsageInfo -- how this Id uses its arguments
95 FBTypeInfo -- the Foldr/Build W/W property of this function.
99 noIdInfo = IdInfo UnknownArity UnknownDemand emptySpecEnv NoStrictnessInfo noUnfolding
100 NoUpdateInfo NoArgUsageInfo NoFBTypeInfo
103 Simply turgid. But BE CAREFUL: don't @apply_to_Id@ if that @Id@
104 will in turn @apply_to_IdInfo@ of the self-same @IdInfo@. (A very
105 nasty loop, friends...)
107 apply_to_IdInfo ty_fn idinfo@(IdInfo arity demand spec strictness unfold
108 update arg_usage fb_ww)
109 | isEmptySpecEnv spec
112 = panic "IdInfo:apply_to_IdInfo"
115 Variant of the same thing for the typechecker.
117 applySubstToIdInfo s0 (IdInfo arity demand spec strictness unfold
118 update arg_usage fb_ww)
119 = panic "IdInfo:applySubstToIdInfo"
123 ppIdInfo :: Bool -- True <=> print specialisations, please
127 ppIdInfo specs_please
128 (IdInfo arity demand specenv strictness unfold update arg_usage fbtype)
130 -- order is important!:
134 ppStrictnessInfo strictness,
137 then empty -- ToDo -- sty (not (isDataCon for_this_id))
138 -- better_id_fn inline_env (mEnvToList specenv)
141 -- DemandInfo needn't be printed since it has no effect on interfaces
147 %************************************************************************
149 \subsection[arity-IdInfo]{Arity info about an @Id@}
151 %************************************************************************
155 = UnknownArity -- No idea
156 | ArityExactly Int -- Arity is exactly this
157 | ArityAtLeast Int -- Arity is this or greater
161 exactArity = ArityExactly
162 atLeastArity = ArityAtLeast
163 unknownArity = UnknownArity
165 arityInfo (IdInfo arity _ _ _ _ _ _ _) = arity
167 addArityInfo (IdInfo _ a b c d e f g) arity = IdInfo arity a b c d e f g
169 ppArityInfo UnknownArity = empty
170 ppArityInfo (ArityExactly arity) = hsep [ptext SLIT("_A_"), int arity]
171 ppArityInfo (ArityAtLeast arity) = hsep [ptext SLIT("_A>_"), int arity]
174 %************************************************************************
176 \subsection[demand-IdInfo]{Demand info about an @Id@}
178 %************************************************************************
180 Whether a value is certain to be demanded or not. (This is the
181 information that is computed by the ``front-end'' of the strictness
184 This information is only used within a module, it is not exported
190 | DemandedAsPer Demand
194 noDemandInfo = UnknownDemand
196 mkDemandInfo :: Demand -> DemandInfo
197 mkDemandInfo demand = DemandedAsPer demand
199 willBeDemanded :: DemandInfo -> Bool
200 willBeDemanded (DemandedAsPer demand) = isStrict demand
201 willBeDemanded _ = False
205 demandInfo (IdInfo _ demand _ _ _ _ _ _) = demand
207 addDemandInfo (IdInfo a _ c d e f g h) demand = IdInfo a demand c d e f g h
209 ppDemandInfo UnknownDemand = text "{-# L #-}"
210 ppDemandInfo (DemandedAsPer info) = hsep [text "{-#", text (showList [info] ""), text "#-}"]
213 %************************************************************************
215 \subsection[specialisation-IdInfo]{Specialisation info about an @Id@}
217 %************************************************************************
219 A @IdSpecEnv@ holds details of an @Id@'s specialisations.
222 type IdSpecEnv = SpecEnv SimplifiableCoreExpr
225 For example, if \tr{f}'s @SpecEnv@ contains the mapping:
227 [List a, b] ===> (\d -> f' a b)
229 then when we find an application of f to matching types, we simply replace
230 it by the matching RHS:
232 f (List Int) Bool ===> (\d -> f' Int Bool)
234 All the stuff about how many dictionaries to discard, and what types
235 to apply the specialised function to, are handled by the fact that the
236 SpecEnv contains a template for the result of the specialisation.
238 There is one more exciting case, which is dealt with in exactly the same
239 way. If the specialised value is unboxed then it is lifted at its
240 definition site and unlifted at its uses. For example:
242 pi :: forall a. Num a => a
244 might have a specialisation
246 [Int#] ===> (case pi' of Lift pi# -> pi#)
248 where pi' :: Lift Int# is the specialised version of pi.
252 specInfo :: IdInfo -> IdSpecEnv
253 specInfo (IdInfo _ _ spec _ _ _ _ _) = spec
255 addSpecInfo id_info spec | isEmptySpecEnv spec = id_info
256 addSpecInfo (IdInfo a b _ d e f g h) spec = IdInfo a b spec d e f g h
260 %************************************************************************
262 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
264 %************************************************************************
266 We specify the strictness of a function by giving information about
267 each of the ``wrapper's'' arguments (see the description about
268 worker/wrapper-style transformations in the PJ/Launchbury paper on
271 The list of @Demands@ specifies: (a)~the strictness properties
272 of a function's arguments; (b)~the {\em existence} of a ``worker''
273 version of the function; and (c)~the type signature of that worker (if
274 it exists); i.e. its calling convention.
280 | BottomGuaranteed -- This Id guarantees never to return;
281 -- it is bottom regardless of its arguments.
282 -- Useful for "error" and other disguised
285 | StrictnessInfo [Demand]
286 Bool -- True <=> there is a worker. There might not be, even for a
287 -- strict function, because:
288 -- (a) the function might be small enough to inline,
289 -- so no need for w/w split
290 -- (b) the strictness info might be "SSS" or something, so no w/w split.
292 -- Worker's Id, if applicable, and a list of the constructors
293 -- mentioned by the wrapper. This is necessary so that the
294 -- renamer can slurp them in. Without this info, the renamer doesn't
295 -- know which data types to slurp in concretely. Remember, for
296 -- strict things we don't put the unfolding in the interface file, to save space.
297 -- This constructor list allows the renamer to behave much as if the
298 -- unfolding *was* in the interface file.
302 mkStrictnessInfo :: [Demand] -> Bool -> StrictnessInfo
304 mkStrictnessInfo xs has_wrkr
305 | all is_lazy xs = NoStrictnessInfo -- Uninteresting
306 | otherwise = StrictnessInfo xs has_wrkr
308 is_lazy (WwLazy False) = True -- NB "Absent" args do *not* count!
309 is_lazy _ = False -- (as they imply a worker)
311 noStrictnessInfo = NoStrictnessInfo
312 mkBottomStrictnessInfo = BottomGuaranteed
314 bottomIsGuaranteed BottomGuaranteed = True
315 bottomIsGuaranteed other = False
317 strictnessInfo (IdInfo _ _ _ strict _ _ _ _) = strict
319 addStrictnessInfo id_info NoStrictnessInfo = id_info
320 addStrictnessInfo (IdInfo a b d _ e f g h) strict = IdInfo a b d strict e f g h
322 ppStrictnessInfo NoStrictnessInfo = empty
323 ppStrictnessInfo BottomGuaranteed = ptext SLIT("_bot_")
325 ppStrictnessInfo (StrictnessInfo wrapper_args wrkr_maybe)
326 = hsep [ptext SLIT("_S_"), text (showList wrapper_args "")]
331 workerExists :: StrictnessInfo -> Bool
332 workerExists (StrictnessInfo _ worker_exists) = worker_exists
333 workerExists other = False
337 %************************************************************************
339 \subsection[unfolding-IdInfo]{Unfolding info about an @Id@}
341 %************************************************************************
344 unfoldInfo (IdInfo _ _ _ _ unfolding _ _ _) = unfolding
346 addUnfoldInfo (IdInfo a b d e _ f g h) uf = IdInfo a b d e uf f g h
349 %************************************************************************
351 \subsection[update-IdInfo]{Update-analysis info about an @Id@}
353 %************************************************************************
358 | SomeUpdateInfo UpdateSpec
360 -- we need Eq/Ord to cross-chk update infos in interfaces
362 -- the form in which we pass update-analysis info between modules:
363 type UpdateSpec = [Int]
367 mkUpdateInfo = SomeUpdateInfo
369 updateInfoMaybe NoUpdateInfo = Nothing
370 updateInfoMaybe (SomeUpdateInfo []) = Nothing
371 updateInfoMaybe (SomeUpdateInfo u) = Just u
374 Text instance so that the update annotations can be read in.
377 #ifdef REALLY_HASKELL_1_3
378 instance Read UpdateInfo where
380 instance Text UpdateInfo where
382 readsPrec p s | null s = panic "IdInfo: empty update pragma?!"
383 | otherwise = [(SomeUpdateInfo (map ok_digit s),"")]
385 ok_digit c | c >= '0' && c <= '2' = ord c - ord '0'
386 | otherwise = panic "IdInfo: not a digit while reading update pragma"
388 updateInfo (IdInfo _ _ _ _ _ update _ _) = update
390 addUpdateInfo id_info NoUpdateInfo = id_info
391 addUpdateInfo (IdInfo a b d e f _ g h) upd_info = IdInfo a b d e f upd_info g h
393 ppUpdateInfo NoUpdateInfo = empty
394 ppUpdateInfo (SomeUpdateInfo []) = empty
395 ppUpdateInfo (SomeUpdateInfo spec) = (<>) (ptext SLIT("_U_ ")) (hcat (map int spec))
398 %************************************************************************
400 \subsection[argUsage-IdInfo]{Argument Usage info about an @Id@}
402 %************************************************************************
407 | SomeArgUsageInfo ArgUsageType
408 -- ??? deriving (Eq, Ord)
410 data ArgUsage = ArgUsage Int -- number of arguments (is linear!)
412 type ArgUsageType = [ArgUsage] -- c_1 -> ... -> BLOB
416 mkArgUsageInfo [] = NoArgUsageInfo
417 mkArgUsageInfo au = SomeArgUsageInfo au
419 getArgUsage :: ArgUsageInfo -> ArgUsageType
420 getArgUsage NoArgUsageInfo = []
421 getArgUsage (SomeArgUsageInfo u) = u
425 argUsageInfo (IdInfo _ _ _ _ _ _ au _) = au
427 addArgUsageInfo id_info NoArgUsageInfo = id_info
428 addArgUsageInfo (IdInfo a b d e f g _ h) au_info = IdInfo a b d e f g au_info h
430 ppArgUsageInfo NoArgUsageInfo = empty
431 ppArgUsageInfo (SomeArgUsageInfo aut) = (<>) (ptext SLIT("_L_ ")) (ppArgUsageType aut)
433 ppArgUsage (ArgUsage n) = int n
434 ppArgUsage (UnknownArgUsage) = char '-'
436 ppArgUsageType aut = hcat
438 hcat (punctuate comma (map ppArgUsage aut)),
442 %************************************************************************
444 \subsection[FBType-IdInfo]{Type of an expression through Foldr/build's eyes}
446 %************************************************************************
451 | SomeFBTypeInfo FBType
453 data FBType = FBType [FBConsum] FBProd deriving (Eq)
455 data FBConsum = FBGoodConsum | FBBadConsum deriving(Eq)
456 data FBProd = FBGoodProd | FBBadProd deriving(Eq)
460 mkFBTypeInfo = SomeFBTypeInfo
462 getFBType :: FBTypeInfo -> Maybe FBType
463 getFBType NoFBTypeInfo = Nothing
464 getFBType (SomeFBTypeInfo u) = Just u
468 fbTypeInfo (IdInfo _ _ _ _ _ _ _ fb) = fb
470 addFBTypeInfo id_info NoFBTypeInfo = id_info
471 addFBTypeInfo (IdInfo a b d e f g h _) fb_info = IdInfo a b d e f g h fb_info
473 ppFBTypeInfo NoFBTypeInfo = empty
474 ppFBTypeInfo (SomeFBTypeInfo (FBType cons prod))
475 = (<>) (ptext SLIT("_F_ ")) (ppFBType cons prod)
477 ppFBType cons prod = hcat
478 ([ char '"' ] ++ map ppCons cons ++ [ char '-', ppProd prod, char '"' ])
480 ppCons FBGoodConsum = char 'G'
481 ppCons FBBadConsum = char 'B'
482 ppProd FBGoodProd = char 'G'
483 ppProd FBBadProd = char 'B'