%
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
+% (c) The University of Glasgow, 1992-2002
%
\section[CLabel]{@CLabel@: Information to make C Labels}
\begin{code}
-#include "HsVersions.h"
-
module CLabel (
CLabel, -- abstract type
mkClosureLabel,
+ mkSRTLabel,
mkInfoTableLabel,
- mkStdEntryLabel,
- mkFastEntryLabel,
+ mkEntryLabel,
+ mkSlowEntryLabel,
mkConEntryLabel,
mkStaticConEntryLabel,
mkRednCountsLabel,
mkConInfoTableLabel,
- mkPhantomInfoTableLabel,
- mkStaticClosureLabel,
mkStaticInfoTableLabel,
- mkVapEntryLabel,
- mkVapInfoTableLabel,
-
- mkConUpdCodePtrVecLabel,
- mkStdUpdCodePtrVecLabel,
-
- mkInfoTableVecTblLabel,
- mkStdUpdVecTblLabel,
+ mkApEntryLabel,
+ mkApInfoTableLabel,
mkReturnPtLabel,
+ mkReturnInfoLabel,
mkVecTblLabel,
mkAltLabel,
mkDefaultLabel,
+ mkBitmapLabel,
+
+ mkClosureTblLabel,
mkAsmTempLabel,
+ mkModuleInitLabel,
+ mkPlainModuleInitLabel,
+
mkErrorStdEntryLabel,
+
+ mkStgUpdatePAPLabel,
+ mkSplitMarkerLabel,
+ mkUpdInfoLabel,
+ mkSeqInfoLabel,
+ mkIndInfoLabel,
+ mkIndStaticInfoLabel,
+ mkRtsGCEntryLabel,
+ mkMainCapabilityLabel,
+ mkCharlikeClosureLabel,
+ mkIntlikeClosureLabel,
+ mkMAP_FROZEN_infoLabel,
+ mkEMPTY_MVAR_infoLabel,
+
+ mkTopTickyCtrLabel,
mkBlackHoleInfoTableLabel,
+ mkCAFBlackHoleInfoTableLabel,
+ mkSECAFBlackHoleInfoTableLabel,
+ mkRtsPrimOpLabel,
+
+ moduleRegdLabel,
+
+ mkSelectorInfoLabel,
+ mkSelectorEntryLabel,
+
+ mkRtsApplyInfoLabel,
+ mkRtsApplyEntryLabel,
+
+ mkForeignLabel,
- needsCDecl, isReadOnly, isAsmTemp, externallyVisibleCLabel,
+ mkCC_Label, mkCCS_Label,
+
+ needsCDecl, isAsmTemp, externallyVisibleCLabel,
+
+ CLabelType(..), labelType, labelDynamic,
pprCLabel
-#if ! OMIT_NATIVE_CODEGEN
- , pprCLabel_asm
-#endif
) where
-IMP_Ubiq(){-uitous-}
-IMPORT_DELOOPER(AbsCLoop) ( CtrlReturnConvention(..),
- ctrlReturnConvAlg
- )
+
+#include "HsVersions.h"
+
#if ! OMIT_NATIVE_CODEGEN
-IMPORT_DELOOPER(NcgLoop) ( underscorePrefix, fmtAsmLbl )
+import {-# SOURCE #-} MachMisc ( underscorePrefix, fmtAsmLbl )
#endif
+import CmdLineOpts ( opt_Static, opt_DoTickyProfiling )
import CStrings ( pp_cSEP )
-import Id ( externallyVisibleId, cmpId_withSpecDataCon,
- isDataCon, isDictFunId,
- isConstMethodId_maybe,
- isDefaultMethodId_maybe,
- isSuperDictSelId_maybe, fIRST_TAG,
- SYN_IE(ConTag), GenId{-instance Outputable-}
- )
-import Maybes ( maybeToBool )
-import PprStyle ( PprStyle(..) )
-import PprType ( showTyCon, GenType{-instance Outputable-} )
-import Pretty ( prettyToUn{-, ppPStr ToDo:rm-} )
-import TyCon ( TyCon{-instance Eq-} )
-import Unique ( showUnique, pprUnique, Unique{-instance Eq-} )
-import Unpretty -- NOTE!! ********************
-import Util ( assertPanic{-, pprTraceToDo:rm-} )
+import DataCon ( ConTag )
+import Module ( moduleName, moduleNameFS,
+ Module, isHomeModule )
+import Name ( Name, getName, isDllName, isExternalName )
+import TyCon ( TyCon )
+import Unique ( pprUnique, Unique )
+import PrimOp ( PrimOp )
+import CostCentre ( CostCentre, CostCentreStack )
+import Outputable
+import FastString
\end{code}
things we want to find out:
* does it need declarations at all? (v common Prelude things are pre-declared)
+* what type does it have? (for generating accurate enough C declarations
+ so that the C compiler won't complain).
+
\begin{code}
data CLabel
= IdLabel -- A family of labels related to the
- CLabelId -- definition of a particular Id
- IdLabelInfo -- Includes DataCon
+ Name -- definition of a particular Id
+ IdLabelInfo
- | TyConLabel -- A family of labels related to the
- TyCon -- definition of a data type
- TyConLabelInfo
+ | DataConLabel -- Ditto data constructors
+ Name
+ DataConLabelInfo
| CaseLabel -- A family of labels related to a particular case expression
Unique -- Unique says which case expression
CaseLabelInfo
+ | TyConLabel TyCon -- currently only one kind of TyconLabel,
+ -- a 'Closure Table'.
+
| AsmTempLabel Unique
- | RtsLabel RtsLabelInfo
+ | ModuleInitLabel
+ Module -- the module name
+ String -- its "way"
+ -- at some point we might want some kind of version number in
+ -- the module init label, to guard against compiling modules in
+ -- the wrong order. We can't use the interface file version however,
+ -- because we don't always recompile modules which depend on a module
+ -- whose version has changed.
- deriving (Eq, Ord)
-\end{code}
-
-The CLabelId is simply so we can declare alternative Eq and Ord
-instances which use cmpId_SpecDataCon (instead of cmpId). This avoids
-comparing the Uniques of two specialised data constructors (which have
-the same as the uniques their respective unspecialised data
-constructors). Instead, the specialising types and the uniques of the
-unspecialised constructors are compared.
+ | PlainModuleInitLabel Module -- without the vesrion & way info
-\begin{code}
-data CLabelId = CLabelId Id
+ | RtsLabel RtsLabelInfo
-instance Ord3 CLabelId where
- cmp (CLabelId a) (CLabelId b) = cmpId_withSpecDataCon a b
+ | ForeignLabel FastString Bool -- a 'C' (or otherwise foreign) label
+ -- Bool <=> is dynamic
-instance Eq CLabelId where
- CLabelId a == CLabelId b = case (a `cmp` b) of { EQ_ -> True; _ -> False }
- CLabelId a /= CLabelId b = case (a `cmp` b) of { EQ_ -> False; _ -> True }
+ | CC_Label CostCentre
+ | CCS_Label CostCentreStack
-instance Ord CLabelId where
- CLabelId a <= CLabelId b = case (a `cmp` b) of { LT_ -> True; EQ_ -> True; GT__ -> False }
- CLabelId a < CLabelId b = case (a `cmp` b) of { LT_ -> True; EQ_ -> False; GT__ -> False }
- CLabelId a >= CLabelId b = case (a `cmp` b) of { LT_ -> False; EQ_ -> True; GT__ -> True }
- CLabelId a > CLabelId b = case (a `cmp` b) of { LT_ -> False; EQ_ -> False; GT__ -> True }
- _tagCmp (CLabelId a) (CLabelId b) = case (a `cmp` b) of { LT_ -> _LT; EQ_ -> _EQ; GT__ -> _GT }
+ deriving (Eq, Ord)
\end{code}
\begin{code}
data IdLabelInfo
= Closure -- Label for (static???) closure
- | StaticClosure -- Static closure -- e.g., nullary constructor
+ | SRT -- Static reference table
+ | InfoTbl -- Info tables for closures; always read-only
+ | Entry -- entry point
+ | Slow -- slow entry point
- | InfoTbl -- Info table for a closure; always read-only
+ -- Ticky-ticky counting
+ | RednCounts -- Label of place to keep reduction-count info for
+ -- this Id
- | EntryStd -- Thunk, or "slow", code entry point (requires arg satis check)
- | EntryFast Int -- entry pt when no arg satisfaction chk needed;
- -- Int is the arity of the function (to be
- -- encoded into the name)
+ | Bitmap -- A bitmap (function or case return)
- | ConEntry -- the only kind of entry pt for constructors
- | ConInfoTbl -- corresponding info table
+ deriving (Eq, Ord)
+data DataConLabelInfo
+ = ConEntry -- the only kind of entry pt for constructors
+ | ConInfoTbl -- corresponding info table
| StaticConEntry -- static constructor entry point
| StaticInfoTbl -- corresponding info table
-
- | PhantomInfoTbl -- for phantom constructors that only exist in regs
-
- | VapInfoTbl Bool -- True <=> the update-reqd version; False <=> the no-update-reqd version
- | VapEntry Bool
-
- -- Ticky-ticky counting
- | RednCounts -- Label of place to keep reduction-count info for this Id
- deriving (Eq, Ord)
-
-
-data TyConLabelInfo
- = UnvecConUpdCode -- Update code for the data type if it's unvectored
-
- | VecConUpdCode ConTag -- One for each constructor which returns in
- -- regs; this code actually performs an update
-
- | StdUpdCode ConTag -- Update code for all constructors which return
- -- in heap. There are a small number of variants,
- -- so that the update code returns (vectored/n or
- -- unvectored) in the right way.
- -- ToDo: maybe replace TyCon/Int with return conv.
-
- | InfoTblVecTbl -- For tables of info tables
-
- | StdUpdVecTbl -- Labels the update code, or table of update codes,
- -- for a particular type.
deriving (Eq, Ord)
data CaseLabelInfo
= CaseReturnPt
+ | CaseReturnInfo
| CaseVecTbl
| CaseAlt ConTag
| CaseDefault
data RtsLabelInfo
= RtsShouldNeverHappenCode
- | RtsBlackHoleInfoTbl
+ | RtsBlackHoleInfoTbl LitString -- black hole with info table name
+
+ | RtsUpdInfo -- upd_frame_info
+ | RtsSeqInfo -- seq_frame_info
+ | RtsGCEntryLabel String -- a heap check fail handler, eg stg_chk_2
+ | RtsMainCapability -- MainCapability
+ | Rts_Closure String -- misc rts closures, eg CHARLIKE_closure
+ | Rts_Info String -- misc rts itbls, eg MUT_ARR_PTRS_FROZEN_info
+ | Rts_Code String -- misc rts code
+
+ | RtsSelectorInfoTbl Bool{-updatable-} Int{-offset-} -- Selector thunks
+ | RtsSelectorEntry Bool{-updatable-} Int{-offset-}
- | RtsSelectorInfoTbl -- Selectors
- Bool -- True <=> the update-reqd version;
- -- False <=> the no-update-reqd version
- Int -- 0-indexed Offset from the "goods"
+ | RtsApInfoTbl Bool{-updatable-} Int{-arity-} -- AP thunks
+ | RtsApEntry Bool{-updatable-} Int{-arity-}
+
+ | RtsPrimOp PrimOp
+
+ | RtsTopTickyCtr
+
+ | RtsModuleRegd
+
+ | RtsApplyInfoLabel LitString
+ | RtsApplyEntryLabel LitString
- | RtsSelectorEntry -- Ditto entry code
- Bool
- Int
deriving (Eq, Ord)
+
+-- Label Type: for generating C declarations.
+
+data CLabelType
+ = RetInfoTblType
+ | InfoTblType
+ | ClosureType
+ | VecTblType
+ | ClosureTblType
+ | CodeType
+ | DataType
\end{code}
\begin{code}
-mkClosureLabel id = IdLabel (CLabelId id) Closure
-mkInfoTableLabel id = IdLabel (CLabelId id) InfoTbl
-mkStdEntryLabel id = IdLabel (CLabelId id) EntryStd
-mkFastEntryLabel id arity = ASSERT(arity > 0)
- IdLabel (CLabelId id) (EntryFast arity)
-
-mkStaticClosureLabel con = ASSERT(isDataCon con)
- IdLabel (CLabelId con) StaticClosure
-mkStaticInfoTableLabel con = ASSERT(isDataCon con)
- IdLabel (CLabelId con) StaticInfoTbl
-mkConInfoTableLabel con = ASSERT(isDataCon con)
- IdLabel (CLabelId con) ConInfoTbl
-mkPhantomInfoTableLabel con = ASSERT(isDataCon con)
- IdLabel (CLabelId con) PhantomInfoTbl
-mkConEntryLabel con = ASSERT(isDataCon con)
- IdLabel (CLabelId con) ConEntry
-mkStaticConEntryLabel con = ASSERT(isDataCon con)
- IdLabel (CLabelId con) StaticConEntry
-
-mkRednCountsLabel id = IdLabel (CLabelId id) RednCounts
-mkVapEntryLabel id upd_flag = IdLabel (CLabelId id) (VapEntry upd_flag)
-mkVapInfoTableLabel id upd_flag = IdLabel (CLabelId id) (VapInfoTbl upd_flag)
-
-mkConUpdCodePtrVecLabel tycon tag = TyConLabel tycon (VecConUpdCode tag)
-mkStdUpdCodePtrVecLabel tycon tag = TyConLabel tycon (StdUpdCode tag)
-
-mkInfoTableVecTblLabel tycon = TyConLabel tycon InfoTblVecTbl
-mkStdUpdVecTblLabel tycon = TyConLabel tycon StdUpdVecTbl
+mkClosureLabel id = IdLabel id Closure
+mkSRTLabel id = IdLabel id SRT
+mkInfoTableLabel id = IdLabel id InfoTbl
+mkEntryLabel id = IdLabel id Entry
+mkSlowEntryLabel id = IdLabel id Slow
+mkBitmapLabel id = IdLabel id Bitmap
+mkRednCountsLabel id = IdLabel id RednCounts
+
+mkStaticInfoTableLabel con = DataConLabel con StaticInfoTbl
+mkConInfoTableLabel con = DataConLabel con ConInfoTbl
+mkConEntryLabel con = DataConLabel con ConEntry
+mkStaticConEntryLabel con = DataConLabel con StaticConEntry
+
mkReturnPtLabel uniq = CaseLabel uniq CaseReturnPt
+mkReturnInfoLabel uniq = CaseLabel uniq CaseReturnInfo
mkVecTblLabel uniq = CaseLabel uniq CaseVecTbl
mkAltLabel uniq tag = CaseLabel uniq (CaseAlt tag)
mkDefaultLabel uniq = CaseLabel uniq CaseDefault
+
+mkClosureTblLabel tycon = TyConLabel tycon
+
mkAsmTempLabel = AsmTempLabel
+mkModuleInitLabel = ModuleInitLabel
+mkPlainModuleInitLabel = PlainModuleInitLabel
+
-- Some fixed runtime system labels
-mkErrorStdEntryLabel = RtsLabel RtsShouldNeverHappenCode
-mkBlackHoleInfoTableLabel = RtsLabel RtsBlackHoleInfoTbl
+mkErrorStdEntryLabel = RtsLabel RtsShouldNeverHappenCode
+mkStgUpdatePAPLabel = RtsLabel (Rts_Code "stg_update_PAP")
+mkSplitMarkerLabel = RtsLabel (Rts_Code "__stg_split_marker")
+mkUpdInfoLabel = RtsLabel RtsUpdInfo
+mkSeqInfoLabel = RtsLabel RtsSeqInfo
+mkIndInfoLabel = RtsLabel (Rts_Info "stg_IND_info")
+mkIndStaticInfoLabel = RtsLabel (Rts_Info "stg_IND_STATIC_info")
+mkRtsGCEntryLabel str = RtsLabel (RtsGCEntryLabel str)
+mkMainCapabilityLabel = RtsLabel RtsMainCapability
+mkCharlikeClosureLabel = RtsLabel (Rts_Closure "stg_CHARLIKE_closure")
+mkIntlikeClosureLabel = RtsLabel (Rts_Closure "stg_INTLIKE_closure")
+mkMAP_FROZEN_infoLabel = RtsLabel (Rts_Info "stg_MUT_ARR_PTRS_FROZEN_info")
+mkEMPTY_MVAR_infoLabel = RtsLabel (Rts_Info "stg_EMPTY_MVAR_info")
+
+mkTopTickyCtrLabel = RtsLabel RtsTopTickyCtr
+mkBlackHoleInfoTableLabel = RtsLabel (RtsBlackHoleInfoTbl SLIT("stg_BLACKHOLE_info"))
+mkCAFBlackHoleInfoTableLabel = RtsLabel (RtsBlackHoleInfoTbl SLIT("stg_CAF_BLACKHOLE_info"))
+mkSECAFBlackHoleInfoTableLabel = if opt_DoTickyProfiling then
+ RtsLabel (RtsBlackHoleInfoTbl SLIT("stg_SE_CAF_BLACKHOLE_info"))
+ else -- RTS won't have info table unless -ticky is on
+ panic "mkSECAFBlackHoleInfoTableLabel requires -ticky"
+mkRtsPrimOpLabel primop = RtsLabel (RtsPrimOp primop)
+
+moduleRegdLabel = RtsLabel RtsModuleRegd
+
+mkSelectorInfoLabel upd off = RtsLabel (RtsSelectorInfoTbl upd off)
+mkSelectorEntryLabel upd off = RtsLabel (RtsSelectorEntry upd off)
+
+mkApInfoTableLabel upd off = RtsLabel (RtsApInfoTbl upd off)
+mkApEntryLabel upd off = RtsLabel (RtsApEntry upd off)
+
+ -- Foreign labels
+
+mkForeignLabel :: FastString -> Bool -> CLabel
+mkForeignLabel str is_dynamic = ForeignLabel str is_dynamic
+
+ -- Cost centres etc.
+
+mkCC_Label cc = CC_Label cc
+mkCCS_Label ccs = CCS_Label ccs
+
+-- Std RTS application routines
+
+mkRtsApplyInfoLabel = RtsLabel . RtsApplyInfoLabel
+mkRtsApplyEntryLabel = RtsLabel . RtsApplyEntryLabel
\end{code}
\begin{code}
needsCDecl :: CLabel -> Bool -- False <=> it's pre-declared; don't bother
-isReadOnly :: CLabel -> Bool -- lives in C "text space"
isAsmTemp :: CLabel -> Bool -- is a local temporary for native code generation
externallyVisibleCLabel :: CLabel -> Bool -- not C "static"
\end{code}
Declarations for (non-prelude) @Id@-based things are needed because of
mutual recursion.
-\begin{code}
-needsCDecl (IdLabel _ _) = True
-needsCDecl (CaseLabel _ _) = False
-
-needsCDecl (TyConLabel _ (StdUpdCode _)) = False
-needsCDecl (TyConLabel _ InfoTblVecTbl) = False
-needsCDecl (TyConLabel _ other) = True
-needsCDecl (AsmTempLabel _) = False
-needsCDecl (RtsLabel _) = False
+Declarations for direct return points are needed, because they may be
+let-no-escapes, which can be recursive.
-needsCDecl other = True
-\end{code}
-
-Whether the labelled thing can be put in C "text space":
\begin{code}
-isReadOnly (IdLabel _ InfoTbl) = True -- info-tables: yes
-isReadOnly (IdLabel _ ConInfoTbl) = True -- and so on, for other
-isReadOnly (IdLabel _ StaticInfoTbl) = True
-isReadOnly (IdLabel _ PhantomInfoTbl) = True
-isReadOnly (IdLabel _ (VapInfoTbl _)) = True
-isReadOnly (IdLabel _ other) = False -- others: pessimistically, no
-
-isReadOnly (TyConLabel _ _) = True
-isReadOnly (CaseLabel _ _) = True
-isReadOnly (AsmTempLabel _) = True
-isReadOnly (RtsLabel _) = True
+ -- don't bother declaring SRT & Bitmap labels, we always make sure
+ -- they are defined before use.
+needsCDecl (IdLabel _ SRT) = False
+needsCDecl (IdLabel _ Bitmap) = False
+needsCDecl (IdLabel _ _) = True
+needsCDecl (CaseLabel _ CaseReturnPt) = True
+needsCDecl (DataConLabel _ _) = True
+needsCDecl (TyConLabel _) = True
+needsCDecl (ModuleInitLabel _ _) = True
+needsCDecl (PlainModuleInitLabel _) = True
+
+needsCDecl (CaseLabel _ _) = False
+needsCDecl (AsmTempLabel _) = False
+needsCDecl (RtsLabel _) = False
+needsCDecl (ForeignLabel _ _) = False
+needsCDecl (CC_Label _) = False
+needsCDecl (CCS_Label _) = False
\end{code}
Whether the label is an assembler temporary:
+
\begin{code}
isAsmTemp (AsmTempLabel _) = True
isAsmTemp _ = False
\end{code}
C ``static'' or not...
+From the point of view of the code generator, a name is
+externally visible if it has to be declared as exported
+in the .o file's symbol table; that is, made non-static.
+
+\begin{code}
+externallyVisibleCLabel (DataConLabel _ _) = True
+externallyVisibleCLabel (TyConLabel tc) = True
+externallyVisibleCLabel (CaseLabel _ _) = False
+externallyVisibleCLabel (AsmTempLabel _) = False
+externallyVisibleCLabel (ModuleInitLabel _ _)= True
+externallyVisibleCLabel (PlainModuleInitLabel _)= True
+externallyVisibleCLabel (RtsLabel RtsModuleRegd) = False --hack
+externallyVisibleCLabel (RtsLabel _) = True
+externallyVisibleCLabel (ForeignLabel _ _) = True
+externallyVisibleCLabel (IdLabel id _) = isExternalName id
+externallyVisibleCLabel (CC_Label _) = False -- not strictly true
+externallyVisibleCLabel (CCS_Label _) = False -- not strictly true
+\end{code}
+
+For generating correct types in label declarations, and also for
+deciding whether the C compiler would like us to use '&' before the
+label to get its address:
+
\begin{code}
-externallyVisibleCLabel (TyConLabel tc _) = True
-externallyVisibleCLabel (CaseLabel _ _) = False
-externallyVisibleCLabel (AsmTempLabel _) = False
-externallyVisibleCLabel (RtsLabel _) = True
-externallyVisibleCLabel (IdLabel (CLabelId id) _)
- | isDataCon id = True
- | is_ConstMethodId id = True -- These are here to ensure splitting works
- | isDictFunId id = True -- when these values have not been exported
- | is_DefaultMethodId id = True
- | is_SuperDictSelId id = True
- | otherwise = externallyVisibleId id
- where
- is_ConstMethodId id = maybeToBool (isConstMethodId_maybe id)
- is_DefaultMethodId id = maybeToBool (isDefaultMethodId_maybe id)
- is_SuperDictSelId id = maybeToBool (isSuperDictSelId_maybe id)
+labelType :: CLabel -> CLabelType
+labelType (RtsLabel (RtsBlackHoleInfoTbl _)) = InfoTblType
+labelType (RtsLabel (RtsSelectorInfoTbl _ _)) = InfoTblType
+labelType (RtsLabel (RtsApInfoTbl _ _)) = InfoTblType
+labelType (RtsLabel RtsUpdInfo) = RetInfoTblType
+labelType (RtsLabel RtsSeqInfo) = RetInfoTblType
+labelType (RtsLabel RtsTopTickyCtr) = CodeType -- XXX
+labelType (RtsLabel (Rts_Info _)) = InfoTblType
+labelType (RtsLabel (RtsApplyInfoLabel _)) = RetInfoTblType
+labelType (RtsLabel (RtsApplyEntryLabel _)) = CodeType
+labelType (CaseLabel _ CaseReturnInfo) = RetInfoTblType
+labelType (CaseLabel _ CaseReturnPt) = CodeType
+labelType (CaseLabel _ CaseVecTbl) = VecTblType
+labelType (TyConLabel _) = ClosureTblType
+labelType (ModuleInitLabel _ _) = CodeType
+labelType (PlainModuleInitLabel _) = CodeType
+labelType (CC_Label _) = CodeType -- hack
+labelType (CCS_Label _) = CodeType -- hack
+
+labelType (IdLabel _ info) =
+ case info of
+ InfoTbl -> InfoTblType
+ Closure -> ClosureType
+ Bitmap -> DataType
+ _ -> CodeType
+
+labelType (DataConLabel _ info) =
+ case info of
+ ConInfoTbl -> InfoTblType
+ StaticInfoTbl -> InfoTblType
+ _ -> CodeType
+
+labelType _ = DataType
\end{code}
+When referring to data in code, we need to know whether
+that data resides in a DLL or not. [Win32 only.]
+@labelDynamic@ returns @True@ if the label is located
+in a DLL, be it a data reference or not.
+
+\begin{code}
+labelDynamic :: CLabel -> Bool
+labelDynamic lbl =
+ case lbl of
+ -- The special case for RtsShouldNeverHappenCode is because the associated address is
+ -- NULL, i.e. not a DLL entry point
+ RtsLabel RtsShouldNeverHappenCode -> False
+ RtsLabel _ -> not opt_Static -- i.e., is the RTS in a DLL or not?
+ IdLabel n k -> isDllName n
+ DataConLabel n k -> isDllName n
+ TyConLabel tc -> isDllName (getName tc)
+ ForeignLabel _ d -> d
+ ModuleInitLabel m _ -> (not opt_Static) && (not (isHomeModule m))
+ PlainModuleInitLabel m -> (not opt_Static) && (not (isHomeModule m))
+ _ -> False
+\end{code}
+
+
OLD?: These GRAN functions are needed for spitting out GRAN_FETCH() at the
right places. It is used to detect when the abstractC statement of an
CCodeBlock actually contains the code for a slow entry point. -- HWL
duplicate declarations in generating C (see @labelSeenTE@ in
@PprAbsC@).
+-----------------------------------------------------------------------------
+Printing out CLabels.
+
+Convention:
+
+ <name>_<type>
+
+where <name> is <Module>_<name> for external names and <unique> for
+internal names. <type> is one of the following:
+
+ info Info table
+ srt Static reference table
+ entry Entry code
+ slow Slow entry code (if any)
+ ret Direct return address
+ vtbl Vector table
+ <n>_alt Case alternative (tag n)
+ dflt Default case alternative
+ btm Large bitmap vector
+ closure Static closure
+ con_entry Dynamic Constructor entry code
+ con_info Dynamic Constructor info table
+ static_entry Static Constructor entry code
+ static_info Static Constructor info table
+ sel_info Selector info table
+ sel_entry Selector entry code
+ cc Cost centre
+ ccs Cost centre stack
+
\begin{code}
--- specialised for PprAsm: saves lots of arg passing in NCG
+pprCLabel :: CLabel -> SDoc
+
#if ! OMIT_NATIVE_CODEGEN
-pprCLabel_asm = pprCLabel (PprForAsm underscorePrefix fmtAsmLbl)
+pprCLabel (AsmTempLabel u)
+ = text (fmtAsmLbl (show u))
#endif
-pprCLabel :: PprStyle -> CLabel -> Unpretty
-
-pprCLabel (PprForAsm _ fmtAsmLbl) (AsmTempLabel u)
- = uppStr (fmtAsmLbl (_UNPK_ (showUnique u)))
-
-pprCLabel (PprForAsm prepend_cSEP _) lbl
- = if prepend_cSEP
- then uppBeside pp_cSEP prLbl
- else prLbl
- where
- prLbl = pprCLabel PprForC lbl
-
-pprCLabel sty (TyConLabel tc UnvecConUpdCode)
- = uppBesides [uppPStr SLIT("ret"), pp_cSEP, ppr_tycon sty tc,
- pp_cSEP, uppPStr SLIT("upd")]
-
-pprCLabel sty (TyConLabel tc (VecConUpdCode tag))
- = uppBesides [uppPStr SLIT("ret"), pp_cSEP, ppr_tycon sty tc, pp_cSEP,
- uppInt tag, pp_cSEP, uppPStr SLIT("upd")]
-
-pprCLabel sty (TyConLabel tc (StdUpdCode tag))
- = case (ctrlReturnConvAlg tc) of
- UnvectoredReturn _ -> uppPStr SLIT("IndUpdRetDir")
- VectoredReturn _ -> uppBeside (uppPStr SLIT("IndUpdRetV")) (uppInt (tag - fIRST_TAG))
-
-pprCLabel sty (TyConLabel tc InfoTblVecTbl)
- = uppBesides [ppr_tycon sty tc, pp_cSEP, uppPStr SLIT("itblvtbl")]
-
-pprCLabel sty (TyConLabel tc StdUpdVecTbl)
- = uppBesides [uppPStr SLIT("vtbl"), pp_cSEP, ppr_tycon sty tc,
- pp_cSEP, uppPStr SLIT("upd")]
-
-pprCLabel sty (CaseLabel u CaseReturnPt)
- = uppBesides [uppPStr SLIT("ret"), pp_cSEP, ppr_u u]
-pprCLabel sty (CaseLabel u CaseVecTbl)
- = uppBesides [uppPStr SLIT("vtbl"), pp_cSEP, ppr_u u]
-pprCLabel sty (CaseLabel u (CaseAlt tag))
- = uppBesides [uppPStr SLIT("djn"), pp_cSEP, ppr_u u, pp_cSEP, uppInt tag]
-pprCLabel sty (CaseLabel u CaseDefault)
- = uppBesides [uppPStr SLIT("djn"), pp_cSEP, ppr_u u]
-
-pprCLabel sty (RtsLabel RtsShouldNeverHappenCode) = uppPStr SLIT("StdErrorCode")
-
-pprCLabel sty (RtsLabel RtsBlackHoleInfoTbl) = uppPStr SLIT("BH_UPD_info")
-
-pprCLabel sty (RtsLabel (RtsSelectorInfoTbl upd_reqd offset))
- = uppBesides [uppPStr SLIT("__sel_info_"), uppStr (show offset),
- uppStr (if upd_reqd then "upd" else "noupd"),
- uppPStr SLIT("__")]
-
-pprCLabel sty (RtsLabel (RtsSelectorEntry upd_reqd offset))
- = uppBesides [uppPStr SLIT("__sel_entry_"), uppStr (show offset),
- uppStr (if upd_reqd then "upd" else "noupd"),
- uppPStr SLIT("__")]
-
-pprCLabel sty (IdLabel (CLabelId id) flavor)
- = uppBeside (prettyToUn (ppr sty id)) (ppFlavor flavor)
-
-ppr_u u = prettyToUn (pprUnique u)
-
-ppr_tycon sty tc
- = let
- str = showTyCon sty tc
- in
- --pprTrace "ppr_tycon:" (ppStr str) $
- uppStr str
-
-ppFlavor :: IdLabelInfo -> Unpretty
-
-ppFlavor x = uppBeside pp_cSEP
- (case x of
- Closure -> uppPStr SLIT("closure")
- InfoTbl -> uppPStr SLIT("info")
- EntryStd -> uppPStr SLIT("entry")
- EntryFast arity -> --false:ASSERT (arity > 0)
- uppBeside (uppPStr SLIT("fast")) (uppInt arity)
- StaticClosure -> uppPStr SLIT("static_closure")
- ConEntry -> uppPStr SLIT("con_entry")
- ConInfoTbl -> uppPStr SLIT("con_info")
- StaticConEntry -> uppPStr SLIT("static_entry")
- StaticInfoTbl -> uppPStr SLIT("static_info")
- PhantomInfoTbl -> uppPStr SLIT("inregs_info")
- VapInfoTbl True -> uppPStr SLIT("vap_info")
- VapInfoTbl False -> uppPStr SLIT("vap_noupd_info")
- VapEntry True -> uppPStr SLIT("vap_entry")
- VapEntry False -> uppPStr SLIT("vap_noupd_entry")
- RednCounts -> uppPStr SLIT("ct")
+pprCLabel lbl =
+#if ! OMIT_NATIVE_CODEGEN
+ getPprStyle $ \ sty ->
+ if asmStyle sty && underscorePrefix then
+ pp_cSEP <> pprCLbl lbl
+ else
+#endif
+ pprCLbl lbl
+
+pprCLbl (CaseLabel u CaseReturnPt)
+ = hcat [pprUnique u, pp_cSEP, ptext SLIT("ret")]
+pprCLbl (CaseLabel u CaseReturnInfo)
+ = hcat [pprUnique u, pp_cSEP, ptext SLIT("info")]
+pprCLbl (CaseLabel u CaseVecTbl)
+ = hcat [pprUnique u, pp_cSEP, ptext SLIT("vtbl")]
+pprCLbl (CaseLabel u (CaseAlt tag))
+ = hcat [pprUnique u, pp_cSEP, int tag, pp_cSEP, ptext SLIT("alt")]
+pprCLbl (CaseLabel u CaseDefault)
+ = hcat [pprUnique u, pp_cSEP, ptext SLIT("dflt")]
+
+pprCLbl (RtsLabel RtsShouldNeverHappenCode) = ptext SLIT("NULL")
+-- used to be stg_error_entry but Windows can't have DLL entry points as static
+-- initialisers, and besides, this ShouldNeverHappen, right?
+
+pprCLbl (RtsLabel RtsUpdInfo) = ptext SLIT("stg_upd_frame_info")
+pprCLbl (RtsLabel RtsSeqInfo) = ptext SLIT("stg_seq_frame_info")
+pprCLbl (RtsLabel RtsMainCapability) = ptext SLIT("MainCapability")
+pprCLbl (RtsLabel (RtsGCEntryLabel str)) = text str
+pprCLbl (RtsLabel (Rts_Closure str)) = text str
+pprCLbl (RtsLabel (Rts_Info str)) = text str
+pprCLbl (RtsLabel (Rts_Code str)) = text str
+
+pprCLbl (RtsLabel RtsTopTickyCtr) = ptext SLIT("top_ct")
+
+pprCLbl (RtsLabel (RtsBlackHoleInfoTbl info)) = ptext info
+
+pprCLbl (RtsLabel (RtsSelectorInfoTbl upd_reqd offset))
+ = hcat [ptext SLIT("stg_sel_"), text (show offset),
+ ptext (if upd_reqd
+ then SLIT("_upd_info")
+ else SLIT("_noupd_info"))
+ ]
+
+pprCLbl (RtsLabel (RtsSelectorEntry upd_reqd offset))
+ = hcat [ptext SLIT("stg_sel_"), text (show offset),
+ ptext (if upd_reqd
+ then SLIT("_upd_entry")
+ else SLIT("_noupd_entry"))
+ ]
+
+pprCLbl (RtsLabel (RtsApInfoTbl upd_reqd arity))
+ = hcat [ptext SLIT("stg_ap_"), text (show arity),
+ ptext (if upd_reqd
+ then SLIT("_upd_info")
+ else SLIT("_noupd_info"))
+ ]
+
+pprCLbl (RtsLabel (RtsApEntry upd_reqd arity))
+ = hcat [ptext SLIT("stg_ap_"), text (show arity),
+ ptext (if upd_reqd
+ then SLIT("_upd_entry")
+ else SLIT("_noupd_entry"))
+ ]
+
+pprCLbl (RtsLabel (RtsApplyInfoLabel fs))
+ = ptext SLIT("stg_ap_") <> ptext fs <> ptext SLIT("_info")
+
+pprCLbl (RtsLabel (RtsApplyEntryLabel fs))
+ = ptext SLIT("stg_ap_") <> ptext fs <> ptext SLIT("_ret")
+
+pprCLbl (RtsLabel (RtsPrimOp primop))
+ = ppr primop <> ptext SLIT("_fast")
+
+pprCLbl (RtsLabel RtsModuleRegd)
+ = ptext SLIT("module_registered")
+
+pprCLbl (ForeignLabel str _)
+ = ftext str
+
+pprCLbl (TyConLabel tc)
+ = hcat [ppr tc, pp_cSEP, ptext SLIT("closure_tbl")]
+
+pprCLbl (IdLabel id flavor) = ppr id <> ppIdFlavor flavor
+pprCLbl (DataConLabel con flavor) = ppr con <> ppConFlavor flavor
+
+pprCLbl (CC_Label cc) = ppr cc
+pprCLbl (CCS_Label ccs) = ppr ccs
+
+pprCLbl (ModuleInitLabel mod way)
+ = ptext SLIT("__stginit_") <> ftext (moduleNameFS (moduleName mod))
+ <> char '_' <> text way
+
+pprCLbl (PlainModuleInitLabel mod)
+ = ptext SLIT("__stginit_") <> ftext (moduleNameFS (moduleName mod))
+
+ppIdFlavor :: IdLabelInfo -> SDoc
+
+ppIdFlavor x = pp_cSEP <>
+ (case x of
+ Closure -> ptext SLIT("closure")
+ SRT -> ptext SLIT("srt")
+ InfoTbl -> ptext SLIT("info")
+ Entry -> ptext SLIT("entry")
+ Slow -> ptext SLIT("slow")
+ RednCounts -> ptext SLIT("ct")
+ Bitmap -> ptext SLIT("btm")
)
+
+ppConFlavor x = pp_cSEP <>
+ (case x of
+ ConEntry -> ptext SLIT("con_entry")
+ ConInfoTbl -> ptext SLIT("con_info")
+ StaticConEntry -> ptext SLIT("static_entry")
+ StaticInfoTbl -> ptext SLIT("static_info")
+ )
\end{code}