summaryrefslogtreecommitdiff
path: root/compiler/cmm/CLabel.hs
diff options
context:
space:
mode:
authorKavon Farvardin <kavon@farvard.in>2018-09-23 15:29:37 -0500
committerKavon Farvardin <kavon@farvard.in>2018-09-23 15:29:37 -0500
commit84c2ad99582391005b5e873198b15e9e9eb4f78d (patch)
treecaa8c2f2ec7e97fbb4977263c6817c9af5025cf4 /compiler/cmm/CLabel.hs
parent8ddb47cfcf5776e9a3c55fd37947c8a95e00fa12 (diff)
parente68b439fe5de61b9a2ca51af472185c62ccb8b46 (diff)
downloadhaskell-wip/T13904.tar.gz
update to current master againwip/T13904
Diffstat (limited to 'compiler/cmm/CLabel.hs')
-rw-r--r--compiler/cmm/CLabel.hs490
1 files changed, 291 insertions, 199 deletions
diff --git a/compiler/cmm/CLabel.hs b/compiler/cmm/CLabel.hs
index 62c8037e9c..12c3357e47 100644
--- a/compiler/cmm/CLabel.hs
+++ b/compiler/cmm/CLabel.hs
@@ -15,30 +15,22 @@ module CLabel (
mkClosureLabel,
mkSRTLabel,
- mkTopSRTLabel,
mkInfoTableLabel,
mkEntryLabel,
- mkSlowEntryLabel,
- mkConEntryLabel,
mkRednCountsLabel,
mkConInfoTableLabel,
- mkLargeSRTLabel,
mkApEntryLabel,
mkApInfoTableLabel,
mkClosureTableLabel,
mkBytesLabel,
+ mkLocalBlockLabel,
mkLocalClosureLabel,
mkLocalInfoTableLabel,
- mkLocalEntryLabel,
- mkLocalConEntryLabel,
- mkLocalConInfoTableLabel,
mkLocalClosureTableLabel,
- mkReturnPtLabel,
- mkReturnInfoLabel,
- mkAltLabel,
- mkDefaultLabel,
+ mkBlockInfoTableLabel,
+
mkBitmapLabel,
mkStringLitLabel,
@@ -53,18 +45,18 @@ module CLabel (
mkBHUpdInfoLabel,
mkIndStaticInfoLabel,
mkMainCapabilityLabel,
- mkMAP_FROZEN_infoLabel,
- mkMAP_FROZEN0_infoLabel,
+ mkMAP_FROZEN_CLEAN_infoLabel,
+ mkMAP_FROZEN_DIRTY_infoLabel,
mkMAP_DIRTY_infoLabel,
- mkSMAP_FROZEN_infoLabel,
- mkSMAP_FROZEN0_infoLabel,
+ mkSMAP_FROZEN_CLEAN_infoLabel,
+ mkSMAP_FROZEN_DIRTY_infoLabel,
mkSMAP_DIRTY_infoLabel,
- mkEMPTY_MVAR_infoLabel,
+ mkBadAlignmentLabel,
mkArrWords_infoLabel,
+ mkSRTInfoLabel,
mkTopTickyCtrLabel,
mkCAFBlackHoleInfoTableLabel,
- mkCAFBlackHoleEntryLabel,
mkRtsPrimOpLabel,
mkRtsSlowFastTickyCtrLabel,
@@ -102,21 +94,28 @@ module CLabel (
mkHpcTicksLabel,
+ -- * Predicates
hasCAF,
- needsCDecl, maybeAsmTemp, externallyVisibleCLabel,
+ needsCDecl, maybeLocalBlockLabel, externallyVisibleCLabel,
isMathFun,
isCFunctionLabel, isGcPtrLabel, labelDynamic,
+ isLocalCLabel,
-- * Conversions
- toClosureLbl, toSlowEntryLbl, toEntryLbl, toInfoLbl, toRednCountsLbl, hasHaskellName,
+ toClosureLbl, toSlowEntryLbl, toEntryLbl, toInfoLbl, hasHaskellName,
- pprCLabel
+ pprCLabel,
+ isInfoTableLabel,
+ isConInfoTableLabel
) where
#include "HsVersions.h"
+import GhcPrelude
+
import IdInfo
import BasicTypes
+import {-# SOURCE #-} BlockId (BlockId, mkBlockId)
import Packages
import Module
import Name
@@ -135,8 +134,8 @@ import PprCore ( {- instances -} )
-- -----------------------------------------------------------------------------
-- The CLabel type
-{-
- | CLabel is an abstract type that supports the following operations:
+{- |
+ 'CLabel' is an abstract type that supports the following operations:
- Pretty printing
@@ -155,6 +154,25 @@ import PprCore ( {- instances -} )
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
@@ -177,6 +195,14 @@ data CLabel
| 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
@@ -190,14 +216,13 @@ data CLabel
FunctionOrData
- -- | A family of labels related to a particular case expression.
- | CaseLabel
- {-# UNPACK #-} !Unique -- Unique says which case expression
- CaseLabelInfo
-
+ -- | 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
@@ -229,10 +254,7 @@ data CLabel
| HpcTicksLabel Module
-- | Static reference table
- | SRTLabel !Unique
-
- -- | Label of an StgLargeSRT
- | LargeSRTLabel
+ | SRTLabel
{-# UNPACK #-} !Unique
-- | A bitmap (function or case return)
@@ -256,14 +278,12 @@ instance Ord CLabel where
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 (CaseLabel u1 a1) (CaseLabel u2 a2) =
- nonDetCmpUnique u1 u2 `thenCmp`
- compare a1 a2
compare (AsmTempLabel u1) (AsmTempLabel u2) = nonDetCmpUnique u1 u2
compare (AsmTempDerivedLabel a1 b1) (AsmTempDerivedLabel a2 b2) =
compare a1 a2 `thenCmp`
@@ -284,8 +304,6 @@ instance Ord CLabel where
compare a1 a2
compare (SRTLabel u1) (SRTLabel u2) =
nonDetCmpUnique u1 u2
- compare (LargeSRTLabel u1) (LargeSRTLabel u2) =
- nonDetCmpUnique u1 u2
compare (LargeBitmapLabel u1) (LargeBitmapLabel u2) =
nonDetCmpUnique u1 u2
compare IdLabel{} _ = LT
@@ -294,10 +312,10 @@ instance Ord CLabel where
compare _ CmmLabel{} = GT
compare RtsLabel{} _ = LT
compare _ RtsLabel{} = GT
+ compare LocalBlockLabel{} _ = LT
+ compare _ LocalBlockLabel{} = GT
compare ForeignLabel{} _ = LT
compare _ ForeignLabel{} = GT
- compare CaseLabel{} _ = LT
- compare _ CaseLabel{} = GT
compare AsmTempLabel{} _ = LT
compare _ AsmTempLabel{} = GT
compare AsmTempDerivedLabel{} _ = LT
@@ -318,8 +336,6 @@ instance Ord CLabel where
compare _ HpcTicksLabel{} = GT
compare SRTLabel{} _ = LT
compare _ SRTLabel{} = GT
- compare LargeSRTLabel{} _ = LT
- compare _ LargeSRTLabel{} = GT
-- | Record where a foreign label is stored.
data ForeignLabelSource
@@ -350,7 +366,8 @@ data ForeignLabelSource
pprDebugCLabel :: CLabel -> SDoc
pprDebugCLabel lbl
= case lbl of
- IdLabel{} -> ppr lbl <> (parens $ text "IdLabel")
+ IdLabel _ _ info-> ppr lbl <> (parens $ text "IdLabel"
+ <> whenPprDebug (text ":" <> text (show info)))
CmmLabel pkg _name _info
-> ppr lbl <> (parens $ text "CmmLabel" <+> ppr pkg)
@@ -367,9 +384,6 @@ pprDebugCLabel lbl
data IdLabelInfo
= Closure -- ^ Label for closure
- | SRT -- ^ Static reference table (TODO: could be removed
- -- with the old code generator, but might be needed
- -- when we implement the New SRT Plan)
| InfoTable -- ^ Info tables for closures; always read-only
| Entry -- ^ Entry point
| Slow -- ^ Slow entry point
@@ -386,16 +400,11 @@ data IdLabelInfo
| 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)
-
-
-data CaseLabelInfo
- = CaseReturnPt
- | CaseReturnInfo
- | CaseAlt ConTag
- | CaseDefault
- deriving (Eq, Ord)
+ deriving (Eq, Ord, Show)
data RtsLabelInfo
@@ -443,73 +452,88 @@ data DynamicLinkerLabelInfo
-- Constructing IdLabels
-- These are always local:
-mkSlowEntryLabel :: Name -> CafInfo -> CLabel
-mkSlowEntryLabel name c = IdLabel name c Slow
-mkTopSRTLabel :: Unique -> CLabel
-mkTopSRTLabel u = SRTLabel u
+mkSRTLabel :: Unique -> CLabel
+mkSRTLabel u = SRTLabel u
-mkSRTLabel :: Name -> CafInfo -> CLabel
mkRednCountsLabel :: Name -> CLabel
-mkSRTLabel name c = IdLabel name c SRT
mkRednCountsLabel name =
IdLabel name NoCafRefs RednCounts -- Note [ticky for LNE]
-- These have local & (possibly) external variants:
mkLocalClosureLabel :: Name -> CafInfo -> CLabel
mkLocalInfoTableLabel :: Name -> CafInfo -> CLabel
-mkLocalEntryLabel :: Name -> CafInfo -> CLabel
mkLocalClosureTableLabel :: Name -> CafInfo -> CLabel
mkLocalClosureLabel name c = IdLabel name c Closure
mkLocalInfoTableLabel name c = IdLabel name c LocalInfoTable
-mkLocalEntryLabel name c = IdLabel name c LocalEntry
mkLocalClosureTableLabel name c = IdLabel name c ClosureTable
mkClosureLabel :: Name -> CafInfo -> CLabel
mkInfoTableLabel :: Name -> CafInfo -> CLabel
mkEntryLabel :: Name -> CafInfo -> CLabel
mkClosureTableLabel :: Name -> CafInfo -> CLabel
-mkLocalConInfoTableLabel :: CafInfo -> Name -> CLabel
-mkLocalConEntryLabel :: CafInfo -> Name -> 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
-mkLocalConInfoTableLabel c con = IdLabel con c ConInfoTable
-mkLocalConEntryLabel c con = IdLabel con c ConEntry
mkConInfoTableLabel name c = IdLabel name c ConInfoTable
mkBytesLabel name = IdLabel name NoCafRefs Bytes
-mkConEntryLabel :: Name -> CafInfo -> CLabel
-mkConEntryLabel name c = IdLabel name c ConEntry
+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, mkSplitMarkerLabel, mkUpdInfoLabel,
mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel,
- mkMAP_FROZEN_infoLabel, mkMAP_FROZEN0_infoLabel, mkMAP_DIRTY_infoLabel,
- mkEMPTY_MVAR_infoLabel, mkTopTickyCtrLabel,
- mkCAFBlackHoleInfoTableLabel, mkCAFBlackHoleEntryLabel,
- mkArrWords_infoLabel, mkSMAP_FROZEN_infoLabel, mkSMAP_FROZEN0_infoLabel,
- mkSMAP_DIRTY_infoLabel :: CLabel
+ 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
mkSplitMarkerLabel = CmmLabel rtsUnitId (fsLit "__stg_split_marker") CmmCode
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_infoLabel = CmmLabel rtsUnitId (fsLit "stg_MUT_ARR_PTRS_FROZEN") CmmInfo
-mkMAP_FROZEN0_infoLabel = CmmLabel rtsUnitId (fsLit "stg_MUT_ARR_PTRS_FROZEN0") CmmInfo
+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
-mkEMPTY_MVAR_infoLabel = CmmLabel rtsUnitId (fsLit "stg_EMPTY_MVAR") CmmInfo
mkTopTickyCtrLabel = CmmLabel rtsUnitId (fsLit "top_ct") CmmData
mkCAFBlackHoleInfoTableLabel = CmmLabel rtsUnitId (fsLit "stg_CAF_BLACKHOLE") CmmInfo
-mkCAFBlackHoleEntryLabel = CmmLabel rtsUnitId (fsLit "stg_CAF_BLACKHOLE") CmmEntry
mkArrWords_infoLabel = CmmLabel rtsUnitId (fsLit "stg_ARR_WORDS") CmmInfo
-mkSMAP_FROZEN_infoLabel = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN") CmmInfo
-mkSMAP_FROZEN0_infoLabel = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN0") 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,
@@ -524,6 +548,8 @@ 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
@@ -592,13 +618,24 @@ isSomeRODataLabel (IdLabel _ _ ClosureTable) = True
isSomeRODataLabel (IdLabel _ _ ConInfoTable) = True
isSomeRODataLabel (IdLabel _ _ InfoTable) = True
isSomeRODataLabel (IdLabel _ _ LocalInfoTable) = True
--- static reference tables defined in haskell (.hs)
-isSomeRODataLabel (IdLabel _ _ SRT) = True
-isSomeRODataLabel (SRTLabel _) = 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
@@ -606,22 +643,9 @@ foreignLabelStdcallInfo _lbl = Nothing
-- Constructing Large*Labels
-mkLargeSRTLabel :: Unique -> CLabel
mkBitmapLabel :: Unique -> CLabel
-mkLargeSRTLabel uniq = LargeSRTLabel uniq
mkBitmapLabel uniq = LargeBitmapLabel uniq
-
--- Constructin CaseLabels
-mkReturnPtLabel :: Unique -> CLabel
-mkReturnInfoLabel :: Unique -> CLabel
-mkAltLabel :: Unique -> ConTag -> CLabel
-mkDefaultLabel :: Unique -> CLabel
-mkReturnPtLabel uniq = CaseLabel uniq CaseReturnPt
-mkReturnInfoLabel uniq = CaseLabel uniq CaseReturnInfo
-mkAltLabel uniq tag = CaseLabel uniq (CaseAlt tag)
-mkDefaultLabel uniq = CaseLabel uniq CaseDefault
-
-- Constructing Cost Center Labels
mkCCLabel :: CostCentre -> CLabel
mkCCSLabel :: CostCentreStack -> CLabel
@@ -682,31 +706,29 @@ 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 (CaseLabel n CaseReturnInfo) = CaseLabel n CaseReturnPt
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 Entry) = IdLabel n c InfoTable
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 (CaseLabel n CaseReturnPt) = CaseLabel n CaseReturnInfo
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)
-toRednCountsLbl :: CLabel -> Maybe CLabel
-toRednCountsLbl = fmap mkRednCountsLabel . hasHaskellName
-
hasHaskellName :: CLabel -> Maybe Name
hasHaskellName (IdLabel n _ _) = Just n
hasHaskellName _ = Nothing
@@ -747,10 +769,9 @@ needsCDecl :: CLabel -> Bool
-- don't bother declaring Bitmap labels, we always make sure
-- they are defined before use.
needsCDecl (SRTLabel _) = True
-needsCDecl (LargeSRTLabel _) = False
needsCDecl (LargeBitmapLabel _) = False
needsCDecl (IdLabel _ _ _) = True
-needsCDecl (CaseLabel _ _) = True
+needsCDecl (LocalBlockLabel _) = True
needsCDecl (StringLitLabel _) = False
needsCDecl (AsmTempLabel _) = False
@@ -773,11 +794,11 @@ needsCDecl (DynamicLinkerLabel {}) = panic "needsCDecl DynamicLinkerLabel"
needsCDecl PicBaseLabel = panic "needsCDecl PicBaseLabel"
needsCDecl (DeadStripPreventer {}) = panic "needsCDecl DeadStripPreventer"
--- | If a label is a local temporary used for native code generation
--- then return just its unique, otherwise nothing.
-maybeAsmTemp :: CLabel -> Maybe Unique
-maybeAsmTemp (AsmTempLabel uq) = Just uq
-maybeAsmTemp _ = Nothing
+-- | 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
@@ -880,11 +901,11 @@ math_funs = mkUniqSet [
-- 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 (CaseLabel _ _) = False
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
@@ -894,14 +915,13 @@ externallyVisibleCLabel (DynamicLinkerLabel _ _) = False
externallyVisibleCLabel (HpcTicksLabel _) = True
externallyVisibleCLabel (LargeBitmapLabel _) = False
externallyVisibleCLabel (SRTLabel _) = False
-externallyVisibleCLabel (LargeSRTLabel _) = False
externallyVisibleCLabel (PicBaseLabel {}) = panic "externallyVisibleCLabel PicBaseLabel"
externallyVisibleCLabel (DeadStripPreventer {}) = panic "externallyVisibleCLabel DeadStripPreventer"
externallyVisibleIdLabel :: IdLabelInfo -> Bool
-externallyVisibleIdLabel SRT = False
externallyVisibleIdLabel LocalInfoTable = False
externallyVisibleIdLabel LocalEntry = False
+externallyVisibleIdLabel BlockInfoTable = False
externallyVisibleIdLabel _ = True
-- -----------------------------------------------------------------------------
@@ -928,6 +948,7 @@ isGcPtrLabel lbl = case labelType lbl of
-- | 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
@@ -939,20 +960,28 @@ labelType (CmmLabel _ _ CmmRet) = CodeLabel
labelType (RtsLabel (RtsSelectorInfoTable _ _)) = DataLabel
labelType (RtsLabel (RtsApInfoTable _ _)) = DataLabel
labelType (RtsLabel (RtsApFast _)) = CodeLabel
-labelType (CaseLabel _ CaseReturnInfo) = DataLabel
-labelType (CaseLabel _ _) = CodeLabel
+labelType (RtsLabel _) = DataLabel
+labelType (LocalBlockLabel _) = CodeLabel
labelType (SRTLabel _) = DataLabel
-labelType (LargeSRTLabel _) = DataLabel
-labelType (LargeBitmapLabel _) = DataLabel
labelType (ForeignLabel _ _ _ IsFunction) = CodeLabel
-labelType (IdLabel _ _ info) = idInfoLabelType info
-labelType _ = DataLabel
+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
@@ -962,28 +991,48 @@ idInfoLabelType info =
-- -----------------------------------------------------------------------------
--- Does a CLabel need dynamic linkage?
+-- | 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 _ -> (WayDyn `elem` ways dflags) && (this_pkg /= rtsUnitId)
+ RtsLabel _ ->
+ (gopt Opt_ExternalDynamicRefs dflags) && (this_pkg /= rtsUnitId)
- IdLabel n _ _ -> isDllName dflags this_mod n
+ 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 ->
- (WayDyn `elem` ways dflags) && (this_pkg /= pkg)
+ (gopt Opt_ExternalDynamicRefs dflags) && (this_pkg /= pkg)
| otherwise ->
- True
+ gopt Opt_ExternalDynamicRefs dflags
+
+ LocalBlockLabel _ -> False
ForeignLabel _ _ source _ ->
if os == OSMinGW32
@@ -999,14 +1048,15 @@ labelDynamic dflags this_mod lbl =
-- When compiling in the "dyn" way, each package is to be
-- linked into its own DLL.
ForeignLabelInPackage pkgId ->
- (WayDyn `elem` ways dflags) && (this_pkg /= pkgId)
+ (gopt Opt_ExternalDynamicRefs dflags) && (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
- HpcTicksLabel m -> (WayDyn `elem` ways dflags) && this_mod /= m
+ HpcTicksLabel m ->
+ (gopt Opt_ExternalDynamicRefs dflags) && this_mod /= m
-- Note that DynamicLinkerLabels do NOT require dynamic linking themselves.
_ -> False
@@ -1028,7 +1078,6 @@ internal names. <type> is one of the following:
info Info table
srt Static reference table
- srtd Static reference table descriptor
entry Entry code (function, closure)
slow Slow entry code (if any)
ret Direct return address
@@ -1082,6 +1131,18 @@ 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
@@ -1089,19 +1150,19 @@ instance Outputable CLabel where
pprCLabel :: Platform -> CLabel -> SDoc
+pprCLabel _ (LocalBlockLabel u)
+ = tempLabelPrefixOrUnderscore <> pprUniqueAlways u
+
pprCLabel platform (AsmTempLabel u)
- | cGhcWithNativeCodeGen == "YES"
- = getPprStyle $ \ sty ->
- if asmStyle sty then
- ptext (asmTempLabelPrefix platform) <> pprUniqueAlways u
- else
- char '_' <> pprUniqueAlways u
+ | not (platformUnregisterised platform)
+ = tempLabelPrefixOrUnderscore <> pprUniqueAlways u
pprCLabel platform (AsmTempDerivedLabel l suf)
| cGhcWithNativeCodeGen == "YES"
= ptext (asmTempLabelPrefix platform)
- <> case l of AsmTempLabel u -> pprUniqueAlways u
- _other -> pprCLabel platform l
+ <> case l of AsmTempLabel u -> pprUniqueAlways u
+ LocalBlockLabel u -> pprUniqueAlways u
+ _other -> pprCLabel platform l
<> ftext suf
pprCLabel platform (DynamicLinkerLabel info lbl)
@@ -1114,7 +1175,15 @@ pprCLabel _ PicBaseLabel
pprCLabel platform (DeadStripPreventer lbl)
| cGhcWithNativeCodeGen == "YES"
- = pprCLabel platform lbl <> text "_dsp"
+ =
+ {-
+ `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 $ text "dsp_"
+ <> pprCLabel platform lbl <> text "_dsp"
pprCLabel _ (StringLitLabel u)
| cGhcWithNativeCodeGen == "YES"
@@ -1144,29 +1213,24 @@ pprCLbl :: CLabel -> SDoc
pprCLbl (StringLitLabel u)
= pprUniqueAlways u <> text "_str"
-pprCLbl (CaseLabel u CaseReturnPt)
- = hcat [pprUniqueAlways u, text "_ret"]
-pprCLbl (CaseLabel u CaseReturnInfo)
- = hcat [pprUniqueAlways u, text "_info"]
-pprCLbl (CaseLabel u (CaseAlt tag))
- = hcat [pprUniqueAlways u, pp_cSEP, int tag, text "_alt"]
-pprCLbl (CaseLabel u CaseDefault)
- = hcat [pprUniqueAlways u, text "_dflt"]
-
pprCLbl (SRTLabel u)
- = pprUniqueAlways u <> pp_cSEP <> text "srt"
+ = tempLabelPrefixOrUnderscore <> pprUniqueAlways u <> pp_cSEP <> text "srt"
-pprCLbl (LargeSRTLabel u) = pprUniqueAlways u <> pp_cSEP <> text "srtd"
-pprCLbl (LargeBitmapLabel u) = text "b" <> pprUniqueAlways u <> pp_cSEP <> text "btm"
+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 assmbly code.
+-- 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))
@@ -1229,7 +1293,8 @@ pprCLbl (RtsLabel (RtsSlowFastTickyCtr pat))
pprCLbl (ForeignLabel str _ _ _)
= ftext str
-pprCLbl (IdLabel name _cafs flavor) = ppr name <> ppIdFlavor flavor
+pprCLbl (IdLabel name _cafs flavor) =
+ internalNamePrefix name <> ppr name <> ppIdFlavor flavor
pprCLbl (CC_Label cc) = ppr cc
pprCLbl (CCS_Label ccs) = ppr ccs
@@ -1247,7 +1312,6 @@ ppIdFlavor :: IdLabelInfo -> SDoc
ppIdFlavor x = pp_cSEP <>
(case x of
Closure -> text "closure"
- SRT -> text "srt"
InfoTable -> text "info"
LocalInfoTable -> text "info"
Entry -> text "entry"
@@ -1258,6 +1322,7 @@ ppIdFlavor x = pp_cSEP <>
ConInfoTable -> text "con_info"
ClosureTable -> text "closure_tbl"
Bytes -> text "bytes"
+ BlockInfoTable -> text "info"
)
@@ -1272,6 +1337,24 @@ instance Outputable ForeignLabelSource where
ForeignLabelInThisPackage -> parens $ text "this package"
ForeignLabelInExternalPackage -> parens $ text "external package"
+internalNamePrefix :: Name -> SDoc
+internalNamePrefix name = getPprStyle $ \ sty ->
+ if codeStyle 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.
@@ -1285,53 +1368,62 @@ asmTempLabelPrefix platform = case platformOS platform of
_ -> sLit ".L"
pprDynamicLinkerAsmLabel :: Platform -> DynamicLinkerLabelInfo -> CLabel -> SDoc
-pprDynamicLinkerAsmLabel platform dllInfo lbl
- = if platformOS platform == OSDarwin
- then if platformArch platform == ArchX86_64
- then 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
- else case dllInfo of
- CodeStub -> char 'L' <> ppr lbl <> text "$stub"
- SymbolPtr -> char 'L' <> ppr lbl <> text "$non_lazy_ptr"
- _ -> panic "pprDynamicLinkerAsmLabel"
-
- else if platformOS platform == OSAIX
- then case dllInfo of
- SymbolPtr -> text "LC.." <> ppr lbl -- GCC's naming convention
- _ -> panic "pprDynamicLinkerAsmLabel"
-
- else if osElfTarget (platformOS platform)
- then if platformArch platform == ArchPPC
- then case dllInfo of
- CodeStub -> -- See Note [.LCTOC1 in PPC PIC code]
- ppr lbl <> text "+32768@plt"
- SymbolPtr -> text ".LC_" <> ppr lbl
- _ -> panic "pprDynamicLinkerAsmLabel"
- else if platformArch platform == ArchX86_64
- then case dllInfo of
- CodeStub -> ppr lbl <> text "@plt"
- GotSymbolPtr -> ppr lbl <> text "@gotpcrel"
- GotSymbolOffset -> ppr lbl
- SymbolPtr -> text ".LC_" <> ppr lbl
- else if platformArch platform == ArchPPC_64 ELF_V1
- || platformArch platform == ArchPPC_64 ELF_V2
- then case dllInfo of
- GotSymbolPtr -> text ".LC_" <> ppr lbl
- <> text "@toc"
- GotSymbolOffset -> ppr lbl
- SymbolPtr -> text ".LC_" <> ppr lbl
- _ -> panic "pprDynamicLinkerAsmLabel"
- else case dllInfo of
- CodeStub -> ppr lbl <> text "@plt"
- SymbolPtr -> text ".LC_" <> ppr lbl
- GotSymbolPtr -> ppr lbl <> text "@got"
- GotSymbolOffset -> ppr lbl <> text "@gotoff"
- else if platformOS platform == OSMinGW32
- then case dllInfo of
- SymbolPtr -> text "__imp_" <> ppr lbl
- _ -> panic "pprDynamicLinkerAsmLabel"
- else panic "pprDynamicLinkerAsmLabel"
-
+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"