2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 % $Id: ClosureInfo.lhs,v 1.43 2000/07/14 08:14:53 simonpj Exp $
6 \section[ClosureInfo]{Data structures which describe closures}
8 Much of the rationale for these things is in the ``details'' part of
13 ClosureInfo, LambdaFormInfo, SMRep, -- all abstract
18 mkClosureLFInfo, mkConLFInfo, mkSelectorLFInfo,
19 mkApLFInfo, mkLFImported, mkLFArgument, mkLFLetNoEscape,
22 closureSize, closureNonHdrSize,
23 closureGoodStuffSize, closurePtrsSize,
26 layOutDynClosure, layOutDynCon, layOutStaticClosure,
27 layOutStaticNoFVClosure,
30 nodeMustPointToIt, getEntryConvention,
31 FCode, CgInfoDownwards, CgState,
35 staticClosureRequired,
36 slowFunEntryCodeRequired, funInfoTableRequired,
38 closureName, infoTableLabelFromCI, fastLabelFromCI,
41 closureLFInfo, closureSMRep, closureUpdReqd,
42 closureSingleEntry, closureReEntrant, closureSemiTag,
47 closureTypeDescr, -- profiling
51 cafBlackHoleClosureInfo, seCafBlackHoleClosureInfo,
55 staticClosureNeedsLink,
59 #include "HsVersions.h"
61 import AbsCSyn ( MagicId, node, VirtualHeapOffset, HeapOffset )
65 import Constants ( mIN_UPD_SIZE, mIN_SIZE_NonUpdHeapObject,
66 mAX_SPEC_FUN_SIZE, mAX_SPEC_THUNK_SIZE, mAX_SPEC_CONSTR_SIZE )
67 import CgRetConv ( assignRegs )
68 import CLabel ( CLabel, mkStdEntryLabel, mkFastEntryLabel,
71 mkCAFBlackHoleInfoTableLabel,
72 mkSECAFBlackHoleInfoTableLabel,
73 mkStaticInfoTableLabel, mkStaticConEntryLabel,
74 mkConEntryLabel, mkClosureLabel,
75 mkSelectorInfoLabel, mkSelectorEntryLabel,
76 mkApInfoTableLabel, mkApEntryLabel,
79 import CmdLineOpts ( opt_SccProfilingOn, opt_OmitBlackHoling,
80 opt_Parallel, opt_DoTickyProfiling,
82 import Id ( Id, idType, idArityInfo )
83 import DataCon ( DataCon, dataConTag, fIRST_TAG, dataConTyCon,
84 isNullaryDataCon, dataConName
86 import TyCon ( isBoxedTupleTyCon )
87 import IdInfo ( ArityInfo(..) )
88 import Name ( Name, isExternallyVisibleName, nameUnique,
90 import OccName ( occNameUserString )
91 import PprType ( getTyDescription )
92 import PrimRep ( getPrimRepSize, separateByPtrFollowness, PrimRep )
93 import SMRep -- all of it
94 import Type ( isUnLiftedType, Type )
95 import BasicTypes ( TopLevelFlag(..), isNotTopLevel, isTopLevel )
96 import Util ( mapAccumL )
100 The ``wrapper'' data type for closure information:
105 Name -- The thing bound to this closure
106 LambdaFormInfo -- info derivable from the *source*
107 SMRep -- representation used by storage manager
110 %************************************************************************
112 \subsection[ClosureInfo-datatypes]{Data types for closure information}
114 %************************************************************************
116 %************************************************************************
118 \subsubsection[LambdaFormInfo-datatype]{@LambdaFormInfo@: source-derivable info}
120 %************************************************************************
124 = LFReEntrant -- Reentrant closure; used for PAPs too
125 Type -- Type of closure (ToDo: remove)
126 TopLevelFlag -- True if top level
128 !Bool -- True <=> no fvs
132 | LFCon -- Constructor
133 DataCon -- The constructor
134 Bool -- True <=> zero arity
137 DataCon -- The tuple constructor
138 Bool -- True <=> zero arity
140 | LFThunk -- Thunk (zero arity)
141 Type -- Type of the thunk (ToDo: remove)
143 !Bool -- True <=> no free vars
144 Bool -- True <=> updatable (i.e., *not* single-entry)
149 | LFArgument -- Used for function arguments. We know nothing about
150 -- this closure. Treat like updatable "LFThunk"...
152 | LFImported -- Used for imported things. We know nothing about this
153 -- closure. Treat like updatable "LFThunk"...
154 -- Imported things which we do know something about use
155 -- one of the other LF constructors (eg LFReEntrant for
158 | LFLetNoEscape -- See LetNoEscape module for precise description of
162 | LFBlackHole -- Used for the closures allocated to hold the result
163 -- of a CAF. We want the target of the update frame to
164 -- be in the heap, so we make a black hole to hold it.
165 CLabel -- Flavour (info label, eg CAF_BLACKHOLE_info).
168 data StandardFormInfo -- Tells whether this thunk has one of a small number
171 = NonStandardThunk -- No, it isn't
174 Int -- 0-origin offset of ak within the "goods" of
175 -- constructor (Recall that the a1,...,an may be laid
176 -- out in the heap in a non-obvious order.)
178 {- A SelectorThunk is of form
183 and the constructor is from a single-constr type.
189 {- An ApThunk is of form
193 The code for the thunk just pushes x2..xn on the stack and enters x1.
194 There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled
195 in the RTS to save space.
200 %************************************************************************
202 \subsection[ClosureInfo-construction]{Functions which build LFInfos}
204 %************************************************************************
206 @mkClosureLFInfo@ figures out the appropriate LFInfo for the closure.
209 mkClosureLFInfo :: Id -- The binder
210 -> TopLevelFlag -- True of top level
212 -> UpdateFlag -- Update flag
214 -> CLabel -- SRT label
218 mkClosureLFInfo bndr top fvs upd_flag args@(_:_) srt_label srt -- Non-empty args
219 = LFReEntrant (idType bndr) top (length args) (null fvs) srt_label srt
221 mkClosureLFInfo bndr top fvs ReEntrant [] srt_label srt
222 = LFReEntrant (idType bndr) top 0 (null fvs) srt_label srt
224 mkClosureLFInfo bndr top fvs upd_flag [] srt_label srt
226 | isUnLiftedType ty = pprPanic "mkClosureLFInfo" (ppr bndr <+> ppr ty)
229 = LFThunk ty top (null fvs) (isUpdatable upd_flag) NonStandardThunk
235 @mkConLFInfo@ is similar, for constructors.
238 mkConLFInfo :: DataCon -> LambdaFormInfo
241 = -- the isNullaryDataCon will do this: ASSERT(isDataCon con)
242 (if isBoxedTupleTyCon (dataConTyCon con) then LFTuple else LFCon)
243 con (isNullaryDataCon con)
245 mkSelectorLFInfo rhs_ty offset updatable
246 = LFThunk rhs_ty NotTopLevel False updatable (SelectorThunk offset)
247 (error "mkSelectorLFInfo: no srt label")
248 (error "mkSelectorLFInfo: no srt")
250 mkApLFInfo rhs_ty upd_flag arity
251 = LFThunk rhs_ty NotTopLevel (arity == 0) (isUpdatable upd_flag)
253 (error "mkApLFInfo: no srt label")
254 (error "mkApLFInfo: no srt")
257 Miscellaneous LF-infos.
260 mkLFArgument = LFArgument
261 mkLFLetNoEscape = LFLetNoEscape
263 mkLFImported :: Id -> LambdaFormInfo
265 = case idArityInfo id of
266 ArityExactly 0 -> LFThunk (idType id)
267 TopLevel True{-no fvs-}
268 True{-updatable-} NonStandardThunk
269 (error "mkLFImported: no srt label")
270 (error "mkLFImported: no srt")
271 ArityExactly n -> LFReEntrant (idType id) TopLevel n True -- n > 0
272 (error "mkLFImported: no srt label")
273 (error "mkLFImported: no srt")
274 other -> LFImported -- Not sure of exact arity
277 %************************************************************************
279 \subsection[ClosureInfo-sizes]{Functions about closure {\em sizes}}
281 %************************************************************************
284 closureSize :: ClosureInfo -> HeapOffset
285 closureSize cl_info@(MkClosureInfo _ _ sm_rep)
286 = fixedHdrSize + closureNonHdrSize cl_info
288 closureNonHdrSize :: ClosureInfo -> Int
289 closureNonHdrSize cl_info@(MkClosureInfo _ lf_info sm_rep)
290 = tot_wds + computeSlopSize tot_wds sm_rep (closureUpdReqd cl_info)
291 --ToDo: pass lf_info?
293 tot_wds = closureGoodStuffSize cl_info
295 closureGoodStuffSize :: ClosureInfo -> Int
296 closureGoodStuffSize (MkClosureInfo _ _ sm_rep)
297 = let (ptrs, nonptrs) = sizes_from_SMRep sm_rep
300 closurePtrsSize :: ClosureInfo -> Int
301 closurePtrsSize (MkClosureInfo _ _ sm_rep)
302 = let (ptrs, _) = sizes_from_SMRep sm_rep
306 sizes_from_SMRep :: SMRep -> (Int,Int)
307 sizes_from_SMRep (GenericRep _ ptrs nonptrs _) = (ptrs, nonptrs)
308 sizes_from_SMRep BlackHoleRep = (0, 0)
311 Computing slop size. WARNING: this looks dodgy --- it has deep
312 knowledge of what the storage manager does with the various
318 Updateable closures must be @mIN_UPD_SIZE@.
321 Indirections require 1 word
323 Appels collector indirections 2 words
325 THEREFORE: @mIN_UPD_SIZE = 2@.
328 Collectable closures which are allocated in the heap
329 must be @mIN_SIZE_NonUpdHeapObject@.
331 Copying collector forward pointer requires 1 word
333 THEREFORE: @mIN_SIZE_NonUpdHeapObject = 1@
336 Static closures have an extra ``static link field'' at the end, but we
337 don't bother taking that into account here.
340 slopSize cl_info@(MkClosureInfo _ lf_info sm_rep)
341 = computeSlopSize (closureGoodStuffSize cl_info) sm_rep
342 (closureUpdReqd cl_info)
344 computeSlopSize :: Int -> SMRep -> Bool -> Int
346 computeSlopSize tot_wds (GenericRep _ _ _ _) True -- Updatable
347 = max 0 (mIN_UPD_SIZE - tot_wds)
349 computeSlopSize tot_wds (GenericRep True _ _ _) False -- Non updatable
352 computeSlopSize tot_wds (GenericRep False _ _ _) False -- Non updatable
353 = max 0 (mIN_SIZE_NonUpdHeapObject - tot_wds) -- Dynamic
355 computeSlopSize tot_wds BlackHoleRep _ -- Updatable
356 = max 0 (mIN_UPD_SIZE - tot_wds)
359 %************************************************************************
361 \subsection[layOutDynClosure]{Lay out a dynamic closure}
363 %************************************************************************
366 layOutDynClosure, layOutStaticClosure
367 :: Name -- STG identifier of this closure
368 -> (a -> PrimRep) -- how to get a PrimRep for the fields
369 -> [a] -- the "things" being layed out
370 -> LambdaFormInfo -- what sort of closure it is
371 -> (ClosureInfo, -- info about the closure
372 [(a, VirtualHeapOffset)]) -- things w/ offsets pinned on them
374 layOutDynClosure name kind_fn things lf_info
375 = (MkClosureInfo name lf_info sm_rep,
378 (tot_wds, -- #ptr_wds + #nonptr_wds
380 things_w_offsets) = mkVirtHeapOffsets kind_fn things
381 sm_rep = chooseDynSMRep lf_info tot_wds ptr_wds
384 A wrapper for when used with data constructors:
387 layOutDynCon :: DataCon
390 -> (ClosureInfo, [(a,VirtualHeapOffset)])
392 layOutDynCon con kind_fn args
393 = layOutDynClosure (dataConName con) kind_fn args (mkConLFInfo con)
396 %************************************************************************
398 \subsection[layOutStaticClosure]{Lay out a static closure}
400 %************************************************************************
402 layOutStaticClosure is only used for laying out static constructors at
405 Static closures for functions are laid out using
406 layOutStaticNoFVClosure.
409 layOutStaticClosure name kind_fn things lf_info
410 = (MkClosureInfo name lf_info
411 (GenericRep is_static ptr_wds (tot_wds - ptr_wds) closure_type),
414 (tot_wds, -- #ptr_wds + #nonptr_wds
416 things_w_offsets) = mkVirtHeapOffsets kind_fn things
418 -- constructors with no pointer fields will definitely be NOCAF things.
419 -- this is a compromise until we can generate both kinds of constructor
420 -- (a normal static kind and the NOCAF_STATIC kind).
421 closure_type = getClosureType is_static tot_wds ptr_wds lf_info
424 layOutStaticNoFVClosure :: Name -> LambdaFormInfo -> ClosureInfo
425 layOutStaticNoFVClosure name lf_info
426 = MkClosureInfo name lf_info (GenericRep is_static 0 0 (getClosureType is_static 0 0 lf_info))
431 %************************************************************************
433 \subsection[SMreps]{Choosing SM reps}
435 %************************************************************************
440 -> Int -> Int -- Tot wds, ptr wds
443 chooseDynSMRep lf_info tot_wds ptr_wds
446 nonptr_wds = tot_wds - ptr_wds
447 closure_type = getClosureType is_static tot_wds ptr_wds lf_info
449 GenericRep is_static ptr_wds nonptr_wds closure_type
451 -- we *do* get non-updatable top-level thunks sometimes. eg. f = g
452 -- gets compiled to a jump to g (if g has non-zero arity), instead of
453 -- messing around with update frames and PAPs. We set the closure type
454 -- to FUN_STATIC in this case.
456 getClosureType :: Bool -> Int -> Int -> LambdaFormInfo -> ClosureType
457 getClosureType is_static tot_wds ptr_wds lf_info
460 | is_static && ptr_wds == 0 -> CONSTR_NOCAF
461 | specialised_rep mAX_SPEC_CONSTR_SIZE -> CONSTR_p_n
462 | otherwise -> CONSTR
465 | is_static && ptr_wds == 0 -> CONSTR_NOCAF
466 | specialised_rep mAX_SPEC_CONSTR_SIZE -> CONSTR_p_n
467 | otherwise -> CONSTR
469 LFReEntrant _ _ _ _ _ _
470 | specialised_rep mAX_SPEC_FUN_SIZE -> FUN_p_n
473 LFThunk _ _ _ _ (SelectorThunk _) _ _ -> THUNK_SELECTOR
475 LFThunk _ _ _ _ _ _ _
476 | specialised_rep mAX_SPEC_THUNK_SIZE -> THUNK_p_n
479 _ -> panic "getClosureType"
481 specialised_rep max_size = not is_static
483 && tot_wds <= max_size
486 %************************************************************************
488 \subsection[mkVirtHeapOffsets]{Assigning heap offsets in a closure}
490 %************************************************************************
492 @mkVirtHeapOffsets@ (the heap version) always returns boxed things with
493 smaller offsets than the unboxed things, and furthermore, the offsets in
498 (a -> PrimRep) -- To be able to grab kinds;
499 -- w/ a kind, we can find boxedness
500 -> [a] -- Things to make offsets for
501 -> (Int, -- *Total* number of words allocated
502 Int, -- Number of words allocated for *pointers*
503 [(a, VirtualHeapOffset)])
504 -- Things with their offsets from start of
505 -- object in order of increasing offset
507 -- First in list gets lowest offset, which is initial offset + 1.
509 mkVirtHeapOffsets kind_fun things
510 = let (ptrs, non_ptrs) = separateByPtrFollowness kind_fun things
511 (wds_of_ptrs, ptrs_w_offsets) = mapAccumL computeOffset 0 ptrs
512 (tot_wds, non_ptrs_w_offsets) = mapAccumL computeOffset wds_of_ptrs non_ptrs
514 (tot_wds, wds_of_ptrs, ptrs_w_offsets ++ non_ptrs_w_offsets)
516 computeOffset wds_so_far thing
517 = (wds_so_far + (getPrimRepSize . kind_fun) thing,
518 (thing, fixedHdrSize + wds_so_far)
522 %************************************************************************
524 \subsection[ClosureInfo-4-questions]{Four major questions about @ClosureInfo@}
526 %************************************************************************
528 Be sure to see the stg-details notes about these...
531 nodeMustPointToIt :: LambdaFormInfo -> FCode Bool
532 nodeMustPointToIt lf_info
535 LFReEntrant ty top arity no_fvs _ _ -> returnFC (
536 not no_fvs || -- Certainly if it has fvs we need to point to it
538 -- If it is not top level we will point to it
539 -- We can have a \r closure with no_fvs which
540 -- is not top level as special case cgRhsClosure
541 -- has been dissabled in favour of let floating
543 -- For lex_profiling we also access the cost centre for a
544 -- non-inherited function i.e. not top level
545 -- the not top case above ensures this is ok.
548 LFCon _ zero_arity -> returnFC True
549 LFTuple _ zero_arity -> returnFC True
551 -- Strictly speaking, the above two don't need Node to point
552 -- to it if the arity = 0. But this is a *really* unlikely
553 -- situation. If we know it's nil (say) and we are entering
554 -- it. Eg: let x = [] in x then we will certainly have inlined
555 -- x, since nil is a simple atom. So we gain little by not
556 -- having Node point to known zero-arity things. On the other
557 -- hand, we do lose something; Patrick's code for figuring out
558 -- when something has been updated but not entered relies on
559 -- having Node point to the result of an update. SLPJ
562 LFThunk _ _ no_fvs updatable NonStandardThunk _ _
563 -> returnFC (updatable || not no_fvs || opt_SccProfilingOn)
565 -- For the non-updatable (single-entry case):
567 -- True if has fvs (in which case we need access to them, and we
568 -- should black-hole it)
569 -- or profiling (in which case we need to recover the cost centre
572 LFThunk _ _ no_fvs updatable some_standard_form_thunk _ _
574 -- Node must point to any standard-form thunk.
576 LFArgument -> returnFC True
577 LFImported -> returnFC True
578 LFBlackHole _ -> returnFC True
579 -- BH entry may require Node to point
581 LFLetNoEscape _ -> returnFC False
584 The entry conventions depend on the type of closure being entered,
585 whether or not it has free variables, and whether we're running
586 sequentially or in parallel.
588 \begin{tabular}{lllll}
589 Closure Characteristics & Parallel & Node Req'd & Argument Passing & Enter Via \\
590 Unknown & no & yes & stack & node \\
591 Known fun ($\ge$ 1 arg), no fvs & no & no & registers & fast entry (enough args) \\
592 \ & \ & \ & \ & slow entry (otherwise) \\
593 Known fun ($\ge$ 1 arg), fvs & no & yes & registers & fast entry (enough args) \\
594 0 arg, no fvs @\r,\s@ & no & no & n/a & direct entry \\
595 0 arg, no fvs @\u@ & no & yes & n/a & node \\
596 0 arg, fvs @\r,\s@ & no & yes & n/a & direct entry \\
597 0 arg, fvs @\u@ & no & yes & n/a & node \\
599 Unknown & yes & yes & stack & node \\
600 Known fun ($\ge$ 1 arg), no fvs & yes & no & registers & fast entry (enough args) \\
601 \ & \ & \ & \ & slow entry (otherwise) \\
602 Known fun ($\ge$ 1 arg), fvs & yes & yes & registers & node \\
603 0 arg, no fvs @\r,\s@ & yes & no & n/a & direct entry \\
604 0 arg, no fvs @\u@ & yes & yes & n/a & node \\
605 0 arg, fvs @\r,\s@ & yes & yes & n/a & node \\
606 0 arg, fvs @\u@ & yes & yes & n/a & node\\
609 When black-holing, single-entry closures could also be entered via node
610 (rather than directly) to catch double-entry.
614 = ViaNode -- The "normal" convention
616 | StdEntry CLabel -- Jump to this code, with args on stack
618 | DirectEntry -- Jump directly, with args in regs
619 CLabel -- The code label
621 [MagicId] -- Its register assignments
624 getEntryConvention :: Name -- Function being applied
625 -> LambdaFormInfo -- Its info
626 -> [PrimRep] -- Available arguments
627 -> FCode EntryConvention
629 getEntryConvention name lf_info arg_kinds
630 = nodeMustPointToIt lf_info `thenFC` \ node_points ->
633 -- if we're parallel, then we must always enter via node. The reason
634 -- is that the closure may have been fetched since we allocated it.
636 if (node_points && opt_Parallel) then ViaNode else
638 -- Commented out by SDM after futher thoughts:
639 -- - the only closure type that can be blackholed is a thunk
640 -- - we already enter thunks via node (unless the closure is
641 -- non-updatable, in which case why is it being re-entered...)
645 LFReEntrant _ _ arity _ _ _ ->
646 if arity == 0 || (length arg_kinds) < arity then
647 StdEntry (mkStdEntryLabel name)
649 DirectEntry (mkFastEntryLabel name arity) arity arg_regs
651 (arg_regs, _) = assignRegs live_regs (take arity arg_kinds)
652 live_regs = if node_points then [node] else []
654 LFCon con True{-zero_arity-}
655 -- a real constructor. Don't bother entering it, just jump
656 -- to the constructor entry code directly.
657 -> --false:ASSERT (null arg_kinds)
658 -- Should have no args (meaning what?)
659 StdEntry (mkStaticConEntryLabel (dataConName con))
661 LFCon con False{-non-zero_arity-}
662 -> --false:ASSERT (null arg_kinds)
663 -- Should have no args (meaning what?)
664 StdEntry (mkConEntryLabel (dataConName con))
666 LFTuple tup zero_arity
667 -> --false:ASSERT (null arg_kinds)
668 -- Should have no args (meaning what?)
669 StdEntry (mkConEntryLabel (dataConName tup))
671 LFThunk _ _ _ updatable std_form_info _ _
672 -> if updatable || opt_DoTickyProfiling -- to catch double entry
673 || opt_SMP -- always enter via node on SMP, since the
674 -- thunk might have been blackholed in the
677 else StdEntry (thunkEntryLabel name std_form_info updatable)
679 LFArgument -> ViaNode
680 LFImported -> ViaNode
681 LFBlackHole _ -> ViaNode -- Presumably the black hole has by now
682 -- been updated, but we don't know with
683 -- what, so we enter via Node
686 -> StdEntry (mkReturnPtLabel (nameUnique name))
689 -> ASSERT(arity == length arg_kinds)
690 DirectEntry (mkReturnPtLabel (nameUnique name)) arity arg_regs
692 (arg_regs, _) = assignRegs [] arg_kinds
693 -- node never points to a LetNoEscape, see above --SDM
694 --live_regs = if node_points then [node] else []
697 blackHoleOnEntry :: ClosureInfo -> Bool
699 -- Static closures are never themselves black-holed.
700 -- Updatable ones will be overwritten with a CAFList cell, which points to a
702 -- Single-entry ones have no fvs to plug, and we trust they don't form part
705 blackHoleOnEntry (MkClosureInfo _ _ rep)
708 -- Never black-hole a static closure
710 blackHoleOnEntry (MkClosureInfo _ lf_info _)
712 LFReEntrant _ _ _ _ _ _ -> False
713 LFLetNoEscape _ -> False
714 LFThunk _ _ no_fvs updatable _ _ _
716 then not opt_OmitBlackHoling
717 else opt_DoTickyProfiling || not no_fvs
718 -- the former to catch double entry,
719 -- and the latter to plug space-leaks. KSW/SDM 1999-04.
721 other -> panic "blackHoleOnEntry" -- Should never happen
723 isStandardFormThunk :: LambdaFormInfo -> Bool
725 isStandardFormThunk (LFThunk _ _ _ _ (SelectorThunk _) _ _) = True
726 isStandardFormThunk (LFThunk _ _ _ _ (ApThunk _) _ _) = True
727 isStandardFormThunk other_lf_info = False
729 maybeSelectorInfo (MkClosureInfo _ (LFThunk _ _ _ _
730 (SelectorThunk offset) _ _) _) = Just offset
731 maybeSelectorInfo _ = Nothing
734 -----------------------------------------------------------------------------
739 infoTblNeedsSRT :: ClosureInfo -> Bool
740 infoTblNeedsSRT (MkClosureInfo _ info _) =
742 LFThunk _ _ _ _ _ _ NoSRT -> False
743 LFThunk _ _ _ _ _ _ _ -> True
745 LFReEntrant _ _ _ _ _ NoSRT -> False
746 LFReEntrant _ _ _ _ _ _ -> True
750 staticClosureNeedsLink :: ClosureInfo -> Bool
751 staticClosureNeedsLink (MkClosureInfo _ info _) =
753 LFThunk _ _ _ _ _ _ NoSRT -> False
754 LFReEntrant _ _ _ _ _ NoSRT -> False
755 LFCon _ True -> False -- zero arity constructors
758 getSRTInfo :: ClosureInfo -> (CLabel, SRT)
759 getSRTInfo (MkClosureInfo _ info _) =
761 LFThunk _ _ _ _ _ lbl srt -> (lbl,srt)
762 LFReEntrant _ _ _ _ lbl srt -> (lbl,srt)
763 _ -> panic "getSRTInfo"
766 Avoiding generating entries and info tables
767 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
768 At present, for every function we generate all of the following,
769 just in case. But they aren't always all needed, as noted below:
771 [NB1: all of this applies only to *functions*. Thunks always
772 have closure, info table, and entry code.]
774 [NB2: All are needed if the function is *exported*, just to play safe.]
777 * Fast-entry code ALWAYS NEEDED
780 Needed iff (a) we have any un-saturated calls to the function
781 OR (b) the function is passed as an arg
782 OR (c) we're in the parallel world and the function has free vars
783 [Reason: in parallel world, we always enter functions
784 with free vars via the closure.]
786 * The function closure
787 Needed iff (a) we have any un-saturated calls to the function
788 OR (b) the function is passed as an arg
789 OR (c) if the function has free vars (ie not top level)
791 Why case (a) here? Because if the arg-satis check fails,
792 UpdatePAP stuffs a pointer to the function closure in the PAP.
793 [Could be changed; UpdatePAP could stuff in a code ptr instead,
794 but doesn't seem worth it.]
796 [NB: these conditions imply that we might need the closure
797 without the slow-entry code. Here's how.
799 f x y = let g w = ...x..y..w...
803 Here we need a closure for g which contains x and y,
804 but since the calls are all saturated we just jump to the
805 fast entry point for g, with R1 pointing to the closure for g.]
808 * Standard info table
809 Needed iff (a) we have any un-saturated calls to the function
810 OR (b) the function is passed as an arg
811 OR (c) the function has free vars (ie not top level)
813 NB. In the sequential world, (c) is only required so that the function closure has
814 an info table to point to, to keep the storage manager happy.
815 If (c) alone is true we could fake up an info table by choosing
816 one of a standard family of info tables, whose entry code just
819 [NB In the parallel world (c) is needed regardless because
820 we enter functions with free vars via the closure.]
822 If (c) is retained, then we'll sometimes generate an info table
823 (for storage mgr purposes) without slow-entry code. Then we need
824 to use an error label in the info table to substitute for the absent
828 staticClosureRequired
833 staticClosureRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
834 (LFReEntrant _ top_level _ _ _ _) -- It's a function
835 = ASSERT( isTopLevel top_level )
836 -- Assumption: it's a top-level, no-free-var binding
837 arg_occ -- There's an argument occurrence
838 || unsat_occ -- There's an unsaturated call
839 || isExternallyVisibleName binder
841 staticClosureRequired binder other_binder_info other_lf_info = True
843 slowFunEntryCodeRequired -- Assumption: it's a function, not a thunk.
848 slowFunEntryCodeRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _) entry_conv
849 = arg_occ -- There's an argument occurrence
850 || unsat_occ -- There's an unsaturated call
851 || isExternallyVisibleName binder
852 || (case entry_conv of { DirectEntry _ _ _ -> False; other -> True })
853 {- The last case deals with the parallel world; a function usually
854 as a DirectEntry convention, but if it doesn't we must generate slow-entry code -}
856 slowFunEntryCodeRequired binder NoStgBinderInfo _ = True
863 funInfoTableRequired binder (StgBinderInfo arg_occ unsat_occ _ _ _)
864 (LFReEntrant _ top_level _ _ _ _)
865 = isNotTopLevel top_level
866 || arg_occ -- There's an argument occurrence
867 || unsat_occ -- There's an unsaturated call
868 || isExternallyVisibleName binder
870 funInfoTableRequired other_binder_info binder other_lf_info = True
873 %************************************************************************
875 \subsection[ClosureInfo-misc-funs]{Misc functions about @ClosureInfo@, etc.}
877 %************************************************************************
881 isStaticClosure :: ClosureInfo -> Bool
882 isStaticClosure (MkClosureInfo _ _ rep) = isStaticRep rep
884 closureName :: ClosureInfo -> Name
885 closureName (MkClosureInfo name _ _) = name
887 closureSMRep :: ClosureInfo -> SMRep
888 closureSMRep (MkClosureInfo _ _ sm_rep) = sm_rep
890 closureLFInfo :: ClosureInfo -> LambdaFormInfo
891 closureLFInfo (MkClosureInfo _ lf_info _) = lf_info
893 closureUpdReqd :: ClosureInfo -> Bool
894 closureUpdReqd (MkClosureInfo _ (LFThunk _ _ _ upd _ _ _) _) = upd
895 closureUpdReqd (MkClosureInfo _ (LFBlackHole _) _) = True
896 -- Black-hole closures are allocated to receive the results of an
897 -- alg case with a named default... so they need to be updated.
898 closureUpdReqd other_closure = False
900 closureSingleEntry :: ClosureInfo -> Bool
901 closureSingleEntry (MkClosureInfo _ (LFThunk _ _ _ upd _ _ _) _) = not upd
902 closureSingleEntry other_closure = False
904 closureReEntrant :: ClosureInfo -> Bool
905 closureReEntrant (MkClosureInfo _ (LFReEntrant _ _ _ _ _ _) _) = True
906 closureReEntrant other_closure = False
910 closureSemiTag :: ClosureInfo -> Maybe Int
911 closureSemiTag (MkClosureInfo _ lf_info _)
913 LFCon data_con _ -> Just (dataConTag data_con - fIRST_TAG)
914 LFTuple _ _ -> Just 0
919 isToplevClosure :: ClosureInfo -> Bool
921 isToplevClosure (MkClosureInfo _ lf_info _)
923 LFReEntrant _ TopLevel _ _ _ _ -> True
924 LFThunk _ TopLevel _ _ _ _ _ -> True
929 isLetNoEscape :: ClosureInfo -> Bool
931 isLetNoEscape (MkClosureInfo _ (LFLetNoEscape _) _) = True
932 isLetNoEscape _ = False
938 fastLabelFromCI :: ClosureInfo -> CLabel
939 fastLabelFromCI (MkClosureInfo name (LFReEntrant _ _ arity _ _ _) _)
940 = mkFastEntryLabel name arity
942 fastLabelFromCI (MkClosureInfo name _ _)
943 = pprPanic "fastLabelFromCI" (ppr name)
945 infoTableLabelFromCI :: ClosureInfo -> CLabel
946 infoTableLabelFromCI (MkClosureInfo id lf_info rep)
948 LFCon con _ -> mkConInfoPtr con rep
949 LFTuple tup _ -> mkConInfoPtr tup rep
951 LFBlackHole info -> info
953 LFThunk _ _ _ upd_flag (SelectorThunk offset) _ _ ->
954 mkSelectorInfoLabel upd_flag offset
956 LFThunk _ _ _ upd_flag (ApThunk arity) _ _ ->
957 mkApInfoTableLabel upd_flag arity
959 other -> {-NO: if isStaticRep rep
960 then mkStaticInfoTableLabel id
961 else -} mkInfoTableLabel id
963 mkConInfoPtr :: DataCon -> SMRep -> CLabel
965 | isStaticRep rep = mkStaticInfoTableLabel name
966 | otherwise = mkConInfoTableLabel name
968 name = dataConName con
970 mkConEntryPtr :: DataCon -> SMRep -> CLabel
971 mkConEntryPtr con rep
972 | isStaticRep rep = mkStaticConEntryLabel (dataConName con)
973 | otherwise = mkConEntryLabel (dataConName con)
975 closureLabelFromCI (MkClosureInfo id _ other_rep) = mkClosureLabel id
977 entryLabelFromCI :: ClosureInfo -> CLabel
978 entryLabelFromCI (MkClosureInfo id lf_info rep)
980 LFThunk _ _ _ upd_flag std_form_info _ _ -> thunkEntryLabel id std_form_info upd_flag
981 LFCon con _ -> mkConEntryPtr con rep
982 LFTuple tup _ -> mkConEntryPtr tup rep
983 other -> mkStdEntryLabel id
985 -- thunkEntryLabel is a local help function, not exported. It's used from both
986 -- entryLabelFromCI and getEntryConvention.
988 thunkEntryLabel thunk_id (ApThunk arity) is_updatable
989 = mkApEntryLabel is_updatable arity
990 thunkEntryLabel thunk_id (SelectorThunk offset) upd_flag
991 = mkSelectorEntryLabel upd_flag offset
992 thunkEntryLabel thunk_id _ is_updatable
993 = mkStdEntryLabel thunk_id
997 allocProfilingMsg :: ClosureInfo -> FAST_STRING
999 allocProfilingMsg (MkClosureInfo _ lf_info _)
1001 LFReEntrant _ _ _ _ _ _ -> SLIT("TICK_ALLOC_FUN")
1002 LFCon _ _ -> SLIT("TICK_ALLOC_CON")
1003 LFTuple _ _ -> SLIT("TICK_ALLOC_CON")
1004 LFThunk _ _ _ True _ _ _ -> SLIT("TICK_ALLOC_UP_THK") -- updatable
1005 LFThunk _ _ _ False _ _ _ -> SLIT("TICK_ALLOC_SE_THK") -- nonupdatable
1006 LFBlackHole _ -> SLIT("TICK_ALLOC_BH")
1007 LFImported -> panic "TICK_ALLOC_IMP"
1010 We need a black-hole closure info to pass to @allocDynClosure@ when we
1011 want to allocate the black hole on entry to a CAF. These are the only
1012 ways to build an LFBlackHole, maintaining the invariant that it really
1013 is a black hole and not something else.
1016 cafBlackHoleClosureInfo (MkClosureInfo name _ _)
1017 = MkClosureInfo name (LFBlackHole mkCAFBlackHoleInfoTableLabel) BlackHoleRep
1019 seCafBlackHoleClosureInfo (MkClosureInfo name _ _)
1020 = MkClosureInfo name (LFBlackHole mkSECAFBlackHoleInfoTableLabel) BlackHoleRep
1023 %************************************************************************
1025 \subsection[ClosureInfo-Profiling-funs]{Misc functions about for profiling info.}
1027 %************************************************************************
1029 Profiling requires two pieces of information to be determined for
1030 each closure's info table --- description and type.
1032 The description is stored directly in the @CClosureInfoTable@ when the
1033 info table is built.
1035 The type is determined from the type information stored with the @Id@
1036 in the closure info using @closureTypeDescr@.
1039 closureTypeDescr :: ClosureInfo -> String
1040 closureTypeDescr (MkClosureInfo name (LFThunk ty _ _ _ _ _ _) _)
1041 = getTyDescription ty
1042 closureTypeDescr (MkClosureInfo name (LFReEntrant ty _ _ _ _ _) _)
1043 = getTyDescription ty
1044 closureTypeDescr (MkClosureInfo name (LFCon data_con _) _)
1045 = occNameUserString (getOccName (dataConTyCon data_con))
1046 closureTypeDescr (MkClosureInfo name lf _)
1047 = showSDoc (ppr name)