2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[ClosureInfo]{Data structures which describe closures}
6 Much of the rationale for these things is in the ``details'' part of
10 #include "HsVersions.h"
13 ClosureInfo, LambdaFormInfo, SMRep, -- all abstract
18 mkClosureLFInfo, mkConLFInfo,
19 mkLFImported, mkLFArgument, mkLFLetNoEscape,
21 closureSize, closureHdrSize,
22 closureNonHdrSize, closureSizeWithoutFixedHdr,
23 closureGoodStuffSize, closurePtrsSize,
24 slopSize, fitsMinUpdSize,
26 layOutDynClosure, layOutDynCon, layOutStaticClosure,
27 layOutStaticNoFVClosure, layOutPhantomClosure,
30 nodeMustPointToIt, getEntryConvention,
33 staticClosureRequired,
34 slowFunEntryCodeRequired, funInfoTableRequired,
35 stdVapRequired, noUpdVapRequired,
37 closureId, infoTableLabelFromCI,
39 entryLabelFromCI, fastLabelFromCI,
40 closureLFInfo, closureSMRep, closureUpdReqd,
41 closureSingleEntry, closureSemiTag, closureType,
42 closureReturnsUnboxedType, getStandardFormThunkInfo,
45 closureKind, closureTypeDescr, -- profiling
47 isStaticClosure, allocProfilingMsg,
51 dataConLiveness -- concurrency
55 IMPORT_DELOOPER(AbsCLoop) -- here for paranoia-checking
61 import CgCompInfo ( mAX_SPEC_SELECTEE_SIZE,
62 mIN_UPD_SIZE, mIN_SIZE_NonUpdHeapObject,
63 mAX_SPEC_ALL_PTRS, mAX_SPEC_MIXED_FIELDS,
67 import CgRetConv ( assignRegs, dataReturnConvAlg,
68 DataReturnConvention(..)
70 import CLabel ( mkStdEntryLabel, mkFastEntryLabel,
71 mkPhantomInfoTableLabel, mkInfoTableLabel,
73 mkBlackHoleInfoTableLabel, mkVapInfoTableLabel,
74 mkStaticInfoTableLabel, mkStaticConEntryLabel,
75 mkConEntryLabel, mkClosureLabel, mkVapEntryLabel
77 import CmdLineOpts ( opt_SccProfilingOn, opt_ForConcurrent )
78 import HeapOffs ( intOff, addOff, totHdrSize, varHdrSize,
80 SYN_IE(VirtualHeapOffset)
82 import Id ( idType, idPrimRep, getIdArity,
84 dataConTag, fIRST_TAG,
85 isDataCon, isNullaryDataCon, dataConTyCon,
86 isTupleCon, SYN_IE(DataCon),
89 import IdInfo ( arityMaybe )
90 import Maybes ( assocMaybe, maybeToBool )
91 import Name ( isLocallyDefined, nameOf, origName )
92 import PprStyle ( PprStyle(..) )
93 import PprType ( GenType{-instance Outputable-} )
94 import Pretty--ToDo:rm
95 import PrelInfo ( maybeCharLikeTyCon, maybeIntLikeTyCon )
96 import PrimRep ( getPrimRepSize, separateByPtrFollowness )
97 import SMRep -- all of it
98 import TyCon ( maybeTyConSingleCon, TyCon{-instance NamedThing-} )
99 import Type ( isPrimType, splitForAllTy, splitFunTyExpandingDictsAndPeeking,
100 mkFunTys, maybeAppSpecDataTyConExpandingDicts
102 import Util ( isIn, mapAccumL, panic, pprPanic, assertPanic )
104 getTyDescription = panic "ClosureInfo.getTyDescription (ToDo)"
107 The ``wrapper'' data type for closure information:
112 Id -- The thing bound to this closure
113 LambdaFormInfo -- info derivable from the *source*
114 SMRep -- representation used by storage manager
117 %************************************************************************
119 \subsection[ClosureInfo-OLD-DOC]{OLD DOCUMENTATION PROBABLY SUPERCEDED BY stg-details}
121 %************************************************************************
123 We can optimise the function-entry code as follows.
126 \item If the ``function'' is not updatable, we can jump directly to its
127 entry code, rather than indirecting via the info pointer in the
128 closure. (For updatable thunks we must go via the closure, in
129 case it has been updated.)
131 \item If the former bullet applies, and the application we are
132 compiling gives the function as many arguments as it needs, we
133 can jump to its fast-entry code. (This only applies if the
134 function has one or more args, because zero-arg closures have
137 \item If the function is a top-level non-constructor or imported, there
138 is no need to make Node point to its closure. In order for
139 this to be right, we need to ensure that:
141 \item If such closures are updatable then they push their
142 static address in the update frame, not Node. Actually
143 we create a black hole and push its address.
145 \item The arg satisfaction check should load Node before jumping to
148 \item Top-level constructor closures need careful handling. If we are to
149 jump direct to the constructor code, we must load Node first, even
150 though they are top-level. But if we go to their ``own''
151 standard-entry code (which loads Node and then jumps to the
152 constructor code) we don't need to load Node.
157 {\em Top level constructors (@mkStaticConEntryInfo@)}
160 x = {y,ys} \ {} Cons {y,ys} -- Std form constructor
163 x-closure: Cons-info-table, y-closure, ys-closure
165 x-entry: Node = x-closure; jump( Cons-entry )
167 x's EntryInfo in its own module:
169 Base-label = Cons -- Not x!!
171 ClosureClass = Constructor
174 So if x is entered, Node will be set up and
175 we'll jump direct to the Cons code.
177 x's EntryInfo in another module: (which may not know that x is a constructor)
179 Base-label = x -- Is x!!
180 NodeMustPoint = False -- All imported things have False
181 ClosureClass = non-committal
184 If x is entered, we'll jump to x-entry, which will set up Node
185 before jumping to the standard Cons code
187 {\em Top level non-constructors (@mkStaticEntryInfo@)}
192 For updatable thunks, x-entry must push an allocated BH in update frame, not Node.
194 For non-zero arity, arg satis check must load Node before jumping to
197 x's EntryInfo in its own module:
200 NodeMustPoint = False
201 ClosureClass = whatever
204 {\em Inner constructors (@mkConEntryInfo@)}
207 Base-label = Cons -- Not x!!
208 NodeMustPoint = True -- If its arity were zero, it would
209 -- have been lifted to top level
210 ClosureClass = Constructor
213 {\em Inner non-constructors (@mkEntryInfo@)}
217 NodeMustPoint = True -- If no free vars, would have been
218 -- lifted to top level
219 ClosureClass = whatever
228 NodeMustPoint = False
229 ClosureClass = whatever
233 THINK: we could omit making Node point to top-level constructors
234 of arity zero; but that might interact nastily with updates.
239 The info we need to import for imported things is:
242 data ImportInfo = UnknownImportInfo
243 | HnfImport Int -- Not updatable, arity given
244 -- Arity can be zero, for (eg) constrs
245 | UpdatableImport -- Must enter via the closure
248 ToDo: move this stuff???
251 mkStaticEntryInfo lbl cl_class
252 = MkEntryInfo lbl False cl_class
254 mkStaticConEntryInfo lbl
255 = MkEntryInfo lbl True ConstructorClosure
257 mkEntryInfo lbl cl_class
258 = MkEntryInfo lbl True cl_class
261 = MkEntryInfo lbl True ConstructorClosure
264 %************************************************************************
266 \subsection[ClosureInfo-datatypes]{Data types for closure information}
268 %************************************************************************
270 %************************************************************************
272 \subsubsection[LambdaFormInfo-datatype]{@LambdaFormInfo@: source-derivable info}
274 %************************************************************************
278 = LFReEntrant -- Reentrant closure; used for PAPs too
279 Bool -- True if top level
281 Bool -- True <=> no fvs
283 | LFCon -- Constructor
284 DataCon -- The constructor (may be specialised)
285 Bool -- True <=> zero arity
288 DataCon -- The tuple constructor (may be specialised)
289 Bool -- True <=> zero arity
291 | LFThunk -- Thunk (zero arity)
292 Bool -- True <=> top level
293 Bool -- True <=> no free vars
294 Bool -- True <=> updatable (i.e., *not* single-entry)
297 | LFArgument -- Used for function arguments. We know nothing about
298 -- this closure. Treat like updatable "LFThunk"...
300 | LFImported -- Used for imported things. We know nothing about this
301 -- closure. Treat like updatable "LFThunk"...
302 -- Imported things which we do know something about use
303 -- one of the other LF constructors (eg LFReEntrant for
306 | LFLetNoEscape -- See LetNoEscape module for precise description of
309 StgLiveVars-- list of variables live in the RHS of the let.
310 -- (ToDo: maybe not used)
312 | LFBlackHole -- Used for the closures allocated to hold the result
313 -- of a CAF. We want the target of the update frame to
314 -- be in the heap, so we make a black hole to hold it.
316 -- This last one is really only for completeness;
317 -- it isn't actually used for anything interesting
318 {- | LFIndirection -}
320 data StandardFormInfo -- Tells whether this thunk has one of a small number
323 = NonStandardThunk -- No, it isn't
327 DataCon -- Constructor
328 Int -- 0-origin offset of ak within the "goods" of constructor
329 -- (Recall that the a1,...,an may be laid out in the heap
330 -- in a non-obvious order.)
332 {- A SelectorThunk is of form
337 and the constructor is from a single-constr type.
338 If we can't convert the heap-offset of the selectee into an Int, e.g.,
339 it's "GEN_VHS+i", we just give up.
345 Bool -- True <=> the function is not top-level, so
346 -- must be stored in the thunk too
348 {- A VapThunk is of form
352 where f is a known function, with arity n
353 So for this thunk we can use the label for f's heap-entry
354 info table (generated when f's defn was dealt with),
355 rather than generating a one-off info table and entry code
360 mkLFArgument = LFArgument
361 mkLFBlackHole = LFBlackHole
362 mkLFLetNoEscape = LFLetNoEscape
364 mkLFImported :: Id -> LambdaFormInfo
366 = case arityMaybe (getIdArity id) of
367 Nothing -> LFImported
368 Just 0 -> LFThunk True{-top-lev-} True{-no fvs-}
369 True{-updatable-} NonStandardThunk
370 Just n -> LFReEntrant True n True -- n > 0
373 %************************************************************************
375 \subsection[ClosureInfo-construction]{Functions which build LFInfos}
377 %************************************************************************
379 @mkClosureLFInfo@ figures out the appropriate LFInfo for the closure.
382 mkClosureLFInfo :: Bool -- True of top level
384 -> UpdateFlag -- Update flag
386 -> StgExpr -- Body of closure: passed so we
387 -- can look for selector thunks!
390 mkClosureLFInfo top fvs upd_flag args@(_:_) body -- Non-empty args
391 = LFReEntrant top (length args) (null fvs)
393 mkClosureLFInfo top fvs ReEntrant [] body
394 = LFReEntrant top 0 (null fvs)
397 OK, this is where we look at the body of the closure to see if it's a
398 selector---turgid, but nothing deep. We are looking for a closure of
399 {\em exactly} the form:
401 ... = [the_fv] \ u [] ->
403 con a_1 ... a_n -> a_i
407 mkClosureLFInfo False -- don't bother if at top-level
408 [the_fv] -- just one...
410 [] -- no args (a thunk)
411 (StgCase (StgApp (StgVarArg scrutinee) [{-no args-}] _)
412 _ _ _ -- ignore live vars and uniq...
414 [(con, params, use_mask,
415 (StgApp (StgVarArg selectee) [{-no args-}] _))]
417 | the_fv == scrutinee -- Scrutinee is the only free variable
418 && maybeToBool maybe_offset -- Selectee is a component of the tuple
419 && maybeToBool offset_into_int_maybe
420 && offset_into_int <= mAX_SPEC_SELECTEE_SIZE -- Offset is small enough
422 -- ASSERT(is_single_constructor) -- Should be true, by causes error for SpecTyCon
423 LFThunk False False True (SelectorThunk scrutinee con offset_into_int)
425 (_, params_w_offsets) = layOutDynCon con idPrimRep params
426 maybe_offset = assocMaybe params_w_offsets selectee
427 Just the_offset = maybe_offset
428 offset_into_int_maybe = intOffsetIntoGoods the_offset
429 Just offset_into_int = offset_into_int_maybe
430 is_single_constructor = maybeToBool (maybeTyConSingleCon tycon)
431 tycon = dataConTyCon con
434 Same kind of thing, looking for vector-apply thunks, of the form:
436 x = [...] \ .. [] -> f a1 .. an
438 where f has arity n. We rely on the arity info inside the Id being correct.
441 mkClosureLFInfo top_level
444 [] -- No args; a thunk
445 (StgApp (StgVarArg fun_id) args _)
446 | not top_level -- A top-level thunk would require a static
447 -- vap_info table, which we don't generate just
448 -- now; so top-level thunks are never standard
450 && isLocallyDefined fun_id -- Must be defined in this module
451 && maybeToBool arity_maybe -- A known function with known arity
452 && fun_arity > 0 -- It'd better be a function!
453 && fun_arity == length args -- Saturated application
454 = LFThunk top_level (null fvs) (isUpdatable upd_flag) (VapThunk fun_id args store_fun_in_vap)
456 arity_maybe = arityMaybe (getIdArity fun_id)
457 Just fun_arity = arity_maybe
459 -- If the function is a free variable then it must be stored
460 -- in the thunk too; if it isn't a free variable it must be
461 -- because it's constant, so it doesn't need to be stored in the thunk
462 store_fun_in_vap = fun_id `is_elem` fvs
464 is_elem = isIn "mkClosureLFInfo"
467 Finally, the general updatable-thing case:
469 mkClosureLFInfo top fvs upd_flag [] body
470 = LFThunk top (null fvs) (isUpdatable upd_flag) NonStandardThunk
472 isUpdatable ReEntrant = False
473 isUpdatable SingleEntry = False
474 isUpdatable Updatable = True
477 @mkConLFInfo@ is similar, for constructors.
480 mkConLFInfo :: DataCon -> LambdaFormInfo
483 = -- the isNullaryDataCon will do this: ASSERT(isDataCon con)
484 (if isTupleCon con then LFTuple else LFCon) con (isNullaryDataCon con)
488 %************************************************************************
490 \subsection[ClosureInfo-sizes]{Functions about closure {\em sizes}}
492 %************************************************************************
495 closureSize :: ClosureInfo -> HeapOffset
496 closureSize cl_info@(MkClosureInfo _ _ sm_rep)
497 = totHdrSize sm_rep `addOff` (intOff (closureNonHdrSize cl_info))
499 closureSizeWithoutFixedHdr :: ClosureInfo -> HeapOffset
500 closureSizeWithoutFixedHdr cl_info@(MkClosureInfo _ _ sm_rep)
501 = varHdrSize sm_rep `addOff` (intOff (closureNonHdrSize cl_info))
503 closureHdrSize :: ClosureInfo -> HeapOffset
504 closureHdrSize (MkClosureInfo _ _ sm_rep)
507 closureNonHdrSize :: ClosureInfo -> Int
508 closureNonHdrSize cl_info@(MkClosureInfo _ lf_info sm_rep)
509 = tot_wds + computeSlopSize tot_wds sm_rep (closureUpdReqd cl_info) --ToDo: pass lf_info?
511 tot_wds = closureGoodStuffSize cl_info
513 closureGoodStuffSize :: ClosureInfo -> Int
514 closureGoodStuffSize (MkClosureInfo _ _ sm_rep)
515 = let (ptrs, nonptrs) = sizes_from_SMRep sm_rep
518 closurePtrsSize :: ClosureInfo -> Int
519 closurePtrsSize (MkClosureInfo _ _ sm_rep)
520 = let (ptrs, _) = sizes_from_SMRep sm_rep
524 sizes_from_SMRep (SpecialisedRep k ptrs nonptrs _) = (ptrs, nonptrs)
525 sizes_from_SMRep (GenericRep ptrs nonptrs _) = (ptrs, nonptrs)
526 sizes_from_SMRep (BigTupleRep ptrs) = (ptrs, 0)
527 sizes_from_SMRep (MuTupleRep ptrs) = (ptrs, 0)
528 sizes_from_SMRep (DataRep nonptrs) = (0, nonptrs)
529 sizes_from_SMRep BlackHoleRep = (0, 0)
530 sizes_from_SMRep (StaticRep ptrs nonptrs) = (ptrs, nonptrs)
532 sizes_from_SMRep PhantomRep = panic "sizes_from_SMRep: PhantomRep"
533 sizes_from_SMRep DynamicRep = panic "sizes_from_SMRep: DynamicRep"
538 fitsMinUpdSize :: ClosureInfo -> Bool
539 fitsMinUpdSize (MkClosureInfo _ _ BlackHoleRep) = True
540 fitsMinUpdSize cl_info = isSpecRep (closureSMRep cl_info) && closureNonHdrSize cl_info <= mIN_UPD_SIZE
543 Computing slop size. WARNING: this looks dodgy --- it has deep
544 knowledge of what the storage manager does with the various
550 Updateable closures must be @mIN_UPD_SIZE@.
553 Cons cell requires 2 words
555 Indirections require 1 word
557 Appels collector indirections 2 words
559 THEREFORE: @mIN_UPD_SIZE = 2@.
562 Collectable closures which are allocated in the heap
563 must be @mIN_SIZE_NonUpdHeapObject@.
565 Copying collector forward pointer requires 1 word
567 THEREFORE: @mIN_SIZE_NonUpdHeapObject = 1@
570 @SpecialisedRep@ closures closures may require slop:
573 @ConstantRep@ and @CharLikeRep@ closures always use the address of
574 a static closure. They are never allocated or
575 collected (eg hold forwarding pointer) hence never any slop.
578 @IntLikeRep@ are never updatable.
579 May need slop to be collected (as they will be size 1 or more
580 this probably has no affect)
583 @SpecRep@ may be updateable and will be collectable
586 @StaticRep@ may require slop if updatable. Non-updatable ones are OK.
589 @GenericRep@ closures will always be larger so never require slop.
592 ***** ToDo: keep an eye on this!
596 slopSize cl_info@(MkClosureInfo _ lf_info sm_rep)
597 = computeSlopSize (closureGoodStuffSize cl_info) sm_rep (closureUpdReqd cl_info)
599 computeSlopSize :: Int -> SMRep -> Bool -> Int
601 computeSlopSize tot_wds (SpecialisedRep ConstantRep _ _ _) _
603 computeSlopSize tot_wds (SpecialisedRep CharLikeRep _ _ _) _
606 computeSlopSize tot_wds (SpecialisedRep _ _ _ _) True -- Updatable
607 = max 0 (mIN_UPD_SIZE - tot_wds)
608 computeSlopSize tot_wds (StaticRep _ _) True -- Updatable
609 = max 0 (mIN_UPD_SIZE - tot_wds)
610 computeSlopSize tot_wds BlackHoleRep _ -- Updatable
611 = max 0 (mIN_UPD_SIZE - tot_wds)
613 computeSlopSize tot_wds (SpecialisedRep _ _ _ _) False -- Not updatable
614 = max 0 (mIN_SIZE_NonUpdHeapObject - tot_wds)
616 computeSlopSize tot_wds other_rep _ -- Any other rep
620 %************************************************************************
622 \subsection[layOutDynClosure]{Lay out a dynamic closure}
624 %************************************************************************
627 layOutDynClosure, layOutStaticClosure
628 :: Id -- STG identifier w/ which this closure assoc'd
629 -> (a -> PrimRep) -- function w/ which to be able to get a PrimRep
630 -> [a] -- the "things" being layed out
631 -> LambdaFormInfo -- what sort of closure it is
632 -> (ClosureInfo, -- info about the closure
633 [(a, VirtualHeapOffset)]) -- things w/ offsets pinned on them
635 layOutDynClosure name kind_fn things lf_info
636 = (MkClosureInfo name lf_info sm_rep,
639 (tot_wds, -- #ptr_wds + #nonptr_wds
641 things_w_offsets) = mkVirtHeapOffsets sm_rep kind_fn things
642 sm_rep = chooseDynSMRep lf_info tot_wds ptr_wds
644 layOutStaticClosure name kind_fn things lf_info
645 = (MkClosureInfo name lf_info (StaticRep ptr_wds (tot_wds - ptr_wds)),
648 (tot_wds, -- #ptr_wds + #nonptr_wds
650 things_w_offsets) = mkVirtHeapOffsets (StaticRep bot bot) kind_fn things
651 bot = panic "layoutStaticClosure"
653 layOutStaticNoFVClosure :: Id -> LambdaFormInfo -> ClosureInfo
654 layOutStaticNoFVClosure name lf_info
655 = MkClosureInfo name lf_info (StaticRep ptr_wds nonptr_wds)
657 -- I am very uncertain that this is right - it will show up when testing
658 -- my dynamic loading code. ADR
659 -- (If it's not right, we'll have to grab the kinds of the arguments from
664 layOutPhantomClosure :: Id -> LambdaFormInfo -> ClosureInfo
665 layOutPhantomClosure name lf_info = MkClosureInfo name lf_info PhantomRep
668 A wrapper for when used with data constructors:
670 layOutDynCon :: DataCon
673 -> (ClosureInfo, [(a,VirtualHeapOffset)])
675 layOutDynCon con kind_fn args
676 = ASSERT(isDataCon con)
677 layOutDynClosure con kind_fn args (mkConLFInfo con)
681 %************************************************************************
683 \subsection[SMreps]{Choosing SM reps}
685 %************************************************************************
690 -> Int -> Int -- Tot wds, ptr wds
693 chooseDynSMRep lf_info tot_wds ptr_wds
695 nonptr_wds = tot_wds - ptr_wds
697 updatekind = case lf_info of
698 LFThunk _ _ upd _ -> if upd then SMUpdatable else SMSingleEntry
699 LFBlackHole -> SMUpdatable
702 if (nonptr_wds == 0 && ptr_wds <= mAX_SPEC_ALL_PTRS)
703 || (tot_wds <= mAX_SPEC_MIXED_FIELDS)
704 || (ptr_wds == 0 && nonptr_wds <= mAX_SPEC_ALL_NONPTRS) then
706 spec_kind = case lf_info of
708 (LFTuple _ True) -> ConstantRep
710 (LFTuple _ _) -> SpecRep
712 (LFCon _ True) -> ConstantRep
714 (LFCon con _ ) -> if maybeToBool (maybeCharLikeTyCon tycon) then CharLikeRep
715 else if maybeToBool (maybeIntLikeTyCon tycon) then IntLikeRep
718 tycon = dataConTyCon con
722 SpecialisedRep spec_kind ptr_wds nonptr_wds updatekind
724 GenericRep ptr_wds nonptr_wds updatekind
728 %************************************************************************
730 \subsection[mkVirtHeapOffsets]{Assigning heap offsets in a closure}
732 %************************************************************************
734 @mkVirtHeapOffsets@ (the heap version) always returns boxed things with
735 smaller offsets than the unboxed things, and furthermore, the offsets in
739 mkVirtHeapOffsets :: SMRep -- Representation to be used by storage manager
740 -> (a -> PrimRep) -- To be able to grab kinds;
741 -- w/ a kind, we can find boxedness
742 -> [a] -- Things to make offsets for
743 -> (Int, -- *Total* number of words allocated
744 Int, -- Number of words allocated for *pointers*
745 [(a, VirtualHeapOffset)])
746 -- Things with their offsets from start of object
747 -- in order of increasing offset
749 -- First in list gets lowest offset, which is initial offset + 1.
751 mkVirtHeapOffsets sm_rep kind_fun things
752 = let (ptrs, non_ptrs) = separateByPtrFollowness kind_fun things
753 (wds_of_ptrs, ptrs_w_offsets) = mapAccumL computeOffset 0 ptrs
754 (tot_wds, non_ptrs_w_offsets) = mapAccumL computeOffset wds_of_ptrs non_ptrs
756 (tot_wds, wds_of_ptrs, ptrs_w_offsets ++ non_ptrs_w_offsets)
758 offset_of_first_word = totHdrSize sm_rep
759 computeOffset wds_so_far thing
760 = (wds_so_far + (getPrimRepSize . kind_fun) thing,
761 (thing, (offset_of_first_word `addOff` (intOff wds_so_far)))
765 %************************************************************************
767 \subsection[ClosureInfo-4-questions]{Four major questions about @ClosureInfo@}
769 %************************************************************************
771 Be sure to see the stg-details notes about these...
774 nodeMustPointToIt :: LambdaFormInfo -> FCode Bool
775 nodeMustPointToIt lf_info
777 do_profiling = opt_SccProfilingOn
780 LFReEntrant top arity no_fvs -> returnFC (
781 not no_fvs || -- Certainly if it has fvs we need to point to it
783 not top -- If it is not top level we will point to it
784 -- We can have a \r closure with no_fvs which
785 -- is not top level as special case cgRhsClosure
786 -- has been dissabled in favour of let floating
788 -- For lex_profiling we also access the cost centre for a
789 -- non-inherited function i.e. not top level
790 -- the not top case above ensures this is ok.
793 LFCon _ zero_arity -> returnFC True
794 LFTuple _ zero_arity -> returnFC True
796 -- Strictly speaking, the above two don't need Node to point
797 -- to it if the arity = 0. But this is a *really* unlikely
798 -- situation. If we know it's nil (say) and we are entering
799 -- it. Eg: let x = [] in x then we will certainly have inlined
800 -- x, since nil is a simple atom. So we gain little by not
801 -- having Node point to known zero-arity things. On the other
802 -- hand, we do lose something; Patrick's code for figuring out
803 -- when something has been updated but not entered relies on
804 -- having Node point to the result of an update. SLPJ
807 LFThunk _ no_fvs updatable _
808 -> returnFC (updatable || not no_fvs || do_profiling)
810 -- For the non-updatable (single-entry case):
812 -- True if has fvs (in which case we need access to them, and we
813 -- should black-hole it)
814 -- or profiling (in which case we need to recover the cost centre
817 LFArgument -> returnFC True
818 LFImported -> returnFC True
819 LFBlackHole -> returnFC True
820 -- BH entry may require Node to point
822 LFLetNoEscape _ _ -> returnFC False
825 The entry conventions depend on the type of closure being entered,
826 whether or not it has free variables, and whether we're running
827 sequentially or in parallel.
829 \begin{tabular}{lllll}
830 Closure Characteristics & Parallel & Node Req'd & Argument Passing & Enter Via \\
831 Unknown & no & yes & stack & node \\
832 Known fun ($\ge$ 1 arg), no fvs & no & no & registers & fast entry (enough args) \\
833 \ & \ & \ & \ & slow entry (otherwise) \\
834 Known fun ($\ge$ 1 arg), fvs & no & yes & registers & fast entry (enough args) \\
835 0 arg, no fvs @\r,\s@ & no & no & n/a & direct entry \\
836 0 arg, no fvs @\u@ & no & yes & n/a & node \\
837 0 arg, fvs @\r,\s@ & no & yes & n/a & direct entry \\
838 0 arg, fvs @\u@ & no & yes & n/a & node \\
840 Unknown & yes & yes & stack & node \\
841 Known fun ($\ge$ 1 arg), no fvs & yes & no & registers & fast entry (enough args) \\
842 \ & \ & \ & \ & slow entry (otherwise) \\
843 Known fun ($\ge$ 1 arg), fvs & yes & yes & registers & node \\
844 0 arg, no fvs @\r,\s@ & yes & no & n/a & direct entry \\
845 0 arg, no fvs @\u@ & yes & yes & n/a & node \\
846 0 arg, fvs @\r,\s@ & yes & yes & n/a & node \\
847 0 arg, fvs @\u@ & yes & yes & n/a & node\\
850 When black-holing, single-entry closures could also be entered via node
851 (rather than directly) to catch double-entry.
855 = ViaNode -- The "normal" convention
857 | StdEntry CLabel -- Jump to this code, with args on stack
858 (Maybe CLabel) -- possibly setting infoptr to this
860 | DirectEntry -- Jump directly to code, with args in regs
861 CLabel -- The code label
863 [MagicId] -- Its register assignments (possibly empty)
865 getEntryConvention :: Id -- Function being applied
866 -> LambdaFormInfo -- Its info
867 -> [PrimRep] -- Available arguments
868 -> FCode EntryConvention
870 getEntryConvention id lf_info arg_kinds
871 = nodeMustPointToIt lf_info `thenFC` \ node_points ->
873 is_concurrent = opt_ForConcurrent
877 if (node_points && is_concurrent) then ViaNode else
881 LFReEntrant _ arity _ ->
882 if arity == 0 || (length arg_kinds) < arity then
883 StdEntry (mkStdEntryLabel id) Nothing
885 DirectEntry (mkFastEntryLabel id arity) arity arg_regs
887 (arg_regs, _) = assignRegs live_regs (take arity arg_kinds)
888 live_regs = if node_points then [node] else []
891 -> let itbl = if zero_arity then
892 mkPhantomInfoTableLabel con
894 mkConInfoTableLabel con
896 --false:ASSERT (null arg_kinds) -- Should have no args (meaning what?)
897 StdEntry (mkConEntryLabel con) (Just itbl)
899 LFTuple tup zero_arity
900 -> --false:ASSERT (null arg_kinds) -- Should have no args (meaning what?)
901 StdEntry (mkConEntryLabel tup) (Just (mkConInfoTableLabel tup))
903 LFThunk _ _ updatable std_form_info
906 else StdEntry (thunkEntryLabel id std_form_info updatable) Nothing
908 LFArgument -> ViaNode
909 LFImported -> ViaNode
910 LFBlackHole -> ViaNode -- Presumably the black hole has by now
911 -- been updated, but we don't know with
912 -- what, so we enter via Node
914 LFLetNoEscape arity _
915 -> ASSERT(arity == length arg_kinds)
916 DirectEntry (mkStdEntryLabel id) arity arg_regs
918 (arg_regs, _) = assignRegs live_regs arg_kinds
919 live_regs = if node_points then [node] else []
922 blackHoleOnEntry :: Bool -- No-black-holing flag
926 -- Static closures are never themselves black-holed.
927 -- Updatable ones will be overwritten with a CAFList cell, which points to a black hole;
928 -- Single-entry ones have no fvs to plug, and we trust they don't form part of a loop.
930 blackHoleOnEntry no_black_holing (MkClosureInfo _ _ (StaticRep _ _)) = False
932 blackHoleOnEntry no_black_holing (MkClosureInfo _ lf_info _)
934 LFReEntrant _ _ _ -> False
935 LFThunk _ no_fvs updatable _
937 then not no_black_holing
939 other -> panic "blackHoleOnEntry" -- Should never happen
941 getStandardFormThunkInfo
943 -> Maybe [StgArg] -- Nothing => not a standard-form thunk
944 -- Just atoms => a standard-form thunk with payload atoms
946 getStandardFormThunkInfo (LFThunk _ _ _ (SelectorThunk scrutinee _ _))
947 = --trace "Selector thunk: missed opportunity to save info table + code"
949 -- Just [StgVarArg scrutinee]
950 -- We can't save the info tbl + code until we have a way to generate
951 -- a fixed family thereof.
953 getStandardFormThunkInfo (LFThunk _ _ _ (VapThunk fun_id args fun_in_payload))
954 | fun_in_payload = Just (StgVarArg fun_id : args)
955 | otherwise = Just args
957 getStandardFormThunkInfo other_lf_info = Nothing
959 maybeSelectorInfo (MkClosureInfo _ (LFThunk _ _ _ (SelectorThunk _ con offset)) _) = Just (con,offset)
960 maybeSelectorInfo _ = Nothing
963 Avoiding generating entries and info tables
964 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
965 At present, for every function we generate all of the following,
966 just in case. But they aren't always all needed, as noted below:
968 [NB1: all of this applies only to *functions*. Thunks always
969 have closure, info table, and entry code.]
971 [NB2: All are needed if the function is *exported*, just to play safe.]
974 * Fast-entry code ALWAYS NEEDED
977 Needed iff (a) we have any un-saturated calls to the function
978 OR (b) the function is passed as an arg
979 OR (c) we're in the parallel world and the function has free vars
980 [Reason: in parallel world, we always enter functions
981 with free vars via the closure.]
983 * The function closure
984 Needed iff (a) we have any un-saturated calls to the function
985 OR (b) the function is passed as an arg
986 OR (c) if the function has free vars (ie not top level)
988 Why case (a) here? Because if the arg-satis check fails,
989 UpdatePAP stuffs a pointer to the function closure in the PAP.
990 [Could be changed; UpdatePAP could stuff in a code ptr instead,
991 but doesn't seem worth it.]
993 [NB: these conditions imply that we might need the closure
994 without the slow-entry code. Here's how.
996 f x y = let g w = ...x..y..w...
1000 Here we need a closure for g which contains x and y,
1001 but since the calls are all saturated we just jump to the
1002 fast entry point for g, with R1 pointing to the closure for g.]
1005 * Standard info table
1006 Needed iff (a) we have any un-saturated calls to the function
1007 OR (b) the function is passed as an arg
1008 OR (c) the function has free vars (ie not top level)
1010 NB. In the sequential world, (c) is only required so that the function closure has
1011 an info table to point to, to keep the storage manager happy.
1012 If (c) alone is true we could fake up an info table by choosing
1013 one of a standard family of info tables, whose entry code just
1016 [NB In the parallel world (c) is needed regardless because
1017 we enter functions with free vars via the closure.]
1019 If (c) is retained, then we'll sometimes generate an info table
1020 (for storage mgr purposes) without slow-entry code. Then we need
1021 to use an error label in the info table to substitute for the absent
1024 * Standard vap-entry code
1025 Standard vap-entry info table
1026 Needed iff we have any updatable thunks of the standard vap-entry shape.
1028 * Single-update vap-entry code
1029 Single-update vap-entry info table
1030 Needed iff we have any non-updatable thunks of the
1031 standard vap-entry shape.
1035 staticClosureRequired
1040 staticClosureRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1041 (LFReEntrant top_level _ _) -- It's a function
1042 = ASSERT( top_level ) -- Assumption: it's a top-level, no-free-var binding
1043 arg_occ -- There's an argument occurrence
1044 || unsat_occ -- There's an unsaturated call
1045 || externallyVisibleId binder
1047 staticClosureRequired binder other_binder_info other_lf_info = True
1049 slowFunEntryCodeRequired -- Assumption: it's a function, not a thunk.
1053 slowFunEntryCodeRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1054 = arg_occ -- There's an argument occurrence
1055 || unsat_occ -- There's an unsaturated call
1056 || externallyVisibleId binder
1057 {- HAS FREE VARS AND IS PARALLEL WORLD -}
1059 slowFunEntryCodeRequired binder NoStgBinderInfo = True
1061 funInfoTableRequired
1066 funInfoTableRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1067 (LFReEntrant top_level _ _)
1069 || arg_occ -- There's an argument occurrence
1070 || unsat_occ -- There's an unsaturated call
1071 || externallyVisibleId binder
1073 funInfoTableRequired other_binder_info binder other_lf_info = True
1075 -- We need the vector-apply entry points for a function if
1076 -- there's a vector-apply occurrence in this module
1078 stdVapRequired, noUpdVapRequired :: StgBinderInfo -> Bool
1080 stdVapRequired binder_info
1081 = case binder_info of
1082 StgBinderInfo _ _ std_vap_occ _ _ -> std_vap_occ
1085 noUpdVapRequired binder_info
1086 = case binder_info of
1087 StgBinderInfo _ _ _ no_upd_vap_occ _ -> no_upd_vap_occ
1091 %************************************************************************
1093 \subsection[ClosureInfo-misc-funs]{Misc functions about @ClosureInfo@, etc.}
1095 %************************************************************************
1099 isStaticClosure :: ClosureInfo -> Bool
1100 isStaticClosure (MkClosureInfo _ _ rep) = isStaticRep rep
1102 closureId :: ClosureInfo -> Id
1103 closureId (MkClosureInfo id _ _) = id
1105 closureSMRep :: ClosureInfo -> SMRep
1106 closureSMRep (MkClosureInfo _ _ sm_rep) = sm_rep
1108 closureLFInfo :: ClosureInfo -> LambdaFormInfo
1109 closureLFInfo (MkClosureInfo _ lf_info _) = lf_info
1111 closureUpdReqd :: ClosureInfo -> Bool
1113 closureUpdReqd (MkClosureInfo _ (LFThunk _ _ upd _) _) = upd
1114 closureUpdReqd (MkClosureInfo _ LFBlackHole _) = True
1115 -- Black-hole closures are allocated to receive the results of an
1116 -- alg case with a named default... so they need to be updated.
1117 closureUpdReqd other_closure = False
1119 closureSingleEntry :: ClosureInfo -> Bool
1121 closureSingleEntry (MkClosureInfo _ (LFThunk _ _ upd _) _) = not upd
1122 closureSingleEntry other_closure = False
1125 Note: @closureType@ returns appropriately specialised tycon and
1128 closureType :: ClosureInfo -> Maybe (TyCon, [Type], [Id])
1130 -- First, a turgid special case. When we are generating the
1131 -- standard code and info-table for Vaps (which is done when the function
1132 -- defn is encountered), we don't have a convenient Id to hand whose
1133 -- type is that of (f x y z). So we need to figure out the type
1134 -- rather than take it from the Id. The Id is probably just "f"!
1136 closureType (MkClosureInfo id (LFThunk _ _ _ (VapThunk fun_id args _)) _)
1137 = maybeAppSpecDataTyConExpandingDicts (fun_result_ty (length args) fun_id)
1139 closureType (MkClosureInfo id lf _) = maybeAppSpecDataTyConExpandingDicts (idType id)
1142 @closureReturnsUnboxedType@ is used to check whether a closure, {\em
1143 once it has eaten its arguments}, returns an unboxed type. For
1144 example, the closure for a function:
1148 returns an unboxed type. This is important when dealing with stack
1151 closureReturnsUnboxedType :: ClosureInfo -> Bool
1153 closureReturnsUnboxedType (MkClosureInfo fun_id (LFReEntrant _ arity _) _)
1154 = isPrimType (fun_result_ty arity fun_id)
1156 closureReturnsUnboxedType other_closure = False
1157 -- All non-function closures aren't functions,
1158 -- and hence are boxed, since they are heap alloc'd
1160 -- ToDo: need anything like this in Type.lhs?
1161 fun_result_ty arity id
1163 (_, de_foralld_ty) = splitForAllTy (idType id)
1164 (arg_tys, res_ty) = splitFunTyExpandingDictsAndPeeking de_foralld_ty
1166 -- ASSERT(arity >= 0 && length arg_tys >= arity)
1167 (if (arity >= 0 && length arg_tys >= arity) then (\x->x) else pprPanic "fun_result_ty:" (ppCat [ppInt arity, ppr PprShowAll id, ppr PprDebug (idType id)])) $
1168 mkFunTys (drop arity arg_tys) res_ty
1172 closureSemiTag :: ClosureInfo -> Int
1174 closureSemiTag (MkClosureInfo _ lf_info _)
1176 LFCon data_con _ -> dataConTag data_con - fIRST_TAG
1178 _ -> fromInteger oTHER_TAG
1182 isToplevClosure :: ClosureInfo -> Bool
1184 isToplevClosure (MkClosureInfo _ lf_info _)
1186 LFReEntrant top _ _ -> top
1187 LFThunk top _ _ _ -> top
1188 _ -> panic "ClosureInfo:isToplevClosure"
1194 infoTableLabelFromCI :: ClosureInfo -> CLabel
1196 infoTableLabelFromCI (MkClosureInfo id lf_info rep)
1198 LFCon con _ -> mkConInfoPtr con rep
1199 LFTuple tup _ -> mkConInfoPtr tup rep
1201 LFBlackHole -> mkBlackHoleInfoTableLabel
1203 LFThunk _ _ upd_flag (VapThunk fun_id args _) -> mkVapInfoTableLabel fun_id upd_flag
1204 -- Use the standard vap info table
1205 -- for the function, rather than a one-off one
1206 -- for this particular closure
1208 {- For now, we generate individual info table and entry code for selector thunks,
1209 so their info table should be labelled in the standard way.
1210 The only special thing about them is that the info table has a field which
1211 tells the GC that it really is a selector.
1213 Later, perhaps, we'll have some standard RTS code for selector-thunk info tables,
1214 in which case this line will spring back to life.
1216 LFThunk _ _ upd_flag (SelectorThunk _ _ offset) -> mkSelectorInfoTableLabel upd_flag offset
1217 -- Ditto for selectors
1220 other -> {-NO: if isStaticRep rep
1221 then mkStaticInfoTableLabel id
1222 else -} mkInfoTableLabel id
1224 mkConInfoPtr :: Id -> SMRep -> CLabel
1225 mkConInfoPtr con rep
1226 = ASSERT(isDataCon con)
1228 PhantomRep -> mkPhantomInfoTableLabel con
1229 StaticRep _ _ -> mkStaticInfoTableLabel con
1230 _ -> mkConInfoTableLabel con
1232 mkConEntryPtr :: Id -> SMRep -> CLabel
1233 mkConEntryPtr con rep
1234 = ASSERT(isDataCon con)
1236 StaticRep _ _ -> mkStaticConEntryLabel con
1237 _ -> mkConEntryLabel con
1240 closureLabelFromCI (MkClosureInfo id _ _) = mkClosureLabel id
1242 entryLabelFromCI :: ClosureInfo -> CLabel
1243 entryLabelFromCI (MkClosureInfo id lf_info rep)
1245 LFThunk _ _ upd_flag std_form_info -> thunkEntryLabel id std_form_info upd_flag
1246 LFCon con _ -> mkConEntryPtr con rep
1247 LFTuple tup _ -> mkConEntryPtr tup rep
1248 other -> mkStdEntryLabel id
1250 -- thunkEntryLabel is a local help function, not exported. It's used from both
1251 -- entryLabelFromCI and getEntryConvention.
1252 -- I don't think it needs to deal with the SelectorThunk case
1253 -- Well, it's falling over now, so I've made it deal with it. (JSM)
1255 thunkEntryLabel thunk_id (VapThunk fun_id args _) is_updatable
1256 = mkVapEntryLabel fun_id is_updatable
1257 thunkEntryLabel thunk_id _ is_updatable
1258 = mkStdEntryLabel thunk_id
1260 fastLabelFromCI :: ClosureInfo -> CLabel
1261 fastLabelFromCI (MkClosureInfo id _ _) = mkFastEntryLabel id fun_arity
1263 arity_maybe = arityMaybe (getIdArity id)
1264 fun_arity = case arity_maybe of
1266 _ -> pprPanic "fastLabelFromCI:no arity:" (ppr PprShowAll id)
1270 allocProfilingMsg :: ClosureInfo -> FAST_STRING
1272 allocProfilingMsg (MkClosureInfo _ lf_info _)
1274 LFReEntrant _ _ _ -> SLIT("ALLOC_FUN")
1275 LFCon _ _ -> SLIT("ALLOC_CON")
1276 LFTuple _ _ -> SLIT("ALLOC_CON")
1277 LFThunk _ _ _ _ -> SLIT("ALLOC_THK")
1278 LFBlackHole -> SLIT("ALLOC_BH")
1279 LFImported -> panic "ALLOC_IMP"
1282 We need a black-hole closure info to pass to @allocDynClosure@ when we
1283 want to allocate the black hole on entry to a CAF.
1286 blackHoleClosureInfo (MkClosureInfo id _ _)
1287 = MkClosureInfo id LFBlackHole BlackHoleRep
1290 The register liveness when returning from a constructor. For
1291 simplicity, we claim just [node] is live for all but PhantomRep's. In
1292 truth, this means that non-constructor info tables also claim node,
1293 but since their liveness information is never used, we don't care.
1296 dataConLiveness (MkClosureInfo con _ PhantomRep)
1297 = case (dataReturnConvAlg con) of
1298 ReturnInRegs regs -> mkLiveRegsMask regs
1299 ReturnInHeap -> panic "dataConLiveness:PhantomRep in heap???"
1301 dataConLiveness _ = mkLiveRegsMask [node]
1304 %************************************************************************
1306 \subsection[ClosureInfo-Profiling-funs]{Misc functions about for profiling info.}
1308 %************************************************************************
1310 Profiling requires three pices of information to be determined for
1311 each closure's info table --- kind, description and type.
1313 The description is stored directly in the @CClosureInfoTable@ when the
1314 info table is built.
1316 The kind is determined from the @LambdaForm@ stored in the closure
1317 info using @closureKind@.
1319 The type is determined from the type information stored with the @Id@
1320 in the closure info using @closureTypeDescr@.
1323 closureKind :: ClosureInfo -> String
1325 closureKind (MkClosureInfo _ lf _)
1327 LFReEntrant _ n _ -> if n > 0 then "FN_K" else "THK_K"
1328 LFCon _ _ -> "CON_K"
1329 LFTuple _ _ -> "CON_K"
1330 LFThunk _ _ _ _ -> "THK_K"
1331 LFBlackHole -> "THK_K" -- consider BHs as thunks for the moment... (ToDo?)
1332 LFImported -> panic "IMP_KIND"
1334 closureTypeDescr :: ClosureInfo -> String
1335 closureTypeDescr (MkClosureInfo id lf _)
1336 = if (isDataCon id) then -- DataCon has function types
1337 _UNPK_ (nameOf (origName "closureTypeDescr" (dataConTyCon id))) -- We want the TyCon not the ->
1339 getTyDescription (idType id)