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, -- UNUSED: closureNonPtrsSize,
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 --OLD auxInfoTableLabelFromCI, isIntLikeRep, -- go away in 0.23
46 closureKind, closureTypeDescr, -- profiling
48 isConstantRep, isSpecRep, isPhantomRep, -- ToDo: Should be in SMRep, perhaps?
49 isStaticClosure, allocProfilingMsg,
51 getSMInfoStr, getSMInitHdrStr, getSMUpdInplaceHdrStr,
52 ltSMRepHdr, --UNUSED: equivSMRepHdr,
55 dataConLiveness, -- concurrency
57 -- and to make the interface self-sufficient...
58 AbstractC, CAddrMode, HeapOffset, MagicId,
59 CgInfoDownwards, CgState, CgIdInfo, CompilationInfo,
60 CLabel, Id, Maybe, PrimKind, FCode(..), TyCon, StgExpr,
61 StgAtom, StgBinderInfo,
62 DataCon(..), PlainStgExpr(..), PlainStgLiveVars(..),
64 UniqSet(..), UniqFM, UpdateFlag(..) -- not abstract
66 IF_ATTACK_PRAGMAS(COMMA mkClosureLabel)
67 IF_ATTACK_PRAGMAS(COMMA getUniDataSpecTyCon_maybe)
76 import CgCompInfo -- some magic constants
78 import CLabelInfo -- Lots of label-making things
79 import CmdLineOpts ( GlobalSwitch(..) )
82 import Maybes ( maybeToBool, assocMaybe, Maybe(..) )
83 import Outputable -- needed for INCLUDE_FRC_METHOD
84 import Pretty -- ( ppStr, Pretty(..) )
85 import PrimKind ( PrimKind, getKindSize, separateByPtrFollowness )
89 The ``wrapper'' data type for closure information:
94 Id -- The thing bound to this closure
95 LambdaFormInfo -- info derivable from the *source*
96 SMRep -- representation used by storage manager
99 %************************************************************************
101 \subsection[ClosureInfo-OLD-DOC]{OLD DOCUMENTATION PROBABLY SUPERCEDED BY stg-details}
103 %************************************************************************
105 We can optimise the function-entry code as follows.
108 \item If the ``function'' is not updatable, we can jump directly to its
109 entry code, rather than indirecting via the info pointer in the
110 closure. (For updatable thunks we must go via the closure, in
111 case it has been updated.)
113 \item If the former bullet applies, and the application we are
114 compiling gives the function as many arguments as it needs, we
115 can jump to its fast-entry code. (This only applies if the
116 function has one or more args, because zero-arg closures have
119 \item If the function is a top-level non-constructor or imported, there
120 is no need to make Node point to its closure. In order for
121 this to be right, we need to ensure that:
123 \item If such closures are updatable then they push their
124 static address in the update frame, not Node. Actually
125 we create a black hole and push its address.
127 \item The arg satisfaction check should load Node before jumping to
130 \item Top-level constructor closures need careful handling. If we are to
131 jump direct to the constructor code, we must load Node first, even
132 though they are top-level. But if we go to their ``own''
133 standard-entry code (which loads Node and then jumps to the
134 constructor code) we don't need to load Node.
139 {\em Top level constructors (@mkStaticConEntryInfo@)}
142 x = {y,ys} \ {} Cons {y,ys} -- Std form constructor
145 x-closure: Cons-info-table, y-closure, ys-closure
147 x-entry: Node = x-closure; jump( Cons-entry )
149 x's EntryInfo in its own module:
151 Base-label = Cons -- Not x!!
153 ClosureClass = Constructor
156 So if x is entered, Node will be set up and
157 we'll jump direct to the Cons code.
159 x's EntryInfo in another module: (which may not know that x is a constructor)
161 Base-label = x -- Is x!!
162 NodeMustPoint = False -- All imported things have False
163 ClosureClass = non-committal
166 If x is entered, we'll jump to x-entry, which will set up Node
167 before jumping to the standard Cons code
169 {\em Top level non-constructors (@mkStaticEntryInfo@)}
174 For updatable thunks, x-entry must push an allocated BH in update frame, not Node.
176 For non-zero arity, arg satis check must load Node before jumping to
179 x's EntryInfo in its own module:
182 NodeMustPoint = False
183 ClosureClass = whatever
186 {\em Inner constructors (@mkConEntryInfo@)}
189 Base-label = Cons -- Not x!!
190 NodeMustPoint = True -- If its arity were zero, it would
191 -- have been lifted to top level
192 ClosureClass = Constructor
195 {\em Inner non-constructors (@mkEntryInfo@)}
199 NodeMustPoint = True -- If no free vars, would have been
200 -- lifted to top level
201 ClosureClass = whatever
210 NodeMustPoint = False
211 ClosureClass = whatever
215 THINK: we could omit making Node point to top-level constructors
216 of arity zero; but that might interact nastily with updates.
221 The info we need to import for imported things is:
224 data ImportInfo = UnknownImportInfo
225 | HnfImport Int -- Not updatable, arity given
226 -- Arity can be zero, for (eg) constrs
227 | UpdatableImport -- Must enter via the closure
230 ToDo: move this stuff???
233 mkStaticEntryInfo lbl cl_class
234 = MkEntryInfo lbl False cl_class
236 mkStaticConEntryInfo lbl
237 = MkEntryInfo lbl True ConstructorClosure
239 mkEntryInfo lbl cl_class
240 = MkEntryInfo lbl True cl_class
243 = MkEntryInfo lbl True ConstructorClosure
246 %************************************************************************
248 \subsection[ClosureInfo-datatypes]{Data types for closure information}
250 %************************************************************************
252 %************************************************************************
254 \subsubsection[LambdaFormInfo-datatype]{@LambdaFormInfo@: source-derivable info}
256 %************************************************************************
260 = LFReEntrant -- Reentrant closure; used for PAPs too
261 Bool -- True if top level
263 Bool -- True <=> no fvs
265 | LFCon -- Constructor
266 DataCon -- The constructor (may be specialised)
267 Bool -- True <=> zero arity
270 DataCon -- The tuple constructor (may be specialised)
271 Bool -- True <=> zero arity
273 | LFThunk -- Thunk (zero arity)
274 Bool -- True <=> top level
275 Bool -- True <=> no free vars
276 Bool -- True <=> updatable (i.e., *not* single-entry)
279 | LFArgument -- Used for function arguments. We know nothing about
280 -- this closure. Treat like updatable "LFThunk"...
282 | LFImported -- Used for imported things. We know nothing about this
283 -- closure. Treat like updatable "LFThunk"...
284 -- Imported things which we do know something about use
285 -- one of the other LF constructors (eg LFReEntrant for
288 | LFLetNoEscape -- See LetNoEscape module for precise description of
291 PlainStgLiveVars-- list of variables live in the RHS of the let.
292 -- (ToDo: maybe not used)
294 | LFBlackHole -- Used for the closures allocated to hold the result
295 -- of a CAF. We want the target of the update frame to
296 -- be in the heap, so we make a black hole to hold it.
298 -- This last one is really only for completeness;
299 -- it isn't actually used for anything interesting
300 {- | LFIndirection -}
302 data StandardFormInfo -- Tells whether this thunk has one of a small number
305 = NonStandardThunk -- No, it isn't
309 DataCon -- Constructor
310 Int -- 0-origin offset of ak within the "goods" of constructor
311 -- (Recall that the a1,...,an may be laid out in the heap
312 -- in a non-obvious order.)
314 {- A SelectorThunk is of form
319 and the constructor is from a single-constr type.
320 If we can't convert the heap-offset of the selectee into an Int, e.g.,
321 it's "GEN_VHS+i", we just give up.
326 [PlainStgAtom] -- Args
327 Bool -- True <=> the function is not top-level, so
328 -- must be stored in the thunk too
330 {- A VapThunk is of form
334 where f is a known function, with arity n
335 So for this thunk we can use the label for f's heap-entry
336 info table (generated when f's defn was dealt with),
337 rather than generating a one-off info table and entry code
342 mkLFArgument = LFArgument
343 mkLFBlackHole = LFBlackHole
344 mkLFLetNoEscape = LFLetNoEscape
346 mkLFImported :: Id -> LambdaFormInfo
348 = case arityMaybe (getIdArity id) of
349 Nothing -> LFImported
350 Just 0 -> LFThunk True{-top-lev-} True{-no fvs-}
351 True{-updatable-} NonStandardThunk
352 Just n -> LFReEntrant True n True -- n > 0
355 %************************************************************************
357 \subsection[ClosureInfo-construction]{Functions which build LFInfos}
359 %************************************************************************
361 @mkClosureLFInfo@ figures out the appropriate LFInfo for the closure.
364 mkClosureLFInfo :: Bool -- True of top level
366 -> UpdateFlag -- Update flag
368 -> PlainStgExpr -- Body of closure: passed so we
369 -- can look for selector thunks!
372 mkClosureLFInfo top fvs upd_flag args@(_:_) body -- Non-empty args
373 = LFReEntrant top (length args) (null fvs)
375 mkClosureLFInfo top fvs ReEntrant [] body
376 = LFReEntrant top 0 (null fvs)
379 OK, this is where we look at the body of the closure to see if it's a
380 selector---turgid, but nothing deep. We are looking for a closure of
381 {\em exactly} the form:
383 ... = [the_fv] \ u [] ->
385 con a_1 ... a_n -> a_i
389 mkClosureLFInfo False -- don't bother if at top-level
390 [the_fv] -- just one...
392 [] -- no args (a thunk)
393 (StgCase (StgApp (StgVarAtom scrutinee) [{-no args-}] _)
394 _ _ _ -- ignore live vars and uniq...
396 [(con, params, use_mask,
397 (StgApp (StgVarAtom selectee) [{-no args-}] _))]
399 | the_fv == scrutinee -- Scrutinee is the only free variable
400 && maybeToBool maybe_offset -- Selectee is a component of the tuple
401 && maybeToBool offset_into_int_maybe
402 && offset_into_int <= mAX_SPEC_SELECTEE_SIZE -- Offset is small enough
404 ASSERT(is_single_constructor) -- This should be true anyway
405 LFThunk False False True (SelectorThunk scrutinee con offset_into_int)
407 (_, params_w_offsets) = layOutDynCon con getIdKind params
408 maybe_offset = assocMaybe params_w_offsets selectee
409 Just the_offset = maybe_offset
410 offset_into_int_maybe = intOffsetIntoGoods the_offset
411 Just offset_into_int = offset_into_int_maybe
412 is_single_constructor = maybeToBool (maybeSingleConstructorTyCon tycon)
413 (_,_,_, tycon) = getDataConSig con
416 Same kind of thing, looking for vector-apply thunks, of the form:
418 x = [...] \ .. [] -> f a1 .. an
420 where f has arity n. We rely on the arity info inside the Id being correct.
423 mkClosureLFInfo top_level
426 [] -- No args; a thunk
427 (StgApp (StgVarAtom fun_id) args _)
428 | not top_level -- A top-level thunk would require a static
429 -- vap_info table, which we don't generate just
430 -- now; so top-level thunks are never standard
432 && isLocallyDefined fun_id -- Must be defined in this module
433 && maybeToBool arity_maybe -- A known function with known arity
434 && fun_arity > 0 -- It'd better be a function!
435 && fun_arity == length args -- Saturated application
436 = LFThunk top_level (null fvs) (isUpdatable upd_flag) (VapThunk fun_id args store_fun_in_vap)
438 arity_maybe = arityMaybe (getIdArity fun_id)
439 Just fun_arity = arity_maybe
441 -- If the function is a free variable then it must be stored
442 -- in the thunk too; if it isn't a free variable it must be
443 -- because it's constant, so it doesn't need to be stored in the thunk
444 store_fun_in_vap = fun_id `is_elem` fvs
446 is_elem = isIn "mkClosureLFInfo"
449 Finally, the general updatable-thing case:
451 mkClosureLFInfo top fvs upd_flag [] body
452 = LFThunk top (null fvs) (isUpdatable upd_flag) NonStandardThunk
454 isUpdatable ReEntrant = False
455 isUpdatable SingleEntry = False
456 isUpdatable Updatable = True
459 @mkConLFInfo@ is similar, for constructors.
462 mkConLFInfo :: DataCon -> LambdaFormInfo
465 = ASSERT(isDataCon con)
467 arity = getDataConArity con
469 if isTupleCon con then
470 LFTuple con (arity == 0)
472 LFCon con (arity == 0)
476 %************************************************************************
478 \subsection[ClosureInfo-sizes]{Functions about closure {\em sizes}}
480 %************************************************************************
483 closureSize :: ClosureInfo -> HeapOffset
484 closureSize cl_info@(MkClosureInfo _ _ sm_rep)
485 = totHdrSize sm_rep `addOff` (intOff (closureNonHdrSize cl_info))
487 closureSizeWithoutFixedHdr :: ClosureInfo -> HeapOffset
488 closureSizeWithoutFixedHdr cl_info@(MkClosureInfo _ _ sm_rep)
489 = varHdrSize sm_rep `addOff` (intOff (closureNonHdrSize cl_info))
491 closureHdrSize :: ClosureInfo -> HeapOffset
492 closureHdrSize (MkClosureInfo _ _ sm_rep)
495 closureNonHdrSize :: ClosureInfo -> Int
496 closureNonHdrSize cl_info@(MkClosureInfo _ lf_info sm_rep)
497 = tot_wds + computeSlopSize tot_wds sm_rep (closureUpdReqd cl_info) --ToDo: pass lf_info?
499 tot_wds = closureGoodStuffSize cl_info
501 closureGoodStuffSize :: ClosureInfo -> Int
502 closureGoodStuffSize (MkClosureInfo _ _ sm_rep)
503 = let (ptrs, nonptrs) = sizes_from_SMRep sm_rep
506 closurePtrsSize :: ClosureInfo -> Int
507 closurePtrsSize (MkClosureInfo _ _ sm_rep)
508 = let (ptrs, _) = sizes_from_SMRep sm_rep
512 sizes_from_SMRep (SpecialisedRep k ptrs nonptrs _) = (ptrs, nonptrs)
513 sizes_from_SMRep (GenericRep ptrs nonptrs _) = (ptrs, nonptrs)
514 sizes_from_SMRep (BigTupleRep ptrs) = (ptrs, 0)
515 sizes_from_SMRep (MuTupleRep ptrs) = (ptrs, 0)
516 sizes_from_SMRep (DataRep nonptrs) = (0, nonptrs)
517 sizes_from_SMRep BlackHoleRep = (0, 0)
518 sizes_from_SMRep (StaticRep ptrs nonptrs) = (ptrs, nonptrs)
520 sizes_from_SMRep PhantomRep = panic "sizes_from_SMRep: PhantomRep"
521 sizes_from_SMRep DynamicRep = panic "sizes_from_SMRep: DynamicRep"
526 fitsMinUpdSize :: ClosureInfo -> Bool
527 fitsMinUpdSize (MkClosureInfo _ _ BlackHoleRep) = True
528 fitsMinUpdSize cl_info = isSpecRep (closureSMRep cl_info) && closureNonHdrSize cl_info <= mIN_UPD_SIZE
531 Computing slop size. WARNING: this looks dodgy --- it has deep
532 knowledge of what the storage manager does with the various
538 Updateable closures must be @mIN_UPD_SIZE@.
541 Cons cell requires 2 words
543 Indirections require 1 word
545 Appels collector indirections 2 words
547 THEREFORE: @mIN_UPD_SIZE = 2@.
550 Collectable closures which are allocated in the heap
551 must be @mIN_SIZE_NonUpdHeapObject@.
553 Copying collector forward pointer requires 1 word
555 THEREFORE: @mIN_SIZE_NonUpdHeapObject = 1@
558 @SpecialisedRep@ closures closures may require slop:
561 @ConstantRep@ and @CharLikeRep@ closures always use the address of
562 a static closure. They are never allocated or
563 collected (eg hold forwarding pointer) hence never any slop.
566 @IntLikeRep@ are never updatable.
567 May need slop to be collected (as they will be size 1 or more
568 this probably has no affect)
571 @SpecRep@ may be updateable and will be collectable
574 @StaticRep@ may require slop if updatable. Non-updatable ones are OK.
577 @GenericRep@ closures will always be larger so never require slop.
580 ***** ToDo: keep an eye on this!
584 slopSize cl_info@(MkClosureInfo _ lf_info sm_rep)
585 = computeSlopSize (closureGoodStuffSize cl_info) sm_rep (closureUpdReqd cl_info)
587 computeSlopSize :: Int -> SMRep -> Bool -> Int
589 computeSlopSize tot_wds (SpecialisedRep ConstantRep _ _ _) _
591 computeSlopSize tot_wds (SpecialisedRep CharLikeRep _ _ _) _
594 computeSlopSize tot_wds (SpecialisedRep _ _ _ _) True -- Updatable
595 = max 0 (mIN_UPD_SIZE - tot_wds)
596 computeSlopSize tot_wds (StaticRep _ _) True -- Updatable
597 = max 0 (mIN_UPD_SIZE - tot_wds)
598 computeSlopSize tot_wds BlackHoleRep _ -- Updatable
599 = max 0 (mIN_UPD_SIZE - tot_wds)
601 computeSlopSize tot_wds (SpecialisedRep _ _ _ _) False -- Not updatable
602 = max 0 (mIN_SIZE_NonUpdHeapObject - tot_wds)
604 computeSlopSize tot_wds other_rep _ -- Any other rep
608 %************************************************************************
610 \subsection[layOutDynClosure]{Lay out a dynamic closure}
612 %************************************************************************
615 layOutDynClosure, layOutStaticClosure
616 :: Id -- STG identifier w/ which this closure assoc'd
617 -> (a -> PrimKind) -- function w/ which to be able to get a PrimKind
618 -> [a] -- the "things" being layed out
619 -> LambdaFormInfo -- what sort of closure it is
620 -> (ClosureInfo, -- info about the closure
621 [(a, VirtualHeapOffset)]) -- things w/ offsets pinned on them
623 layOutDynClosure name kind_fn things lf_info
624 = (MkClosureInfo name lf_info sm_rep,
627 (tot_wds, -- #ptr_wds + #nonptr_wds
629 things_w_offsets) = mkVirtHeapOffsets sm_rep kind_fn things
630 sm_rep = chooseDynSMRep lf_info tot_wds ptr_wds
632 layOutStaticClosure name kind_fn things lf_info
633 = (MkClosureInfo name lf_info (StaticRep ptr_wds (tot_wds - ptr_wds)),
636 (tot_wds, -- #ptr_wds + #nonptr_wds
638 things_w_offsets) = mkVirtHeapOffsets (StaticRep bot bot) kind_fn things
639 bot = panic "layoutStaticClosure"
641 layOutStaticNoFVClosure :: Id -> LambdaFormInfo -> ClosureInfo
642 layOutStaticNoFVClosure name lf_info
643 = MkClosureInfo name lf_info (StaticRep ptr_wds nonptr_wds)
645 -- I am very uncertain that this is right - it will show up when testing
646 -- my dynamic loading code. ADR
647 -- (If it's not right, we'll have to grab the kinds of the arguments from
652 layOutPhantomClosure :: Id -> LambdaFormInfo -> ClosureInfo
653 layOutPhantomClosure name lf_info = MkClosureInfo name lf_info PhantomRep
656 A wrapper for when used with data constructors:
658 layOutDynCon :: DataCon
661 -> (ClosureInfo, [(a,VirtualHeapOffset)])
663 layOutDynCon con kind_fn args
664 = ASSERT(isDataCon con)
665 layOutDynClosure con kind_fn args (mkConLFInfo con)
669 %************************************************************************
671 \subsection[SMreps]{Choosing SM reps}
673 %************************************************************************
678 -> Int -> Int -- Tot wds, ptr wds
681 chooseDynSMRep lf_info tot_wds ptr_wds
683 nonptr_wds = tot_wds - ptr_wds
685 updatekind = case lf_info of
686 LFThunk _ _ upd _ -> if upd then SMUpdatable else SMSingleEntry
687 LFBlackHole -> SMUpdatable
690 if (nonptr_wds == 0 && ptr_wds <= mAX_SPEC_ALL_PTRS)
691 || (tot_wds <= mAX_SPEC_MIXED_FIELDS)
692 || (ptr_wds == 0 && nonptr_wds <= mAX_SPEC_ALL_NONPTRS) then
694 spec_kind = case lf_info of
696 (LFTuple _ True) -> ConstantRep
698 (LFTuple _ _) -> SpecRep
700 (LFCon _ True) -> ConstantRep
702 (LFCon con _ ) -> if maybeToBool (maybeCharLikeTyCon tycon) then CharLikeRep
703 else if maybeToBool (maybeIntLikeTyCon tycon) then IntLikeRep
706 tycon = getDataConTyCon con
710 SpecialisedRep spec_kind ptr_wds nonptr_wds updatekind
712 GenericRep ptr_wds nonptr_wds updatekind
716 %************************************************************************
718 \subsection[mkVirtHeapOffsets]{Assigning heap offsets in a closure}
720 %************************************************************************
722 @mkVirtHeapOffsets@ (the heap version) always returns boxed things with
723 smaller offsets than the unboxed things, and furthermore, the offsets in
727 mkVirtHeapOffsets :: SMRep -- Representation to be used by storage manager
728 -> (a -> PrimKind) -- To be able to grab kinds;
729 -- w/ a kind, we can find boxedness
730 -> [a] -- Things to make offsets for
731 -> (Int, -- *Total* number of words allocated
732 Int, -- Number of words allocated for *pointers*
733 [(a, VirtualHeapOffset)]) -- Things with their offsets from start of object
734 -- in order of increasing offset
736 -- First in list gets lowest offset, which is initial offset + 1.
738 mkVirtHeapOffsets sm_rep kind_fun things
739 = let (ptrs, non_ptrs) = separateByPtrFollowness kind_fun things
740 (wds_of_ptrs, ptrs_w_offsets) = mapAccumL computeOffset 0 ptrs
741 (tot_wds, non_ptrs_w_offsets) = mapAccumL computeOffset wds_of_ptrs non_ptrs
743 (tot_wds, wds_of_ptrs, ptrs_w_offsets ++ non_ptrs_w_offsets)
745 offset_of_first_word = totHdrSize sm_rep
746 computeOffset wds_so_far thing
747 = (wds_so_far + (getKindSize . kind_fun) thing,
748 (thing, (offset_of_first_word `addOff` (intOff wds_so_far)))
752 %************************************************************************
754 \subsection[ClosureInfo-4-questions]{Four major questions about @ClosureInfo@}
756 %************************************************************************
758 Be sure to see the stg-details notes about these...
761 nodeMustPointToIt :: LambdaFormInfo -> FCode Bool
762 nodeMustPointToIt lf_info
763 = isSwitchSetC SccProfilingOn `thenFC` \ do_profiling ->
766 LFReEntrant top arity no_fvs -> returnFC (
767 not no_fvs || -- Certainly if it has fvs we need to point to it
769 not top -- If it is not top level we will point to it
770 -- We can have a \r closure with no_fvs which
771 -- is not top level as special case cgRhsClosure
772 -- has been dissabled in favour of let floating
774 --OLD: || (arity == 0 && do_profiling)
775 -- -- Access to cost centre required for 0 arity if profiling
776 -- -- Simon: WHY? (94/12)
778 -- For lex_profiling we also access the cost centre for a
779 -- non-inherited function i.e. not top level
780 -- the not top case above ensures this is ok.
783 LFCon _ zero_arity -> returnFC True
784 LFTuple _ zero_arity -> returnFC True
786 -- Strictly speaking, the above two don't need Node to point
787 -- to it if the arity = 0. But this is a *really* unlikely
788 -- situation. If we know it's nil (say) and we are entering
789 -- it. Eg: let x = [] in x then we will certainly have inlined
790 -- x, since nil is a simple atom. So we gain little by not
791 -- having Node point to known zero-arity things. On the other
792 -- hand, we do lose something; Patrick's code for figuring out
793 -- when something has been updated but not entered relies on
794 -- having Node point to the result of an update. SLPJ
797 LFThunk _ no_fvs updatable _
798 -> returnFC (updatable || not no_fvs || do_profiling)
800 -- For the non-updatable (single-entry case):
802 -- True if has fvs (in which case we need access to them, and we
803 -- should black-hole it)
804 -- or profiling (in which case we need to recover the cost centre
807 LFArgument -> returnFC True
808 LFImported -> returnFC True
809 LFBlackHole -> returnFC True
810 -- BH entry may require Node to point
812 LFLetNoEscape _ _ -> returnFC False
815 The entry conventions depend on the type of closure being entered,
816 whether or not it has free variables, and whether we're running
817 sequentially or in parallel.
819 \begin{tabular}{lllll}
820 Closure Characteristics & Parallel & Node Req'd & Argument Passing & Enter Via \\
821 Unknown & no & yes & stack & node \\
822 Known fun ($\ge$ 1 arg), no fvs & no & no & registers & fast entry (enough args) \\
823 \ & \ & \ & \ & slow entry (otherwise) \\
824 Known fun ($\ge$ 1 arg), fvs & no & yes & registers & fast entry (enough args) \\
825 0 arg, no fvs @\r,\s@ & no & no & n/a & direct entry \\
826 0 arg, no fvs @\u@ & no & yes & n/a & node \\
827 0 arg, fvs @\r,\s@ & no & yes & n/a & direct entry \\
828 0 arg, fvs @\u@ & no & yes & n/a & node \\
830 Unknown & yes & yes & stack & node \\
831 Known fun ($\ge$ 1 arg), no fvs & yes & no & registers & fast entry (enough args) \\
832 \ & \ & \ & \ & slow entry (otherwise) \\
833 Known fun ($\ge$ 1 arg), fvs & yes & yes & registers & node \\
834 0 arg, no fvs @\r,\s@ & yes & no & n/a & direct entry \\
835 0 arg, no fvs @\u@ & yes & yes & n/a & node \\
836 0 arg, fvs @\r,\s@ & yes & yes & n/a & node \\
837 0 arg, fvs @\u@ & yes & yes & n/a & node\\
840 When black-holing, single-entry closures could also be entered via node
841 (rather than directly) to catch double-entry.
845 = ViaNode -- The "normal" convention
847 | StdEntry CLabel -- Jump to this code, with args on stack
848 (Maybe CLabel) -- possibly setting infoptr to this
850 | DirectEntry -- Jump directly to code, with args in regs
851 CLabel -- The code label
853 [MagicId] -- Its register assignments (possibly empty)
855 getEntryConvention :: Id -- Function being applied
856 -> LambdaFormInfo -- Its info
857 -> [PrimKind] -- Available arguments
858 -> FCode EntryConvention
860 getEntryConvention id lf_info arg_kinds
861 = nodeMustPointToIt lf_info `thenFC` \ node_points ->
862 isSwitchSetC ForConcurrent `thenFC` \ is_concurrent ->
863 getIntSwitchChkrC `thenFC` \ isw_chkr ->
866 if (node_points && is_concurrent) then ViaNode else
870 LFReEntrant _ arity _ ->
871 if arity == 0 || (length arg_kinds) < arity then
872 StdEntry (mkStdEntryLabel id) Nothing
874 DirectEntry (mkFastEntryLabel id arity) arity arg_regs
876 (arg_regs, _) = assignRegs isw_chkr live_regs (take arity arg_kinds)
877 live_regs = if node_points then [node] else []
880 -> let itbl = if zero_arity then
881 mkPhantomInfoTableLabel con
884 in StdEntry (mkStdEntryLabel con) (Just itbl)
885 -- Should have no args
886 LFTuple tup zero_arity
887 -> StdEntry (mkStdEntryLabel tup)
888 (Just (mkInfoTableLabel tup))
889 -- Should have no args
891 LFThunk _ _ updatable std_form_info
894 else StdEntry (thunkEntryLabel id std_form_info updatable) Nothing
896 LFArgument -> ViaNode
897 LFImported -> ViaNode
898 LFBlackHole -> ViaNode -- Presumably the black hole has by now
899 -- been updated, but we don't know with
900 -- what, so we enter via Node
902 LFLetNoEscape arity _
903 -> ASSERT(arity == length arg_kinds)
904 DirectEntry (mkStdEntryLabel id) arity arg_regs
906 (arg_regs, _) = assignRegs isw_chkr live_regs arg_kinds
907 live_regs = if node_points then [node] else []
910 blackHoleOnEntry :: Bool -- No-black-holing flag
914 -- Static closures are never themselves black-holed.
915 -- Updatable ones will be overwritten with a CAFList cell, which points to a black hole;
916 -- Single-entry ones have no fvs to plug, and we trust they don't form part of a loop.
918 blackHoleOnEntry no_black_holing (MkClosureInfo _ _ (StaticRep _ _)) = False
920 blackHoleOnEntry no_black_holing (MkClosureInfo _ lf_info _)
922 LFReEntrant _ _ _ -> False
923 LFThunk _ no_fvs updatable _
925 then not no_black_holing
927 other -> panic "blackHoleOnEntry" -- Should never happen
929 getStandardFormThunkInfo
931 -> Maybe [PlainStgAtom] -- Nothing => not a standard-form thunk
932 -- Just atoms => a standard-form thunk with payload atoms
934 getStandardFormThunkInfo (LFThunk _ _ _ (SelectorThunk scrutinee _ _))
935 = --trace "Selector thunk: missed opportunity to save info table + code"
937 -- Just [StgVarAtom scrutinee]
938 -- We can't save the info tbl + code until we have a way to generate
939 -- a fixed family thereof.
941 getStandardFormThunkInfo (LFThunk _ _ _ (VapThunk fun_id args fun_in_payload))
942 | fun_in_payload = Just (StgVarAtom fun_id : args)
943 | otherwise = Just args
945 getStandardFormThunkInfo other_lf_info = Nothing
947 maybeSelectorInfo (MkClosureInfo _ (LFThunk _ _ _ (SelectorThunk _ con offset)) _) = Just (con,offset)
948 maybeSelectorInfo _ = Nothing
951 Avoiding generating entries and info tables
952 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
953 At present, for every function we generate all of the following,
954 just in case. But they aren't always all needed, as noted below:
956 [NB1: all of this applies only to *functions*. Thunks always
957 have closure, info table, and entry code.]
959 [NB2: All are needed if the function is *exported*, just to play safe.]
962 * Fast-entry code ALWAYS NEEDED
965 Needed iff (a) we have any un-saturated calls to the function
966 OR (b) the function is passed as an arg
967 OR (c) we're in the parallel world and the function has free vars
968 [Reason: in parallel world, we always enter functions
969 with free vars via the closure.]
971 * The function closure
972 Needed iff (a) we have any un-saturated calls to the function
973 OR (b) the function is passed as an arg
974 OR (c) if the function has free vars (ie not top level)
976 Why case (a) here? Because if the arg-satis check fails,
977 UpdatePAP stuffs a pointer to the function closure in the PAP.
978 [Could be changed; UpdatePAP could stuff in a code ptr instead,
979 but doesn't seem worth it.]
981 [NB: these conditions imply that we might need the closure
982 without the slow-entry code. Here's how.
984 f x y = let g w = ...x..y..w...
988 Here we need a closure for g which contains x and y,
989 but since the calls are all saturated we just jump to the
990 fast entry point for g, with R1 pointing to the closure for g.]
993 * Standard info table
994 Needed iff (a) we have any un-saturated calls to the function
995 OR (b) the function is passed as an arg
996 OR (c) the function has free vars (ie not top level)
998 NB. In the sequential world, (c) is only required so that the function closure has
999 an info table to point to, to keep the storage manager happy.
1000 If (c) alone is true we could fake up an info table by choosing
1001 one of a standard family of info tables, whose entry code just
1004 [NB In the parallel world (c) is needed regardless because
1005 we enter functions with free vars via the closure.]
1007 If (c) is retained, then we'll sometimes generate an info table
1008 (for storage mgr purposes) without slow-entry code. Then we need
1009 to use an error label in the info table to substitute for the absent
1012 * Standard vap-entry code
1013 Standard vap-entry info table
1014 Needed iff we have any updatable thunks of the standard vap-entry shape.
1016 * Single-update vap-entry code
1017 Single-update vap-entry info table
1018 Needed iff we have any non-updatable thunks of the
1019 standard vap-entry shape.
1023 staticClosureRequired
1028 staticClosureRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1029 (LFReEntrant top_level _ _) -- It's a function
1030 = ASSERT( top_level ) -- Assumption: it's a top-level, no-free-var binding
1031 arg_occ -- There's an argument occurrence
1032 || unsat_occ -- There's an unsaturated call
1033 || externallyVisibleId binder
1035 staticClosureRequired binder other_binder_info other_lf_info = True
1037 slowFunEntryCodeRequired -- Assumption: it's a function, not a thunk.
1041 slowFunEntryCodeRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1042 = arg_occ -- There's an argument occurrence
1043 || unsat_occ -- There's an unsaturated call
1044 || externallyVisibleId binder
1045 {- HAS FREE VARS AND IS PARALLEL WORLD -}
1047 slowFunEntryCodeRequired binder NoStgBinderInfo = True
1049 funInfoTableRequired
1054 funInfoTableRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1055 (LFReEntrant top_level _ _)
1057 || arg_occ -- There's an argument occurrence
1058 || unsat_occ -- There's an unsaturated call
1059 || externallyVisibleId binder
1061 funInfoTableRequired other_binder_info binder other_lf_info = True
1063 -- We need the vector-apply entry points for a function if
1064 -- there's a vector-apply occurrence in this module
1066 stdVapRequired, noUpdVapRequired :: StgBinderInfo -> Bool
1068 stdVapRequired binder_info
1069 = case binder_info of
1070 StgBinderInfo _ _ std_vap_occ _ _ -> std_vap_occ
1073 noUpdVapRequired binder_info
1074 = case binder_info of
1075 StgBinderInfo _ _ _ no_upd_vap_occ _ -> no_upd_vap_occ
1079 %************************************************************************
1081 \subsection[ClosureInfo-misc-funs]{Misc functions about @ClosureInfo@, etc.}
1083 %************************************************************************
1086 isConstantRep, isSpecRep, isStaticRep, isPhantomRep, isIntLikeRep :: SMRep -> Bool
1087 isConstantRep (SpecialisedRep ConstantRep _ _ _) = True
1088 isConstantRep other = False
1090 isSpecRep (SpecialisedRep kind _ _ _) = True -- All the kinds of Spec closures
1091 isSpecRep other = False -- True indicates that the _VHS is 0 !
1093 isStaticRep (StaticRep _ _) = True
1094 isStaticRep _ = False
1096 isPhantomRep PhantomRep = True
1097 isPhantomRep _ = False
1099 isIntLikeRep (SpecialisedRep IntLikeRep _ _ _) = True
1100 isIntLikeRep other = False
1102 isStaticClosure :: ClosureInfo -> Bool
1103 isStaticClosure (MkClosureInfo _ _ rep) = isStaticRep rep
1105 closureId :: ClosureInfo -> Id
1106 closureId (MkClosureInfo id _ _) = id
1108 closureSMRep :: ClosureInfo -> SMRep
1109 closureSMRep (MkClosureInfo _ _ sm_rep) = sm_rep
1111 closureLFInfo :: ClosureInfo -> LambdaFormInfo
1112 closureLFInfo (MkClosureInfo _ lf_info _) = lf_info
1114 closureUpdReqd :: ClosureInfo -> Bool
1116 closureUpdReqd (MkClosureInfo _ (LFThunk _ _ upd _) _) = upd
1117 closureUpdReqd (MkClosureInfo _ LFBlackHole _) = True
1118 -- Black-hole closures are allocated to receive the results of an
1119 -- alg case with a named default... so they need to be updated.
1120 closureUpdReqd other_closure = False
1122 closureSingleEntry :: ClosureInfo -> Bool
1124 closureSingleEntry (MkClosureInfo _ (LFThunk _ _ upd _) _) = not upd
1125 closureSingleEntry other_closure = False
1128 Note: @closureType@ returns appropriately specialised tycon and
1131 closureType :: ClosureInfo -> Maybe (TyCon, [UniType], [Id])
1133 -- First, a turgid special case. When we are generating the
1134 -- standard code and info-table for Vaps (which is done when the function
1135 -- defn is encountered), we don't have a convenient Id to hand whose
1136 -- type is that of (f x y z). So we need to figure out the type
1137 -- rather than take it from the Id. The Id is probably just "f"!
1139 closureType (MkClosureInfo id (LFThunk _ _ _ (VapThunk fun_id args _)) _)
1140 = getUniDataSpecTyCon_maybe (funResultTy de_foralld_ty (length args))
1142 (_, de_foralld_ty) = splitForalls (getIdUniType fun_id)
1144 closureType (MkClosureInfo id lf _) = getUniDataSpecTyCon_maybe (getIdUniType id)
1147 @closureReturnsUnboxedType@ is used to check whether a closure, {\em
1148 once it has eaten its arguments}, returns an unboxed type. For
1149 example, the closure for a function:
1153 returns an unboxed type. This is important when dealing with stack
1156 closureReturnsUnboxedType :: ClosureInfo -> Bool
1158 closureReturnsUnboxedType (MkClosureInfo fun_id (LFReEntrant _ arity _) _)
1159 = isPrimType (funResultTy de_foralld_ty arity)
1161 (_, de_foralld_ty) = splitForalls (getIdUniType fun_id)
1163 closureReturnsUnboxedType other_closure = False
1164 -- All non-function closures aren't functions,
1165 -- and hence are boxed, since they are heap alloc'd
1169 closureSemiTag :: ClosureInfo -> Int
1171 closureSemiTag (MkClosureInfo _ lf_info _)
1173 LFCon data_con _ -> getDataConTag data_con - fIRST_TAG
1175 --UNUSED: LFIndirection -> fromInteger iND_TAG
1176 _ -> fromInteger oTHER_TAG
1182 infoTableLabelFromCI :: ClosureInfo -> CLabel
1184 infoTableLabelFromCI (MkClosureInfo id lf_info rep)
1186 LFCon con _ -> mkConInfoPtr con rep
1187 LFTuple tup _ -> mkConInfoPtr tup rep
1189 LFBlackHole -> mkBlackHoleInfoTableLabel
1191 LFThunk _ _ upd_flag (VapThunk fun_id args _) -> mkVapInfoTableLabel fun_id upd_flag
1192 -- Use the standard vap info table
1193 -- for the function, rather than a one-off one
1194 -- for this particular closure
1196 {- For now, we generate individual info table and entry code for selector thunks,
1197 so their info table should be labelled in the standard way.
1198 The only special thing about them is that the info table has a field which
1199 tells the GC that it really is a selector.
1201 Later, perhaps, we'll have some standard RTS code for selector-thunk info tables,
1202 in which case this line will spring back to life.
1204 LFThunk _ _ upd_flag (SelectorThunk _ _ offset) -> mkSelectorInfoTableLabel upd_flag offset
1205 -- Ditto for selectors
1208 other -> {-NO: if isStaticRep rep
1209 then mkStaticInfoTableLabel id
1210 else -} mkInfoTableLabel id
1212 mkConInfoPtr :: Id -> SMRep -> CLabel
1213 mkConInfoPtr id rep =
1215 PhantomRep -> mkPhantomInfoTableLabel id
1216 StaticRep _ _ -> mkStaticInfoTableLabel id
1217 _ -> mkInfoTableLabel id
1219 mkConEntryPtr :: Id -> SMRep -> CLabel
1220 mkConEntryPtr id rep =
1222 StaticRep _ _ -> mkStaticConEntryLabel id
1223 _ -> mkConEntryLabel id
1226 closureLabelFromCI (MkClosureInfo id _ _) = mkClosureLabel id
1228 entryLabelFromCI :: ClosureInfo -> CLabel
1229 entryLabelFromCI (MkClosureInfo id lf_info rep)
1231 LFThunk _ _ upd_flag std_form_info -> thunkEntryLabel id std_form_info upd_flag
1232 LFCon con _ -> mkConEntryPtr con rep
1233 LFTuple tup _ -> mkConEntryPtr tup rep
1234 other -> mkStdEntryLabel id
1236 -- thunkEntryLabel is a local help function, not exported. It's used from both
1237 -- entryLabelFromCI and getEntryConvention.
1238 -- I don't think it needs to deal with the SelectorThunk case
1239 -- Well, it's falling over now, so I've made it deal with it. (JSM)
1241 thunkEntryLabel thunk_id (VapThunk fun_id args _) is_updatable
1242 = mkVapEntryLabel fun_id is_updatable
1243 thunkEntryLabel thunk_id _ is_updatable
1244 = mkStdEntryLabel thunk_id
1246 fastLabelFromCI :: ClosureInfo -> CLabel
1247 fastLabelFromCI (MkClosureInfo id _ _) = mkFastEntryLabel id fun_arity
1249 arity_maybe = arityMaybe (getIdArity id)
1250 fun_arity = case arity_maybe of
1252 _ -> pprPanic "fastLabelFromCI:no arity:" (ppr PprShowAll id)
1256 allocProfilingMsg :: ClosureInfo -> FAST_STRING
1258 allocProfilingMsg (MkClosureInfo _ lf_info _)
1260 LFReEntrant _ _ _ -> SLIT("ALLOC_FUN")
1261 LFCon _ _ -> SLIT("ALLOC_CON")
1262 LFTuple _ _ -> SLIT("ALLOC_CON")
1263 LFThunk _ _ _ _ -> SLIT("ALLOC_THK")
1264 LFBlackHole -> SLIT("ALLOC_BH")
1265 --UNUSED: LFIndirection -> panic "ALLOC_IND"
1266 LFImported -> panic "ALLOC_IMP"
1269 We need a black-hole closure info to pass to @allocDynClosure@
1270 when we want to allocate the black hole on entry to a CAF.
1273 blackHoleClosureInfo (MkClosureInfo id _ _) = MkClosureInfo id LFBlackHole BlackHoleRep
1276 The register liveness when returning from a constructor. For simplicity,
1277 we claim just [node] is live for all but PhantomRep's. In truth, this means
1278 that non-constructor info tables also claim node, but since their liveness
1279 information is never used, we don't care.
1283 dataConLiveness isw_chkr (MkClosureInfo con _ PhantomRep)
1284 = case (dataReturnConvAlg isw_chkr con) of
1285 ReturnInRegs regs -> mkLiveRegsBitMask regs
1286 ReturnInHeap -> panic "dataConLiveness:PhantomRep in heap???"
1288 dataConLiveness _ _ = mkLiveRegsBitMask [node]
1291 %************************************************************************
1293 \subsection[ClosureInfo-Profiling-funs]{Misc functions about for profiling info.}
1295 %************************************************************************
1297 Profiling requires three pices of information to be determined for
1298 each closure's info table --- kind, description and type.
1300 The description is stored directly in the @CClosureInfoTable@ when the
1301 info table is built.
1303 The kind is determined from the @LambdaForm@ stored in the closure
1304 info using @closureKind@.
1306 The type is determined from the type information stored with the @Id@
1307 in the closure info using @closureTypeDescr@.
1310 closureKind :: ClosureInfo -> String
1312 closureKind (MkClosureInfo _ lf _)
1314 LFReEntrant _ n _ -> if n > 0 then "FN_K" else "THK_K"
1315 LFCon _ _ -> "CON_K"
1316 LFTuple _ _ -> "CON_K"
1317 LFThunk _ _ _ _ -> "THK_K"
1318 LFBlackHole -> "THK_K" -- consider BHs as thunks for the moment... (ToDo?)
1319 --UNUSED: LFIndirection -> panic "IND_KIND"
1320 LFImported -> panic "IMP_KIND"
1322 closureTypeDescr :: ClosureInfo -> String
1323 closureTypeDescr (MkClosureInfo id lf _)
1324 = if (isDataCon id) then -- DataCon has function types
1325 _UNPK_ (getOccurrenceName (getDataConTyCon id)) -- We want the TyCon not the ->
1327 getUniTyDescription (getIdUniType id)