CLabel.hs 59.5 KB
Newer Older
1 2 3 4
-----------------------------------------------------------------------------
--
-- Object-file symbols (called CLabel for histerical raisins).
--
Simon Marlow's avatar
Simon Marlow committed
5
-- (c) The University of Glasgow 2004-2006
6 7 8
--
-----------------------------------------------------------------------------

9
{-# LANGUAGE CPP #-}
10
{-# LANGUAGE BangPatterns #-}
11
{-# LANGUAGE LambdaCase #-}
12

13
module GHC.Cmm.CLabel (
Ian Lynagh's avatar
Ian Lynagh committed
14 15 16 17 18
        CLabel, -- abstract type
        ForeignLabelSource(..),
        pprDebugCLabel,

        mkClosureLabel,
19
        mkSRTLabel,
Ian Lynagh's avatar
Ian Lynagh committed
20 21 22 23 24 25 26
        mkInfoTableLabel,
        mkEntryLabel,
        mkRednCountsLabel,
        mkConInfoTableLabel,
        mkApEntryLabel,
        mkApInfoTableLabel,
        mkClosureTableLabel,
27
        mkBytesLabel,
Ian Lynagh's avatar
Ian Lynagh committed
28

29
        mkLocalBlockLabel,
Ian Lynagh's avatar
Ian Lynagh committed
30 31 32 33
        mkLocalClosureLabel,
        mkLocalInfoTableLabel,
        mkLocalClosureTableLabel,

34 35
        mkBlockInfoTableLabel,

Ian Lynagh's avatar
Ian Lynagh committed
36 37 38 39
        mkBitmapLabel,
        mkStringLitLabel,

        mkAsmTempLabel,
Peter Wortmann's avatar
Peter Wortmann committed
40 41
        mkAsmTempDerivedLabel,
        mkAsmTempEndLabel,
42
        mkAsmTempDieLabel,
43

Ian Lynagh's avatar
Ian Lynagh committed
44
        mkDirty_MUT_VAR_Label,
45
        mkNonmovingWriteBarrierEnabledLabel,
Ian Lynagh's avatar
Ian Lynagh committed
46 47 48
        mkUpdInfoLabel,
        mkBHUpdInfoLabel,
        mkIndStaticInfoLabel,
49
        mkMainCapabilityLabel,
50 51
        mkMAP_FROZEN_CLEAN_infoLabel,
        mkMAP_FROZEN_DIRTY_infoLabel,
Ian Lynagh's avatar
Ian Lynagh committed
52
        mkMAP_DIRTY_infoLabel,
53 54
        mkSMAP_FROZEN_CLEAN_infoLabel,
        mkSMAP_FROZEN_DIRTY_infoLabel,
55
        mkSMAP_DIRTY_infoLabel,
Ben Gamari's avatar
Ben Gamari committed
56
        mkBadAlignmentLabel,
57
        mkArrWords_infoLabel,
58
        mkSRTInfoLabel,
59

Ian Lynagh's avatar
Ian Lynagh committed
60
        mkTopTickyCtrLabel,
61
        mkCAFBlackHoleInfoTableLabel,
Ian Lynagh's avatar
Ian Lynagh committed
62
        mkRtsPrimOpLabel,
nfrisby's avatar
nfrisby committed
63
        mkRtsSlowFastTickyCtrLabel,
64

65
        mkSelectorInfoLabel,
Ian Lynagh's avatar
Ian Lynagh committed
66
        mkSelectorEntryLabel,
67

Ian Lynagh's avatar
Ian Lynagh committed
68 69 70 71 72 73
        mkCmmInfoLabel,
        mkCmmEntryLabel,
        mkCmmRetInfoLabel,
        mkCmmRetLabel,
        mkCmmCodeLabel,
        mkCmmDataLabel,
74
        mkCmmClosureLabel,
75

Ian Lynagh's avatar
Ian Lynagh committed
76
        mkRtsApFastLabel,
77

78 79
        mkPrimCallLabel,

Ian Lynagh's avatar
Ian Lynagh committed
80
        mkForeignLabel,
81
        addLabelSize,
82

83
        foreignLabelStdcallInfo,
84
        isBytesLabel,
85
        isForeignLabel,
86 87
        isSomeRODataLabel,
        isStaticClosureLabel,
Ian Lynagh's avatar
Ian Lynagh committed
88
        mkCCLabel, mkCCSLabel,
89

90 91 92
        DynamicLinkerLabelInfo(..),
        mkDynamicLinkerLabel,
        dynamicLinkerLabelInfo,
Ian Lynagh's avatar
Ian Lynagh committed
93

94
        mkPicBaseLabel,
95
        mkDeadStripPreventer,
96

andy@galois.com's avatar
andy@galois.com committed
97 98
        mkHpcTicksLabel,

99
        -- * Predicates
100
        hasCAF,
101
        needsCDecl, maybeLocalBlockLabel, externallyVisibleCLabel,
102
        isMathFun,
Ian Lynagh's avatar
Ian Lynagh committed
103
        isCFunctionLabel, isGcPtrLabel, labelDynamic,
104
        isLocalCLabel, mayRedirectTo,
105 106

        -- * Conversions
107
        toClosureLbl, toSlowEntryLbl, toEntryLbl, toInfoLbl, hasHaskellName,
108

109 110
        pprCLabel,
        isInfoTableLabel,
111
        isConInfoTableLabel,
112
        isIdLabel, isTickyLabel
113 114
    ) where

115 116
#include "HsVersions.h"

117
import GHC.Prelude
118

Sylvain Henry's avatar
Sylvain Henry committed
119 120
import GHC.Types.Id.Info
import GHC.Types.Basic
121
import {-# SOURCE #-} GHC.Cmm.BlockId (BlockId, mkBlockId)
Sylvain Henry's avatar
Sylvain Henry committed
122 123
import GHC.Unit.State
import GHC.Unit
Sylvain Henry's avatar
Sylvain Henry committed
124 125
import GHC.Types.Name
import GHC.Types.Unique
Sylvain Henry's avatar
Sylvain Henry committed
126
import GHC.Builtin.PrimOps
Sylvain Henry's avatar
Sylvain Henry committed
127
import GHC.Types.CostCentre
128 129
import GHC.Utils.Outputable
import GHC.Data.FastString
Sylvain Henry's avatar
Sylvain Henry committed
130
import GHC.Driver.Session
John Ericson's avatar
John Ericson committed
131
import GHC.Platform
Sylvain Henry's avatar
Sylvain Henry committed
132
import GHC.Types.Unique.Set
133
import GHC.Utils.Misc
Sylvain Henry's avatar
Sylvain Henry committed
134
import GHC.Core.Ppr ( {- instances -} )
135
import GHC.CmmToAsm.Config
136 137 138 139

-- -----------------------------------------------------------------------------
-- The CLabel type

Ben Gamari's avatar
Ben Gamari committed
140 141
{- |
  'CLabel' is an abstract type that supports the following operations:
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159

  - 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.
Ben Gamari's avatar
Ben Gamari committed
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178

  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.
179 180 181
-}

data CLabel
182
  = -- | A label related to the definition of a particular Id or Con in a .hs file.
Ian Lynagh's avatar
Ian Lynagh committed
183 184
    IdLabel
        Name
185
        CafInfo
Ian Lynagh's avatar
Ian Lynagh committed
186 187
        IdLabelInfo             -- encodes the suffix of the label

188
  -- | A label from a .cmm file that is not associated with a .hs level Id.
Ian Lynagh's avatar
Ian Lynagh committed
189
  | CmmLabel
190
        Unit                    -- what package the label belongs to.
Ian Lynagh's avatar
Ian Lynagh committed
191 192
        FastString              -- identifier giving the prefix of the label
        CmmLabelInfo            -- encodes the suffix of the label
193 194 195

  -- | 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
Ian Lynagh's avatar
Ian Lynagh committed
196
  --    If it doesn't have an algorithmically generated name then use a CmmLabel
197
  --    instead and give it an appropriate UnitId argument.
Ian Lynagh's avatar
Ian Lynagh committed
198 199
  | RtsLabel
        RtsLabelInfo
200

201 202 203 204 205 206 207 208
  -- | 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

209 210
  -- | A 'C' (or otherwise foreign) label.
  --
Ian Lynagh's avatar
Ian Lynagh committed
211 212 213 214 215 216
  | 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.
217

Ian Lynagh's avatar
Ian Lynagh committed
218
        ForeignLabelSource      -- what package the foreign label is in.
219

220 221
        FunctionOrData

Ben Gamari's avatar
Ben Gamari committed
222 223
  -- | Local temporary label used for native (or LLVM) code generation; must not
  -- appear outside of these contexts. Use primarily for debug information
Ian Lynagh's avatar
Ian Lynagh committed
224 225
  | AsmTempLabel
        {-# UNPACK #-} !Unique
226

Ben Gamari's avatar
Ben Gamari committed
227 228
  -- | A label \"derived\" from another 'CLabel' by the addition of a suffix.
  -- Must not occur outside of the NCG or LLVM code generators.
Peter Wortmann's avatar
Peter Wortmann committed
229 230 231 232
  | AsmTempDerivedLabel
        CLabel
        FastString              -- suffix

233
  | StringLitLabel
Ian Lynagh's avatar
Ian Lynagh committed
234
        {-# UNPACK #-} !Unique
235

236 237 238
  | CC_Label  CostCentre
  | CCS_Label CostCentreStack

Ian Lynagh's avatar
Ian Lynagh committed
239 240 241

  -- | These labels are generated and used inside the NCG only.
  --    They are special variants of a label used for dynamic linking
242
  --    see module PositionIndependentCode for details.
243
  | DynamicLinkerLabel DynamicLinkerLabelInfo CLabel
Ian Lynagh's avatar
Ian Lynagh committed
244 245 246 247

  -- | 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
248 249
  --    is pretty-printed as 1b, referring to the previous definition
  --    of 1: in the assembler source file.
Ian Lynagh's avatar
Ian Lynagh committed
250 251
  | PicBaseLabel

252 253
  -- | A label before an info table to prevent excessive dead-stripping on darwin
  | DeadStripPreventer CLabel
254

255

256 257
  -- | Per-module table of tick locations
  | HpcTicksLabel Module
258

259
  -- | Static reference table
260
  | SRTLabel
261 262
        {-# UNPACK #-} !Unique

263 264
  -- | A bitmap (function or case return)
  | LargeBitmapLabel
265 266
        {-# UNPACK #-} !Unique

niteria's avatar
niteria committed
267 268
  deriving Eq

269 270 271 272
isIdLabel :: CLabel -> Bool
isIdLabel IdLabel{} = True
isIdLabel _ = False

273 274 275 276 277 278
-- Used in SRT analysis. See Note [Ticky labels in SRT analysis] in
-- GHC.Cmm.Info.Build.
isTickyLabel :: CLabel -> Bool
isTickyLabel (IdLabel _ _ RednCounts) = True
isTickyLabel _ = False

niteria's avatar
niteria committed
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
-- 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
294
  compare (LocalBlockLabel u1) (LocalBlockLabel u2) = nonDetCmpUnique u1 u2
niteria's avatar
niteria committed
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
  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
328 329
  compare LocalBlockLabel{} _ = LT
  compare _ LocalBlockLabel{} = GT
niteria's avatar
niteria committed
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
  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
352 353 354 355 356

-- | Record where a foreign label is stored.
data ForeignLabelSource

   -- | Label is in a named package
357
   = ForeignLabelInPackage Unit
Ian Lynagh's avatar
Ian Lynagh committed
358

359
   -- | Label is in some external, system package that doesn't also
Ian Lynagh's avatar
Ian Lynagh committed
360 361 362 363
   --   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
364

365
   -- | Label is in the package currently being compiled.
Ian Lynagh's avatar
Ian Lynagh committed
366 367 368 369
   --   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.
370
   | ForeignLabelInThisPackage
Ian Lynagh's avatar
Ian Lynagh committed
371 372

   deriving (Eq, Ord)
373 374 375


-- | For debugging problems with the CLabel representation.
Ian Lynagh's avatar
Ian Lynagh committed
376 377
--      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.
378
--
379 380
pprDebugCLabel :: CLabel -> SDoc
pprDebugCLabel lbl
381
 = case lbl of
382 383
        IdLabel _ _ info-> ppr lbl <> (parens $ text "IdLabel"
                                       <> whenPprDebug (text ":" <> text (show info)))
Ian Lynagh's avatar
Ian Lynagh committed
384
        CmmLabel pkg _name _info
Ian Lynagh's avatar
Ian Lynagh committed
385
         -> ppr lbl <> (parens $ text "CmmLabel" <+> ppr pkg)
386

Ian Lynagh's avatar
Ian Lynagh committed
387
        RtsLabel{}      -> ppr lbl <> (parens $ text "RtsLabel")
388

Ian Lynagh's avatar
Ian Lynagh committed
389
        ForeignLabel _name mSuffix src funOrData
Ian Lynagh's avatar
Ian Lynagh committed
390
            -> ppr lbl <> (parens $ text "ForeignLabel"
Ian Lynagh's avatar
Ian Lynagh committed
391 392 393
                                <+> ppr mSuffix
                                <+> ppr src
                                <+> ppr funOrData)
394

395
        _               -> ppr lbl <> (parens $ text "other CLabel")
396 397


398
data IdLabelInfo
Ian Lynagh's avatar
Ian Lynagh committed
399
  = Closure             -- ^ Label for closure
400
  | InfoTable           -- ^ Info tables for closures; always read-only
Ian Lynagh's avatar
Ian Lynagh committed
401
  | Entry               -- ^ Entry point
402
  | Slow                -- ^ Slow entry point
403

404 405 406 407
  | 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
408

Ian Lynagh's avatar
Ian Lynagh committed
409 410
  | ConEntry            -- ^ Constructor entry point
  | ConInfoTable        -- ^ Corresponding info table
411

Ian Lynagh's avatar
Ian Lynagh committed
412
  | ClosureTable        -- ^ Table of closures for Enum tycons
413

414 415
  | Bytes               -- ^ Content of a string literal. See
                        -- Note [Bytes label].
416 417 418
  | BlockInfoTable      -- ^ Like LocalInfoTable but for a proc-point block
                        -- instead of a closure entry-point.
                        -- See Note [Proc-point local block entry-point].
419

420
  deriving (Eq, Ord, Show)
421 422 423


data RtsLabelInfo
424 425
  = RtsSelectorInfoTable Bool{-updatable-} Int{-offset-}  -- ^ Selector thunks
  | RtsSelectorEntry     Bool{-updatable-} Int{-offset-}
426

427 428
  | RtsApInfoTable       Bool{-updatable-} Int{-arity-}    -- ^ AP thunks
  | RtsApEntry           Bool{-updatable-} Int{-arity-}
429 430

  | RtsPrimOp PrimOp
Ian Lynagh's avatar
Ian Lynagh committed
431
  | RtsApFast     FastString    -- ^ _fast versions of generic apply
nfrisby's avatar
nfrisby committed
432
  | RtsSlowFastTickyCtr String
433 434

  deriving (Eq, Ord)
Sylvain Henry's avatar
Sylvain Henry committed
435
  -- NOTE: Eq on PtrString compares the pointer only, so this isn't
436
  -- a real equality.
437

438 439

-- | What type of Cmm label we're dealing with.
Ian Lynagh's avatar
Ian Lynagh committed
440 441
--      Determines the suffix appended to the name when a CLabel.CmmLabel
--      is pretty printed.
442
data CmmLabelInfo
443
  = CmmInfo                     -- ^ misc rts info tables,      suffix _info
Ian Lynagh's avatar
Ian Lynagh committed
444 445 446
  | CmmEntry                    -- ^ misc rts entry points,     suffix _entry
  | CmmRetInfo                  -- ^ misc rts ret info tables,  suffix _info
  | CmmRet                      -- ^ misc rts return points,    suffix _ret
447
  | CmmData                     -- ^ misc rts data bits, eg CHARLIKE_closure
Ian Lynagh's avatar
Ian Lynagh committed
448
  | CmmCode                     -- ^ misc rts code
449
  | CmmClosure                  -- ^ closures eg CHARLIKE_closure
Ian Lynagh's avatar
Ian Lynagh committed
450
  | CmmPrimCall                 -- ^ a prim call to some hand written Cmm code
451 452
  deriving (Eq, Ord)

453
data DynamicLinkerLabelInfo
Ian Lynagh's avatar
Ian Lynagh committed
454 455 456 457 458
  = CodeStub                    -- MachO: Lfoo$stub, ELF: foo@plt
  | SymbolPtr                   -- MachO: Lfoo$non_lazy_ptr, Windows: __imp_foo
  | GotSymbolPtr                -- ELF: foo@got
  | GotSymbolOffset             -- ELF: foo@gotoff

459
  deriving (Eq, Ord)
Ian Lynagh's avatar
Ian Lynagh committed
460

461

462 463
-- -----------------------------------------------------------------------------
-- Constructing CLabels
464
-- -----------------------------------------------------------------------------
465

Ian Lynagh's avatar
Ian Lynagh committed
466
-- Constructing IdLabels
467
-- These are always local:
468

469 470
mkSRTLabel     :: Unique -> CLabel
mkSRTLabel u = SRTLabel u
471

nfrisby's avatar
nfrisby committed
472
mkRednCountsLabel :: Name -> CLabel
473
mkRednCountsLabel name = IdLabel name NoCafRefs RednCounts  -- Note [ticky for LNE]
474 475

-- These have local & (possibly) external variants:
Ian Lynagh's avatar
Ian Lynagh committed
476 477 478
mkLocalClosureLabel      :: Name -> CafInfo -> CLabel
mkLocalInfoTableLabel    :: Name -> CafInfo -> CLabel
mkLocalClosureTableLabel :: Name -> CafInfo -> CLabel
479
mkLocalClosureLabel   !name !c  = IdLabel name  c Closure
480
mkLocalInfoTableLabel   name c  = IdLabel name  c LocalInfoTable
481 482
mkLocalClosureTableLabel name c = IdLabel name  c ClosureTable

Ian Lynagh's avatar
Ian Lynagh committed
483 484 485 486 487
mkClosureLabel              :: Name -> CafInfo -> CLabel
mkInfoTableLabel            :: Name -> CafInfo -> CLabel
mkEntryLabel                :: Name -> CafInfo -> CLabel
mkClosureTableLabel         :: Name -> CafInfo -> CLabel
mkConInfoTableLabel         :: Name -> CafInfo -> CLabel
488
mkBytesLabel                :: Name -> CLabel
489
mkClosureLabel name         c     = IdLabel name c Closure
490
mkInfoTableLabel name       c     = IdLabel name c InfoTable
491
mkEntryLabel name           c     = IdLabel name c Entry
492
mkClosureTableLabel name    c     = IdLabel name c ClosureTable
493
mkConInfoTableLabel name    c     = IdLabel name c ConInfoTable
494
mkBytesLabel name                 = IdLabel name NoCafRefs Bytes
495

496 497 498 499
mkBlockInfoTableLabel :: Name -> CafInfo -> CLabel
mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable
                               -- See Note [Proc-point local block entry-point].

500
-- Constructing Cmm Labels
501 502 503
mkDirty_MUT_VAR_Label,
    mkNonmovingWriteBarrierEnabledLabel,
    mkUpdInfoLabel,
Ian Lynagh's avatar
Ian Lynagh committed
504
    mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel,
505 506
    mkMAP_FROZEN_CLEAN_infoLabel, mkMAP_FROZEN_DIRTY_infoLabel,
    mkMAP_DIRTY_infoLabel,
507 508 509
    mkArrWords_infoLabel,
    mkTopTickyCtrLabel,
    mkCAFBlackHoleInfoTableLabel,
510
    mkSMAP_FROZEN_CLEAN_infoLabel, mkSMAP_FROZEN_DIRTY_infoLabel,
Ben Gamari's avatar
Ben Gamari committed
511
    mkSMAP_DIRTY_infoLabel, mkBadAlignmentLabel :: CLabel
512
mkDirty_MUT_VAR_Label           = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction
513 514
mkNonmovingWriteBarrierEnabledLabel
                                = CmmLabel rtsUnitId (fsLit "nonmoving_write_barrier_enabled") CmmData
515 516 517 518
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
519 520
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
521 522 523 524
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
525 526
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
527
mkSMAP_DIRTY_infoLabel          = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_DIRTY") CmmInfo
Ben Gamari's avatar
Ben Gamari committed
528
mkBadAlignmentLabel             = CmmLabel rtsUnitId (fsLit "stg_badAlignment")      CmmEntry
529

530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
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"

553
-----
554
mkCmmInfoLabel,   mkCmmEntryLabel, mkCmmRetInfoLabel, mkCmmRetLabel,
555
  mkCmmCodeLabel, mkCmmDataLabel,  mkCmmClosureLabel
556
        :: Unit -> FastString -> CLabel
557

Ian Lynagh's avatar
Ian Lynagh committed
558 559 560 561 562 563
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
564
mkCmmClosureLabel   pkg str     = CmmLabel pkg str CmmClosure
565

566 567
mkLocalBlockLabel :: Unique -> CLabel
mkLocalBlockLabel u = LocalBlockLabel u
568 569

-- Constructing RtsLabels
Ian Lynagh's avatar
Ian Lynagh committed
570
mkRtsPrimOpLabel :: PrimOp -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
571
mkRtsPrimOpLabel primop         = RtsLabel (RtsPrimOp primop)
572

Ian Lynagh's avatar
Ian Lynagh committed
573 574
mkSelectorInfoLabel  :: Bool -> Int -> CLabel
mkSelectorEntryLabel :: Bool -> Int -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
575 576
mkSelectorInfoLabel  upd off    = RtsLabel (RtsSelectorInfoTable upd off)
mkSelectorEntryLabel upd off    = RtsLabel (RtsSelectorEntry     upd off)
577

Ian Lynagh's avatar
Ian Lynagh committed
578 579
mkApInfoTableLabel :: Bool -> Int -> CLabel
mkApEntryLabel     :: Bool -> Int -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
580 581
mkApInfoTableLabel   upd off    = RtsLabel (RtsApInfoTable       upd off)
mkApEntryLabel       upd off    = RtsLabel (RtsApEntry           upd off)
582

583

584
-- A call to some primitive hand written Cmm code
585
mkPrimCallLabel :: PrimCall -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
586 587
mkPrimCallLabel (PrimCall str pkg)
        = CmmLabel pkg str CmmPrimCall
588

589

590
-- Constructing ForeignLabels
591

592
-- | Make a foreign label
Ian Lynagh's avatar
Ian Lynagh committed
593 594 595 596 597 598
mkForeignLabel
        :: FastString           -- name
        -> Maybe Int            -- size prefix
        -> ForeignLabelSource   -- what package it's in
        -> FunctionOrData
        -> CLabel
599

600
mkForeignLabel = ForeignLabel
601 602 603


-- | Update the label size field in a ForeignLabel
604
addLabelSize :: CLabel -> Int -> CLabel
605 606
addLabelSize (ForeignLabel str _ src  fod) sz
    = ForeignLabel str (Just sz) src fod
607
addLabelSize label _
608
    = label
609

610 611 612 613 614
-- | Whether label is a top-level string literal
isBytesLabel :: CLabel -> Bool
isBytesLabel (IdLabel _ _ Bytes) = True
isBytesLabel _lbl = False

615 616 617 618 619
-- | Whether label is a non-haskell label (defined in C code)
isForeignLabel :: CLabel -> Bool
isForeignLabel (ForeignLabel _ _ _ _) = True
isForeignLabel _lbl = False

620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
-- | 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
635
isSomeRODataLabel (IdLabel _ _ BlockInfoTable) = True
636 637 638 639
-- info table defined in cmm (.cmm)
isSomeRODataLabel (CmmLabel _ _ CmmInfo) = True
isSomeRODataLabel _lbl = False

640 641 642 643 644 645 646 647 648 649 650 651 652
-- | 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

653
-- | Get the label size field from a ForeignLabel
654
foreignLabelStdcallInfo :: CLabel -> Maybe Int
655
foreignLabelStdcallInfo (ForeignLabel _ info _ _) = info
656 657
foreignLabelStdcallInfo _lbl = Nothing

658

659
-- Constructing Large*Labels
Ian Lynagh's avatar
Ian Lynagh committed
660
mkBitmapLabel   :: Unique -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
661
mkBitmapLabel   uniq            = LargeBitmapLabel uniq
662 663

-- Constructing Cost Center Labels
Ian Lynagh's avatar
Ian Lynagh committed
664 665
mkCCLabel  :: CostCentre      -> CLabel
mkCCSLabel :: CostCentreStack -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
666 667
mkCCLabel           cc          = CC_Label cc
mkCCSLabel          ccs         = CCS_Label ccs
668

Ian Lynagh's avatar
Ian Lynagh committed
669
mkRtsApFastLabel :: FastString -> CLabel
670 671
mkRtsApFastLabel str = RtsLabel (RtsApFast str)

nfrisby's avatar
nfrisby committed
672 673
mkRtsSlowFastTickyCtrLabel :: String -> CLabel
mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat)
674

andy@galois.com's avatar
andy@galois.com committed
675

676
-- Constructing Code Coverage Labels
Ian Lynagh's avatar
Ian Lynagh committed
677
mkHpcTicksLabel :: Module -> CLabel
andy@galois.com's avatar
andy@galois.com committed
678 679
mkHpcTicksLabel                = HpcTicksLabel

680 681

-- Constructing labels used for dynamic linking
682
mkDynamicLinkerLabel :: DynamicLinkerLabelInfo -> CLabel -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
683
mkDynamicLinkerLabel            = DynamicLinkerLabel
684 685 686

dynamicLinkerLabelInfo :: CLabel -> Maybe (DynamicLinkerLabelInfo, CLabel)
dynamicLinkerLabelInfo (DynamicLinkerLabel info lbl) = Just (info, lbl)
Ian Lynagh's avatar
Ian Lynagh committed
687 688
dynamicLinkerLabelInfo _        = Nothing

689
mkPicBaseLabel :: CLabel
Ian Lynagh's avatar
Ian Lynagh committed
690
mkPicBaseLabel                  = PicBaseLabel
691

692 693

-- Constructing miscellaneous other labels
694
mkDeadStripPreventer :: CLabel -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
695
mkDeadStripPreventer lbl        = DeadStripPreventer lbl
696 697

mkStringLitLabel :: Unique -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
698
mkStringLitLabel                = StringLitLabel
699 700

mkAsmTempLabel :: Uniquable a => a -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
701
mkAsmTempLabel a                = AsmTempLabel (getUnique a)
702

Peter Wortmann's avatar
Peter Wortmann committed
703 704 705 706 707
mkAsmTempDerivedLabel :: CLabel -> FastString -> CLabel
mkAsmTempDerivedLabel = AsmTempDerivedLabel

mkAsmTempEndLabel :: CLabel -> CLabel
mkAsmTempEndLabel l = mkAsmTempDerivedLabel l (fsLit "_end")
708

709 710 711 712 713
-- | Construct a label for a DWARF Debug Information Entity (DIE)
-- describing another symbol.
mkAsmTempDieLabel :: CLabel -> CLabel
mkAsmTempDieLabel l = mkAsmTempDerivedLabel l (fsLit "_die")

714
-- -----------------------------------------------------------------------------
715 716
-- Convert between different kinds of label

717 718
toClosureLbl :: CLabel -> CLabel
toClosureLbl (IdLabel n c _) = IdLabel n c Closure
719
toClosureLbl (CmmLabel m str _) = CmmLabel m str CmmClosure
720 721 722
toClosureLbl l = pprPanic "toClosureLbl" (ppr l)

toSlowEntryLbl :: CLabel -> CLabel
723 724
toSlowEntryLbl (IdLabel n _ BlockInfoTable)
  = pprPanic "toSlowEntryLbl" (ppr n)
725 726 727 728 729 730
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
731
toEntryLbl (IdLabel n _ BlockInfoTable)  = mkLocalBlockLabel (nameUnique n)
732
                              -- See Note [Proc-point local block entry-point].
733 734 735 736 737 738 739 740 741 742 743 744
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)
745

nfrisby's avatar
nfrisby committed
746 747 748 749
hasHaskellName :: CLabel -> Maybe Name
hasHaskellName (IdLabel n _ _) = Just n
hasHaskellName _               = Nothing

750
-- -----------------------------------------------------------------------------
nfrisby's avatar
nfrisby committed
751
-- Does a CLabel's referent itself refer to a CAF?
752
hasCAF :: CLabel -> Bool
nfrisby's avatar
nfrisby committed
753
hasCAF (IdLabel _ _ RednCounts) = False -- Note [ticky for LNE]
754 755
hasCAF (IdLabel _ MayHaveCafRefs _) = True
hasCAF _                            = False
756

nfrisby's avatar
nfrisby committed
757 758 759 760 761
-- 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
762
-- GHC.Cmm.Info.Build.cafTransfers would consider such a ticky label
nfrisby's avatar
nfrisby committed
763 764 765 766 767 768 769 770 771 772 773 774
-- 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.
775

776 777
-- -----------------------------------------------------------------------------
-- Does a CLabel need declaring before use or not?
778
--
779
-- See wiki:commentary/compiler/backends/ppr-c#prototypes
780 781 782

needsCDecl :: CLabel -> Bool
  -- False <=> it's pre-declared; don't bother
783
  -- don't bother declaring Bitmap labels, we always make sure
784
  -- they are defined before use.
785
needsCDecl (SRTLabel _)                 = True
Ian Lynagh's avatar
Ian Lynagh committed
786 787
needsCDecl (LargeBitmapLabel _)         = False
needsCDecl (IdLabel _ _ _)              = True
788
needsCDecl (LocalBlockLabel _)          = True
789

Ian Lynagh's avatar
Ian Lynagh committed
790 791
needsCDecl (StringLitLabel _)           = False
needsCDecl (AsmTempLabel _)             = False
Peter Wortmann's avatar
Peter Wortmann committed
792
needsCDecl (AsmTempDerivedLabel _ _)    = False
Ian Lynagh's avatar
Ian Lynagh committed
793 794 795 796 797
needsCDecl (RtsLabel _)                 = False

needsCDecl (CmmLabel pkgId _ _)
        -- Prototypes for labels defined in the runtime system are imported
        --      into HC files via includes/Stg.h.
798
        | pkgId == rtsUnitId         = False
Ian Lynagh's avatar
Ian Lynagh committed
799 800 801 802 803 804 805

        -- 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
andy@galois.com's avatar
andy@galois.com committed
806
needsCDecl (HpcTicksLabel _)            = True
Ian Lynagh's avatar
Ian Lynagh committed
807 808 809
needsCDecl (DynamicLinkerLabel {})      = panic "needsCDecl DynamicLinkerLabel"
needsCDecl PicBaseLabel                 = panic "needsCDecl PicBaseLabel"
needsCDecl (DeadStripPreventer {})      = panic "needsCDecl DeadStripPreventer"
810

811 812 813 814 815
-- | 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
816

817

Ian Lynagh's avatar
Ian Lynagh committed
818
-- | Check whether a label corresponds to a C function that has
819
--      a prototype in a system header somewhere, or is built-in
820
--      to the C compiler. For these labels we avoid generating our
821
--      own C prototypes.
822
isMathFun :: CLabel -> Bool
Ian Lynagh's avatar
Ian Lynagh committed
823
isMathFun (ForeignLabel fs _ _ _)       = fs `elementOfUniqSet` math_funs
824 825
isMathFun _ = False

Ian Lynagh's avatar
Ian Lynagh committed
826
math_funs :: UniqSet FastString
827
math_funs = mkUniqSet [
828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
        -- _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