summaryrefslogtreecommitdiff
path: root/compiler/cmm/CLabel.hs
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2020-01-07 02:44:39 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-01-25 05:22:20 -0500
commit6e2d9ee25bce06ae51d2f1cf8df4f7422106a383 (patch)
tree4bb0aa9527bc0bed4fb2e991eb02d0f031d514bf /compiler/cmm/CLabel.hs
parentc3fde723633d1788e4ded8c6f59eb7cef1ae95fd (diff)
downloadhaskell-6e2d9ee25bce06ae51d2f1cf8df4f7422106a383.tar.gz
Module hierarchy: Cmm (cf #13009)
Diffstat (limited to 'compiler/cmm/CLabel.hs')
-rw-r--r--compiler/cmm/CLabel.hs1571
1 files changed, 0 insertions, 1571 deletions
diff --git a/compiler/cmm/CLabel.hs b/compiler/cmm/CLabel.hs
deleted file mode 100644
index fb2f06716d..0000000000
--- a/compiler/cmm/CLabel.hs
+++ /dev/null
@@ -1,1571 +0,0 @@
------------------------------------------------------------------------------
---
--- Object-file symbols (called CLabel for histerical raisins).
---
--- (c) The University of Glasgow 2004-2006
---
------------------------------------------------------------------------------
-
-{-# LANGUAGE CPP #-}
-
-module CLabel (
- CLabel, -- abstract type
- ForeignLabelSource(..),
- pprDebugCLabel,
-
- mkClosureLabel,
- mkSRTLabel,
- mkInfoTableLabel,
- mkEntryLabel,
- mkRednCountsLabel,
- mkConInfoTableLabel,
- mkApEntryLabel,
- mkApInfoTableLabel,
- mkClosureTableLabel,
- mkBytesLabel,
-
- mkLocalBlockLabel,
- mkLocalClosureLabel,
- mkLocalInfoTableLabel,
- mkLocalClosureTableLabel,
-
- mkBlockInfoTableLabel,
-
- mkBitmapLabel,
- mkStringLitLabel,
-
- mkAsmTempLabel,
- mkAsmTempDerivedLabel,
- mkAsmTempEndLabel,
- mkAsmTempDieLabel,
-
- mkDirty_MUT_VAR_Label,
- mkNonmovingWriteBarrierEnabledLabel,
- mkUpdInfoLabel,
- mkBHUpdInfoLabel,
- mkIndStaticInfoLabel,
- mkMainCapabilityLabel,
- mkMAP_FROZEN_CLEAN_infoLabel,
- mkMAP_FROZEN_DIRTY_infoLabel,
- mkMAP_DIRTY_infoLabel,
- mkSMAP_FROZEN_CLEAN_infoLabel,
- mkSMAP_FROZEN_DIRTY_infoLabel,
- mkSMAP_DIRTY_infoLabel,
- mkBadAlignmentLabel,
- mkArrWords_infoLabel,
- mkSRTInfoLabel,
-
- mkTopTickyCtrLabel,
- mkCAFBlackHoleInfoTableLabel,
- mkRtsPrimOpLabel,
- mkRtsSlowFastTickyCtrLabel,
-
- mkSelectorInfoLabel,
- mkSelectorEntryLabel,
-
- mkCmmInfoLabel,
- mkCmmEntryLabel,
- mkCmmRetInfoLabel,
- mkCmmRetLabel,
- mkCmmCodeLabel,
- mkCmmDataLabel,
- mkCmmClosureLabel,
-
- mkRtsApFastLabel,
-
- mkPrimCallLabel,
-
- mkForeignLabel,
- addLabelSize,
-
- foreignLabelStdcallInfo,
- isBytesLabel,
- isForeignLabel,
- isSomeRODataLabel,
- isStaticClosureLabel,
- mkCCLabel, mkCCSLabel,
-
- DynamicLinkerLabelInfo(..),
- mkDynamicLinkerLabel,
- dynamicLinkerLabelInfo,
-
- mkPicBaseLabel,
- mkDeadStripPreventer,
-
- mkHpcTicksLabel,
-
- -- * Predicates
- hasCAF,
- needsCDecl, maybeLocalBlockLabel, externallyVisibleCLabel,
- isMathFun,
- isCFunctionLabel, isGcPtrLabel, labelDynamic,
- isLocalCLabel, mayRedirectTo,
-
- -- * Conversions
- toClosureLbl, toSlowEntryLbl, toEntryLbl, toInfoLbl, hasHaskellName,
-
- pprCLabel,
- isInfoTableLabel,
- isConInfoTableLabel
- ) where
-
-#include "HsVersions.h"
-
-import GhcPrelude
-
-import IdInfo
-import BasicTypes
-import {-# SOURCE #-} BlockId (BlockId, mkBlockId)
-import Packages
-import Module
-import Name
-import Unique
-import PrimOp
-import CostCentre
-import Outputable
-import FastString
-import DynFlags
-import GHC.Platform
-import UniqSet
-import Util
-import PprCore ( {- instances -} )
-
--- -----------------------------------------------------------------------------
--- The CLabel type
-
-{- |
- 'CLabel' is an abstract type that supports the following operations:
-
- - Pretty printing
-
- - In a C file, does it need to be declared before use? (i.e. is it
- guaranteed to be already in scope in the places we need to refer to it?)
-
- - If it needs to be declared, what type (code or data) should it be
- declared to have?
-
- - Is it visible outside this object file or not?
-
- - Is it "dynamic" (see details below)
-
- - Eq and Ord, so that we can make sets of CLabels (currently only
- used in outputting C as far as I can tell, to avoid generating
- more than one declaration for any given label).
-
- - Converting an info table label into an entry label.
-
- CLabel usage is a bit messy in GHC as they are used in a number of different
- contexts:
-
- - By the C-- AST to identify labels
-
- - By the unregisterised C code generator ("PprC") for naming functions (hence
- the name 'CLabel')
-
- - By the native and LLVM code generators to identify labels
-
- For extra fun, each of these uses a slightly different subset of constructors
- (e.g. 'AsmTempLabel' and 'AsmTempDerivedLabel' are used only in the NCG and
- LLVM backends).
-
- In general, we use 'IdLabel' to represent Haskell things early in the
- pipeline. However, later optimization passes will often represent blocks they
- create with 'LocalBlockLabel' where there is no obvious 'Name' to hang off the
- label.
--}
-
-data CLabel
- = -- | A label related to the definition of a particular Id or Con in a .hs file.
- IdLabel
- Name
- CafInfo
- IdLabelInfo -- encodes the suffix of the label
-
- -- | A label from a .cmm file that is not associated with a .hs level Id.
- | CmmLabel
- UnitId -- what package the label belongs to.
- FastString -- identifier giving the prefix of the label
- CmmLabelInfo -- encodes the suffix of the label
-
- -- | A label with a baked-in \/ algorithmically generated name that definitely
- -- comes from the RTS. The code for it must compile into libHSrts.a \/ libHSrts.so
- -- If it doesn't have an algorithmically generated name then use a CmmLabel
- -- instead and give it an appropriate UnitId argument.
- | RtsLabel
- RtsLabelInfo
-
- -- | A label associated with a block. These aren't visible outside of the
- -- compilation unit in which they are defined. These are generally used to
- -- name blocks produced by Cmm-to-Cmm passes and the native code generator,
- -- where we don't have a 'Name' to associate the label to and therefore can't
- -- use 'IdLabel'.
- | LocalBlockLabel
- {-# UNPACK #-} !Unique
-
- -- | A 'C' (or otherwise foreign) label.
- --
- | ForeignLabel
- FastString -- name of the imported label.
-
- (Maybe Int) -- possible '@n' suffix for stdcall functions
- -- When generating C, the '@n' suffix is omitted, but when
- -- generating assembler we must add it to the label.
-
- ForeignLabelSource -- what package the foreign label is in.
-
- FunctionOrData
-
- -- | Local temporary label used for native (or LLVM) code generation; must not
- -- appear outside of these contexts. Use primarily for debug information
- | AsmTempLabel
- {-# UNPACK #-} !Unique
-
- -- | A label \"derived\" from another 'CLabel' by the addition of a suffix.
- -- Must not occur outside of the NCG or LLVM code generators.
- | AsmTempDerivedLabel
- CLabel
- FastString -- suffix
-
- | StringLitLabel
- {-# UNPACK #-} !Unique
-
- | CC_Label CostCentre
- | CCS_Label CostCentreStack
-
-
- -- | These labels are generated and used inside the NCG only.
- -- They are special variants of a label used for dynamic linking
- -- see module PositionIndependentCode for details.
- | DynamicLinkerLabel DynamicLinkerLabelInfo CLabel
-
- -- | This label is generated and used inside the NCG only.
- -- It is used as a base for PIC calculations on some platforms.
- -- It takes the form of a local numeric assembler label '1'; and
- -- is pretty-printed as 1b, referring to the previous definition
- -- of 1: in the assembler source file.
- | PicBaseLabel
-
- -- | A label before an info table to prevent excessive dead-stripping on darwin
- | DeadStripPreventer CLabel
-
-
- -- | Per-module table of tick locations
- | HpcTicksLabel Module
-
- -- | Static reference table
- | SRTLabel
- {-# UNPACK #-} !Unique
-
- -- | A bitmap (function or case return)
- | LargeBitmapLabel
- {-# UNPACK #-} !Unique
-
- deriving Eq
-
--- This is laborious, but necessary. We can't derive Ord because
--- Unique doesn't have an Ord instance. Note nonDetCmpUnique in the
--- implementation. See Note [No Ord for Unique]
--- This is non-deterministic but we do not currently support deterministic
--- code-generation. See Note [Unique Determinism and code generation]
-instance Ord CLabel where
- compare (IdLabel a1 b1 c1) (IdLabel a2 b2 c2) =
- compare a1 a2 `thenCmp`
- compare b1 b2 `thenCmp`
- compare c1 c2
- compare (CmmLabel a1 b1 c1) (CmmLabel a2 b2 c2) =
- compare a1 a2 `thenCmp`
- compare b1 b2 `thenCmp`
- compare c1 c2
- compare (RtsLabel a1) (RtsLabel a2) = compare a1 a2
- compare (LocalBlockLabel u1) (LocalBlockLabel u2) = nonDetCmpUnique u1 u2
- compare (ForeignLabel a1 b1 c1 d1) (ForeignLabel a2 b2 c2 d2) =
- compare a1 a2 `thenCmp`
- compare b1 b2 `thenCmp`
- compare c1 c2 `thenCmp`
- compare d1 d2
- compare (AsmTempLabel u1) (AsmTempLabel u2) = nonDetCmpUnique u1 u2
- compare (AsmTempDerivedLabel a1 b1) (AsmTempDerivedLabel a2 b2) =
- compare a1 a2 `thenCmp`
- compare b1 b2
- compare (StringLitLabel u1) (StringLitLabel u2) =
- nonDetCmpUnique u1 u2
- compare (CC_Label a1) (CC_Label a2) =
- compare a1 a2
- compare (CCS_Label a1) (CCS_Label a2) =
- compare a1 a2
- compare (DynamicLinkerLabel a1 b1) (DynamicLinkerLabel a2 b2) =
- compare a1 a2 `thenCmp`
- compare b1 b2
- compare PicBaseLabel PicBaseLabel = EQ
- compare (DeadStripPreventer a1) (DeadStripPreventer a2) =
- compare a1 a2
- compare (HpcTicksLabel a1) (HpcTicksLabel a2) =
- compare a1 a2
- compare (SRTLabel u1) (SRTLabel u2) =
- nonDetCmpUnique u1 u2
- compare (LargeBitmapLabel u1) (LargeBitmapLabel u2) =
- nonDetCmpUnique u1 u2
- compare IdLabel{} _ = LT
- compare _ IdLabel{} = GT
- compare CmmLabel{} _ = LT
- compare _ CmmLabel{} = GT
- compare RtsLabel{} _ = LT
- compare _ RtsLabel{} = GT
- compare LocalBlockLabel{} _ = LT
- compare _ LocalBlockLabel{} = GT
- compare ForeignLabel{} _ = LT
- compare _ ForeignLabel{} = GT
- compare AsmTempLabel{} _ = LT
- compare _ AsmTempLabel{} = GT
- compare AsmTempDerivedLabel{} _ = LT
- compare _ AsmTempDerivedLabel{} = GT
- compare StringLitLabel{} _ = LT
- compare _ StringLitLabel{} = GT
- compare CC_Label{} _ = LT
- compare _ CC_Label{} = GT
- compare CCS_Label{} _ = LT
- compare _ CCS_Label{} = GT
- compare DynamicLinkerLabel{} _ = LT
- compare _ DynamicLinkerLabel{} = GT
- compare PicBaseLabel{} _ = LT
- compare _ PicBaseLabel{} = GT
- compare DeadStripPreventer{} _ = LT
- compare _ DeadStripPreventer{} = GT
- compare HpcTicksLabel{} _ = LT
- compare _ HpcTicksLabel{} = GT
- compare SRTLabel{} _ = LT
- compare _ SRTLabel{} = GT
-
--- | Record where a foreign label is stored.
-data ForeignLabelSource
-
- -- | Label is in a named package
- = ForeignLabelInPackage UnitId
-
- -- | Label is in some external, system package that doesn't also
- -- contain compiled Haskell code, and is not associated with any .hi files.
- -- We don't have to worry about Haskell code being inlined from
- -- external packages. It is safe to treat the RTS package as "external".
- | ForeignLabelInExternalPackage
-
- -- | Label is in the package currently being compiled.
- -- This is only used for creating hacky tmp labels during code generation.
- -- Don't use it in any code that might be inlined across a package boundary
- -- (ie, core code) else the information will be wrong relative to the
- -- destination module.
- | ForeignLabelInThisPackage
-
- deriving (Eq, Ord)
-
-
--- | For debugging problems with the CLabel representation.
--- We can't make a Show instance for CLabel because lots of its components don't have instances.
--- The regular Outputable instance only shows the label name, and not its other info.
---
-pprDebugCLabel :: CLabel -> SDoc
-pprDebugCLabel lbl
- = case lbl of
- IdLabel _ _ info-> ppr lbl <> (parens $ text "IdLabel"
- <> whenPprDebug (text ":" <> text (show info)))
- CmmLabel pkg _name _info
- -> ppr lbl <> (parens $ text "CmmLabel" <+> ppr pkg)
-
- RtsLabel{} -> ppr lbl <> (parens $ text "RtsLabel")
-
- ForeignLabel _name mSuffix src funOrData
- -> ppr lbl <> (parens $ text "ForeignLabel"
- <+> ppr mSuffix
- <+> ppr src
- <+> ppr funOrData)
-
- _ -> ppr lbl <> (parens $ text "other CLabel")
-
-
-data IdLabelInfo
- = Closure -- ^ Label for closure
- | InfoTable -- ^ Info tables for closures; always read-only
- | Entry -- ^ Entry point
- | Slow -- ^ Slow entry point
-
- | LocalInfoTable -- ^ Like InfoTable but not externally visible
- | LocalEntry -- ^ Like Entry but not externally visible
-
- | RednCounts -- ^ Label of place to keep Ticky-ticky info for this Id
-
- | ConEntry -- ^ Constructor entry point
- | ConInfoTable -- ^ Corresponding info table
-
- | ClosureTable -- ^ Table of closures for Enum tycons
-
- | Bytes -- ^ Content of a string literal. See
- -- Note [Bytes label].
- | BlockInfoTable -- ^ Like LocalInfoTable but for a proc-point block
- -- instead of a closure entry-point.
- -- See Note [Proc-point local block entry-point].
-
- deriving (Eq, Ord, Show)
-
-
-data RtsLabelInfo
- = RtsSelectorInfoTable Bool{-updatable-} Int{-offset-} -- ^ Selector thunks
- | RtsSelectorEntry Bool{-updatable-} Int{-offset-}
-
- | RtsApInfoTable Bool{-updatable-} Int{-arity-} -- ^ AP thunks
- | RtsApEntry Bool{-updatable-} Int{-arity-}
-
- | RtsPrimOp PrimOp
- | RtsApFast FastString -- ^ _fast versions of generic apply
- | RtsSlowFastTickyCtr String
-
- deriving (Eq, Ord)
- -- NOTE: Eq on PtrString compares the pointer only, so this isn't
- -- a real equality.
-
-
--- | What type of Cmm label we're dealing with.
--- Determines the suffix appended to the name when a CLabel.CmmLabel
--- is pretty printed.
-data CmmLabelInfo
- = CmmInfo -- ^ misc rts info tables, suffix _info
- | CmmEntry -- ^ misc rts entry points, suffix _entry
- | CmmRetInfo -- ^ misc rts ret info tables, suffix _info
- | CmmRet -- ^ misc rts return points, suffix _ret
- | CmmData -- ^ misc rts data bits, eg CHARLIKE_closure
- | CmmCode -- ^ misc rts code
- | CmmClosure -- ^ closures eg CHARLIKE_closure
- | CmmPrimCall -- ^ a prim call to some hand written Cmm code
- deriving (Eq, Ord)
-
-data DynamicLinkerLabelInfo
- = CodeStub -- MachO: Lfoo$stub, ELF: foo@plt
- | SymbolPtr -- MachO: Lfoo$non_lazy_ptr, Windows: __imp_foo
- | GotSymbolPtr -- ELF: foo@got
- | GotSymbolOffset -- ELF: foo@gotoff
-
- deriving (Eq, Ord)
-
-
--- -----------------------------------------------------------------------------
--- Constructing CLabels
--- -----------------------------------------------------------------------------
-
--- Constructing IdLabels
--- These are always local:
-
-mkSRTLabel :: Unique -> CLabel
-mkSRTLabel u = SRTLabel u
-
-mkRednCountsLabel :: Name -> CLabel
-mkRednCountsLabel name =
- IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE]
-
--- These have local & (possibly) external variants:
-mkLocalClosureLabel :: Name -> CafInfo -> CLabel
-mkLocalInfoTableLabel :: Name -> CafInfo -> CLabel
-mkLocalClosureTableLabel :: Name -> CafInfo -> CLabel
-mkLocalClosureLabel name c = IdLabel name c Closure
-mkLocalInfoTableLabel name c = IdLabel name c LocalInfoTable
-mkLocalClosureTableLabel name c = IdLabel name c ClosureTable
-
-mkClosureLabel :: Name -> CafInfo -> CLabel
-mkInfoTableLabel :: Name -> CafInfo -> CLabel
-mkEntryLabel :: Name -> CafInfo -> CLabel
-mkClosureTableLabel :: Name -> CafInfo -> CLabel
-mkConInfoTableLabel :: Name -> CafInfo -> CLabel
-mkBytesLabel :: Name -> CLabel
-mkClosureLabel name c = IdLabel name c Closure
-mkInfoTableLabel name c = IdLabel name c InfoTable
-mkEntryLabel name c = IdLabel name c Entry
-mkClosureTableLabel name c = IdLabel name c ClosureTable
-mkConInfoTableLabel name c = IdLabel name c ConInfoTable
-mkBytesLabel name = IdLabel name NoCafRefs Bytes
-
-mkBlockInfoTableLabel :: Name -> CafInfo -> CLabel
-mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable
- -- See Note [Proc-point local block entry-point].
-
--- Constructing Cmm Labels
-mkDirty_MUT_VAR_Label,
- mkNonmovingWriteBarrierEnabledLabel,
- mkUpdInfoLabel,
- mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel,
- mkMAP_FROZEN_CLEAN_infoLabel, mkMAP_FROZEN_DIRTY_infoLabel,
- mkMAP_DIRTY_infoLabel,
- mkArrWords_infoLabel,
- mkTopTickyCtrLabel,
- mkCAFBlackHoleInfoTableLabel,
- mkSMAP_FROZEN_CLEAN_infoLabel, mkSMAP_FROZEN_DIRTY_infoLabel,
- mkSMAP_DIRTY_infoLabel, mkBadAlignmentLabel :: CLabel
-mkDirty_MUT_VAR_Label = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction
-mkNonmovingWriteBarrierEnabledLabel
- = CmmLabel rtsUnitId (fsLit "nonmoving_write_barrier_enabled") CmmData
-mkUpdInfoLabel = CmmLabel rtsUnitId (fsLit "stg_upd_frame") CmmInfo
-mkBHUpdInfoLabel = CmmLabel rtsUnitId (fsLit "stg_bh_upd_frame" ) CmmInfo
-mkIndStaticInfoLabel = CmmLabel rtsUnitId (fsLit "stg_IND_STATIC") CmmInfo
-mkMainCapabilityLabel = CmmLabel rtsUnitId (fsLit "MainCapability") CmmData
-mkMAP_FROZEN_CLEAN_infoLabel = CmmLabel rtsUnitId (fsLit "stg_MUT_ARR_PTRS_FROZEN_CLEAN") CmmInfo
-mkMAP_FROZEN_DIRTY_infoLabel = CmmLabel rtsUnitId (fsLit "stg_MUT_ARR_PTRS_FROZEN_DIRTY") CmmInfo
-mkMAP_DIRTY_infoLabel = CmmLabel rtsUnitId (fsLit "stg_MUT_ARR_PTRS_DIRTY") CmmInfo
-mkTopTickyCtrLabel = CmmLabel rtsUnitId (fsLit "top_ct") CmmData
-mkCAFBlackHoleInfoTableLabel = CmmLabel rtsUnitId (fsLit "stg_CAF_BLACKHOLE") CmmInfo
-mkArrWords_infoLabel = CmmLabel rtsUnitId (fsLit "stg_ARR_WORDS") CmmInfo
-mkSMAP_FROZEN_CLEAN_infoLabel = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN_CLEAN") CmmInfo
-mkSMAP_FROZEN_DIRTY_infoLabel = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN_DIRTY") CmmInfo
-mkSMAP_DIRTY_infoLabel = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_DIRTY") CmmInfo
-mkBadAlignmentLabel = CmmLabel rtsUnitId (fsLit "stg_badAlignment") CmmEntry
-
-mkSRTInfoLabel :: Int -> CLabel
-mkSRTInfoLabel n = CmmLabel rtsUnitId lbl CmmInfo
- where
- lbl =
- case n of
- 1 -> fsLit "stg_SRT_1"
- 2 -> fsLit "stg_SRT_2"
- 3 -> fsLit "stg_SRT_3"
- 4 -> fsLit "stg_SRT_4"
- 5 -> fsLit "stg_SRT_5"
- 6 -> fsLit "stg_SRT_6"
- 7 -> fsLit "stg_SRT_7"
- 8 -> fsLit "stg_SRT_8"
- 9 -> fsLit "stg_SRT_9"
- 10 -> fsLit "stg_SRT_10"
- 11 -> fsLit "stg_SRT_11"
- 12 -> fsLit "stg_SRT_12"
- 13 -> fsLit "stg_SRT_13"
- 14 -> fsLit "stg_SRT_14"
- 15 -> fsLit "stg_SRT_15"
- 16 -> fsLit "stg_SRT_16"
- _ -> panic "mkSRTInfoLabel"
-
------
-mkCmmInfoLabel, mkCmmEntryLabel, mkCmmRetInfoLabel, mkCmmRetLabel,
- mkCmmCodeLabel, mkCmmDataLabel, mkCmmClosureLabel
- :: UnitId -> FastString -> CLabel
-
-mkCmmInfoLabel pkg str = CmmLabel pkg str CmmInfo
-mkCmmEntryLabel pkg str = CmmLabel pkg str CmmEntry
-mkCmmRetInfoLabel pkg str = CmmLabel pkg str CmmRetInfo
-mkCmmRetLabel pkg str = CmmLabel pkg str CmmRet
-mkCmmCodeLabel pkg str = CmmLabel pkg str CmmCode
-mkCmmDataLabel pkg str = CmmLabel pkg str CmmData
-mkCmmClosureLabel pkg str = CmmLabel pkg str CmmClosure
-
-mkLocalBlockLabel :: Unique -> CLabel
-mkLocalBlockLabel u = LocalBlockLabel u
-
--- Constructing RtsLabels
-mkRtsPrimOpLabel :: PrimOp -> CLabel
-mkRtsPrimOpLabel primop = RtsLabel (RtsPrimOp primop)
-
-mkSelectorInfoLabel :: Bool -> Int -> CLabel
-mkSelectorEntryLabel :: Bool -> Int -> CLabel
-mkSelectorInfoLabel upd off = RtsLabel (RtsSelectorInfoTable upd off)
-mkSelectorEntryLabel upd off = RtsLabel (RtsSelectorEntry upd off)
-
-mkApInfoTableLabel :: Bool -> Int -> CLabel
-mkApEntryLabel :: Bool -> Int -> CLabel
-mkApInfoTableLabel upd off = RtsLabel (RtsApInfoTable upd off)
-mkApEntryLabel upd off = RtsLabel (RtsApEntry upd off)
-
-
--- A call to some primitive hand written Cmm code
-mkPrimCallLabel :: PrimCall -> CLabel
-mkPrimCallLabel (PrimCall str pkg)
- = CmmLabel pkg str CmmPrimCall
-
-
--- Constructing ForeignLabels
-
--- | Make a foreign label
-mkForeignLabel
- :: FastString -- name
- -> Maybe Int -- size prefix
- -> ForeignLabelSource -- what package it's in
- -> FunctionOrData
- -> CLabel
-
-mkForeignLabel = ForeignLabel
-
-
--- | Update the label size field in a ForeignLabel
-addLabelSize :: CLabel -> Int -> CLabel
-addLabelSize (ForeignLabel str _ src fod) sz
- = ForeignLabel str (Just sz) src fod
-addLabelSize label _
- = label
-
--- | Whether label is a top-level string literal
-isBytesLabel :: CLabel -> Bool
-isBytesLabel (IdLabel _ _ Bytes) = True
-isBytesLabel _lbl = False
-
--- | Whether label is a non-haskell label (defined in C code)
-isForeignLabel :: CLabel -> Bool
-isForeignLabel (ForeignLabel _ _ _ _) = True
-isForeignLabel _lbl = False
-
--- | Whether label is a static closure label (can come from haskell or cmm)
-isStaticClosureLabel :: CLabel -> Bool
--- Closure defined in haskell (.hs)
-isStaticClosureLabel (IdLabel _ _ Closure) = True
--- Closure defined in cmm
-isStaticClosureLabel (CmmLabel _ _ CmmClosure) = True
-isStaticClosureLabel _lbl = False
-
--- | Whether label is a .rodata label
-isSomeRODataLabel :: CLabel -> Bool
--- info table defined in haskell (.hs)
-isSomeRODataLabel (IdLabel _ _ ClosureTable) = True
-isSomeRODataLabel (IdLabel _ _ ConInfoTable) = True
-isSomeRODataLabel (IdLabel _ _ InfoTable) = True
-isSomeRODataLabel (IdLabel _ _ LocalInfoTable) = True
-isSomeRODataLabel (IdLabel _ _ BlockInfoTable) = True
--- info table defined in cmm (.cmm)
-isSomeRODataLabel (CmmLabel _ _ CmmInfo) = True
-isSomeRODataLabel _lbl = False
-
--- | Whether label is points to some kind of info table
-isInfoTableLabel :: CLabel -> Bool
-isInfoTableLabel (IdLabel _ _ InfoTable) = True
-isInfoTableLabel (IdLabel _ _ LocalInfoTable) = True
-isInfoTableLabel (IdLabel _ _ ConInfoTable) = True
-isInfoTableLabel (IdLabel _ _ BlockInfoTable) = True
-isInfoTableLabel _ = False
-
--- | Whether label is points to constructor info table
-isConInfoTableLabel :: CLabel -> Bool
-isConInfoTableLabel (IdLabel _ _ ConInfoTable) = True
-isConInfoTableLabel _ = False
-
--- | Get the label size field from a ForeignLabel
-foreignLabelStdcallInfo :: CLabel -> Maybe Int
-foreignLabelStdcallInfo (ForeignLabel _ info _ _) = info
-foreignLabelStdcallInfo _lbl = Nothing
-
-
--- Constructing Large*Labels
-mkBitmapLabel :: Unique -> CLabel
-mkBitmapLabel uniq = LargeBitmapLabel uniq
-
--- Constructing Cost Center Labels
-mkCCLabel :: CostCentre -> CLabel
-mkCCSLabel :: CostCentreStack -> CLabel
-mkCCLabel cc = CC_Label cc
-mkCCSLabel ccs = CCS_Label ccs
-
-mkRtsApFastLabel :: FastString -> CLabel
-mkRtsApFastLabel str = RtsLabel (RtsApFast str)
-
-mkRtsSlowFastTickyCtrLabel :: String -> CLabel
-mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat)
-
-
--- Constructing Code Coverage Labels
-mkHpcTicksLabel :: Module -> CLabel
-mkHpcTicksLabel = HpcTicksLabel
-
-
--- Constructing labels used for dynamic linking
-mkDynamicLinkerLabel :: DynamicLinkerLabelInfo -> CLabel -> CLabel
-mkDynamicLinkerLabel = DynamicLinkerLabel
-
-dynamicLinkerLabelInfo :: CLabel -> Maybe (DynamicLinkerLabelInfo, CLabel)
-dynamicLinkerLabelInfo (DynamicLinkerLabel info lbl) = Just (info, lbl)
-dynamicLinkerLabelInfo _ = Nothing
-
-mkPicBaseLabel :: CLabel
-mkPicBaseLabel = PicBaseLabel
-
-
--- Constructing miscellaneous other labels
-mkDeadStripPreventer :: CLabel -> CLabel
-mkDeadStripPreventer lbl = DeadStripPreventer lbl
-
-mkStringLitLabel :: Unique -> CLabel
-mkStringLitLabel = StringLitLabel
-
-mkAsmTempLabel :: Uniquable a => a -> CLabel
-mkAsmTempLabel a = AsmTempLabel (getUnique a)
-
-mkAsmTempDerivedLabel :: CLabel -> FastString -> CLabel
-mkAsmTempDerivedLabel = AsmTempDerivedLabel
-
-mkAsmTempEndLabel :: CLabel -> CLabel
-mkAsmTempEndLabel l = mkAsmTempDerivedLabel l (fsLit "_end")
-
--- | Construct a label for a DWARF Debug Information Entity (DIE)
--- describing another symbol.
-mkAsmTempDieLabel :: CLabel -> CLabel
-mkAsmTempDieLabel l = mkAsmTempDerivedLabel l (fsLit "_die")
-
--- -----------------------------------------------------------------------------
--- Convert between different kinds of label
-
-toClosureLbl :: CLabel -> CLabel
-toClosureLbl (IdLabel n c _) = IdLabel n c Closure
-toClosureLbl (CmmLabel m str _) = CmmLabel m str CmmClosure
-toClosureLbl l = pprPanic "toClosureLbl" (ppr l)
-
-toSlowEntryLbl :: CLabel -> CLabel
-toSlowEntryLbl (IdLabel n _ BlockInfoTable)
- = pprPanic "toSlowEntryLbl" (ppr n)
-toSlowEntryLbl (IdLabel n c _) = IdLabel n c Slow
-toSlowEntryLbl l = pprPanic "toSlowEntryLbl" (ppr l)
-
-toEntryLbl :: CLabel -> CLabel
-toEntryLbl (IdLabel n c LocalInfoTable) = IdLabel n c LocalEntry
-toEntryLbl (IdLabel n c ConInfoTable) = IdLabel n c ConEntry
-toEntryLbl (IdLabel n _ BlockInfoTable) = mkLocalBlockLabel (nameUnique n)
- -- See Note [Proc-point local block entry-point].
-toEntryLbl (IdLabel n c _) = IdLabel n c Entry
-toEntryLbl (CmmLabel m str CmmInfo) = CmmLabel m str CmmEntry
-toEntryLbl (CmmLabel m str CmmRetInfo) = CmmLabel m str CmmRet
-toEntryLbl l = pprPanic "toEntryLbl" (ppr l)
-
-toInfoLbl :: CLabel -> CLabel
-toInfoLbl (IdLabel n c LocalEntry) = IdLabel n c LocalInfoTable
-toInfoLbl (IdLabel n c ConEntry) = IdLabel n c ConInfoTable
-toInfoLbl (IdLabel n c _) = IdLabel n c InfoTable
-toInfoLbl (CmmLabel m str CmmEntry) = CmmLabel m str CmmInfo
-toInfoLbl (CmmLabel m str CmmRet) = CmmLabel m str CmmRetInfo
-toInfoLbl l = pprPanic "CLabel.toInfoLbl" (ppr l)
-
-hasHaskellName :: CLabel -> Maybe Name
-hasHaskellName (IdLabel n _ _) = Just n
-hasHaskellName _ = Nothing
-
--- -----------------------------------------------------------------------------
--- Does a CLabel's referent itself refer to a CAF?
-hasCAF :: CLabel -> Bool
-hasCAF (IdLabel _ _ RednCounts) = False -- Note [ticky for LNE]
-hasCAF (IdLabel _ MayHaveCafRefs _) = True
-hasCAF _ = False
-
--- Note [ticky for LNE]
--- ~~~~~~~~~~~~~~~~~~~~~
-
--- Until 14 Feb 2013, every ticky counter was associated with a
--- closure. Thus, ticky labels used IdLabel. It is odd that
--- CmmBuildInfoTables.cafTransfers would consider such a ticky label
--- reason to add the name to the CAFEnv (and thus eventually the SRT),
--- but it was harmless because the ticky was only used if the closure
--- was also.
---
--- Since we now have ticky counters for LNEs, it is no longer the case
--- that every ticky counter has an actual closure. So I changed the
--- generation of ticky counters' CLabels to not result in their
--- associated id ending up in the SRT.
---
--- NB IdLabel is still appropriate for ticky ids (as opposed to
--- CmmLabel) because the LNE's counter is still related to an .hs Id,
--- that Id just isn't for a proper closure.
-
--- -----------------------------------------------------------------------------
--- Does a CLabel need declaring before use or not?
---
--- See wiki:commentary/compiler/backends/ppr-c#prototypes
-
-needsCDecl :: CLabel -> Bool
- -- False <=> it's pre-declared; don't bother
- -- don't bother declaring Bitmap labels, we always make sure
- -- they are defined before use.
-needsCDecl (SRTLabel _) = True
-needsCDecl (LargeBitmapLabel _) = False
-needsCDecl (IdLabel _ _ _) = True
-needsCDecl (LocalBlockLabel _) = True
-
-needsCDecl (StringLitLabel _) = False
-needsCDecl (AsmTempLabel _) = False
-needsCDecl (AsmTempDerivedLabel _ _) = False
-needsCDecl (RtsLabel _) = False
-
-needsCDecl (CmmLabel pkgId _ _)
- -- Prototypes for labels defined in the runtime system are imported
- -- into HC files via includes/Stg.h.
- | pkgId == rtsUnitId = False
-
- -- For other labels we inline one into the HC file directly.
- | otherwise = True
-
-needsCDecl l@(ForeignLabel{}) = not (isMathFun l)
-needsCDecl (CC_Label _) = True
-needsCDecl (CCS_Label _) = True
-needsCDecl (HpcTicksLabel _) = True
-needsCDecl (DynamicLinkerLabel {}) = panic "needsCDecl DynamicLinkerLabel"
-needsCDecl PicBaseLabel = panic "needsCDecl PicBaseLabel"
-needsCDecl (DeadStripPreventer {}) = panic "needsCDecl DeadStripPreventer"
-
--- | If a label is a local block label then return just its 'BlockId', otherwise
--- 'Nothing'.
-maybeLocalBlockLabel :: CLabel -> Maybe BlockId
-maybeLocalBlockLabel (LocalBlockLabel uq) = Just $ mkBlockId uq
-maybeLocalBlockLabel _ = Nothing
-
-
--- | Check whether a label corresponds to a C function that has
--- a prototype in a system header somewhere, or is built-in
--- to the C compiler. For these labels we avoid generating our
--- own C prototypes.
-isMathFun :: CLabel -> Bool
-isMathFun (ForeignLabel fs _ _ _) = fs `elementOfUniqSet` math_funs
-isMathFun _ = False
-
-math_funs :: UniqSet FastString
-math_funs = mkUniqSet [
- -- _ISOC99_SOURCE
- (fsLit "acos"), (fsLit "acosf"), (fsLit "acosh"),
- (fsLit "acoshf"), (fsLit "acoshl"), (fsLit "acosl"),
- (fsLit "asin"), (fsLit "asinf"), (fsLit "asinl"),
- (fsLit "asinh"), (fsLit "asinhf"), (fsLit "asinhl"),
- (fsLit "atan"), (fsLit "atanf"), (fsLit "atanl"),
- (fsLit "atan2"), (fsLit "atan2f"), (fsLit "atan2l"),
- (fsLit "atanh"), (fsLit "atanhf"), (fsLit "atanhl"),
- (fsLit "cbrt"), (fsLit "cbrtf"), (fsLit "cbrtl"),
- (fsLit "ceil"), (fsLit "ceilf"), (fsLit "ceill"),
- (fsLit "copysign"), (fsLit "copysignf"), (fsLit "copysignl"),
- (fsLit "cos"), (fsLit "cosf"), (fsLit "cosl"),
- (fsLit "cosh"), (fsLit "coshf"), (fsLit "coshl"),
- (fsLit "erf"), (fsLit "erff"), (fsLit "erfl"),
- (fsLit "erfc"), (fsLit "erfcf"), (fsLit "erfcl"),
- (fsLit "exp"), (fsLit "expf"), (fsLit "expl"),
- (fsLit "exp2"), (fsLit "exp2f"), (fsLit "exp2l"),
- (fsLit "expm1"), (fsLit "expm1f"), (fsLit "expm1l"),
- (fsLit "fabs"), (fsLit "fabsf"), (fsLit "fabsl"),
- (fsLit "fdim"), (fsLit "fdimf"), (fsLit "fdiml"),
- (fsLit "floor"), (fsLit "floorf"), (fsLit "floorl"),
- (fsLit "fma"), (fsLit "fmaf"), (fsLit "fmal"),
- (fsLit "fmax"), (fsLit "fmaxf"), (fsLit "fmaxl"),
- (fsLit "fmin"), (fsLit "fminf"), (fsLit "fminl"),
- (fsLit "fmod"), (fsLit "fmodf"), (fsLit "fmodl"),
- (fsLit "frexp"), (fsLit "frexpf"), (fsLit "frexpl"),
- (fsLit "hypot"), (fsLit "hypotf"), (fsLit "hypotl"),
- (fsLit "ilogb"), (fsLit "ilogbf"), (fsLit "ilogbl"),
- (fsLit "ldexp"), (fsLit "ldexpf"), (fsLit "ldexpl"),
- (fsLit "lgamma"), (fsLit "lgammaf"), (fsLit "lgammal"),
- (fsLit "llrint"), (fsLit "llrintf"), (fsLit "llrintl"),
- (fsLit "llround"), (fsLit "llroundf"), (fsLit "llroundl"),
- (fsLit "log"), (fsLit "logf"), (fsLit "logl"),
- (fsLit "log10l"), (fsLit "log10"), (fsLit "log10f"),
- (fsLit "log1pl"), (fsLit "log1p"), (fsLit "log1pf"),
- (fsLit "log2"), (fsLit "log2f"), (fsLit "log2l"),
- (fsLit "logb"), (fsLit "logbf"), (fsLit "logbl"),
- (fsLit "lrint"), (fsLit "lrintf"), (fsLit "lrintl"),
- (fsLit "lround"), (fsLit "lroundf"), (fsLit "lroundl"),
- (fsLit "modf"), (fsLit "modff"), (fsLit "modfl"),
- (fsLit "nan"), (fsLit "nanf"), (fsLit "nanl"),
- (fsLit "nearbyint"), (fsLit "nearbyintf"), (fsLit "nearbyintl"),
- (fsLit "nextafter"), (fsLit "nextafterf"), (fsLit "nextafterl"),
- (fsLit "nexttoward"), (fsLit "nexttowardf"), (fsLit "nexttowardl"),
- (fsLit "pow"), (fsLit "powf"), (fsLit "powl"),
- (fsLit "remainder"), (fsLit "remainderf"), (fsLit "remainderl"),
- (fsLit "remquo"), (fsLit "remquof"), (fsLit "remquol"),
- (fsLit "rint"), (fsLit "rintf"), (fsLit "rintl"),
- (fsLit "round"), (fsLit "roundf"), (fsLit "roundl"),
- (fsLit "scalbln"), (fsLit "scalblnf"), (fsLit "scalblnl"),
- (fsLit "scalbn"), (fsLit "scalbnf"), (fsLit "scalbnl"),
- (fsLit "sin"), (fsLit "sinf"), (fsLit "sinl"),
- (fsLit "sinh"), (fsLit "sinhf"), (fsLit "sinhl"),
- (fsLit "sqrt"), (fsLit "sqrtf"), (fsLit "sqrtl"),
- (fsLit "tan"), (fsLit "tanf"), (fsLit "tanl"),
- (fsLit "tanh"), (fsLit "tanhf"), (fsLit "tanhl"),
- (fsLit "tgamma"), (fsLit "tgammaf"), (fsLit "tgammal"),
- (fsLit "trunc"), (fsLit "truncf"), (fsLit "truncl"),
- -- ISO C 99 also defines these function-like macros in math.h:
- -- fpclassify, isfinite, isinf, isnormal, signbit, isgreater,
- -- isgreaterequal, isless, islessequal, islessgreater, isunordered
-
- -- additional symbols from _BSD_SOURCE
- (fsLit "drem"), (fsLit "dremf"), (fsLit "dreml"),
- (fsLit "finite"), (fsLit "finitef"), (fsLit "finitel"),
- (fsLit "gamma"), (fsLit "gammaf"), (fsLit "gammal"),
- (fsLit "isinf"), (fsLit "isinff"), (fsLit "isinfl"),
- (fsLit "isnan"), (fsLit "isnanf"), (fsLit "isnanl"),
- (fsLit "j0"), (fsLit "j0f"), (fsLit "j0l"),
- (fsLit "j1"), (fsLit "j1f"), (fsLit "j1l"),
- (fsLit "jn"), (fsLit "jnf"), (fsLit "jnl"),
- (fsLit "lgamma_r"), (fsLit "lgammaf_r"), (fsLit "lgammal_r"),
- (fsLit "scalb"), (fsLit "scalbf"), (fsLit "scalbl"),
- (fsLit "significand"), (fsLit "significandf"), (fsLit "significandl"),
- (fsLit "y0"), (fsLit "y0f"), (fsLit "y0l"),
- (fsLit "y1"), (fsLit "y1f"), (fsLit "y1l"),
- (fsLit "yn"), (fsLit "ynf"), (fsLit "ynl"),
-
- -- These functions are described in IEEE Std 754-2008 -
- -- Standard for Floating-Point Arithmetic and ISO/IEC TS 18661
- (fsLit "nextup"), (fsLit "nextupf"), (fsLit "nextupl"),
- (fsLit "nextdown"), (fsLit "nextdownf"), (fsLit "nextdownl")
- ]
-
--- -----------------------------------------------------------------------------
--- | Is a CLabel visible outside this object file 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.
-externallyVisibleCLabel :: CLabel -> Bool -- not C "static"
-externallyVisibleCLabel (StringLitLabel _) = False
-externallyVisibleCLabel (AsmTempLabel _) = False
-externallyVisibleCLabel (AsmTempDerivedLabel _ _)= False
-externallyVisibleCLabel (RtsLabel _) = True
-externallyVisibleCLabel (LocalBlockLabel _) = False
-externallyVisibleCLabel (CmmLabel _ _ _) = True
-externallyVisibleCLabel (ForeignLabel{}) = True
-externallyVisibleCLabel (IdLabel name _ info) = isExternalName name && externallyVisibleIdLabel info
-externallyVisibleCLabel (CC_Label _) = True
-externallyVisibleCLabel (CCS_Label _) = True
-externallyVisibleCLabel (DynamicLinkerLabel _ _) = False
-externallyVisibleCLabel (HpcTicksLabel _) = True
-externallyVisibleCLabel (LargeBitmapLabel _) = False
-externallyVisibleCLabel (SRTLabel _) = False
-externallyVisibleCLabel (PicBaseLabel {}) = panic "externallyVisibleCLabel PicBaseLabel"
-externallyVisibleCLabel (DeadStripPreventer {}) = panic "externallyVisibleCLabel DeadStripPreventer"
-
-externallyVisibleIdLabel :: IdLabelInfo -> Bool
-externallyVisibleIdLabel LocalInfoTable = False
-externallyVisibleIdLabel LocalEntry = False
-externallyVisibleIdLabel BlockInfoTable = False
-externallyVisibleIdLabel _ = True
-
--- -----------------------------------------------------------------------------
--- Finding the "type" of a CLabel
-
--- For generating correct types in label declarations:
-
-data CLabelType
- = CodeLabel -- Address of some executable instructions
- | DataLabel -- Address of data, not a GC ptr
- | GcPtrLabel -- Address of a (presumably static) GC object
-
-isCFunctionLabel :: CLabel -> Bool
-isCFunctionLabel lbl = case labelType lbl of
- CodeLabel -> True
- _other -> False
-
-isGcPtrLabel :: CLabel -> Bool
-isGcPtrLabel lbl = case labelType lbl of
- GcPtrLabel -> True
- _other -> False
-
-
--- | Work out the general type of data at the address of this label
--- whether it be code, data, or static GC object.
-labelType :: CLabel -> CLabelType
-labelType (IdLabel _ _ info) = idInfoLabelType info
-labelType (CmmLabel _ _ CmmData) = DataLabel
-labelType (CmmLabel _ _ CmmClosure) = GcPtrLabel
-labelType (CmmLabel _ _ CmmCode) = CodeLabel
-labelType (CmmLabel _ _ CmmInfo) = DataLabel
-labelType (CmmLabel _ _ CmmEntry) = CodeLabel
-labelType (CmmLabel _ _ CmmPrimCall) = CodeLabel
-labelType (CmmLabel _ _ CmmRetInfo) = DataLabel
-labelType (CmmLabel _ _ CmmRet) = CodeLabel
-labelType (RtsLabel (RtsSelectorInfoTable _ _)) = DataLabel
-labelType (RtsLabel (RtsApInfoTable _ _)) = DataLabel
-labelType (RtsLabel (RtsApFast _)) = CodeLabel
-labelType (RtsLabel _) = DataLabel
-labelType (LocalBlockLabel _) = CodeLabel
-labelType (SRTLabel _) = DataLabel
-labelType (ForeignLabel _ _ _ IsFunction) = CodeLabel
-labelType (ForeignLabel _ _ _ IsData) = DataLabel
-labelType (AsmTempLabel _) = panic "labelType(AsmTempLabel)"
-labelType (AsmTempDerivedLabel _ _) = panic "labelType(AsmTempDerivedLabel)"
-labelType (StringLitLabel _) = DataLabel
-labelType (CC_Label _) = DataLabel
-labelType (CCS_Label _) = DataLabel
-labelType (DynamicLinkerLabel _ _) = DataLabel -- Is this right?
-labelType PicBaseLabel = DataLabel
-labelType (DeadStripPreventer _) = DataLabel
-labelType (HpcTicksLabel _) = DataLabel
-labelType (LargeBitmapLabel _) = DataLabel
-
-idInfoLabelType :: IdLabelInfo -> CLabelType
-idInfoLabelType info =
- case info of
- InfoTable -> DataLabel
- LocalInfoTable -> DataLabel
- BlockInfoTable -> DataLabel
- Closure -> GcPtrLabel
- ConInfoTable -> DataLabel
- ClosureTable -> DataLabel
- RednCounts -> DataLabel
- Bytes -> DataLabel
- _ -> CodeLabel
-
-
--- -----------------------------------------------------------------------------
-
--- | Is a 'CLabel' defined in the current module being compiled?
---
--- Sometimes we can optimise references within a compilation unit in ways that
--- we couldn't for inter-module references. This provides a conservative
--- estimate of whether a 'CLabel' lives in the current module.
-isLocalCLabel :: Module -> CLabel -> Bool
-isLocalCLabel this_mod lbl =
- case lbl of
- IdLabel name _ _
- | isInternalName name -> True
- | otherwise -> nameModule name == this_mod
- LocalBlockLabel _ -> True
- _ -> False
-
--- -----------------------------------------------------------------------------
-
--- | Does a 'CLabel' need dynamic linkage?
---
--- 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.
-labelDynamic :: DynFlags -> Module -> CLabel -> Bool
-labelDynamic dflags this_mod lbl =
- case lbl of
- -- is the RTS in a DLL or not?
- RtsLabel _ ->
- externalDynamicRefs && (this_pkg /= rtsUnitId)
-
- IdLabel n _ _ ->
- isDllName dflags this_mod n
-
- -- When compiling in the "dyn" way, each package is to be linked into
- -- its own shared library.
- CmmLabel pkg _ _
- | os == OSMinGW32 ->
- externalDynamicRefs && (this_pkg /= pkg)
- | otherwise ->
- gopt Opt_ExternalDynamicRefs dflags
-
- LocalBlockLabel _ -> False
-
- ForeignLabel _ _ source _ ->
- if os == OSMinGW32
- then case source of
- -- Foreign label is in some un-named foreign package (or DLL).
- ForeignLabelInExternalPackage -> True
-
- -- Foreign label is linked into the same package as the
- -- source file currently being compiled.
- ForeignLabelInThisPackage -> False
-
- -- Foreign label is in some named package.
- -- When compiling in the "dyn" way, each package is to be
- -- linked into its own DLL.
- ForeignLabelInPackage pkgId ->
- externalDynamicRefs && (this_pkg /= pkgId)
-
- else -- On Mac OS X and on ELF platforms, false positives are OK,
- -- so we claim that all foreign imports come from dynamic
- -- libraries
- True
-
- CC_Label cc ->
- externalDynamicRefs && not (ccFromThisModule cc this_mod)
-
- -- CCS_Label always contains a CostCentre defined in the current module
- CCS_Label _ -> False
-
- HpcTicksLabel m ->
- externalDynamicRefs && this_mod /= m
-
- -- Note that DynamicLinkerLabels do NOT require dynamic linking themselves.
- _ -> False
- where
- externalDynamicRefs = gopt Opt_ExternalDynamicRefs dflags
- os = platformOS (targetPlatform dflags)
- this_pkg = moduleUnitId this_mod
-
-
------------------------------------------------------------------------------
--- 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 (function, closure)
- 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
-
-Many of these distinctions are only for documentation reasons. For
-example, _ret is only distinguished from _entry to make it easy to
-tell whether a code fragment is a return point or a closure/function
-entry.
-
-Note [Closure and info labels]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-For a function 'foo, we have:
- foo_info : Points to the info table describing foo's closure
- (and entry code for foo with tables next to code)
- foo_closure : Static (no-free-var) closure only:
- points to the statically-allocated closure
-
-For a data constructor (such as Just or Nothing), we have:
- Just_con_info: Info table for the data constructor itself
- the first word of a heap-allocated Just
- Just_info: Info table for the *worker function*, an
- ordinary Haskell function of arity 1 that
- allocates a (Just x) box:
- Just = \x -> Just x
- Just_closure: The closure for this worker
-
- Nothing_closure: a statically allocated closure for Nothing
- Nothing_static_info: info table for Nothing_closure
-
-All these must be exported symbol, EXCEPT Just_info. We don't need to
-export this because in other modules we either have
- * A reference to 'Just'; use Just_closure
- * A saturated call 'Just x'; allocate using Just_con_info
-Not exporting these Just_info labels reduces the number of symbols
-somewhat.
-
-Note [Bytes label]
-~~~~~~~~~~~~~~~~~~
-For a top-level string literal 'foo', we have just one symbol 'foo_bytes', which
-points to a static data block containing the content of the literal.
-
-Note [Proc-point local block entry-points]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A label for a proc-point local block entry-point has no "_entry" suffix. With
-`infoTblLbl` we derive an info table label from a proc-point block ID. If
-we convert such an info table label into an entry label we must produce
-the label without an "_entry" suffix. So an info table label records
-the fact that it was derived from a block ID in `IdLabelInfo` as
-`BlockInfoTable`.
-
-The info table label and the local block label are both local labels
-and are not externally visible.
--}
-
-instance Outputable CLabel where
- ppr c = sdocWithDynFlags $ \dynFlags -> pprCLabel dynFlags c
-
-pprCLabel :: DynFlags -> CLabel -> SDoc
-
-pprCLabel _ (LocalBlockLabel u)
- = tempLabelPrefixOrUnderscore <> pprUniqueAlways u
-
-pprCLabel dynFlags (AsmTempLabel u)
- | not (platformUnregisterised $ targetPlatform dynFlags)
- = tempLabelPrefixOrUnderscore <> pprUniqueAlways u
-
-pprCLabel dynFlags (AsmTempDerivedLabel l suf)
- | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags
- = ptext (asmTempLabelPrefix $ targetPlatform dynFlags)
- <> case l of AsmTempLabel u -> pprUniqueAlways u
- LocalBlockLabel u -> pprUniqueAlways u
- _other -> pprCLabel dynFlags l
- <> ftext suf
-
-pprCLabel dynFlags (DynamicLinkerLabel info lbl)
- | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags
- = pprDynamicLinkerAsmLabel (targetPlatform dynFlags) info lbl
-
-pprCLabel dynFlags PicBaseLabel
- | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags
- = text "1b"
-
-pprCLabel dynFlags (DeadStripPreventer lbl)
- | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags
- =
- {-
- `lbl` can be temp one but we need to ensure that dsp label will stay
- in the final binary so we prepend non-temp prefix ("dsp_") and
- optional `_` (underscore) because this is how you mark non-temp symbols
- on some platforms (Darwin)
- -}
- maybe_underscore dynFlags $ text "dsp_"
- <> pprCLabel dynFlags lbl <> text "_dsp"
-
-pprCLabel dynFlags (StringLitLabel u)
- | platformMisc_ghcWithNativeCodeGen $ platformMisc dynFlags
- = pprUniqueAlways u <> ptext (sLit "_str")
-
-pprCLabel dynFlags lbl
- = getPprStyle $ \ sty ->
- if platformMisc_ghcWithNativeCodeGen (platformMisc dynFlags) && asmStyle sty
- then maybe_underscore dynFlags $ pprAsmCLbl (targetPlatform dynFlags) lbl
- else pprCLbl lbl
-
-maybe_underscore :: DynFlags -> SDoc -> SDoc
-maybe_underscore dynFlags doc =
- if platformMisc_leadingUnderscore $ platformMisc dynFlags
- then pp_cSEP <> doc
- else doc
-
-pprAsmCLbl :: Platform -> CLabel -> SDoc
-pprAsmCLbl platform (ForeignLabel fs (Just sz) _ _)
- | platformOS platform == OSMinGW32
- -- In asm mode, we need to put the suffix on a stdcall ForeignLabel.
- -- (The C compiler does this itself).
- = ftext fs <> char '@' <> int sz
-pprAsmCLbl _ lbl
- = pprCLbl lbl
-
-pprCLbl :: CLabel -> SDoc
-pprCLbl (StringLitLabel u)
- = pprUniqueAlways u <> text "_str"
-
-pprCLbl (SRTLabel u)
- = tempLabelPrefixOrUnderscore <> pprUniqueAlways u <> pp_cSEP <> text "srt"
-
-pprCLbl (LargeBitmapLabel u) =
- tempLabelPrefixOrUnderscore
- <> char 'b' <> pprUniqueAlways u <> pp_cSEP <> text "btm"
--- Some bitsmaps for tuple constructors have a numeric tag (e.g. '7')
--- until that gets resolved we'll just force them to start
--- with a letter so the label will be legal assembly code.
-
-
-pprCLbl (CmmLabel _ str CmmCode) = ftext str
-pprCLbl (CmmLabel _ str CmmData) = ftext str
-pprCLbl (CmmLabel _ str CmmPrimCall) = ftext str
-
-pprCLbl (LocalBlockLabel u) =
- tempLabelPrefixOrUnderscore <> text "blk_" <> pprUniqueAlways u
-
-pprCLbl (RtsLabel (RtsApFast str)) = ftext str <> text "_fast"
-
-pprCLbl (RtsLabel (RtsSelectorInfoTable upd_reqd offset))
- = sdocWithDynFlags $ \dflags ->
- ASSERT(offset >= 0 && offset <= mAX_SPEC_SELECTEE_SIZE dflags)
- hcat [text "stg_sel_", text (show offset),
- ptext (if upd_reqd
- then (sLit "_upd_info")
- else (sLit "_noupd_info"))
- ]
-
-pprCLbl (RtsLabel (RtsSelectorEntry upd_reqd offset))
- = sdocWithDynFlags $ \dflags ->
- ASSERT(offset >= 0 && offset <= mAX_SPEC_SELECTEE_SIZE dflags)
- hcat [text "stg_sel_", text (show offset),
- ptext (if upd_reqd
- then (sLit "_upd_entry")
- else (sLit "_noupd_entry"))
- ]
-
-pprCLbl (RtsLabel (RtsApInfoTable upd_reqd arity))
- = sdocWithDynFlags $ \dflags ->
- ASSERT(arity > 0 && arity <= mAX_SPEC_AP_SIZE dflags)
- hcat [text "stg_ap_", text (show arity),
- ptext (if upd_reqd
- then (sLit "_upd_info")
- else (sLit "_noupd_info"))
- ]
-
-pprCLbl (RtsLabel (RtsApEntry upd_reqd arity))
- = sdocWithDynFlags $ \dflags ->
- ASSERT(arity > 0 && arity <= mAX_SPEC_AP_SIZE dflags)
- hcat [text "stg_ap_", text (show arity),
- ptext (if upd_reqd
- then (sLit "_upd_entry")
- else (sLit "_noupd_entry"))
- ]
-
-pprCLbl (CmmLabel _ fs CmmInfo)
- = ftext fs <> text "_info"
-
-pprCLbl (CmmLabel _ fs CmmEntry)
- = ftext fs <> text "_entry"
-
-pprCLbl (CmmLabel _ fs CmmRetInfo)
- = ftext fs <> text "_info"
-
-pprCLbl (CmmLabel _ fs CmmRet)
- = ftext fs <> text "_ret"
-
-pprCLbl (CmmLabel _ fs CmmClosure)
- = ftext fs <> text "_closure"
-
-pprCLbl (RtsLabel (RtsPrimOp primop))
- = text "stg_" <> ppr primop
-
-pprCLbl (RtsLabel (RtsSlowFastTickyCtr pat))
- = text "SLOW_CALL_fast_" <> text pat <> ptext (sLit "_ctr")
-
-pprCLbl (ForeignLabel str _ _ _)
- = ftext str
-
-pprCLbl (IdLabel name _cafs flavor) =
- internalNamePrefix name <> ppr name <> ppIdFlavor flavor
-
-pprCLbl (CC_Label cc) = ppr cc
-pprCLbl (CCS_Label ccs) = ppr ccs
-
-pprCLbl (HpcTicksLabel mod)
- = text "_hpc_tickboxes_" <> ppr mod <> ptext (sLit "_hpc")
-
-pprCLbl (AsmTempLabel {}) = panic "pprCLbl AsmTempLabel"
-pprCLbl (AsmTempDerivedLabel {})= panic "pprCLbl AsmTempDerivedLabel"
-pprCLbl (DynamicLinkerLabel {}) = panic "pprCLbl DynamicLinkerLabel"
-pprCLbl (PicBaseLabel {}) = panic "pprCLbl PicBaseLabel"
-pprCLbl (DeadStripPreventer {}) = panic "pprCLbl DeadStripPreventer"
-
-ppIdFlavor :: IdLabelInfo -> SDoc
-ppIdFlavor x = pp_cSEP <> text
- (case x of
- Closure -> "closure"
- InfoTable -> "info"
- LocalInfoTable -> "info"
- Entry -> "entry"
- LocalEntry -> "entry"
- Slow -> "slow"
- RednCounts -> "ct"
- ConEntry -> "con_entry"
- ConInfoTable -> "con_info"
- ClosureTable -> "closure_tbl"
- Bytes -> "bytes"
- BlockInfoTable -> "info"
- )
-
-
-pp_cSEP :: SDoc
-pp_cSEP = char '_'
-
-
-instance Outputable ForeignLabelSource where
- ppr fs
- = case fs of
- ForeignLabelInPackage pkgId -> parens $ text "package: " <> ppr pkgId
- ForeignLabelInThisPackage -> parens $ text "this package"
- ForeignLabelInExternalPackage -> parens $ text "external package"
-
-internalNamePrefix :: Name -> SDoc
-internalNamePrefix name = getPprStyle $ \ sty ->
- if asmStyle sty && isRandomGenerated then
- sdocWithPlatform $ \platform ->
- ptext (asmTempLabelPrefix platform)
- else
- empty
- where
- isRandomGenerated = not $ isExternalName name
-
-tempLabelPrefixOrUnderscore :: SDoc
-tempLabelPrefixOrUnderscore = sdocWithPlatform $ \platform ->
- getPprStyle $ \ sty ->
- if asmStyle sty then
- ptext (asmTempLabelPrefix platform)
- else
- char '_'
-
--- -----------------------------------------------------------------------------
--- Machine-dependent knowledge about labels.
-
-asmTempLabelPrefix :: Platform -> PtrString -- for formatting labels
-asmTempLabelPrefix platform = case platformOS platform of
- OSDarwin -> sLit "L"
- OSAIX -> sLit "__L" -- follow IBM XL C's convention
- _ -> sLit ".L"
-
-pprDynamicLinkerAsmLabel :: Platform -> DynamicLinkerLabelInfo -> CLabel -> SDoc
-pprDynamicLinkerAsmLabel platform dllInfo lbl =
- case platformOS platform of
- OSDarwin
- | platformArch platform == ArchX86_64 ->
- case dllInfo of
- CodeStub -> char 'L' <> ppr lbl <> text "$stub"
- SymbolPtr -> char 'L' <> ppr lbl <> text "$non_lazy_ptr"
- GotSymbolPtr -> ppr lbl <> text "@GOTPCREL"
- GotSymbolOffset -> ppr lbl
- | otherwise ->
- case dllInfo of
- CodeStub -> char 'L' <> ppr lbl <> text "$stub"
- SymbolPtr -> char 'L' <> ppr lbl <> text "$non_lazy_ptr"
- _ -> panic "pprDynamicLinkerAsmLabel"
-
- OSAIX ->
- case dllInfo of
- SymbolPtr -> text "LC.." <> ppr lbl -- GCC's naming convention
- _ -> panic "pprDynamicLinkerAsmLabel"
-
- _ | osElfTarget (platformOS platform) -> elfLabel
-
- OSMinGW32 ->
- case dllInfo of
- SymbolPtr -> text "__imp_" <> ppr lbl
- _ -> panic "pprDynamicLinkerAsmLabel"
-
- _ -> panic "pprDynamicLinkerAsmLabel"
- where
- elfLabel
- | platformArch platform == ArchPPC
- = case dllInfo of
- CodeStub -> -- See Note [.LCTOC1 in PPC PIC code]
- ppr lbl <> text "+32768@plt"
- SymbolPtr -> text ".LC_" <> ppr lbl
- _ -> panic "pprDynamicLinkerAsmLabel"
-
- | platformArch platform == ArchX86_64
- = case dllInfo of
- CodeStub -> ppr lbl <> text "@plt"
- GotSymbolPtr -> ppr lbl <> text "@gotpcrel"
- GotSymbolOffset -> ppr lbl
- SymbolPtr -> text ".LC_" <> ppr lbl
-
- | platformArch platform == ArchPPC_64 ELF_V1
- || platformArch platform == ArchPPC_64 ELF_V2
- = case dllInfo of
- GotSymbolPtr -> text ".LC_" <> ppr lbl
- <> text "@toc"
- GotSymbolOffset -> ppr lbl
- SymbolPtr -> text ".LC_" <> ppr lbl
- _ -> panic "pprDynamicLinkerAsmLabel"
-
- | otherwise
- = case dllInfo of
- CodeStub -> ppr lbl <> text "@plt"
- SymbolPtr -> text ".LC_" <> ppr lbl
- GotSymbolPtr -> ppr lbl <> text "@got"
- GotSymbolOffset -> ppr lbl <> text "@gotoff"
-
--- Figure out whether `symbol` may serve as an alias
--- to `target` within one compilation unit.
---
--- This is true if any of these holds:
--- * `target` is a module-internal haskell name.
--- * `target` is an exported name, but comes from the same
--- module as `symbol`
---
--- These are sufficient conditions for establishing e.g. a
--- GNU assembly alias ('.equiv' directive). Sadly, there is
--- no such thing as an alias to an imported symbol (conf.
--- http://blog.omega-prime.co.uk/2011/07/06/the-sad-state-of-symbol-aliases/)
--- See note [emit-time elimination of static indirections].
---
--- Precondition is that both labels represent the
--- same semantic value.
-
-mayRedirectTo :: CLabel -> CLabel -> Bool
-mayRedirectTo symbol target
- | Just nam <- haskellName
- , staticClosureLabel
- , isExternalName nam
- , Just mod <- nameModule_maybe nam
- , Just anam <- hasHaskellName symbol
- , Just amod <- nameModule_maybe anam
- = amod == mod
-
- | Just nam <- haskellName
- , staticClosureLabel
- , isInternalName nam
- = True
-
- | otherwise = False
- where staticClosureLabel = isStaticClosureLabel target
- haskellName = hasHaskellName target
-
-
-{-
-Note [emit-time elimination of static indirections]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-As described in #15155, certain static values are representationally
-equivalent, e.g. 'cast'ed values (when created by 'newtype' wrappers).
-
- newtype A = A Int
- {-# NOINLINE a #-}
- a = A 42
-
-a1_rYB :: Int
-[GblId, Caf=NoCafRefs, Unf=OtherCon []]
-a1_rYB = GHC.Types.I# 42#
-
-a [InlPrag=NOINLINE] :: A
-[GblId, Unf=OtherCon []]
-a = a1_rYB `cast` (Sym (T15155.N:A[0]) :: Int ~R# A)
-
-Formerly we created static indirections for these (IND_STATIC), which
-consist of a statically allocated forwarding closure that contains
-the (possibly tagged) indirectee. (See CMM/assembly below.)
-This approach is suboptimal for two reasons:
- (a) they occupy extra space,
- (b) they need to be entered in order to obtain the indirectee,
- thus they cannot be tagged.
-
-Fortunately there is a common case where static indirections can be
-eliminated while emitting assembly (native or LLVM), viz. when the
-indirectee is in the same module (object file) as the symbol that
-points to it. In this case an assembly-level identification can
-be created ('.equiv' directive), and as such the same object will
-be assigned two names in the symbol table. Any of the identified
-symbols can be referenced by a tagged pointer.
-
-Currently the 'mayRedirectTo' predicate will
-give a clue whether a label can be equated with another, already
-emitted, label (which can in turn be an alias). The general mechanics
-is that we identify data (IND_STATIC closures) that are amenable
-to aliasing while pretty-printing of assembly output, and emit the
-'.equiv' directive instead of static data in such a case.
-
-Here is a sketch how the output is massaged:
-
- Consider
-newtype A = A Int
-{-# NOINLINE a #-}
-a = A 42 -- I# 42# is the indirectee
- -- 'a' is exported
-
- results in STG
-
-a1_rXq :: GHC.Types.Int
-[GblId, Caf=NoCafRefs, Unf=OtherCon []] =
- CCS_DONT_CARE GHC.Types.I#! [42#];
-
-T15155.a [InlPrag=NOINLINE] :: T15155.A
-[GblId, Unf=OtherCon []] =
- CAF_ccs \ u [] a1_rXq;
-
- and CMM
-
-[section ""data" . a1_rXq_closure" {
- a1_rXq_closure:
- const GHC.Types.I#_con_info;
- const 42;
- }]
-
-[section ""data" . T15155.a_closure" {
- T15155.a_closure:
- const stg_IND_STATIC_info;
- const a1_rXq_closure+1;
- const 0;
- const 0;
- }]
-
-The emitted assembly is
-
-#### INDIRECTEE
-a1_rXq_closure: -- module local haskell value
- .quad GHC.Types.I#_con_info -- an Int
- .quad 42
-
-#### BEFORE
-.globl T15155.a_closure -- exported newtype wrapped value
-T15155.a_closure:
- .quad stg_IND_STATIC_info -- the closure info
- .quad a1_rXq_closure+1 -- indirectee ('+1' being the tag)
- .quad 0
- .quad 0
-
-#### AFTER
-.globl T15155.a_closure -- exported newtype wrapped value
-.equiv a1_rXq_closure,T15155.a_closure -- both are shared
-
-The transformation is performed because
- T15155.a_closure `mayRedirectTo` a1_rXq_closure+1
-returns True.
--}