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
10 #include "HsVersions.h"
17 applySubstToIdInfo, apply_to_IdInfo, -- not for general use, please
19 OptIdInfo(..), -- class; for convenience only
20 -- all the *Infos herein are instances of it
22 -- component "id infos"; also abstract:
27 mkArityInfo, unknownArity, arityMaybe,
33 MatchEnv, -- the SpecEnv (why is this exported???)
34 StrictnessInfo(..), -- non-abstract
35 Demand(..), -- non-abstract
37 wwLazy, wwStrict, wwUnpack, wwPrim, wwEnum,
38 indicatesWorker, nonAbsentArgs,
39 mkStrictnessInfo, mkBottomStrictnessInfo,
40 getWrapperArgTypeCategories,
46 noInfo_UF, getInfo_UF, addInfo_UF, -- to avoid instance virus
71 IMPORT_1_3(Char(toLower))
73 IMPORT_DELOOPER(IdLoop) -- IdInfo is a dependency-loop ranch, and
74 -- we break those loops by using IdLoop and
75 -- *not* importing much of anything else,
76 -- except from the very general "utils".
78 import CmdLineOpts ( opt_OmitInterfacePragmas )
79 import Maybes ( firstJust )
80 import MatchEnv ( nullMEnv, isEmptyMEnv, mEnvToList, MatchEnv )
81 import Outputable ( ifPprInterface, Outputable(..){-instances-} )
82 import PprStyle ( PprStyle(..) )
84 import SrcLoc ( mkUnknownSrcLoc )
85 import Type ( eqSimpleTy, splitFunTyExpandingDicts )
86 import Util ( mapAccumL, panic, assertPanic, pprPanic )
88 #ifdef REALLY_HASKELL_1_3
89 ord = fromEnum :: Char -> Int
92 applySubstToTy = panic "IdInfo.applySubstToTy"
93 showTypeCategory = panic "IdInfo.showTypeCategory"
94 mkFormSummary = panic "IdInfo.mkFormSummary"
95 isWrapperFor = panic "IdInfo.isWrapperFor"
96 pprCoreUnfolding = panic "IdInfo.pprCoreUnfolding"
99 An @IdInfo@ gives {\em optional} information about an @Id@. If
100 present it never lies, but it may not be present, in which case there
101 is always a conservative assumption which can be made.
103 Two @Id@s may have different info even though they have the same
104 @Unique@ (and are hence the same @Id@); for example, one might lack
105 the properties attached to the other.
107 The @IdInfo@ gives information about the value, or definition, of the
108 @Id@. It does {\em not} contain information about the @Id@'s usage
109 (except for @DemandInfo@? ToDo).
114 ArityInfo -- Its arity
116 DemandInfo -- Whether or not it is definitely
119 (MatchEnv [Type] CoreExpr)
120 -- Specialisations of this function which exist
121 -- This corresponds to a SpecEnv which we do
122 -- not import directly to avoid loop
124 StrictnessInfo -- Strictness properties, notably
125 -- how to conjure up "worker" functions
127 UnfoldingDetails -- Its unfolding; for locally-defined
128 -- things, this can *only* be NoUnfoldingDetails
130 UpdateInfo -- Which args should be updated
132 DeforestInfo -- Whether its definition should be
133 -- unfolded during deforestation
135 ArgUsageInfo -- how this Id uses its arguments
137 FBTypeInfo -- the Foldr/Build W/W property of this function.
139 SrcLoc -- Source location of definition
141 -- ToDo: SrcLoc is in FullNames too (could rm?) but it
142 -- is needed here too for things like ConstMethodIds and the
143 -- like, which don't have full-names of their own Mind you,
144 -- perhaps the Name for a constant method could give the
145 -- class/type involved?
149 noIdInfo = IdInfo noInfo noInfo noInfo noInfo noInfo_UF
150 noInfo noInfo noInfo noInfo mkUnknownSrcLoc
152 -- "boring" means: nothing to put in interface
153 boringIdInfo (IdInfo UnknownArity
160 _ {- arg_usage: currently no interface effect -}
162 _ {- src_loc: no effect on interfaces-}
164 | null (mEnvToList specenv)
165 && boring_strictness strictness
166 && boring_unfolding unfolding
169 boring_strictness NoStrictnessInfo = True
170 boring_strictness BottomGuaranteed = False
171 boring_strictness (StrictnessInfo wrap_args _) = all_present_WwLazies wrap_args
173 boring_unfolding NoUnfoldingDetails = True
174 boring_unfolding _ = False
176 boringIdInfo _ = False
178 pp_NONE = ppPStr SLIT("_N_")
181 Simply turgid. But BE CAREFUL: don't @apply_to_Id@ if that @Id@
182 will in turn @apply_to_IdInfo@ of the self-same @IdInfo@. (A very
183 nasty loop, friends...)
185 apply_to_IdInfo ty_fn idinfo@(IdInfo arity demand spec strictness unfold
186 update deforest arg_usage fb_ww srcloc)
190 = panic "IdInfo:apply_to_IdInfo"
193 new_spec = apply_spec spec
196 -- apply_strict strictness `thenLft` \ new_strict ->
197 -- apply_wrap wrap `thenLft` \ new_wrap ->
199 IdInfo arity demand new_spec strictness unfold
200 update deforest arg_usage fb_ww srcloc
202 apply_spec (SpecEnv is)
203 = SpecEnv (map do_one is)
205 do_one (SpecInfo ty_maybes ds spec_id)
206 = --apply_to_Id ty_fn spec_id `thenLft` \ new_spec_id ->
207 SpecInfo (map apply_to_maybe ty_maybes) ds spec_id
209 apply_to_maybe Nothing = Nothing
210 apply_to_maybe (Just ty) = Just (ty_fn ty)
214 apply_strict info@NoStrictnessInfo = returnLft info
215 apply_strict BottomGuaranteed = ???
216 apply_strict (StrictnessInfo wrap_arg_info id_maybe)
218 Nothing -> returnLft Nothing
219 Just xx -> applySubstToId subst xx `thenLft` \ new_xx ->
220 returnLft (Just new_xx)
221 ) `thenLft` \ new_id_maybe ->
222 returnLft (StrictnessInfo wrap_arg_info new_id_maybe)
226 Variant of the same thing for the typechecker.
228 applySubstToIdInfo s0 (IdInfo arity demand spec strictness unfold
229 update deforest arg_usage fb_ww srcloc)
230 = panic "IdInfo:applySubstToIdInfo"
232 case (apply_spec s0 spec) of { (s1, new_spec) ->
233 (s1, IdInfo arity demand new_spec strictness unfold update deforest arg_usage fb_ww srcloc) }
235 apply_spec s0 (SpecEnv is)
236 = case (mapAccumL do_one s0 is) of { (s1, new_is) ->
237 (s1, SpecEnv new_is) }
239 do_one s0 (SpecInfo ty_maybes ds spec_id)
240 = case (mapAccumL apply_to_maybe s0 ty_maybes) of { (s1, new_maybes) ->
241 (s1, SpecInfo new_maybes ds spec_id) }
243 apply_to_maybe s0 Nothing = (s0, Nothing)
244 apply_to_maybe s0 (Just ty)
245 = case (applySubstToTy s0 ty) of { (s1, new_ty) ->
252 -> Id -- The Id for which we're printing this IdInfo
253 -> Bool -- True <=> print specialisations, please
254 -> (Id -> Id) -- to look up "better Ids" w/ better IdInfos;
255 -> IdEnv UnfoldingDetails
256 -- inlining info for top-level fns in this module
257 -> IdInfo -- see MkIface notes
260 ppIdInfo sty for_this_id specs_please better_id_fn inline_env
261 i@(IdInfo arity demand specenv strictness unfold update deforest arg_usage fbtype srcloc)
263 = ppPStr SLIT("_NI_")
268 -- order is important!:
269 ppInfo sty better_id_fn arity,
270 ppInfo sty better_id_fn update,
271 ppInfo sty better_id_fn deforest,
273 pp_strictness sty (Just for_this_id)
274 better_id_fn inline_env strictness,
276 if bottomIsGuaranteed strictness
278 else pp_unfolding sty for_this_id inline_env unfold,
281 then ppSpecs sty (not (isDataCon for_this_id))
282 better_id_fn inline_env (mEnvToList specenv)
285 -- DemandInfo needn't be printed since it has no effect on interfaces
286 ppInfo sty better_id_fn demand,
287 ppInfo sty better_id_fn fbtype
291 PprInterface -> if opt_OmitInterfacePragmas
297 %************************************************************************
299 \subsection[OptIdInfo-class]{The @OptIdInfo@ class (keeps things tidier)}
301 %************************************************************************
304 class OptIdInfo a where
306 getInfo :: IdInfo -> a
307 addInfo :: IdInfo -> a -> IdInfo
308 -- By default, "addInfo" will not overwrite
309 -- "info" with "non-info"; look at any instance
310 -- to see an example.
311 ppInfo :: PprStyle -> (Id -> Id) -> a -> Pretty
314 %************************************************************************
316 \subsection[srcloc-IdInfo]{Source-location info in an @IdInfo@}
318 %************************************************************************
320 Not used much, but...
322 getSrcLocIdInfo (IdInfo _ _ _ _ _ _ _ _ _ src_loc) = src_loc
325 %************************************************************************
327 \subsection[arity-IdInfo]{Arity info about an @Id@}
329 %************************************************************************
333 = UnknownArity -- no idea
334 | ArityExactly Int -- arity is exactly this
338 mkArityInfo = ArityExactly
339 unknownArity = UnknownArity
341 arityMaybe :: ArityInfo -> Maybe Int
343 arityMaybe UnknownArity = Nothing
344 arityMaybe (ArityExactly i) = Just i
348 instance OptIdInfo ArityInfo where
349 noInfo = UnknownArity
351 getInfo (IdInfo arity _ _ _ _ _ _ _ _ _) = arity
353 addInfo id_info UnknownArity = id_info
354 addInfo (IdInfo _ a c d e f g h i j) arity = IdInfo arity a c d e f g h i j
356 ppInfo sty _ UnknownArity = ifPprInterface sty pp_NONE
357 ppInfo sty _ (ArityExactly arity) = ppCat [ppPStr SLIT("_A_"), ppInt arity]
360 %************************************************************************
362 \subsection[demand-IdInfo]{Demand info about an @Id@}
364 %************************************************************************
366 Whether a value is certain to be demanded or not. (This is the
367 information that is computed by the ``front-end'' of the strictness
370 This information is only used within a module, it is not exported
376 | DemandedAsPer Demand
380 mkDemandInfo :: Demand -> DemandInfo
381 mkDemandInfo demand = DemandedAsPer demand
383 willBeDemanded :: DemandInfo -> Bool
384 willBeDemanded (DemandedAsPer demand) = isStrict demand
385 willBeDemanded _ = False
389 instance OptIdInfo DemandInfo where
390 noInfo = UnknownDemand
392 getInfo (IdInfo _ demand _ _ _ _ _ _ _ _) = demand
394 {- DELETED! If this line is in, there is no way to
395 nuke a DemandInfo, and we have to be able to do that
396 when floating let-bindings around
397 addInfo id_info UnknownDemand = id_info
399 addInfo (IdInfo a _ c d e f g h i j) demand = IdInfo a demand c d e f g h i j
401 ppInfo PprInterface _ _ = ppNil
402 ppInfo sty _ UnknownDemand = ppStr "{-# L #-}"
403 ppInfo sty _ (DemandedAsPer info)
404 = ppCat [ppStr "{-#", ppStr (showList [info] ""), ppStr "#-}"]
407 %************************************************************************
409 \subsection[specialisation-IdInfo]{Specialisation info about an @Id@}
411 %************************************************************************
416 instance OptIdInfo (MatchEnv [Type] CoreExpr) where
419 getInfo (IdInfo _ _ spec _ _ _ _ _ _ _) = spec
421 addInfo id_info spec | null (mEnvToList spec) = id_info
422 addInfo (IdInfo a b _ d e f g h i j) spec = IdInfo a b spec d e f g h i j
424 ppInfo sty better_id_fn spec
425 = ppSpecs sty True better_id_fn nullIdEnv (mEnvToList spec)
427 ppSpecs sty print_spec_id_info better_id_fn inline_env spec_env
428 = if null spec_env then ppNil else panic "IdInfo:ppSpecs"
431 %************************************************************************
433 \subsection[strictness-IdInfo]{Strictness info about an @Id@}
435 %************************************************************************
437 We specify the strictness of a function by giving information about
438 each of the ``wrapper's'' arguments (see the description about
439 worker/wrapper-style transformations in the PJ/Launchbury paper on
442 The list of @Demands@ specifies: (a)~the strictness properties
443 of a function's arguments; (b)~the {\em existence} of a ``worker''
444 version of the function; and (c)~the type signature of that worker (if
445 it exists); i.e. its calling convention.
451 | BottomGuaranteed -- This Id guarantees never to return;
452 -- it is bottom regardless of its arguments.
453 -- Useful for "error" and other disguised
456 | StrictnessInfo [Demand] -- the main stuff; see below.
457 (Maybe Id) -- worker's Id, if applicable.
460 This type is also actually used in the strictness analyser:
463 = WwLazy -- Argument is lazy as far as we know
464 MaybeAbsent -- (does not imply worker's existence [etc]).
465 -- If MaybeAbsent == True, then it is
466 -- *definitely* lazy. (NB: Absence implies
469 | WwStrict -- Argument is strict but that's all we know
470 -- (does not imply worker's existence or any
471 -- calling-convention magic)
473 | WwUnpack -- Argument is strict & a single-constructor
474 [Demand] -- type; its constituent parts (whose StrictInfos
475 -- are in the list) should be passed
476 -- as arguments to the worker.
478 | WwPrim -- Argument is of primitive type, therefore
479 -- strict; doesn't imply existence of a worker;
480 -- argument should be passed as is to worker.
482 | WwEnum -- Argument is strict & an enumeration type;
483 -- an Int# representing the tag (start counting
484 -- at zero) should be passed to the worker.
486 -- we need Eq/Ord to cross-chk update infos in interfaces
488 type MaybeAbsent = Bool -- True <=> not even used
490 -- versions that don't worry about Absence:
491 wwLazy = WwLazy False
493 wwUnpack xs = WwUnpack xs
499 mkStrictnessInfo :: [Demand] -> Maybe Id -> StrictnessInfo
501 mkStrictnessInfo [] _ = NoStrictnessInfo
502 mkStrictnessInfo xs wrkr = StrictnessInfo xs wrkr
504 mkBottomStrictnessInfo = BottomGuaranteed
506 bottomIsGuaranteed BottomGuaranteed = True
507 bottomIsGuaranteed other = False
509 getWrapperArgTypeCategories
510 :: Type -- wrapper's type
511 -> StrictnessInfo -- strictness info about its args
514 getWrapperArgTypeCategories _ NoStrictnessInfo = Nothing
515 getWrapperArgTypeCategories _ BottomGuaranteed
516 = trace "getWrapperArgTypeCategories:BottomGuaranteed!" Nothing -- wrong
517 getWrapperArgTypeCategories _ (StrictnessInfo [] _) = Nothing
519 getWrapperArgTypeCategories ty (StrictnessInfo arg_info _)
520 = Just (mkWrapperArgTypeCategories ty arg_info)
522 workerExists :: StrictnessInfo -> Bool
523 workerExists (StrictnessInfo _ (Just worker_id)) = True
524 workerExists other = False
526 getWorkerId :: StrictnessInfo -> Id
528 getWorkerId (StrictnessInfo _ (Just worker_id)) = worker_id
530 getWorkerId junk = pprPanic "getWorkerId: " (ppInfo PprDebug (\x->x) junk)
535 isStrict :: Demand -> Bool
537 isStrict WwStrict = True
538 isStrict (WwUnpack _) = True
539 isStrict WwPrim = True
540 isStrict WwEnum = True
543 nonAbsentArgs :: [Demand] -> Int
546 = foldr tick_non 0 cmpts
548 tick_non (WwLazy True) acc = acc
549 tick_non other acc = acc + 1
551 all_present_WwLazies :: [Demand] -> Bool
552 all_present_WwLazies infos
553 = and (map is_L infos)
555 is_L (WwLazy False) = True -- False <=> "Absent" args do *not* count!
556 is_L _ = False -- (as they imply a worker)
559 WDP 95/04: It is no longer enough to look at a list of @Demands@ for
560 an ``Unpack'' or an ``Absent'' and declare a worker. We also have to
561 check that @mAX_WORKER_ARGS@ hasn't been exceeded. Therefore,
562 @indicatesWorker@ mirrors the process used in @mk_ww_arg_processing@
563 in \tr{WwLib.lhs}. A worker is ``indicated'' when we hit an Unpack
564 or an Absent {\em that we accept}.
566 indicatesWorker :: [Demand] -> Bool
569 = fake_mk_ww (trace "mAX_WORKER_ARGS" 6 - nonAbsentArgs dems) dems
571 fake_mk_ww _ [] = False
572 fake_mk_ww _ (WwLazy True : _) = True -- we accepted an Absent
573 fake_mk_ww extra_args (WwUnpack cmpnts : dems)
574 | extra_args_now > 0 = True -- we accepted an Unpack
576 extra_args_now = extra_args + 1 - nonAbsentArgs cmpnts
578 fake_mk_ww extra_args (_ : dems)
579 = fake_mk_ww extra_args dems
583 mkWrapperArgTypeCategories
584 :: Type -- wrapper's type
585 -> [Demand] -- info about its arguments
586 -> String -- a string saying lots about the args
588 mkWrapperArgTypeCategories wrapper_ty wrap_info
589 = case (splitFunTyExpandingDicts wrapper_ty) of { (arg_tys,_) ->
590 map do_one (wrap_info `zip` (map showTypeCategory arg_tys)) }
592 -- ToDo: this needs FIXING UP (it was a hack anyway...)
593 do_one (WwPrim, _) = 'P'
594 do_one (WwEnum, _) = 'E'
595 do_one (WwStrict, arg_ty_char) = arg_ty_char
596 do_one (WwUnpack _, arg_ty_char)
597 = if arg_ty_char `elem` "CIJFDTS"
598 then toLower arg_ty_char
599 else if arg_ty_char == '+' then 't'
600 else trace ("mkWrapp..:funny char:"++[arg_ty_char]) '-'
601 do_one (other_wrap_info, _) = '-'
604 Whether a worker exists depends on whether the worker has an
605 absent argument, a @WwUnpack@ argument, (or @WwEnum@ ToDo???) arguments.
607 If a @WwUnpack@ argument is for an {\em abstract} type (or one that
608 will be abstract outside this module), which might happen for an
609 imported function, then we can't (or don't want to...) unpack the arg
610 as the worker requires. Hence we have to give up altogether, and call
611 the wrapper only; so under these circumstances we return \tr{False}.
614 #ifdef REALLY_HASKELL_1_3
615 instance Read Demand where
617 instance Text Demand where
619 readList str = read_em [{-acc-}] str
621 read_em acc [] = [(reverse acc, "")]
622 -- lower case indicates absence...
623 read_em acc ('L' : xs) = read_em (WwLazy False : acc) xs
624 read_em acc ('A' : xs) = read_em (WwLazy True : acc) xs
625 read_em acc ('S' : xs) = read_em (WwStrict : acc) xs
626 read_em acc ('P' : xs) = read_em (WwPrim : acc) xs
627 read_em acc ('E' : xs) = read_em (WwEnum : acc) xs
629 read_em acc (')' : xs) = [(reverse acc, xs)]
630 read_em acc ( 'U' : '(' : xs)
631 = case (read_em [] xs) of
632 [(stuff, rest)] -> read_em (WwUnpack stuff : acc) rest
633 _ -> panic ("Text.Demand:"++str++"::"++xs)
635 read_em acc other = panic ("IdInfo.readem:"++other)
637 #ifdef REALLY_HASKELL_1_3
638 instance Show Demand where
640 showList wrap_args rest = (concat (map show1 wrap_args)) ++ rest
642 show1 (WwLazy False) = "L"
643 show1 (WwLazy True) = "A"
647 show1 (WwUnpack args)= "U(" ++ (concat (map show1 args)) ++ ")"
649 instance Outputable Demand where
650 ppr sty si = ppStr (showList [si] "")
652 instance OptIdInfo StrictnessInfo where
653 noInfo = NoStrictnessInfo
655 getInfo (IdInfo _ _ _ strict _ _ _ _ _ _) = strict
657 addInfo id_info NoStrictnessInfo = id_info
658 addInfo (IdInfo a b d _ e f g h i j) strict = IdInfo a b d strict e f g h i j
660 ppInfo sty better_id_fn strictness_info
661 = pp_strictness sty Nothing better_id_fn nullIdEnv strictness_info
664 We'll omit the worker info if the thing has an explicit unfolding
667 pp_strictness sty _ _ _ NoStrictnessInfo = ifPprInterface sty pp_NONE
669 pp_strictness sty _ _ _ BottomGuaranteed = ppPStr SLIT("_S_ _!_")
671 pp_strictness sty for_this_id_maybe better_id_fn inline_env
672 info@(StrictnessInfo wrapper_args wrkr_maybe)
674 (have_wrkr, wrkr_id) = case wrkr_maybe of
675 Nothing -> (False, panic "ppInfo(Strictness)")
676 Just xx -> (True, xx)
678 wrkr_to_print = better_id_fn wrkr_id
679 wrkr_info = getIdInfo wrkr_to_print
681 -- if we aren't going to be able to *read* the strictness info
682 -- in TcPragmas, we need not even print it.
684 = if not (indicatesWorker wrapper_args) then
685 wrapper_args -- no worker/wrappering in any case
687 case for_this_id_maybe of
688 Nothing -> wrapper_args
689 Just id -> if externallyVisibleId id
690 && (unfoldingUnfriendlyId id || not have_wrkr) then
691 -- pprTrace "IdInfo: unworker-ising:" (ppCat [ppr PprDebug have_wrkr, ppr PprDebug id]) $
692 map un_workerise wrapper_args
697 = case for_this_id_maybe of
699 Just id -> isWorkerId id
701 am_printing_iface = case sty of { PprInterface -> True ; _ -> False }
704 = ppBesides [ppStr "_S_ \"",
705 ppStr (showList wrapper_args_to_use ""), ppStr "\""]
708 = ppBesides [ ppSP, ppChar '{',
709 ppIdInfo sty wrkr_to_print True{-wrkr specs, yes!-} better_id_fn inline_env wrkr_info,
712 if all_present_WwLazies wrapper_args_to_use then -- too boring
713 ifPprInterface sty pp_NONE
715 else if id_is_worker && am_printing_iface then
716 pp_NONE -- we don't put worker strictness in interfaces
717 -- (it can be deduced)
719 else if not (indicatesWorker wrapper_args_to_use)
721 || boringIdInfo wrkr_info then
722 ppBeside pp_basic_info ppNil
724 ppBeside pp_basic_info pp_with_worker
726 un_workerise (WwLazy _) = WwLazy False -- avoid absence
727 un_workerise (WwUnpack _) = WwStrict
728 un_workerise other = other
731 %************************************************************************
733 \subsection[unfolding-IdInfo]{Unfolding info about an @Id@}
735 %************************************************************************
738 mkUnfolding guide expr
739 = GenForm (mkFormSummary NoStrictnessInfo expr)
740 (occurAnalyseGlobalExpr expr)
745 noInfo_UF = NoUnfoldingDetails
747 getInfo_UF (IdInfo _ _ _ _ unfolding _ _ _ _ _)
749 GenForm _ _ BadUnfolding -> NoUnfoldingDetails
750 unfolding_as_was -> unfolding_as_was
752 -- getInfo_UF ensures that any BadUnfoldings are never returned
753 -- We had to delay the test required in TcPragmas until now due
754 -- to strictness constraints in TcPragmas
756 addInfo_UF id_info@(IdInfo a b c d e f g h i j) NoUnfoldingDetails = id_info
757 addInfo_UF (IdInfo a b d e _ f g h i j) uf = IdInfo a b d e uf f g h i j
761 pp_unfolding sty for_this_id inline_env uf_details
762 = case (lookupIdEnv inline_env for_this_id) of
763 Nothing -> pp uf_details
766 pp NoUnfoldingDetails = pp_NONE
769 = ppCat [ppPStr SLIT("_MF_"), ppPStr tag]
771 pp (GenForm _ _ BadUnfolding) = pp_NONE
773 pp (GenForm _ template guide)
775 untagged = unTagBinders template
777 if untagged `isWrapperFor` for_this_id
778 then -- pprTrace "IdInfo:isWrapperFor:" (ppAbove (ppr PprDebug for_this_id) (ppr PprDebug untagged))
780 else ppCat [ppPStr SLIT("_F_"), ppr sty guide, pprCoreUnfolding untagged]
784 %************************************************************************
786 \subsection[update-IdInfo]{Update-analysis info about an @Id@}
788 %************************************************************************
793 | SomeUpdateInfo UpdateSpec
795 -- we need Eq/Ord to cross-chk update infos in interfaces
797 -- the form in which we pass update-analysis info between modules:
798 type UpdateSpec = [Int]
802 mkUpdateInfo = SomeUpdateInfo
804 updateInfoMaybe NoUpdateInfo = Nothing
805 updateInfoMaybe (SomeUpdateInfo []) = Nothing
806 updateInfoMaybe (SomeUpdateInfo u) = Just u
809 Text instance so that the update annotations can be read in.
812 #ifdef REALLY_HASKELL_1_3
813 instance Read UpdateInfo where
815 instance Text UpdateInfo where
817 readsPrec p s | null s = panic "IdInfo: empty update pragma?!"
818 | otherwise = [(SomeUpdateInfo (map ok_digit s),"")]
820 ok_digit c | c >= '0' && c <= '2' = ord c - ord '0'
821 | otherwise = panic "IdInfo: not a digit while reading update pragma"
823 instance OptIdInfo UpdateInfo where
824 noInfo = NoUpdateInfo
826 getInfo (IdInfo _ _ _ _ _ update _ _ _ _) = update
828 addInfo id_info NoUpdateInfo = id_info
829 addInfo (IdInfo a b d e f _ g h i j) upd_info = IdInfo a b d e f upd_info g h i j
831 ppInfo sty better_id_fn NoUpdateInfo = ifPprInterface sty pp_NONE
832 ppInfo sty better_id_fn (SomeUpdateInfo []) = ifPprInterface sty pp_NONE
833 ppInfo sty better_id_fn (SomeUpdateInfo spec)
834 = ppBeside (ppPStr SLIT("_U_ ")) (ppBesides (map ppInt spec))
837 %************************************************************************
839 \subsection[deforest-IdInfo]{Deforestation info about an @Id@}
841 %************************************************************************
843 The deforest info says whether this Id is to be unfolded during
844 deforestation. Therefore, when the deforest pragma is true, we must
845 also have the unfolding information available for this Id.
849 = Don'tDeforest -- just a bool, might extend this
850 | DoDeforest -- later.
851 -- deriving (Eq, Ord)
855 instance OptIdInfo DeforestInfo where
856 noInfo = Don'tDeforest
858 getInfo (IdInfo _ _ _ _ _ _ deforest _ _ _) = deforest
860 addInfo id_info Don'tDeforest = id_info
861 addInfo (IdInfo a b d e f g _ h i j) deforest =
862 IdInfo a b d e f g deforest h i j
864 ppInfo sty better_id_fn Don'tDeforest
865 = ifPprInterface sty pp_NONE
866 ppInfo sty better_id_fn DoDeforest
867 = ppPStr SLIT("_DEFOREST_")
870 %************************************************************************
872 \subsection[argUsage-IdInfo]{Argument Usage info about an @Id@}
874 %************************************************************************
879 | SomeArgUsageInfo ArgUsageType
880 -- ??? deriving (Eq, Ord)
882 data ArgUsage = ArgUsage Int -- number of arguments (is linear!)
884 type ArgUsageType = [ArgUsage] -- c_1 -> ... -> BLOB
888 mkArgUsageInfo = SomeArgUsageInfo
890 getArgUsage :: ArgUsageInfo -> ArgUsageType
891 getArgUsage NoArgUsageInfo = []
892 getArgUsage (SomeArgUsageInfo u) = u
896 instance OptIdInfo ArgUsageInfo where
897 noInfo = NoArgUsageInfo
899 getInfo (IdInfo _ _ _ _ _ _ _ au _ _) = au
901 addInfo id_info NoArgUsageInfo = id_info
902 addInfo (IdInfo a b d e f g h _ i j) au_info = IdInfo a b d e f g h au_info i j
904 ppInfo sty better_id_fn NoArgUsageInfo = ifPprInterface sty pp_NONE
905 ppInfo sty better_id_fn (SomeArgUsageInfo []) = ifPprInterface sty pp_NONE
906 ppInfo sty better_id_fn (SomeArgUsageInfo aut)
907 = ppBeside (ppPStr SLIT("_L_ ")) (ppArgUsageType aut)
910 ppArgUsage (ArgUsage n) = ppInt n
911 ppArgUsage (UnknownArgUsage) = ppChar '-'
913 ppArgUsageType aut = ppBesides
915 ppIntersperse ppComma (map ppArgUsage aut),
918 %************************************************************************
920 \subsection[FBType-IdInfo]{Type of an expression through Foldr/build's eyes}
922 %************************************************************************
927 | SomeFBTypeInfo FBType
928 -- ??? deriving (Eq, Ord)
930 data FBType = FBType [FBConsum] FBProd deriving (Eq)
932 data FBConsum = FBGoodConsum | FBBadConsum deriving(Eq)
933 data FBProd = FBGoodProd | FBBadProd deriving(Eq)
937 mkFBTypeInfo = SomeFBTypeInfo
939 getFBType :: FBTypeInfo -> Maybe FBType
940 getFBType NoFBTypeInfo = Nothing
941 getFBType (SomeFBTypeInfo u) = Just u
945 instance OptIdInfo FBTypeInfo where
946 noInfo = NoFBTypeInfo
948 getInfo (IdInfo _ _ _ _ _ _ _ _ fb _) = fb
950 addInfo id_info NoFBTypeInfo = id_info
951 addInfo (IdInfo a b d e f g h i _ j) fb_info = IdInfo a b d e f g h i fb_info j
953 ppInfo PprInterface _ NoFBTypeInfo = ppNil
954 ppInfo sty _ NoFBTypeInfo = ifPprInterface sty pp_NONE
955 ppInfo sty _ (SomeFBTypeInfo (FBType cons prod))
956 = ppBeside (ppPStr SLIT("_F_ ")) (ppFBType cons prod)
958 --ppFBType (FBType n) = ppBesides [ppInt n]
959 --ppFBType (UnknownFBType) = ppBesides [ppStr "-"]
962 ppFBType cons prod = ppBesides
963 ([ ppChar '"' ] ++ map ppCons cons ++ [ ppChar '-', ppProd prod, ppChar '"' ])
965 ppCons FBGoodConsum = ppChar 'G'
966 ppCons FBBadConsum = ppChar 'B'
967 ppProd FBGoodProd = ppChar 'G'
968 ppProd FBBadProd = ppChar 'B'