2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
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,
28 mkVirtHeapOffsets, -- for GHCI
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,
44 closureKind, closureTypeDescr, -- profiling
46 isConstantRep, isSpecRep, isPhantomRep, -- ToDo: Should be in SMRep, perhaps?
47 isStaticClosure, allocProfilingMsg,
49 getSMInfoStr, getSMInitHdrStr, getSMUpdInplaceHdrStr,
53 dataConLiveness -- concurrency
55 -- and to make the interface self-sufficient...
64 import CgCompInfo -- some magic constants
66 import CLabel -- Lots of label-making things
67 import CmdLineOpts ( GlobalSwitch(..) )
70 import Maybes ( maybeToBool, assocMaybe, Maybe(..) )
71 import Outputable -- needed for INCLUDE_FRC_METHOD
72 import Pretty -- ( ppStr, Pretty(..) )
73 import PrimRep ( PrimRep, getPrimRepSize, separateByPtrFollowness )
77 The ``wrapper'' data type for closure information:
82 Id -- The thing bound to this closure
83 LambdaFormInfo -- info derivable from the *source*
84 SMRep -- representation used by storage manager
87 %************************************************************************
89 \subsection[ClosureInfo-OLD-DOC]{OLD DOCUMENTATION PROBABLY SUPERCEDED BY stg-details}
91 %************************************************************************
93 We can optimise the function-entry code as follows.
96 \item If the ``function'' is not updatable, we can jump directly to its
97 entry code, rather than indirecting via the info pointer in the
98 closure. (For updatable thunks we must go via the closure, in
99 case it has been updated.)
101 \item If the former bullet applies, and the application we are
102 compiling gives the function as many arguments as it needs, we
103 can jump to its fast-entry code. (This only applies if the
104 function has one or more args, because zero-arg closures have
107 \item If the function is a top-level non-constructor or imported, there
108 is no need to make Node point to its closure. In order for
109 this to be right, we need to ensure that:
111 \item If such closures are updatable then they push their
112 static address in the update frame, not Node. Actually
113 we create a black hole and push its address.
115 \item The arg satisfaction check should load Node before jumping to
118 \item Top-level constructor closures need careful handling. If we are to
119 jump direct to the constructor code, we must load Node first, even
120 though they are top-level. But if we go to their ``own''
121 standard-entry code (which loads Node and then jumps to the
122 constructor code) we don't need to load Node.
127 {\em Top level constructors (@mkStaticConEntryInfo@)}
130 x = {y,ys} \ {} Cons {y,ys} -- Std form constructor
133 x-closure: Cons-info-table, y-closure, ys-closure
135 x-entry: Node = x-closure; jump( Cons-entry )
137 x's EntryInfo in its own module:
139 Base-label = Cons -- Not x!!
141 ClosureClass = Constructor
144 So if x is entered, Node will be set up and
145 we'll jump direct to the Cons code.
147 x's EntryInfo in another module: (which may not know that x is a constructor)
149 Base-label = x -- Is x!!
150 NodeMustPoint = False -- All imported things have False
151 ClosureClass = non-committal
154 If x is entered, we'll jump to x-entry, which will set up Node
155 before jumping to the standard Cons code
157 {\em Top level non-constructors (@mkStaticEntryInfo@)}
162 For updatable thunks, x-entry must push an allocated BH in update frame, not Node.
164 For non-zero arity, arg satis check must load Node before jumping to
167 x's EntryInfo in its own module:
170 NodeMustPoint = False
171 ClosureClass = whatever
174 {\em Inner constructors (@mkConEntryInfo@)}
177 Base-label = Cons -- Not x!!
178 NodeMustPoint = True -- If its arity were zero, it would
179 -- have been lifted to top level
180 ClosureClass = Constructor
183 {\em Inner non-constructors (@mkEntryInfo@)}
187 NodeMustPoint = True -- If no free vars, would have been
188 -- lifted to top level
189 ClosureClass = whatever
198 NodeMustPoint = False
199 ClosureClass = whatever
203 THINK: we could omit making Node point to top-level constructors
204 of arity zero; but that might interact nastily with updates.
209 The info we need to import for imported things is:
212 data ImportInfo = UnknownImportInfo
213 | HnfImport Int -- Not updatable, arity given
214 -- Arity can be zero, for (eg) constrs
215 | UpdatableImport -- Must enter via the closure
218 ToDo: move this stuff???
221 mkStaticEntryInfo lbl cl_class
222 = MkEntryInfo lbl False cl_class
224 mkStaticConEntryInfo lbl
225 = MkEntryInfo lbl True ConstructorClosure
227 mkEntryInfo lbl cl_class
228 = MkEntryInfo lbl True cl_class
231 = MkEntryInfo lbl True ConstructorClosure
234 %************************************************************************
236 \subsection[ClosureInfo-datatypes]{Data types for closure information}
238 %************************************************************************
240 %************************************************************************
242 \subsubsection[LambdaFormInfo-datatype]{@LambdaFormInfo@: source-derivable info}
244 %************************************************************************
248 = LFReEntrant -- Reentrant closure; used for PAPs too
249 Bool -- True if top level
251 Bool -- True <=> no fvs
253 | LFCon -- Constructor
254 DataCon -- The constructor (may be specialised)
255 Bool -- True <=> zero arity
258 DataCon -- The tuple constructor (may be specialised)
259 Bool -- True <=> zero arity
261 | LFThunk -- Thunk (zero arity)
262 Bool -- True <=> top level
263 Bool -- True <=> no free vars
264 Bool -- True <=> updatable (i.e., *not* single-entry)
267 | LFArgument -- Used for function arguments. We know nothing about
268 -- this closure. Treat like updatable "LFThunk"...
270 | LFImported -- Used for imported things. We know nothing about this
271 -- closure. Treat like updatable "LFThunk"...
272 -- Imported things which we do know something about use
273 -- one of the other LF constructors (eg LFReEntrant for
276 | LFLetNoEscape -- See LetNoEscape module for precise description of
279 StgLiveVars-- list of variables live in the RHS of the let.
280 -- (ToDo: maybe not used)
282 | LFBlackHole -- Used for the closures allocated to hold the result
283 -- of a CAF. We want the target of the update frame to
284 -- be in the heap, so we make a black hole to hold it.
286 -- This last one is really only for completeness;
287 -- it isn't actually used for anything interesting
288 {- | LFIndirection -}
290 data StandardFormInfo -- Tells whether this thunk has one of a small number
293 = NonStandardThunk -- No, it isn't
297 DataCon -- Constructor
298 Int -- 0-origin offset of ak within the "goods" of constructor
299 -- (Recall that the a1,...,an may be laid out in the heap
300 -- in a non-obvious order.)
302 {- A SelectorThunk is of form
307 and the constructor is from a single-constr type.
308 If we can't convert the heap-offset of the selectee into an Int, e.g.,
309 it's "GEN_VHS+i", we just give up.
315 Bool -- True <=> the function is not top-level, so
316 -- must be stored in the thunk too
318 {- A VapThunk is of form
322 where f is a known function, with arity n
323 So for this thunk we can use the label for f's heap-entry
324 info table (generated when f's defn was dealt with),
325 rather than generating a one-off info table and entry code
330 mkLFArgument = LFArgument
331 mkLFBlackHole = LFBlackHole
332 mkLFLetNoEscape = LFLetNoEscape
334 mkLFImported :: Id -> LambdaFormInfo
336 = case arityMaybe (getIdArity id) of
337 Nothing -> LFImported
338 Just 0 -> LFThunk True{-top-lev-} True{-no fvs-}
339 True{-updatable-} NonStandardThunk
340 Just n -> LFReEntrant True n True -- n > 0
343 %************************************************************************
345 \subsection[ClosureInfo-construction]{Functions which build LFInfos}
347 %************************************************************************
349 @mkClosureLFInfo@ figures out the appropriate LFInfo for the closure.
352 mkClosureLFInfo :: Bool -- True of top level
354 -> UpdateFlag -- Update flag
356 -> StgExpr -- Body of closure: passed so we
357 -- can look for selector thunks!
360 mkClosureLFInfo top fvs upd_flag args@(_:_) body -- Non-empty args
361 = LFReEntrant top (length args) (null fvs)
363 mkClosureLFInfo top fvs ReEntrant [] body
364 = LFReEntrant top 0 (null fvs)
367 OK, this is where we look at the body of the closure to see if it's a
368 selector---turgid, but nothing deep. We are looking for a closure of
369 {\em exactly} the form:
371 ... = [the_fv] \ u [] ->
373 con a_1 ... a_n -> a_i
377 mkClosureLFInfo False -- don't bother if at top-level
378 [the_fv] -- just one...
380 [] -- no args (a thunk)
381 (StgCase (StgApp (StgVarArg scrutinee) [{-no args-}] _)
382 _ _ _ -- ignore live vars and uniq...
384 [(con, params, use_mask,
385 (StgApp (StgVarArg selectee) [{-no args-}] _))]
387 | the_fv == scrutinee -- Scrutinee is the only free variable
388 && maybeToBool maybe_offset -- Selectee is a component of the tuple
389 && maybeToBool offset_into_int_maybe
390 && offset_into_int <= mAX_SPEC_SELECTEE_SIZE -- Offset is small enough
392 -- ASSERT(is_single_constructor) -- Should be true, by causes error for SpecTyCon
393 LFThunk False False True (SelectorThunk scrutinee con offset_into_int)
395 (_, params_w_offsets) = layOutDynCon con getIdPrimRep params
396 maybe_offset = assocMaybe params_w_offsets selectee
397 Just the_offset = maybe_offset
398 offset_into_int_maybe = intOffsetIntoGoods the_offset
399 Just offset_into_int = offset_into_int_maybe
400 is_single_constructor = maybeToBool (maybeSingleConstructorTyCon tycon)
401 (_,_,_, tycon) = getDataConSig con
404 Same kind of thing, looking for vector-apply thunks, of the form:
406 x = [...] \ .. [] -> f a1 .. an
408 where f has arity n. We rely on the arity info inside the Id being correct.
411 mkClosureLFInfo top_level
414 [] -- No args; a thunk
415 (StgApp (StgVarArg fun_id) args _)
416 | not top_level -- A top-level thunk would require a static
417 -- vap_info table, which we don't generate just
418 -- now; so top-level thunks are never standard
420 && isLocallyDefined fun_id -- Must be defined in this module
421 && maybeToBool arity_maybe -- A known function with known arity
422 && fun_arity > 0 -- It'd better be a function!
423 && fun_arity == length args -- Saturated application
424 = LFThunk top_level (null fvs) (isUpdatable upd_flag) (VapThunk fun_id args store_fun_in_vap)
426 arity_maybe = arityMaybe (getIdArity fun_id)
427 Just fun_arity = arity_maybe
429 -- If the function is a free variable then it must be stored
430 -- in the thunk too; if it isn't a free variable it must be
431 -- because it's constant, so it doesn't need to be stored in the thunk
432 store_fun_in_vap = fun_id `is_elem` fvs
434 is_elem = isIn "mkClosureLFInfo"
437 Finally, the general updatable-thing case:
439 mkClosureLFInfo top fvs upd_flag [] body
440 = LFThunk top (null fvs) (isUpdatable upd_flag) NonStandardThunk
442 isUpdatable ReEntrant = False
443 isUpdatable SingleEntry = False
444 isUpdatable Updatable = True
447 @mkConLFInfo@ is similar, for constructors.
450 mkConLFInfo :: DataCon -> LambdaFormInfo
453 = ASSERT(isDataCon con)
455 arity = getDataConArity con
457 if isTupleCon con then
458 LFTuple con (arity == 0)
460 LFCon con (arity == 0)
464 %************************************************************************
466 \subsection[ClosureInfo-sizes]{Functions about closure {\em sizes}}
468 %************************************************************************
471 closureSize :: ClosureInfo -> HeapOffset
472 closureSize cl_info@(MkClosureInfo _ _ sm_rep)
473 = totHdrSize sm_rep `addOff` (intOff (closureNonHdrSize cl_info))
475 closureSizeWithoutFixedHdr :: ClosureInfo -> HeapOffset
476 closureSizeWithoutFixedHdr cl_info@(MkClosureInfo _ _ sm_rep)
477 = varHdrSize sm_rep `addOff` (intOff (closureNonHdrSize cl_info))
479 closureHdrSize :: ClosureInfo -> HeapOffset
480 closureHdrSize (MkClosureInfo _ _ sm_rep)
483 closureNonHdrSize :: ClosureInfo -> Int
484 closureNonHdrSize cl_info@(MkClosureInfo _ lf_info sm_rep)
485 = tot_wds + computeSlopSize tot_wds sm_rep (closureUpdReqd cl_info) --ToDo: pass lf_info?
487 tot_wds = closureGoodStuffSize cl_info
489 closureGoodStuffSize :: ClosureInfo -> Int
490 closureGoodStuffSize (MkClosureInfo _ _ sm_rep)
491 = let (ptrs, nonptrs) = sizes_from_SMRep sm_rep
494 closurePtrsSize :: ClosureInfo -> Int
495 closurePtrsSize (MkClosureInfo _ _ sm_rep)
496 = let (ptrs, _) = sizes_from_SMRep sm_rep
500 sizes_from_SMRep (SpecialisedRep k ptrs nonptrs _) = (ptrs, nonptrs)
501 sizes_from_SMRep (GenericRep ptrs nonptrs _) = (ptrs, nonptrs)
502 sizes_from_SMRep (BigTupleRep ptrs) = (ptrs, 0)
503 sizes_from_SMRep (MuTupleRep ptrs) = (ptrs, 0)
504 sizes_from_SMRep (DataRep nonptrs) = (0, nonptrs)
505 sizes_from_SMRep BlackHoleRep = (0, 0)
506 sizes_from_SMRep (StaticRep ptrs nonptrs) = (ptrs, nonptrs)
508 sizes_from_SMRep PhantomRep = panic "sizes_from_SMRep: PhantomRep"
509 sizes_from_SMRep DynamicRep = panic "sizes_from_SMRep: DynamicRep"
514 fitsMinUpdSize :: ClosureInfo -> Bool
515 fitsMinUpdSize (MkClosureInfo _ _ BlackHoleRep) = True
516 fitsMinUpdSize cl_info = isSpecRep (closureSMRep cl_info) && closureNonHdrSize cl_info <= mIN_UPD_SIZE
519 Computing slop size. WARNING: this looks dodgy --- it has deep
520 knowledge of what the storage manager does with the various
526 Updateable closures must be @mIN_UPD_SIZE@.
529 Cons cell requires 2 words
531 Indirections require 1 word
533 Appels collector indirections 2 words
535 THEREFORE: @mIN_UPD_SIZE = 2@.
538 Collectable closures which are allocated in the heap
539 must be @mIN_SIZE_NonUpdHeapObject@.
541 Copying collector forward pointer requires 1 word
543 THEREFORE: @mIN_SIZE_NonUpdHeapObject = 1@
546 @SpecialisedRep@ closures closures may require slop:
549 @ConstantRep@ and @CharLikeRep@ closures always use the address of
550 a static closure. They are never allocated or
551 collected (eg hold forwarding pointer) hence never any slop.
554 @IntLikeRep@ are never updatable.
555 May need slop to be collected (as they will be size 1 or more
556 this probably has no affect)
559 @SpecRep@ may be updateable and will be collectable
562 @StaticRep@ may require slop if updatable. Non-updatable ones are OK.
565 @GenericRep@ closures will always be larger so never require slop.
568 ***** ToDo: keep an eye on this!
572 slopSize cl_info@(MkClosureInfo _ lf_info sm_rep)
573 = computeSlopSize (closureGoodStuffSize cl_info) sm_rep (closureUpdReqd cl_info)
575 computeSlopSize :: Int -> SMRep -> Bool -> Int
577 computeSlopSize tot_wds (SpecialisedRep ConstantRep _ _ _) _
579 computeSlopSize tot_wds (SpecialisedRep CharLikeRep _ _ _) _
582 computeSlopSize tot_wds (SpecialisedRep _ _ _ _) True -- Updatable
583 = max 0 (mIN_UPD_SIZE - tot_wds)
584 computeSlopSize tot_wds (StaticRep _ _) True -- Updatable
585 = max 0 (mIN_UPD_SIZE - tot_wds)
586 computeSlopSize tot_wds BlackHoleRep _ -- Updatable
587 = max 0 (mIN_UPD_SIZE - tot_wds)
589 computeSlopSize tot_wds (SpecialisedRep _ _ _ _) False -- Not updatable
590 = max 0 (mIN_SIZE_NonUpdHeapObject - tot_wds)
592 computeSlopSize tot_wds other_rep _ -- Any other rep
596 %************************************************************************
598 \subsection[layOutDynClosure]{Lay out a dynamic closure}
600 %************************************************************************
603 layOutDynClosure, layOutStaticClosure
604 :: Id -- STG identifier w/ which this closure assoc'd
605 -> (a -> PrimRep) -- function w/ which to be able to get a PrimRep
606 -> [a] -- the "things" being layed out
607 -> LambdaFormInfo -- what sort of closure it is
608 -> (ClosureInfo, -- info about the closure
609 [(a, VirtualHeapOffset)]) -- things w/ offsets pinned on them
611 layOutDynClosure name kind_fn things lf_info
612 = (MkClosureInfo name lf_info sm_rep,
615 (tot_wds, -- #ptr_wds + #nonptr_wds
617 things_w_offsets) = mkVirtHeapOffsets sm_rep kind_fn things
618 sm_rep = chooseDynSMRep lf_info tot_wds ptr_wds
620 layOutStaticClosure name kind_fn things lf_info
621 = (MkClosureInfo name lf_info (StaticRep ptr_wds (tot_wds - ptr_wds)),
624 (tot_wds, -- #ptr_wds + #nonptr_wds
626 things_w_offsets) = mkVirtHeapOffsets (StaticRep bot bot) kind_fn things
627 bot = panic "layoutStaticClosure"
629 layOutStaticNoFVClosure :: Id -> LambdaFormInfo -> ClosureInfo
630 layOutStaticNoFVClosure name lf_info
631 = MkClosureInfo name lf_info (StaticRep ptr_wds nonptr_wds)
633 -- I am very uncertain that this is right - it will show up when testing
634 -- my dynamic loading code. ADR
635 -- (If it's not right, we'll have to grab the kinds of the arguments from
640 layOutPhantomClosure :: Id -> LambdaFormInfo -> ClosureInfo
641 layOutPhantomClosure name lf_info = MkClosureInfo name lf_info PhantomRep
644 A wrapper for when used with data constructors:
646 layOutDynCon :: DataCon
649 -> (ClosureInfo, [(a,VirtualHeapOffset)])
651 layOutDynCon con kind_fn args
652 = ASSERT(isDataCon con)
653 layOutDynClosure con kind_fn args (mkConLFInfo con)
657 %************************************************************************
659 \subsection[SMreps]{Choosing SM reps}
661 %************************************************************************
666 -> Int -> Int -- Tot wds, ptr wds
669 chooseDynSMRep lf_info tot_wds ptr_wds
671 nonptr_wds = tot_wds - ptr_wds
673 updatekind = case lf_info of
674 LFThunk _ _ upd _ -> if upd then SMUpdatable else SMSingleEntry
675 LFBlackHole -> SMUpdatable
678 if (nonptr_wds == 0 && ptr_wds <= mAX_SPEC_ALL_PTRS)
679 || (tot_wds <= mAX_SPEC_MIXED_FIELDS)
680 || (ptr_wds == 0 && nonptr_wds <= mAX_SPEC_ALL_NONPTRS) then
682 spec_kind = case lf_info of
684 (LFTuple _ True) -> ConstantRep
686 (LFTuple _ _) -> SpecRep
688 (LFCon _ True) -> ConstantRep
690 (LFCon con _ ) -> if maybeToBool (maybeCharLikeTyCon tycon) then CharLikeRep
691 else if maybeToBool (maybeIntLikeTyCon tycon) then IntLikeRep
694 tycon = getDataConTyCon con
698 SpecialisedRep spec_kind ptr_wds nonptr_wds updatekind
700 GenericRep ptr_wds nonptr_wds updatekind
704 %************************************************************************
706 \subsection[mkVirtHeapOffsets]{Assigning heap offsets in a closure}
708 %************************************************************************
710 @mkVirtHeapOffsets@ (the heap version) always returns boxed things with
711 smaller offsets than the unboxed things, and furthermore, the offsets in
715 mkVirtHeapOffsets :: SMRep -- Representation to be used by storage manager
716 -> (a -> PrimRep) -- To be able to grab kinds;
717 -- w/ a kind, we can find boxedness
718 -> [a] -- Things to make offsets for
719 -> (Int, -- *Total* number of words allocated
720 Int, -- Number of words allocated for *pointers*
721 [(a, VirtualHeapOffset)]) -- Things with their offsets from start of object
722 -- in order of increasing offset
724 -- First in list gets lowest offset, which is initial offset + 1.
726 mkVirtHeapOffsets sm_rep kind_fun things
727 = let (ptrs, non_ptrs) = separateByPtrFollowness kind_fun things
728 (wds_of_ptrs, ptrs_w_offsets) = mapAccumL computeOffset 0 ptrs
729 (tot_wds, non_ptrs_w_offsets) = mapAccumL computeOffset wds_of_ptrs non_ptrs
731 (tot_wds, wds_of_ptrs, ptrs_w_offsets ++ non_ptrs_w_offsets)
733 offset_of_first_word = totHdrSize sm_rep
734 computeOffset wds_so_far thing
735 = (wds_so_far + (getPrimRepSize . kind_fun) thing,
736 (thing, (offset_of_first_word `addOff` (intOff wds_so_far)))
740 %************************************************************************
742 \subsection[ClosureInfo-4-questions]{Four major questions about @ClosureInfo@}
744 %************************************************************************
746 Be sure to see the stg-details notes about these...
749 nodeMustPointToIt :: LambdaFormInfo -> FCode Bool
750 nodeMustPointToIt lf_info
751 = isSwitchSetC SccProfilingOn `thenFC` \ do_profiling ->
754 LFReEntrant top arity no_fvs -> returnFC (
755 not no_fvs || -- Certainly if it has fvs we need to point to it
757 not top -- If it is not top level we will point to it
758 -- We can have a \r closure with no_fvs which
759 -- is not top level as special case cgRhsClosure
760 -- has been dissabled in favour of let floating
762 -- For lex_profiling we also access the cost centre for a
763 -- non-inherited function i.e. not top level
764 -- the not top case above ensures this is ok.
767 LFCon _ zero_arity -> returnFC True
768 LFTuple _ zero_arity -> returnFC True
770 -- Strictly speaking, the above two don't need Node to point
771 -- to it if the arity = 0. But this is a *really* unlikely
772 -- situation. If we know it's nil (say) and we are entering
773 -- it. Eg: let x = [] in x then we will certainly have inlined
774 -- x, since nil is a simple atom. So we gain little by not
775 -- having Node point to known zero-arity things. On the other
776 -- hand, we do lose something; Patrick's code for figuring out
777 -- when something has been updated but not entered relies on
778 -- having Node point to the result of an update. SLPJ
781 LFThunk _ no_fvs updatable _
782 -> returnFC (updatable || not no_fvs || do_profiling)
784 -- For the non-updatable (single-entry case):
786 -- True if has fvs (in which case we need access to them, and we
787 -- should black-hole it)
788 -- or profiling (in which case we need to recover the cost centre
791 LFArgument -> returnFC True
792 LFImported -> returnFC True
793 LFBlackHole -> returnFC True
794 -- BH entry may require Node to point
796 LFLetNoEscape _ _ -> returnFC False
799 The entry conventions depend on the type of closure being entered,
800 whether or not it has free variables, and whether we're running
801 sequentially or in parallel.
803 \begin{tabular}{lllll}
804 Closure Characteristics & Parallel & Node Req'd & Argument Passing & Enter Via \\
805 Unknown & no & yes & stack & node \\
806 Known fun ($\ge$ 1 arg), no fvs & no & no & registers & fast entry (enough args) \\
807 \ & \ & \ & \ & slow entry (otherwise) \\
808 Known fun ($\ge$ 1 arg), fvs & no & yes & registers & fast entry (enough args) \\
809 0 arg, no fvs @\r,\s@ & no & no & n/a & direct entry \\
810 0 arg, no fvs @\u@ & no & yes & n/a & node \\
811 0 arg, fvs @\r,\s@ & no & yes & n/a & direct entry \\
812 0 arg, fvs @\u@ & no & yes & n/a & node \\
814 Unknown & yes & yes & stack & node \\
815 Known fun ($\ge$ 1 arg), no fvs & yes & no & registers & fast entry (enough args) \\
816 \ & \ & \ & \ & slow entry (otherwise) \\
817 Known fun ($\ge$ 1 arg), fvs & yes & yes & registers & node \\
818 0 arg, no fvs @\r,\s@ & yes & no & n/a & direct entry \\
819 0 arg, no fvs @\u@ & yes & yes & n/a & node \\
820 0 arg, fvs @\r,\s@ & yes & yes & n/a & node \\
821 0 arg, fvs @\u@ & yes & yes & n/a & node\\
824 When black-holing, single-entry closures could also be entered via node
825 (rather than directly) to catch double-entry.
829 = ViaNode -- The "normal" convention
831 | StdEntry CLabel -- Jump to this code, with args on stack
832 (Maybe CLabel) -- possibly setting infoptr to this
834 | DirectEntry -- Jump directly to code, with args in regs
835 CLabel -- The code label
837 [MagicId] -- Its register assignments (possibly empty)
839 getEntryConvention :: Id -- Function being applied
840 -> LambdaFormInfo -- Its info
841 -> [PrimRep] -- Available arguments
842 -> FCode EntryConvention
844 getEntryConvention id lf_info arg_kinds
845 = nodeMustPointToIt lf_info `thenFC` \ node_points ->
846 isSwitchSetC ForConcurrent `thenFC` \ is_concurrent ->
847 getIntSwitchChkrC `thenFC` \ isw_chkr ->
850 if (node_points && is_concurrent) then ViaNode else
854 LFReEntrant _ arity _ ->
855 if arity == 0 || (length arg_kinds) < arity then
856 StdEntry (mkStdEntryLabel id) Nothing
858 DirectEntry (mkFastEntryLabel id arity) arity arg_regs
860 (arg_regs, _) = assignRegs isw_chkr live_regs (take arity arg_kinds)
861 live_regs = if node_points then [node] else []
864 -> let itbl = if zero_arity then
865 mkPhantomInfoTableLabel con
868 in StdEntry (mkStdEntryLabel con) (Just itbl)
869 -- Should have no args
870 LFTuple tup zero_arity
871 -> StdEntry (mkStdEntryLabel tup)
872 (Just (mkInfoTableLabel tup))
873 -- Should have no args
875 LFThunk _ _ updatable std_form_info
878 else StdEntry (thunkEntryLabel id std_form_info updatable) Nothing
880 LFArgument -> ViaNode
881 LFImported -> ViaNode
882 LFBlackHole -> ViaNode -- Presumably the black hole has by now
883 -- been updated, but we don't know with
884 -- what, so we enter via Node
886 LFLetNoEscape arity _
887 -> ASSERT(arity == length arg_kinds)
888 DirectEntry (mkStdEntryLabel id) arity arg_regs
890 (arg_regs, _) = assignRegs isw_chkr live_regs arg_kinds
891 live_regs = if node_points then [node] else []
894 blackHoleOnEntry :: Bool -- No-black-holing flag
898 -- Static closures are never themselves black-holed.
899 -- Updatable ones will be overwritten with a CAFList cell, which points to a black hole;
900 -- Single-entry ones have no fvs to plug, and we trust they don't form part of a loop.
902 blackHoleOnEntry no_black_holing (MkClosureInfo _ _ (StaticRep _ _)) = False
904 blackHoleOnEntry no_black_holing (MkClosureInfo _ lf_info _)
906 LFReEntrant _ _ _ -> False
907 LFThunk _ no_fvs updatable _
909 then not no_black_holing
911 other -> panic "blackHoleOnEntry" -- Should never happen
913 getStandardFormThunkInfo
915 -> Maybe [StgArg] -- Nothing => not a standard-form thunk
916 -- Just atoms => a standard-form thunk with payload atoms
918 getStandardFormThunkInfo (LFThunk _ _ _ (SelectorThunk scrutinee _ _))
919 = --trace "Selector thunk: missed opportunity to save info table + code"
921 -- Just [StgVarArg scrutinee]
922 -- We can't save the info tbl + code until we have a way to generate
923 -- a fixed family thereof.
925 getStandardFormThunkInfo (LFThunk _ _ _ (VapThunk fun_id args fun_in_payload))
926 | fun_in_payload = Just (StgVarArg fun_id : args)
927 | otherwise = Just args
929 getStandardFormThunkInfo other_lf_info = Nothing
931 maybeSelectorInfo (MkClosureInfo _ (LFThunk _ _ _ (SelectorThunk _ con offset)) _) = Just (con,offset)
932 maybeSelectorInfo _ = Nothing
935 Avoiding generating entries and info tables
936 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
937 At present, for every function we generate all of the following,
938 just in case. But they aren't always all needed, as noted below:
940 [NB1: all of this applies only to *functions*. Thunks always
941 have closure, info table, and entry code.]
943 [NB2: All are needed if the function is *exported*, just to play safe.]
946 * Fast-entry code ALWAYS NEEDED
949 Needed iff (a) we have any un-saturated calls to the function
950 OR (b) the function is passed as an arg
951 OR (c) we're in the parallel world and the function has free vars
952 [Reason: in parallel world, we always enter functions
953 with free vars via the closure.]
955 * The function closure
956 Needed iff (a) we have any un-saturated calls to the function
957 OR (b) the function is passed as an arg
958 OR (c) if the function has free vars (ie not top level)
960 Why case (a) here? Because if the arg-satis check fails,
961 UpdatePAP stuffs a pointer to the function closure in the PAP.
962 [Could be changed; UpdatePAP could stuff in a code ptr instead,
963 but doesn't seem worth it.]
965 [NB: these conditions imply that we might need the closure
966 without the slow-entry code. Here's how.
968 f x y = let g w = ...x..y..w...
972 Here we need a closure for g which contains x and y,
973 but since the calls are all saturated we just jump to the
974 fast entry point for g, with R1 pointing to the closure for g.]
977 * Standard info table
978 Needed iff (a) we have any un-saturated calls to the function
979 OR (b) the function is passed as an arg
980 OR (c) the function has free vars (ie not top level)
982 NB. In the sequential world, (c) is only required so that the function closure has
983 an info table to point to, to keep the storage manager happy.
984 If (c) alone is true we could fake up an info table by choosing
985 one of a standard family of info tables, whose entry code just
988 [NB In the parallel world (c) is needed regardless because
989 we enter functions with free vars via the closure.]
991 If (c) is retained, then we'll sometimes generate an info table
992 (for storage mgr purposes) without slow-entry code. Then we need
993 to use an error label in the info table to substitute for the absent
996 * Standard vap-entry code
997 Standard vap-entry info table
998 Needed iff we have any updatable thunks of the standard vap-entry shape.
1000 * Single-update vap-entry code
1001 Single-update vap-entry info table
1002 Needed iff we have any non-updatable thunks of the
1003 standard vap-entry shape.
1007 staticClosureRequired
1012 staticClosureRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1013 (LFReEntrant top_level _ _) -- It's a function
1014 = ASSERT( top_level ) -- Assumption: it's a top-level, no-free-var binding
1015 arg_occ -- There's an argument occurrence
1016 || unsat_occ -- There's an unsaturated call
1017 || externallyVisibleId binder
1019 staticClosureRequired binder other_binder_info other_lf_info = True
1021 slowFunEntryCodeRequired -- Assumption: it's a function, not a thunk.
1025 slowFunEntryCodeRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1026 = arg_occ -- There's an argument occurrence
1027 || unsat_occ -- There's an unsaturated call
1028 || externallyVisibleId binder
1029 {- HAS FREE VARS AND IS PARALLEL WORLD -}
1031 slowFunEntryCodeRequired binder NoStgBinderInfo = True
1033 funInfoTableRequired
1038 funInfoTableRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1039 (LFReEntrant top_level _ _)
1041 || arg_occ -- There's an argument occurrence
1042 || unsat_occ -- There's an unsaturated call
1043 || externallyVisibleId binder
1045 funInfoTableRequired other_binder_info binder other_lf_info = True
1047 -- We need the vector-apply entry points for a function if
1048 -- there's a vector-apply occurrence in this module
1050 stdVapRequired, noUpdVapRequired :: StgBinderInfo -> Bool
1052 stdVapRequired binder_info
1053 = case binder_info of
1054 StgBinderInfo _ _ std_vap_occ _ _ -> std_vap_occ
1057 noUpdVapRequired binder_info
1058 = case binder_info of
1059 StgBinderInfo _ _ _ no_upd_vap_occ _ -> no_upd_vap_occ
1063 %************************************************************************
1065 \subsection[ClosureInfo-misc-funs]{Misc functions about @ClosureInfo@, etc.}
1067 %************************************************************************
1070 isConstantRep, isSpecRep, isStaticRep, isPhantomRep, isIntLikeRep :: SMRep -> Bool
1071 isConstantRep (SpecialisedRep ConstantRep _ _ _) = True
1072 isConstantRep other = False
1074 isSpecRep (SpecialisedRep kind _ _ _) = True -- All the kinds of Spec closures
1075 isSpecRep other = False -- True indicates that the _VHS is 0 !
1077 isStaticRep (StaticRep _ _) = True
1078 isStaticRep _ = False
1080 isPhantomRep PhantomRep = True
1081 isPhantomRep _ = False
1083 isIntLikeRep (SpecialisedRep IntLikeRep _ _ _) = True
1084 isIntLikeRep other = False
1086 isStaticClosure :: ClosureInfo -> Bool
1087 isStaticClosure (MkClosureInfo _ _ rep) = isStaticRep rep
1089 closureId :: ClosureInfo -> Id
1090 closureId (MkClosureInfo id _ _) = id
1092 closureSMRep :: ClosureInfo -> SMRep
1093 closureSMRep (MkClosureInfo _ _ sm_rep) = sm_rep
1095 closureLFInfo :: ClosureInfo -> LambdaFormInfo
1096 closureLFInfo (MkClosureInfo _ lf_info _) = lf_info
1098 closureUpdReqd :: ClosureInfo -> Bool
1100 closureUpdReqd (MkClosureInfo _ (LFThunk _ _ upd _) _) = upd
1101 closureUpdReqd (MkClosureInfo _ LFBlackHole _) = True
1102 -- Black-hole closures are allocated to receive the results of an
1103 -- alg case with a named default... so they need to be updated.
1104 closureUpdReqd other_closure = False
1106 closureSingleEntry :: ClosureInfo -> Bool
1108 closureSingleEntry (MkClosureInfo _ (LFThunk _ _ upd _) _) = not upd
1109 closureSingleEntry other_closure = False
1112 Note: @closureType@ returns appropriately specialised tycon and
1115 closureType :: ClosureInfo -> Maybe (TyCon, [Type], [Id])
1117 -- First, a turgid special case. When we are generating the
1118 -- standard code and info-table for Vaps (which is done when the function
1119 -- defn is encountered), we don't have a convenient Id to hand whose
1120 -- type is that of (f x y z). So we need to figure out the type
1121 -- rather than take it from the Id. The Id is probably just "f"!
1123 closureType (MkClosureInfo id (LFThunk _ _ _ (VapThunk fun_id args _)) _)
1124 = getUniDataSpecTyCon_maybe (funResultTy de_foralld_ty (length args))
1126 (_, de_foralld_ty) = splitForalls (idType fun_id)
1128 closureType (MkClosureInfo id lf _) = getUniDataSpecTyCon_maybe (idType id)
1131 @closureReturnsUnboxedType@ is used to check whether a closure, {\em
1132 once it has eaten its arguments}, returns an unboxed type. For
1133 example, the closure for a function:
1137 returns an unboxed type. This is important when dealing with stack
1140 closureReturnsUnboxedType :: ClosureInfo -> Bool
1142 closureReturnsUnboxedType (MkClosureInfo fun_id (LFReEntrant _ arity _) _)
1143 = isPrimType (funResultTy de_foralld_ty arity)
1145 (_, de_foralld_ty) = splitForalls (idType fun_id)
1147 closureReturnsUnboxedType other_closure = False
1148 -- All non-function closures aren't functions,
1149 -- and hence are boxed, since they are heap alloc'd
1153 closureSemiTag :: ClosureInfo -> Int
1155 closureSemiTag (MkClosureInfo _ lf_info _)
1157 LFCon data_con _ -> getDataConTag data_con - fIRST_TAG
1159 _ -> fromInteger oTHER_TAG
1165 infoTableLabelFromCI :: ClosureInfo -> CLabel
1167 infoTableLabelFromCI (MkClosureInfo id lf_info rep)
1169 LFCon con _ -> mkConInfoPtr con rep
1170 LFTuple tup _ -> mkConInfoPtr tup rep
1172 LFBlackHole -> mkBlackHoleInfoTableLabel
1174 LFThunk _ _ upd_flag (VapThunk fun_id args _) -> mkVapInfoTableLabel fun_id upd_flag
1175 -- Use the standard vap info table
1176 -- for the function, rather than a one-off one
1177 -- for this particular closure
1179 {- For now, we generate individual info table and entry code for selector thunks,
1180 so their info table should be labelled in the standard way.
1181 The only special thing about them is that the info table has a field which
1182 tells the GC that it really is a selector.
1184 Later, perhaps, we'll have some standard RTS code for selector-thunk info tables,
1185 in which case this line will spring back to life.
1187 LFThunk _ _ upd_flag (SelectorThunk _ _ offset) -> mkSelectorInfoTableLabel upd_flag offset
1188 -- Ditto for selectors
1191 other -> {-NO: if isStaticRep rep
1192 then mkStaticInfoTableLabel id
1193 else -} mkInfoTableLabel id
1195 mkConInfoPtr :: Id -> SMRep -> CLabel
1196 mkConInfoPtr id rep =
1198 PhantomRep -> mkPhantomInfoTableLabel id
1199 StaticRep _ _ -> mkStaticInfoTableLabel id
1200 _ -> mkInfoTableLabel id
1202 mkConEntryPtr :: Id -> SMRep -> CLabel
1203 mkConEntryPtr id rep =
1205 StaticRep _ _ -> mkStaticConEntryLabel id
1206 _ -> mkConEntryLabel id
1209 closureLabelFromCI (MkClosureInfo id _ _) = mkClosureLabel id
1211 entryLabelFromCI :: ClosureInfo -> CLabel
1212 entryLabelFromCI (MkClosureInfo id lf_info rep)
1214 LFThunk _ _ upd_flag std_form_info -> thunkEntryLabel id std_form_info upd_flag
1215 LFCon con _ -> mkConEntryPtr con rep
1216 LFTuple tup _ -> mkConEntryPtr tup rep
1217 other -> mkStdEntryLabel id
1219 -- thunkEntryLabel is a local help function, not exported. It's used from both
1220 -- entryLabelFromCI and getEntryConvention.
1221 -- I don't think it needs to deal with the SelectorThunk case
1222 -- Well, it's falling over now, so I've made it deal with it. (JSM)
1224 thunkEntryLabel thunk_id (VapThunk fun_id args _) is_updatable
1225 = mkVapEntryLabel fun_id is_updatable
1226 thunkEntryLabel thunk_id _ is_updatable
1227 = mkStdEntryLabel thunk_id
1229 fastLabelFromCI :: ClosureInfo -> CLabel
1230 fastLabelFromCI (MkClosureInfo id _ _) = mkFastEntryLabel id fun_arity
1232 arity_maybe = arityMaybe (getIdArity id)
1233 fun_arity = case arity_maybe of
1235 _ -> pprPanic "fastLabelFromCI:no arity:" (ppr PprShowAll id)
1239 allocProfilingMsg :: ClosureInfo -> FAST_STRING
1241 allocProfilingMsg (MkClosureInfo _ lf_info _)
1243 LFReEntrant _ _ _ -> SLIT("ALLOC_FUN")
1244 LFCon _ _ -> SLIT("ALLOC_CON")
1245 LFTuple _ _ -> SLIT("ALLOC_CON")
1246 LFThunk _ _ _ _ -> SLIT("ALLOC_THK")
1247 LFBlackHole -> SLIT("ALLOC_BH")
1248 LFImported -> panic "ALLOC_IMP"
1251 We need a black-hole closure info to pass to @allocDynClosure@
1252 when we want to allocate the black hole on entry to a CAF.
1255 blackHoleClosureInfo (MkClosureInfo id _ _) = MkClosureInfo id LFBlackHole BlackHoleRep
1258 The register liveness when returning from a constructor. For simplicity,
1259 we claim just [node] is live for all but PhantomRep's. In truth, this means
1260 that non-constructor info tables also claim node, but since their liveness
1261 information is never used, we don't care.
1265 dataConLiveness isw_chkr (MkClosureInfo con _ PhantomRep)
1266 = case (dataReturnConvAlg isw_chkr con) of
1267 ReturnInRegs regs -> mkLiveRegsBitMask regs
1268 ReturnInHeap -> panic "dataConLiveness:PhantomRep in heap???"
1270 dataConLiveness _ _ = mkLiveRegsBitMask [node]
1273 %************************************************************************
1275 \subsection[ClosureInfo-Profiling-funs]{Misc functions about for profiling info.}
1277 %************************************************************************
1279 Profiling requires three pices of information to be determined for
1280 each closure's info table --- kind, description and type.
1282 The description is stored directly in the @CClosureInfoTable@ when the
1283 info table is built.
1285 The kind is determined from the @LambdaForm@ stored in the closure
1286 info using @closureKind@.
1288 The type is determined from the type information stored with the @Id@
1289 in the closure info using @closureTypeDescr@.
1292 closureKind :: ClosureInfo -> String
1294 closureKind (MkClosureInfo _ lf _)
1296 LFReEntrant _ n _ -> if n > 0 then "FN_K" else "THK_K"
1297 LFCon _ _ -> "CON_K"
1298 LFTuple _ _ -> "CON_K"
1299 LFThunk _ _ _ _ -> "THK_K"
1300 LFBlackHole -> "THK_K" -- consider BHs as thunks for the moment... (ToDo?)
1301 LFImported -> panic "IMP_KIND"
1303 closureTypeDescr :: ClosureInfo -> String
1304 closureTypeDescr (MkClosureInfo id lf _)
1305 = if (isDataCon id) then -- DataCon has function types
1306 _UNPK_ (getOccurrenceName (getDataConTyCon id)) -- We want the TyCon not the ->
1308 getUniTyDescription (idType id)