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,
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 isStaticClosure, allocProfilingMsg,
50 dataConLiveness -- concurrency
54 import AbsCLoop -- here for paranoia-checking
60 import CgCompInfo ( mAX_SPEC_SELECTEE_SIZE,
61 mIN_UPD_SIZE, mIN_SIZE_NonUpdHeapObject,
62 mAX_SPEC_ALL_PTRS, mAX_SPEC_MIXED_FIELDS,
66 import CgRetConv ( assignRegs, dataReturnConvAlg,
67 DataReturnConvention(..)
69 import CLabel ( mkStdEntryLabel, mkFastEntryLabel,
70 mkPhantomInfoTableLabel, mkInfoTableLabel,
71 mkBlackHoleInfoTableLabel, mkVapInfoTableLabel,
72 mkStaticInfoTableLabel, mkStaticConEntryLabel,
73 mkConEntryLabel, mkClosureLabel, mkVapEntryLabel
75 import CmdLineOpts ( opt_SccProfilingOn, opt_ForConcurrent )
76 import HeapOffs ( intOff, addOff, totHdrSize, varHdrSize,
80 import Id ( idType, idPrimRep, getIdArity,
81 externallyVisibleId, dataConSig,
82 dataConTag, fIRST_TAG,
83 isDataCon, dataConArity, dataConTyCon,
84 isTupleCon, DataCon(..),
87 import IdInfo ( arityMaybe )
88 import Maybes ( assocMaybe, maybeToBool )
89 import PprStyle ( PprStyle(..) )
90 import PprType ( GenType{-instance Outputable-} )
91 import PrimRep ( getPrimRepSize, separateByPtrFollowness )
92 import SMRep -- all of it
93 import TyCon ( maybeTyConSingleCon, TyCon{-instance NamedThing-} )
94 import Type ( isPrimType, splitForAllTy, splitFunTy, mkFunTys )
95 import Util ( isIn, mapAccumL, panic, pprPanic, assertPanic )
97 maybeCharLikeTyCon = panic "ClosureInfo.maybeCharLikeTyCon (ToDo)"
98 maybeIntLikeTyCon = panic "ClosureInfo.maybeIntLikeTyCon (ToDo)"
99 getDataSpecTyCon_maybe = panic "ClosureInfo.getDataSpecTyCon_maybe (ToDo)"
100 getTyDescription = panic "ClosureInfo.getTyDescription (ToDo)"
103 The ``wrapper'' data type for closure information:
108 Id -- The thing bound to this closure
109 LambdaFormInfo -- info derivable from the *source*
110 SMRep -- representation used by storage manager
113 %************************************************************************
115 \subsection[ClosureInfo-OLD-DOC]{OLD DOCUMENTATION PROBABLY SUPERCEDED BY stg-details}
117 %************************************************************************
119 We can optimise the function-entry code as follows.
122 \item If the ``function'' is not updatable, we can jump directly to its
123 entry code, rather than indirecting via the info pointer in the
124 closure. (For updatable thunks we must go via the closure, in
125 case it has been updated.)
127 \item If the former bullet applies, and the application we are
128 compiling gives the function as many arguments as it needs, we
129 can jump to its fast-entry code. (This only applies if the
130 function has one or more args, because zero-arg closures have
133 \item If the function is a top-level non-constructor or imported, there
134 is no need to make Node point to its closure. In order for
135 this to be right, we need to ensure that:
137 \item If such closures are updatable then they push their
138 static address in the update frame, not Node. Actually
139 we create a black hole and push its address.
141 \item The arg satisfaction check should load Node before jumping to
144 \item Top-level constructor closures need careful handling. If we are to
145 jump direct to the constructor code, we must load Node first, even
146 though they are top-level. But if we go to their ``own''
147 standard-entry code (which loads Node and then jumps to the
148 constructor code) we don't need to load Node.
153 {\em Top level constructors (@mkStaticConEntryInfo@)}
156 x = {y,ys} \ {} Cons {y,ys} -- Std form constructor
159 x-closure: Cons-info-table, y-closure, ys-closure
161 x-entry: Node = x-closure; jump( Cons-entry )
163 x's EntryInfo in its own module:
165 Base-label = Cons -- Not x!!
167 ClosureClass = Constructor
170 So if x is entered, Node will be set up and
171 we'll jump direct to the Cons code.
173 x's EntryInfo in another module: (which may not know that x is a constructor)
175 Base-label = x -- Is x!!
176 NodeMustPoint = False -- All imported things have False
177 ClosureClass = non-committal
180 If x is entered, we'll jump to x-entry, which will set up Node
181 before jumping to the standard Cons code
183 {\em Top level non-constructors (@mkStaticEntryInfo@)}
188 For updatable thunks, x-entry must push an allocated BH in update frame, not Node.
190 For non-zero arity, arg satis check must load Node before jumping to
193 x's EntryInfo in its own module:
196 NodeMustPoint = False
197 ClosureClass = whatever
200 {\em Inner constructors (@mkConEntryInfo@)}
203 Base-label = Cons -- Not x!!
204 NodeMustPoint = True -- If its arity were zero, it would
205 -- have been lifted to top level
206 ClosureClass = Constructor
209 {\em Inner non-constructors (@mkEntryInfo@)}
213 NodeMustPoint = True -- If no free vars, would have been
214 -- lifted to top level
215 ClosureClass = whatever
224 NodeMustPoint = False
225 ClosureClass = whatever
229 THINK: we could omit making Node point to top-level constructors
230 of arity zero; but that might interact nastily with updates.
235 The info we need to import for imported things is:
238 data ImportInfo = UnknownImportInfo
239 | HnfImport Int -- Not updatable, arity given
240 -- Arity can be zero, for (eg) constrs
241 | UpdatableImport -- Must enter via the closure
244 ToDo: move this stuff???
247 mkStaticEntryInfo lbl cl_class
248 = MkEntryInfo lbl False cl_class
250 mkStaticConEntryInfo lbl
251 = MkEntryInfo lbl True ConstructorClosure
253 mkEntryInfo lbl cl_class
254 = MkEntryInfo lbl True cl_class
257 = MkEntryInfo lbl True ConstructorClosure
260 %************************************************************************
262 \subsection[ClosureInfo-datatypes]{Data types for closure information}
264 %************************************************************************
266 %************************************************************************
268 \subsubsection[LambdaFormInfo-datatype]{@LambdaFormInfo@: source-derivable info}
270 %************************************************************************
274 = LFReEntrant -- Reentrant closure; used for PAPs too
275 Bool -- True if top level
277 Bool -- True <=> no fvs
279 | LFCon -- Constructor
280 DataCon -- The constructor (may be specialised)
281 Bool -- True <=> zero arity
284 DataCon -- The tuple constructor (may be specialised)
285 Bool -- True <=> zero arity
287 | LFThunk -- Thunk (zero arity)
288 Bool -- True <=> top level
289 Bool -- True <=> no free vars
290 Bool -- True <=> updatable (i.e., *not* single-entry)
293 | LFArgument -- Used for function arguments. We know nothing about
294 -- this closure. Treat like updatable "LFThunk"...
296 | LFImported -- Used for imported things. We know nothing about this
297 -- closure. Treat like updatable "LFThunk"...
298 -- Imported things which we do know something about use
299 -- one of the other LF constructors (eg LFReEntrant for
302 | LFLetNoEscape -- See LetNoEscape module for precise description of
305 StgLiveVars-- list of variables live in the RHS of the let.
306 -- (ToDo: maybe not used)
308 | LFBlackHole -- Used for the closures allocated to hold the result
309 -- of a CAF. We want the target of the update frame to
310 -- be in the heap, so we make a black hole to hold it.
312 -- This last one is really only for completeness;
313 -- it isn't actually used for anything interesting
314 {- | LFIndirection -}
316 data StandardFormInfo -- Tells whether this thunk has one of a small number
319 = NonStandardThunk -- No, it isn't
323 DataCon -- Constructor
324 Int -- 0-origin offset of ak within the "goods" of constructor
325 -- (Recall that the a1,...,an may be laid out in the heap
326 -- in a non-obvious order.)
328 {- A SelectorThunk is of form
333 and the constructor is from a single-constr type.
334 If we can't convert the heap-offset of the selectee into an Int, e.g.,
335 it's "GEN_VHS+i", we just give up.
341 Bool -- True <=> the function is not top-level, so
342 -- must be stored in the thunk too
344 {- A VapThunk is of form
348 where f is a known function, with arity n
349 So for this thunk we can use the label for f's heap-entry
350 info table (generated when f's defn was dealt with),
351 rather than generating a one-off info table and entry code
356 mkLFArgument = LFArgument
357 mkLFBlackHole = LFBlackHole
358 mkLFLetNoEscape = LFLetNoEscape
360 mkLFImported :: Id -> LambdaFormInfo
362 = case arityMaybe (getIdArity id) of
363 Nothing -> LFImported
364 Just 0 -> LFThunk True{-top-lev-} True{-no fvs-}
365 True{-updatable-} NonStandardThunk
366 Just n -> LFReEntrant True n True -- n > 0
369 %************************************************************************
371 \subsection[ClosureInfo-construction]{Functions which build LFInfos}
373 %************************************************************************
375 @mkClosureLFInfo@ figures out the appropriate LFInfo for the closure.
378 mkClosureLFInfo :: Bool -- True of top level
380 -> UpdateFlag -- Update flag
382 -> StgExpr -- Body of closure: passed so we
383 -- can look for selector thunks!
386 mkClosureLFInfo top fvs upd_flag args@(_:_) body -- Non-empty args
387 = LFReEntrant top (length args) (null fvs)
389 mkClosureLFInfo top fvs ReEntrant [] body
390 = LFReEntrant top 0 (null fvs)
393 OK, this is where we look at the body of the closure to see if it's a
394 selector---turgid, but nothing deep. We are looking for a closure of
395 {\em exactly} the form:
397 ... = [the_fv] \ u [] ->
399 con a_1 ... a_n -> a_i
403 mkClosureLFInfo False -- don't bother if at top-level
404 [the_fv] -- just one...
406 [] -- no args (a thunk)
407 (StgCase (StgApp (StgVarArg scrutinee) [{-no args-}] _)
408 _ _ _ -- ignore live vars and uniq...
410 [(con, params, use_mask,
411 (StgApp (StgVarArg selectee) [{-no args-}] _))]
413 | the_fv == scrutinee -- Scrutinee is the only free variable
414 && maybeToBool maybe_offset -- Selectee is a component of the tuple
415 && maybeToBool offset_into_int_maybe
416 && offset_into_int <= mAX_SPEC_SELECTEE_SIZE -- Offset is small enough
418 -- ASSERT(is_single_constructor) -- Should be true, by causes error for SpecTyCon
419 LFThunk False False True (SelectorThunk scrutinee con offset_into_int)
421 (_, params_w_offsets) = layOutDynCon con idPrimRep params
422 maybe_offset = assocMaybe params_w_offsets selectee
423 Just the_offset = maybe_offset
424 offset_into_int_maybe = intOffsetIntoGoods the_offset
425 Just offset_into_int = offset_into_int_maybe
426 is_single_constructor = maybeToBool (maybeTyConSingleCon tycon)
427 (_,_,_, tycon) = dataConSig con
430 Same kind of thing, looking for vector-apply thunks, of the form:
432 x = [...] \ .. [] -> f a1 .. an
434 where f has arity n. We rely on the arity info inside the Id being correct.
437 mkClosureLFInfo top_level
440 [] -- No args; a thunk
441 (StgApp (StgVarArg fun_id) args _)
442 | not top_level -- A top-level thunk would require a static
443 -- vap_info table, which we don't generate just
444 -- now; so top-level thunks are never standard
446 && isLocallyDefined fun_id -- Must be defined in this module
447 && maybeToBool arity_maybe -- A known function with known arity
448 && fun_arity > 0 -- It'd better be a function!
449 && fun_arity == length args -- Saturated application
450 = LFThunk top_level (null fvs) (isUpdatable upd_flag) (VapThunk fun_id args store_fun_in_vap)
452 arity_maybe = arityMaybe (getIdArity fun_id)
453 Just fun_arity = arity_maybe
455 -- If the function is a free variable then it must be stored
456 -- in the thunk too; if it isn't a free variable it must be
457 -- because it's constant, so it doesn't need to be stored in the thunk
458 store_fun_in_vap = fun_id `is_elem` fvs
460 is_elem = isIn "mkClosureLFInfo"
463 Finally, the general updatable-thing case:
465 mkClosureLFInfo top fvs upd_flag [] body
466 = LFThunk top (null fvs) (isUpdatable upd_flag) NonStandardThunk
468 isUpdatable ReEntrant = False
469 isUpdatable SingleEntry = False
470 isUpdatable Updatable = True
473 @mkConLFInfo@ is similar, for constructors.
476 mkConLFInfo :: DataCon -> LambdaFormInfo
479 = ASSERT(isDataCon con)
481 arity = dataConArity con
483 if isTupleCon con then
484 LFTuple con (arity == 0)
486 LFCon con (arity == 0)
490 %************************************************************************
492 \subsection[ClosureInfo-sizes]{Functions about closure {\em sizes}}
494 %************************************************************************
497 closureSize :: ClosureInfo -> HeapOffset
498 closureSize cl_info@(MkClosureInfo _ _ sm_rep)
499 = totHdrSize sm_rep `addOff` (intOff (closureNonHdrSize cl_info))
501 closureSizeWithoutFixedHdr :: ClosureInfo -> HeapOffset
502 closureSizeWithoutFixedHdr cl_info@(MkClosureInfo _ _ sm_rep)
503 = varHdrSize sm_rep `addOff` (intOff (closureNonHdrSize cl_info))
505 closureHdrSize :: ClosureInfo -> HeapOffset
506 closureHdrSize (MkClosureInfo _ _ sm_rep)
509 closureNonHdrSize :: ClosureInfo -> Int
510 closureNonHdrSize cl_info@(MkClosureInfo _ lf_info sm_rep)
511 = tot_wds + computeSlopSize tot_wds sm_rep (closureUpdReqd cl_info) --ToDo: pass lf_info?
513 tot_wds = closureGoodStuffSize cl_info
515 closureGoodStuffSize :: ClosureInfo -> Int
516 closureGoodStuffSize (MkClosureInfo _ _ sm_rep)
517 = let (ptrs, nonptrs) = sizes_from_SMRep sm_rep
520 closurePtrsSize :: ClosureInfo -> Int
521 closurePtrsSize (MkClosureInfo _ _ sm_rep)
522 = let (ptrs, _) = sizes_from_SMRep sm_rep
526 sizes_from_SMRep (SpecialisedRep k ptrs nonptrs _) = (ptrs, nonptrs)
527 sizes_from_SMRep (GenericRep ptrs nonptrs _) = (ptrs, nonptrs)
528 sizes_from_SMRep (BigTupleRep ptrs) = (ptrs, 0)
529 sizes_from_SMRep (MuTupleRep ptrs) = (ptrs, 0)
530 sizes_from_SMRep (DataRep nonptrs) = (0, nonptrs)
531 sizes_from_SMRep BlackHoleRep = (0, 0)
532 sizes_from_SMRep (StaticRep ptrs nonptrs) = (ptrs, nonptrs)
534 sizes_from_SMRep PhantomRep = panic "sizes_from_SMRep: PhantomRep"
535 sizes_from_SMRep DynamicRep = panic "sizes_from_SMRep: DynamicRep"
540 fitsMinUpdSize :: ClosureInfo -> Bool
541 fitsMinUpdSize (MkClosureInfo _ _ BlackHoleRep) = True
542 fitsMinUpdSize cl_info = isSpecRep (closureSMRep cl_info) && closureNonHdrSize cl_info <= mIN_UPD_SIZE
545 Computing slop size. WARNING: this looks dodgy --- it has deep
546 knowledge of what the storage manager does with the various
552 Updateable closures must be @mIN_UPD_SIZE@.
555 Cons cell requires 2 words
557 Indirections require 1 word
559 Appels collector indirections 2 words
561 THEREFORE: @mIN_UPD_SIZE = 2@.
564 Collectable closures which are allocated in the heap
565 must be @mIN_SIZE_NonUpdHeapObject@.
567 Copying collector forward pointer requires 1 word
569 THEREFORE: @mIN_SIZE_NonUpdHeapObject = 1@
572 @SpecialisedRep@ closures closures may require slop:
575 @ConstantRep@ and @CharLikeRep@ closures always use the address of
576 a static closure. They are never allocated or
577 collected (eg hold forwarding pointer) hence never any slop.
580 @IntLikeRep@ are never updatable.
581 May need slop to be collected (as they will be size 1 or more
582 this probably has no affect)
585 @SpecRep@ may be updateable and will be collectable
588 @StaticRep@ may require slop if updatable. Non-updatable ones are OK.
591 @GenericRep@ closures will always be larger so never require slop.
594 ***** ToDo: keep an eye on this!
598 slopSize cl_info@(MkClosureInfo _ lf_info sm_rep)
599 = computeSlopSize (closureGoodStuffSize cl_info) sm_rep (closureUpdReqd cl_info)
601 computeSlopSize :: Int -> SMRep -> Bool -> Int
603 computeSlopSize tot_wds (SpecialisedRep ConstantRep _ _ _) _
605 computeSlopSize tot_wds (SpecialisedRep CharLikeRep _ _ _) _
608 computeSlopSize tot_wds (SpecialisedRep _ _ _ _) True -- Updatable
609 = max 0 (mIN_UPD_SIZE - tot_wds)
610 computeSlopSize tot_wds (StaticRep _ _) True -- Updatable
611 = max 0 (mIN_UPD_SIZE - tot_wds)
612 computeSlopSize tot_wds BlackHoleRep _ -- Updatable
613 = max 0 (mIN_UPD_SIZE - tot_wds)
615 computeSlopSize tot_wds (SpecialisedRep _ _ _ _) False -- Not updatable
616 = max 0 (mIN_SIZE_NonUpdHeapObject - tot_wds)
618 computeSlopSize tot_wds other_rep _ -- Any other rep
622 %************************************************************************
624 \subsection[layOutDynClosure]{Lay out a dynamic closure}
626 %************************************************************************
629 layOutDynClosure, layOutStaticClosure
630 :: Id -- STG identifier w/ which this closure assoc'd
631 -> (a -> PrimRep) -- function w/ which to be able to get a PrimRep
632 -> [a] -- the "things" being layed out
633 -> LambdaFormInfo -- what sort of closure it is
634 -> (ClosureInfo, -- info about the closure
635 [(a, VirtualHeapOffset)]) -- things w/ offsets pinned on them
637 layOutDynClosure name kind_fn things lf_info
638 = (MkClosureInfo name lf_info sm_rep,
641 (tot_wds, -- #ptr_wds + #nonptr_wds
643 things_w_offsets) = mkVirtHeapOffsets sm_rep kind_fn things
644 sm_rep = chooseDynSMRep lf_info tot_wds ptr_wds
646 layOutStaticClosure name kind_fn things lf_info
647 = (MkClosureInfo name lf_info (StaticRep ptr_wds (tot_wds - ptr_wds)),
650 (tot_wds, -- #ptr_wds + #nonptr_wds
652 things_w_offsets) = mkVirtHeapOffsets (StaticRep bot bot) kind_fn things
653 bot = panic "layoutStaticClosure"
655 layOutStaticNoFVClosure :: Id -> LambdaFormInfo -> ClosureInfo
656 layOutStaticNoFVClosure name lf_info
657 = MkClosureInfo name lf_info (StaticRep ptr_wds nonptr_wds)
659 -- I am very uncertain that this is right - it will show up when testing
660 -- my dynamic loading code. ADR
661 -- (If it's not right, we'll have to grab the kinds of the arguments from
666 layOutPhantomClosure :: Id -> LambdaFormInfo -> ClosureInfo
667 layOutPhantomClosure name lf_info = MkClosureInfo name lf_info PhantomRep
670 A wrapper for when used with data constructors:
672 layOutDynCon :: DataCon
675 -> (ClosureInfo, [(a,VirtualHeapOffset)])
677 layOutDynCon con kind_fn args
678 = ASSERT(isDataCon con)
679 layOutDynClosure con kind_fn args (mkConLFInfo con)
683 %************************************************************************
685 \subsection[SMreps]{Choosing SM reps}
687 %************************************************************************
692 -> Int -> Int -- Tot wds, ptr wds
695 chooseDynSMRep lf_info tot_wds ptr_wds
697 nonptr_wds = tot_wds - ptr_wds
699 updatekind = case lf_info of
700 LFThunk _ _ upd _ -> if upd then SMUpdatable else SMSingleEntry
701 LFBlackHole -> SMUpdatable
704 if (nonptr_wds == 0 && ptr_wds <= mAX_SPEC_ALL_PTRS)
705 || (tot_wds <= mAX_SPEC_MIXED_FIELDS)
706 || (ptr_wds == 0 && nonptr_wds <= mAX_SPEC_ALL_NONPTRS) then
708 spec_kind = case lf_info of
710 (LFTuple _ True) -> ConstantRep
712 (LFTuple _ _) -> SpecRep
714 (LFCon _ True) -> ConstantRep
716 (LFCon con _ ) -> if maybeToBool (maybeCharLikeTyCon tycon) then CharLikeRep
717 else if maybeToBool (maybeIntLikeTyCon tycon) then IntLikeRep
720 tycon = dataConTyCon con
724 SpecialisedRep spec_kind ptr_wds nonptr_wds updatekind
726 GenericRep ptr_wds nonptr_wds updatekind
730 %************************************************************************
732 \subsection[mkVirtHeapOffsets]{Assigning heap offsets in a closure}
734 %************************************************************************
736 @mkVirtHeapOffsets@ (the heap version) always returns boxed things with
737 smaller offsets than the unboxed things, and furthermore, the offsets in
741 mkVirtHeapOffsets :: SMRep -- Representation to be used by storage manager
742 -> (a -> PrimRep) -- To be able to grab kinds;
743 -- w/ a kind, we can find boxedness
744 -> [a] -- Things to make offsets for
745 -> (Int, -- *Total* number of words allocated
746 Int, -- Number of words allocated for *pointers*
747 [(a, VirtualHeapOffset)])
748 -- Things with their offsets from start of object
749 -- in order of increasing offset
751 -- First in list gets lowest offset, which is initial offset + 1.
753 mkVirtHeapOffsets sm_rep kind_fun things
754 = let (ptrs, non_ptrs) = separateByPtrFollowness kind_fun things
755 (wds_of_ptrs, ptrs_w_offsets) = mapAccumL computeOffset 0 ptrs
756 (tot_wds, non_ptrs_w_offsets) = mapAccumL computeOffset wds_of_ptrs non_ptrs
758 (tot_wds, wds_of_ptrs, ptrs_w_offsets ++ non_ptrs_w_offsets)
760 offset_of_first_word = totHdrSize sm_rep
761 computeOffset wds_so_far thing
762 = (wds_so_far + (getPrimRepSize . kind_fun) thing,
763 (thing, (offset_of_first_word `addOff` (intOff wds_so_far)))
767 %************************************************************************
769 \subsection[ClosureInfo-4-questions]{Four major questions about @ClosureInfo@}
771 %************************************************************************
773 Be sure to see the stg-details notes about these...
776 nodeMustPointToIt :: LambdaFormInfo -> FCode Bool
777 nodeMustPointToIt lf_info
779 do_profiling = opt_SccProfilingOn
782 LFReEntrant top arity no_fvs -> returnFC (
783 not no_fvs || -- Certainly if it has fvs we need to point to it
785 not top -- If it is not top level we will point to it
786 -- We can have a \r closure with no_fvs which
787 -- is not top level as special case cgRhsClosure
788 -- has been dissabled in favour of let floating
790 -- For lex_profiling we also access the cost centre for a
791 -- non-inherited function i.e. not top level
792 -- the not top case above ensures this is ok.
795 LFCon _ zero_arity -> returnFC True
796 LFTuple _ zero_arity -> returnFC True
798 -- Strictly speaking, the above two don't need Node to point
799 -- to it if the arity = 0. But this is a *really* unlikely
800 -- situation. If we know it's nil (say) and we are entering
801 -- it. Eg: let x = [] in x then we will certainly have inlined
802 -- x, since nil is a simple atom. So we gain little by not
803 -- having Node point to known zero-arity things. On the other
804 -- hand, we do lose something; Patrick's code for figuring out
805 -- when something has been updated but not entered relies on
806 -- having Node point to the result of an update. SLPJ
809 LFThunk _ no_fvs updatable _
810 -> returnFC (updatable || not no_fvs || do_profiling)
812 -- For the non-updatable (single-entry case):
814 -- True if has fvs (in which case we need access to them, and we
815 -- should black-hole it)
816 -- or profiling (in which case we need to recover the cost centre
819 LFArgument -> returnFC True
820 LFImported -> returnFC True
821 LFBlackHole -> returnFC True
822 -- BH entry may require Node to point
824 LFLetNoEscape _ _ -> returnFC False
827 The entry conventions depend on the type of closure being entered,
828 whether or not it has free variables, and whether we're running
829 sequentially or in parallel.
831 \begin{tabular}{lllll}
832 Closure Characteristics & Parallel & Node Req'd & Argument Passing & Enter Via \\
833 Unknown & no & yes & stack & node \\
834 Known fun ($\ge$ 1 arg), no fvs & no & no & registers & fast entry (enough args) \\
835 \ & \ & \ & \ & slow entry (otherwise) \\
836 Known fun ($\ge$ 1 arg), fvs & no & yes & registers & fast entry (enough args) \\
837 0 arg, no fvs @\r,\s@ & no & no & n/a & direct entry \\
838 0 arg, no fvs @\u@ & no & yes & n/a & node \\
839 0 arg, fvs @\r,\s@ & no & yes & n/a & direct entry \\
840 0 arg, fvs @\u@ & no & yes & n/a & node \\
842 Unknown & yes & yes & stack & node \\
843 Known fun ($\ge$ 1 arg), no fvs & yes & no & registers & fast entry (enough args) \\
844 \ & \ & \ & \ & slow entry (otherwise) \\
845 Known fun ($\ge$ 1 arg), fvs & yes & yes & registers & node \\
846 0 arg, no fvs @\r,\s@ & yes & no & n/a & direct entry \\
847 0 arg, no fvs @\u@ & yes & yes & n/a & node \\
848 0 arg, fvs @\r,\s@ & yes & yes & n/a & node \\
849 0 arg, fvs @\u@ & yes & yes & n/a & node\\
852 When black-holing, single-entry closures could also be entered via node
853 (rather than directly) to catch double-entry.
857 = ViaNode -- The "normal" convention
859 | StdEntry CLabel -- Jump to this code, with args on stack
860 (Maybe CLabel) -- possibly setting infoptr to this
862 | DirectEntry -- Jump directly to code, with args in regs
863 CLabel -- The code label
865 [MagicId] -- Its register assignments (possibly empty)
867 getEntryConvention :: Id -- Function being applied
868 -> LambdaFormInfo -- Its info
869 -> [PrimRep] -- Available arguments
870 -> FCode EntryConvention
872 getEntryConvention id lf_info arg_kinds
873 = nodeMustPointToIt lf_info `thenFC` \ node_points ->
875 is_concurrent = opt_ForConcurrent
879 if (node_points && is_concurrent) then ViaNode else
883 LFReEntrant _ arity _ ->
884 if arity == 0 || (length arg_kinds) < arity then
885 StdEntry (mkStdEntryLabel id) Nothing
887 DirectEntry (mkFastEntryLabel id arity) arity arg_regs
889 (arg_regs, _) = assignRegs live_regs (take arity arg_kinds)
890 live_regs = if node_points then [node] else []
893 -> let itbl = if zero_arity then
894 mkPhantomInfoTableLabel con
897 in StdEntry (mkStdEntryLabel con) (Just itbl)
898 -- Should have no args
899 LFTuple tup zero_arity
900 -> StdEntry (mkStdEntryLabel tup)
901 (Just (mkInfoTableLabel tup))
902 -- Should have no args
904 LFThunk _ _ updatable std_form_info
907 else StdEntry (thunkEntryLabel id std_form_info updatable) Nothing
909 LFArgument -> ViaNode
910 LFImported -> ViaNode
911 LFBlackHole -> ViaNode -- Presumably the black hole has by now
912 -- been updated, but we don't know with
913 -- what, so we enter via Node
915 LFLetNoEscape arity _
916 -> ASSERT(arity == length arg_kinds)
917 DirectEntry (mkStdEntryLabel id) arity arg_regs
919 (arg_regs, _) = assignRegs live_regs arg_kinds
920 live_regs = if node_points then [node] else []
923 blackHoleOnEntry :: Bool -- No-black-holing flag
927 -- Static closures are never themselves black-holed.
928 -- Updatable ones will be overwritten with a CAFList cell, which points to a black hole;
929 -- Single-entry ones have no fvs to plug, and we trust they don't form part of a loop.
931 blackHoleOnEntry no_black_holing (MkClosureInfo _ _ (StaticRep _ _)) = False
933 blackHoleOnEntry no_black_holing (MkClosureInfo _ lf_info _)
935 LFReEntrant _ _ _ -> False
936 LFThunk _ no_fvs updatable _
938 then not no_black_holing
940 other -> panic "blackHoleOnEntry" -- Should never happen
942 getStandardFormThunkInfo
944 -> Maybe [StgArg] -- Nothing => not a standard-form thunk
945 -- Just atoms => a standard-form thunk with payload atoms
947 getStandardFormThunkInfo (LFThunk _ _ _ (SelectorThunk scrutinee _ _))
948 = --trace "Selector thunk: missed opportunity to save info table + code"
950 -- Just [StgVarArg scrutinee]
951 -- We can't save the info tbl + code until we have a way to generate
952 -- a fixed family thereof.
954 getStandardFormThunkInfo (LFThunk _ _ _ (VapThunk fun_id args fun_in_payload))
955 | fun_in_payload = Just (StgVarArg fun_id : args)
956 | otherwise = Just args
958 getStandardFormThunkInfo other_lf_info = Nothing
960 maybeSelectorInfo (MkClosureInfo _ (LFThunk _ _ _ (SelectorThunk _ con offset)) _) = Just (con,offset)
961 maybeSelectorInfo _ = Nothing
964 Avoiding generating entries and info tables
965 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
966 At present, for every function we generate all of the following,
967 just in case. But they aren't always all needed, as noted below:
969 [NB1: all of this applies only to *functions*. Thunks always
970 have closure, info table, and entry code.]
972 [NB2: All are needed if the function is *exported*, just to play safe.]
975 * Fast-entry code ALWAYS NEEDED
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) we're in the parallel world and the function has free vars
981 [Reason: in parallel world, we always enter functions
982 with free vars via the closure.]
984 * The function closure
985 Needed iff (a) we have any un-saturated calls to the function
986 OR (b) the function is passed as an arg
987 OR (c) if the function has free vars (ie not top level)
989 Why case (a) here? Because if the arg-satis check fails,
990 UpdatePAP stuffs a pointer to the function closure in the PAP.
991 [Could be changed; UpdatePAP could stuff in a code ptr instead,
992 but doesn't seem worth it.]
994 [NB: these conditions imply that we might need the closure
995 without the slow-entry code. Here's how.
997 f x y = let g w = ...x..y..w...
1001 Here we need a closure for g which contains x and y,
1002 but since the calls are all saturated we just jump to the
1003 fast entry point for g, with R1 pointing to the closure for g.]
1006 * Standard info table
1007 Needed iff (a) we have any un-saturated calls to the function
1008 OR (b) the function is passed as an arg
1009 OR (c) the function has free vars (ie not top level)
1011 NB. In the sequential world, (c) is only required so that the function closure has
1012 an info table to point to, to keep the storage manager happy.
1013 If (c) alone is true we could fake up an info table by choosing
1014 one of a standard family of info tables, whose entry code just
1017 [NB In the parallel world (c) is needed regardless because
1018 we enter functions with free vars via the closure.]
1020 If (c) is retained, then we'll sometimes generate an info table
1021 (for storage mgr purposes) without slow-entry code. Then we need
1022 to use an error label in the info table to substitute for the absent
1025 * Standard vap-entry code
1026 Standard vap-entry info table
1027 Needed iff we have any updatable thunks of the standard vap-entry shape.
1029 * Single-update vap-entry code
1030 Single-update vap-entry info table
1031 Needed iff we have any non-updatable thunks of the
1032 standard vap-entry shape.
1036 staticClosureRequired
1041 staticClosureRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1042 (LFReEntrant top_level _ _) -- It's a function
1043 = ASSERT( top_level ) -- Assumption: it's a top-level, no-free-var binding
1044 arg_occ -- There's an argument occurrence
1045 || unsat_occ -- There's an unsaturated call
1046 || externallyVisibleId binder
1048 staticClosureRequired binder other_binder_info other_lf_info = True
1050 slowFunEntryCodeRequired -- Assumption: it's a function, not a thunk.
1054 slowFunEntryCodeRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1055 = arg_occ -- There's an argument occurrence
1056 || unsat_occ -- There's an unsaturated call
1057 || externallyVisibleId binder
1058 {- HAS FREE VARS AND IS PARALLEL WORLD -}
1060 slowFunEntryCodeRequired binder NoStgBinderInfo = True
1062 funInfoTableRequired
1067 funInfoTableRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
1068 (LFReEntrant top_level _ _)
1070 || arg_occ -- There's an argument occurrence
1071 || unsat_occ -- There's an unsaturated call
1072 || externallyVisibleId binder
1074 funInfoTableRequired other_binder_info binder other_lf_info = True
1076 -- We need the vector-apply entry points for a function if
1077 -- there's a vector-apply occurrence in this module
1079 stdVapRequired, noUpdVapRequired :: StgBinderInfo -> Bool
1081 stdVapRequired binder_info
1082 = case binder_info of
1083 StgBinderInfo _ _ std_vap_occ _ _ -> std_vap_occ
1086 noUpdVapRequired binder_info
1087 = case binder_info of
1088 StgBinderInfo _ _ _ no_upd_vap_occ _ -> no_upd_vap_occ
1092 %************************************************************************
1094 \subsection[ClosureInfo-misc-funs]{Misc functions about @ClosureInfo@, etc.}
1096 %************************************************************************
1100 isStaticClosure :: ClosureInfo -> Bool
1101 isStaticClosure (MkClosureInfo _ _ rep) = isStaticRep rep
1103 closureId :: ClosureInfo -> Id
1104 closureId (MkClosureInfo id _ _) = id
1106 closureSMRep :: ClosureInfo -> SMRep
1107 closureSMRep (MkClosureInfo _ _ sm_rep) = sm_rep
1109 closureLFInfo :: ClosureInfo -> LambdaFormInfo
1110 closureLFInfo (MkClosureInfo _ lf_info _) = lf_info
1112 closureUpdReqd :: ClosureInfo -> Bool
1114 closureUpdReqd (MkClosureInfo _ (LFThunk _ _ upd _) _) = upd
1115 closureUpdReqd (MkClosureInfo _ LFBlackHole _) = True
1116 -- Black-hole closures are allocated to receive the results of an
1117 -- alg case with a named default... so they need to be updated.
1118 closureUpdReqd other_closure = False
1120 closureSingleEntry :: ClosureInfo -> Bool
1122 closureSingleEntry (MkClosureInfo _ (LFThunk _ _ upd _) _) = not upd
1123 closureSingleEntry other_closure = False
1126 Note: @closureType@ returns appropriately specialised tycon and
1129 closureType :: ClosureInfo -> Maybe (TyCon, [Type], [Id])
1131 -- First, a turgid special case. When we are generating the
1132 -- standard code and info-table for Vaps (which is done when the function
1133 -- defn is encountered), we don't have a convenient Id to hand whose
1134 -- type is that of (f x y z). So we need to figure out the type
1135 -- rather than take it from the Id. The Id is probably just "f"!
1137 closureType (MkClosureInfo id (LFThunk _ _ _ (VapThunk fun_id args _)) _)
1138 = getDataSpecTyCon_maybe (fun_result_ty (length args) fun_id)
1140 closureType (MkClosureInfo id lf _) = getDataSpecTyCon_maybe (idType id)
1143 @closureReturnsUnboxedType@ is used to check whether a closure, {\em
1144 once it has eaten its arguments}, returns an unboxed type. For
1145 example, the closure for a function:
1149 returns an unboxed type. This is important when dealing with stack
1152 closureReturnsUnboxedType :: ClosureInfo -> Bool
1154 closureReturnsUnboxedType (MkClosureInfo fun_id (LFReEntrant _ arity _) _)
1155 = isPrimType (fun_result_ty arity fun_id)
1157 closureReturnsUnboxedType other_closure = False
1158 -- All non-function closures aren't functions,
1159 -- and hence are boxed, since they are heap alloc'd
1161 -- ToDo: need anything like this in Type.lhs?
1162 fun_result_ty arity id
1164 (_, de_foralld_ty) = splitForAllTy (idType id)
1165 (arg_tys, res_ty) = splitFunTy{-w/ dicts as args?-} de_foralld_ty
1167 ASSERT(arity >= 0 && length arg_tys >= arity)
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
1184 infoTableLabelFromCI :: ClosureInfo -> CLabel
1186 infoTableLabelFromCI (MkClosureInfo id lf_info rep)
1188 LFCon con _ -> mkConInfoPtr con rep
1189 LFTuple tup _ -> mkConInfoPtr tup rep
1191 LFBlackHole -> mkBlackHoleInfoTableLabel
1193 LFThunk _ _ upd_flag (VapThunk fun_id args _) -> mkVapInfoTableLabel fun_id upd_flag
1194 -- Use the standard vap info table
1195 -- for the function, rather than a one-off one
1196 -- for this particular closure
1198 {- For now, we generate individual info table and entry code for selector thunks,
1199 so their info table should be labelled in the standard way.
1200 The only special thing about them is that the info table has a field which
1201 tells the GC that it really is a selector.
1203 Later, perhaps, we'll have some standard RTS code for selector-thunk info tables,
1204 in which case this line will spring back to life.
1206 LFThunk _ _ upd_flag (SelectorThunk _ _ offset) -> mkSelectorInfoTableLabel upd_flag offset
1207 -- Ditto for selectors
1210 other -> {-NO: if isStaticRep rep
1211 then mkStaticInfoTableLabel id
1212 else -} mkInfoTableLabel id
1214 mkConInfoPtr :: Id -> SMRep -> CLabel
1215 mkConInfoPtr id rep =
1217 PhantomRep -> mkPhantomInfoTableLabel id
1218 StaticRep _ _ -> mkStaticInfoTableLabel id
1219 _ -> mkInfoTableLabel id
1221 mkConEntryPtr :: Id -> SMRep -> CLabel
1222 mkConEntryPtr id rep =
1224 StaticRep _ _ -> mkStaticConEntryLabel id
1225 _ -> mkConEntryLabel id
1228 closureLabelFromCI (MkClosureInfo id _ _) = mkClosureLabel id
1230 entryLabelFromCI :: ClosureInfo -> CLabel
1231 entryLabelFromCI (MkClosureInfo id lf_info rep)
1233 LFThunk _ _ upd_flag std_form_info -> thunkEntryLabel id std_form_info upd_flag
1234 LFCon con _ -> mkConEntryPtr con rep
1235 LFTuple tup _ -> mkConEntryPtr tup rep
1236 other -> mkStdEntryLabel id
1238 -- thunkEntryLabel is a local help function, not exported. It's used from both
1239 -- entryLabelFromCI and getEntryConvention.
1240 -- I don't think it needs to deal with the SelectorThunk case
1241 -- Well, it's falling over now, so I've made it deal with it. (JSM)
1243 thunkEntryLabel thunk_id (VapThunk fun_id args _) is_updatable
1244 = mkVapEntryLabel fun_id is_updatable
1245 thunkEntryLabel thunk_id _ is_updatable
1246 = mkStdEntryLabel thunk_id
1248 fastLabelFromCI :: ClosureInfo -> CLabel
1249 fastLabelFromCI (MkClosureInfo id _ _) = mkFastEntryLabel id fun_arity
1251 arity_maybe = arityMaybe (getIdArity id)
1252 fun_arity = case arity_maybe of
1254 _ -> pprPanic "fastLabelFromCI:no arity:" (ppr PprShowAll id)
1258 allocProfilingMsg :: ClosureInfo -> FAST_STRING
1260 allocProfilingMsg (MkClosureInfo _ lf_info _)
1262 LFReEntrant _ _ _ -> SLIT("ALLOC_FUN")
1263 LFCon _ _ -> SLIT("ALLOC_CON")
1264 LFTuple _ _ -> SLIT("ALLOC_CON")
1265 LFThunk _ _ _ _ -> SLIT("ALLOC_THK")
1266 LFBlackHole -> SLIT("ALLOC_BH")
1267 LFImported -> panic "ALLOC_IMP"
1270 We need a black-hole closure info to pass to @allocDynClosure@ when we
1271 want to allocate the black hole on entry to a CAF.
1274 blackHoleClosureInfo (MkClosureInfo id _ _)
1275 = MkClosureInfo id LFBlackHole BlackHoleRep
1278 The register liveness when returning from a constructor. For
1279 simplicity, we claim just [node] is live for all but PhantomRep's. In
1280 truth, this means that non-constructor info tables also claim node,
1281 but since their liveness information is never used, we don't care.
1284 dataConLiveness (MkClosureInfo con _ PhantomRep)
1285 = case (dataReturnConvAlg con) of
1286 ReturnInRegs regs -> mkLiveRegsMask regs
1287 ReturnInHeap -> panic "dataConLiveness:PhantomRep in heap???"
1289 dataConLiveness _ = mkLiveRegsMask [node]
1292 %************************************************************************
1294 \subsection[ClosureInfo-Profiling-funs]{Misc functions about for profiling info.}
1296 %************************************************************************
1298 Profiling requires three pices of information to be determined for
1299 each closure's info table --- kind, description and type.
1301 The description is stored directly in the @CClosureInfoTable@ when the
1302 info table is built.
1304 The kind is determined from the @LambdaForm@ stored in the closure
1305 info using @closureKind@.
1307 The type is determined from the type information stored with the @Id@
1308 in the closure info using @closureTypeDescr@.
1311 closureKind :: ClosureInfo -> String
1313 closureKind (MkClosureInfo _ lf _)
1315 LFReEntrant _ n _ -> if n > 0 then "FN_K" else "THK_K"
1316 LFCon _ _ -> "CON_K"
1317 LFTuple _ _ -> "CON_K"
1318 LFThunk _ _ _ _ -> "THK_K"
1319 LFBlackHole -> "THK_K" -- consider BHs as thunks for the moment... (ToDo?)
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 (dataConTyCon id)) -- We want the TyCon not the ->
1327 getTyDescription (idType id)