CLabel.hs 59.6 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

12
module GHC.Cmm.CLabel (
13 14 15 16 17
        CLabel, -- abstract type
        ForeignLabelSource(..),
        pprDebugCLabel,

        mkClosureLabel,
18
        mkSRTLabel,
19 20 21 22 23 24 25
        mkInfoTableLabel,
        mkEntryLabel,
        mkRednCountsLabel,
        mkConInfoTableLabel,
        mkApEntryLabel,
        mkApInfoTableLabel,
        mkClosureTableLabel,
26
        mkBytesLabel,
27

28
        mkLocalBlockLabel,
29 30 31 32
        mkLocalClosureLabel,
        mkLocalInfoTableLabel,
        mkLocalClosureTableLabel,

33 34
        mkBlockInfoTableLabel,

35 36 37 38
        mkBitmapLabel,
        mkStringLitLabel,

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

43
        mkDirty_MUT_VAR_Label,
44
        mkNonmovingWriteBarrierEnabledLabel,
45 46 47
        mkUpdInfoLabel,
        mkBHUpdInfoLabel,
        mkIndStaticInfoLabel,
48
        mkMainCapabilityLabel,
49 50
        mkMAP_FROZEN_CLEAN_infoLabel,
        mkMAP_FROZEN_DIRTY_infoLabel,
51
        mkMAP_DIRTY_infoLabel,
52 53
        mkSMAP_FROZEN_CLEAN_infoLabel,
        mkSMAP_FROZEN_DIRTY_infoLabel,
54
        mkSMAP_DIRTY_infoLabel,
55
        mkBadAlignmentLabel,
56
        mkArrWords_infoLabel,
57
        mkSRTInfoLabel,
58

59
        mkTopTickyCtrLabel,
60
        mkCAFBlackHoleInfoTableLabel,
61
        mkRtsPrimOpLabel,
nfrisby's avatar
nfrisby committed
62
        mkRtsSlowFastTickyCtrLabel,
63

64
        mkSelectorInfoLabel,
65
        mkSelectorEntryLabel,
66

67 68 69 70 71 72
        mkCmmInfoLabel,
        mkCmmEntryLabel,
        mkCmmRetInfoLabel,
        mkCmmRetLabel,
        mkCmmCodeLabel,
        mkCmmDataLabel,
73
        mkCmmClosureLabel,
74

75
        mkRtsApFastLabel,
76

77 78
        mkPrimCallLabel,

79
        mkForeignLabel,
80
        addLabelSize,
81

82
        foreignLabelStdcallInfo,
83
        isBytesLabel,
84
        isForeignLabel,
85 86
        isSomeRODataLabel,
        isStaticClosureLabel,
87
        mkCCLabel, mkCCSLabel,
88

89 90 91
        DynamicLinkerLabelInfo(..),
        mkDynamicLinkerLabel,
        dynamicLinkerLabelInfo,
92

93
        mkPicBaseLabel,
94
        mkDeadStripPreventer,
95

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

98
        -- * Predicates
99
        hasCAF,
100
        needsCDecl, maybeLocalBlockLabel, externallyVisibleCLabel,
101
        isMathFun,
102
        isCFunctionLabel, isGcPtrLabel, labelDynamic,
103
        isLocalCLabel, mayRedirectTo,
104 105

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

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

114 115
#include "HsVersions.h"

116 117
import GhcPrelude

118
import IdInfo
119
import BasicTypes
120
import {-# SOURCE #-} GHC.Cmm.BlockId (BlockId, mkBlockId)
Sylvain Henry's avatar
Sylvain Henry committed
121
import GHC.Driver.Packages
Simon Marlow's avatar
Simon Marlow committed
122 123 124 125 126
import Module
import Name
import Unique
import PrimOp
import CostCentre
127 128
import Outputable
import FastString
Sylvain Henry's avatar
Sylvain Henry committed
129
import GHC.Driver.Session
John Ericson's avatar
John Ericson committed
130
import GHC.Platform
131
import UniqSet
132
import Util
Sylvain Henry's avatar
Sylvain Henry committed
133
import GHC.Core.Ppr ( {- instances -} )
134 135 136 137

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

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

  - 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
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176

  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.
177 178 179
-}

data CLabel
180
  = -- | A label related to the definition of a particular Id or Con in a .hs file.
181 182
    IdLabel
        Name
183
        CafInfo
184 185
        IdLabelInfo             -- encodes the suffix of the label

186
  -- | A label from a .cmm file that is not associated with a .hs level Id.
187
  | CmmLabel
188
        UnitId               -- what package the label belongs to.
189 190
        FastString              -- identifier giving the prefix of the label
        CmmLabelInfo            -- encodes the suffix of the label
191 192 193

  -- | 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
194
  --    If it doesn't have an algorithmically generated name then use a CmmLabel
195
  --    instead and give it an appropriate UnitId argument.
196 197
  | RtsLabel
        RtsLabelInfo
198

199 200 201 202 203 204 205 206
  -- | 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

207 208
  -- | A 'C' (or otherwise foreign) label.
  --
209 210 211 212 213 214
  | 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.
215

216
        ForeignLabelSource      -- what package the foreign label is in.
217

218 219
        FunctionOrData

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

Ben Gamari's avatar
Ben Gamari committed
225 226
  -- | 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
227 228 229 230
  | AsmTempDerivedLabel
        CLabel
        FastString              -- suffix

231
  | StringLitLabel
232
        {-# UNPACK #-} !Unique
233

234 235 236
  | CC_Label  CostCentre
  | CCS_Label CostCentreStack

237 238 239

  -- | These labels are generated and used inside the NCG only.
  --    They are special variants of a label used for dynamic linking
240
  --    see module PositionIndependentCode for details.
241
  | DynamicLinkerLabel DynamicLinkerLabelInfo CLabel
242 243 244 245

  -- | 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
246 247
  --    is pretty-printed as 1b, referring to the previous definition
  --    of 1: in the assembler source file.
248 249
  | PicBaseLabel

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

253

254 255
  -- | Per-module table of tick locations
  | HpcTicksLabel Module
256

257
  -- | Static reference table
258
  | SRTLabel
259 260
        {-# UNPACK #-} !Unique

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

niteria's avatar
niteria committed
265 266
  deriving Eq

267 268 269 270
isIdLabel :: CLabel -> Bool
isIdLabel IdLabel{} = True
isIdLabel _ = False

niteria's avatar
niteria committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
-- 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
286
  compare (LocalBlockLabel u1) (LocalBlockLabel u2) = nonDetCmpUnique u1 u2
niteria's avatar
niteria committed
287 288 289 290 291 292 293 294 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
  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
320 321
  compare LocalBlockLabel{} _ = LT
  compare _ LocalBlockLabel{} = GT
niteria's avatar
niteria committed
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
  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
344 345 346 347 348

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

   -- | Label is in a named package
349
   = ForeignLabelInPackage      UnitId
350

351
   -- | Label is in some external, system package that doesn't also
352 353 354 355
   --   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
356

357
   -- | Label is in the package currently being compiled.
358 359 360 361
   --   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.
362
   | ForeignLabelInThisPackage
363 364

   deriving (Eq, Ord)
365 366 367


-- | For debugging problems with the CLabel representation.
368 369
--      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.
370
--
371 372
pprDebugCLabel :: CLabel -> SDoc
pprDebugCLabel lbl
373
 = case lbl of
374 375
        IdLabel _ _ info-> ppr lbl <> (parens $ text "IdLabel"
                                       <> whenPprDebug (text ":" <> text (show info)))
Ian Lynagh's avatar
Ian Lynagh committed
376
        CmmLabel pkg _name _info
Ian Lynagh's avatar
Ian Lynagh committed
377
         -> ppr lbl <> (parens $ text "CmmLabel" <+> ppr pkg)
378

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

Ian Lynagh's avatar
Ian Lynagh committed
381
        ForeignLabel _name mSuffix src funOrData
Ian Lynagh's avatar
Ian Lynagh committed
382
            -> ppr lbl <> (parens $ text "ForeignLabel"
383 384 385
                                <+> ppr mSuffix
                                <+> ppr src
                                <+> ppr funOrData)
386

387
        _               -> ppr lbl <> (parens $ text "other CLabel")
388 389


390
data IdLabelInfo
391
  = Closure             -- ^ Label for closure
392
  | InfoTable           -- ^ Info tables for closures; always read-only
393
  | Entry               -- ^ Entry point
394
  | Slow                -- ^ Slow entry point
395

396 397 398 399
  | 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
400

401 402
  | ConEntry            -- ^ Constructor entry point
  | ConInfoTable        -- ^ Corresponding info table
403

404
  | ClosureTable        -- ^ Table of closures for Enum tycons
405

406 407
  | Bytes               -- ^ Content of a string literal. See
                        -- Note [Bytes label].
408 409 410
  | BlockInfoTable      -- ^ Like LocalInfoTable but for a proc-point block
                        -- instead of a closure entry-point.
                        -- See Note [Proc-point local block entry-point].
411

412
  deriving (Eq, Ord, Show)
413 414 415


data RtsLabelInfo
416 417
  = RtsSelectorInfoTable Bool{-updatable-} Int{-offset-}  -- ^ Selector thunks
  | RtsSelectorEntry     Bool{-updatable-} Int{-offset-}
418

419 420
  | RtsApInfoTable       Bool{-updatable-} Int{-arity-}    -- ^ AP thunks
  | RtsApEntry           Bool{-updatable-} Int{-arity-}
421 422

  | RtsPrimOp PrimOp
423
  | RtsApFast     FastString    -- ^ _fast versions of generic apply
nfrisby's avatar
nfrisby committed
424
  | RtsSlowFastTickyCtr String
425 426

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

430 431

-- | What type of Cmm label we're dealing with.
432 433
--      Determines the suffix appended to the name when a CLabel.CmmLabel
--      is pretty printed.
434
data CmmLabelInfo
435
  = CmmInfo                     -- ^ misc rts info tables,      suffix _info
436 437 438
  | CmmEntry                    -- ^ misc rts entry points,     suffix _entry
  | CmmRetInfo                  -- ^ misc rts ret info tables,  suffix _info
  | CmmRet                      -- ^ misc rts return points,    suffix _ret
439
  | CmmData                     -- ^ misc rts data bits, eg CHARLIKE_closure
440
  | CmmCode                     -- ^ misc rts code
441
  | CmmClosure                  -- ^ closures eg CHARLIKE_closure
442
  | CmmPrimCall                 -- ^ a prim call to some hand written Cmm code
443 444
  deriving (Eq, Ord)

445
data DynamicLinkerLabelInfo
446 447 448 449 450
  = CodeStub                    -- MachO: Lfoo$stub, ELF: foo@plt
  | SymbolPtr                   -- MachO: Lfoo$non_lazy_ptr, Windows: __imp_foo
  | GotSymbolPtr                -- ELF: foo@got
  | GotSymbolOffset             -- ELF: foo@gotoff

451
  deriving (Eq, Ord)
452

453

454 455
-- -----------------------------------------------------------------------------
-- Constructing CLabels
456
-- -----------------------------------------------------------------------------
457

458
-- Constructing IdLabels
459
-- These are always local:
460

461 462
mkSRTLabel     :: Unique -> CLabel
mkSRTLabel u = SRTLabel u
463

nfrisby's avatar
nfrisby committed
464 465 466
mkRednCountsLabel :: Name -> CLabel
mkRednCountsLabel       name    =
  IdLabel name NoCafRefs RednCounts  -- Note [ticky for LNE]
467 468

-- These have local & (possibly) external variants:
Ian Lynagh's avatar
Ian Lynagh committed
469 470 471
mkLocalClosureLabel      :: Name -> CafInfo -> CLabel
mkLocalInfoTableLabel    :: Name -> CafInfo -> CLabel
mkLocalClosureTableLabel :: Name -> CafInfo -> CLabel
472
mkLocalClosureLabel   !name !c  = IdLabel name  c Closure
473
mkLocalInfoTableLabel   name c  = IdLabel name  c LocalInfoTable
474 475
mkLocalClosureTableLabel name c = IdLabel name  c ClosureTable

Ian Lynagh's avatar
Ian Lynagh committed
476 477 478 479 480
mkClosureLabel              :: Name -> CafInfo -> CLabel
mkInfoTableLabel            :: Name -> CafInfo -> CLabel
mkEntryLabel                :: Name -> CafInfo -> CLabel
mkClosureTableLabel         :: Name -> CafInfo -> CLabel
mkConInfoTableLabel         :: Name -> CafInfo -> CLabel
481
mkBytesLabel                :: Name -> CLabel
482
mkClosureLabel name         c     = IdLabel name c Closure
483
mkInfoTableLabel name       c     = IdLabel name c InfoTable
484
mkEntryLabel name           c     = IdLabel name c Entry
485
mkClosureTableLabel name    c     = IdLabel name c ClosureTable
486
mkConInfoTableLabel name    c     = IdLabel name c ConInfoTable
487
mkBytesLabel name                 = IdLabel name NoCafRefs Bytes
488

489 490 491 492
mkBlockInfoTableLabel :: Name -> CafInfo -> CLabel
mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable
                               -- See Note [Proc-point local block entry-point].

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

523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
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"

546
-----
547
mkCmmInfoLabel,   mkCmmEntryLabel, mkCmmRetInfoLabel, mkCmmRetLabel,
548
  mkCmmCodeLabel, mkCmmDataLabel,  mkCmmClosureLabel
549
        :: UnitId -> FastString -> CLabel
550

551 552 553 554 555 556
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
557
mkCmmClosureLabel   pkg str     = CmmLabel pkg str CmmClosure
558

559 560
mkLocalBlockLabel :: Unique -> CLabel
mkLocalBlockLabel u = LocalBlockLabel u
561 562

-- Constructing RtsLabels
Ian Lynagh's avatar
Ian Lynagh committed
563
mkRtsPrimOpLabel :: PrimOp -> CLabel
564
mkRtsPrimOpLabel primop         = RtsLabel (RtsPrimOp primop)
565

Ian Lynagh's avatar
Ian Lynagh committed
566 567
mkSelectorInfoLabel  :: Bool -> Int -> CLabel
mkSelectorEntryLabel :: Bool -> Int -> CLabel
568 569
mkSelectorInfoLabel  upd off    = RtsLabel (RtsSelectorInfoTable upd off)
mkSelectorEntryLabel upd off    = RtsLabel (RtsSelectorEntry     upd off)
570

Ian Lynagh's avatar
Ian Lynagh committed
571 572
mkApInfoTableLabel :: Bool -> Int -> CLabel
mkApEntryLabel     :: Bool -> Int -> CLabel
573 574
mkApInfoTableLabel   upd off    = RtsLabel (RtsApInfoTable       upd off)
mkApEntryLabel       upd off    = RtsLabel (RtsApEntry           upd off)
575

576

577
-- A call to some primitive hand written Cmm code
578
mkPrimCallLabel :: PrimCall -> CLabel
579 580
mkPrimCallLabel (PrimCall str pkg)
        = CmmLabel pkg str CmmPrimCall
581

582

583
-- Constructing ForeignLabels
584

585
-- | Make a foreign label
586 587 588 589 590 591
mkForeignLabel
        :: FastString           -- name
        -> Maybe Int            -- size prefix
        -> ForeignLabelSource   -- what package it's in
        -> FunctionOrData
        -> CLabel
592

593
mkForeignLabel = ForeignLabel
594 595 596


-- | Update the label size field in a ForeignLabel
597
addLabelSize :: CLabel -> Int -> CLabel
598 599
addLabelSize (ForeignLabel str _ src  fod) sz
    = ForeignLabel str (Just sz) src fod
600
addLabelSize label _
601
    = label
602

603 604 605 606 607
-- | Whether label is a top-level string literal
isBytesLabel :: CLabel -> Bool
isBytesLabel (IdLabel _ _ Bytes) = True
isBytesLabel _lbl = False

608 609 610 611 612
-- | Whether label is a non-haskell label (defined in C code)
isForeignLabel :: CLabel -> Bool
isForeignLabel (ForeignLabel _ _ _ _) = True
isForeignLabel _lbl = False

613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
-- | 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
628
isSomeRODataLabel (IdLabel _ _ BlockInfoTable) = True
629 630 631 632
-- info table defined in cmm (.cmm)
isSomeRODataLabel (CmmLabel _ _ CmmInfo) = True
isSomeRODataLabel _lbl = False

633 634 635 636 637 638 639 640 641 642 643 644 645
-- | 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

646
-- | Get the label size field from a ForeignLabel
647
foreignLabelStdcallInfo :: CLabel -> Maybe Int
648
foreignLabelStdcallInfo (ForeignLabel _ info _ _) = info
649 650
foreignLabelStdcallInfo _lbl = Nothing

651

652
-- Constructing Large*Labels
Ian Lynagh's avatar
Ian Lynagh committed
653
mkBitmapLabel   :: Unique -> CLabel
654
mkBitmapLabel   uniq            = LargeBitmapLabel uniq
655 656

-- Constructing Cost Center Labels
Ian Lynagh's avatar
Ian Lynagh committed
657 658
mkCCLabel  :: CostCentre      -> CLabel
mkCCSLabel :: CostCentreStack -> CLabel
659 660
mkCCLabel           cc          = CC_Label cc
mkCCSLabel          ccs         = CCS_Label ccs
661

Ian Lynagh's avatar
Ian Lynagh committed
662
mkRtsApFastLabel :: FastString -> CLabel
663 664
mkRtsApFastLabel str = RtsLabel (RtsApFast str)

nfrisby's avatar
nfrisby committed
665 666
mkRtsSlowFastTickyCtrLabel :: String -> CLabel
mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat)
667

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

669
-- Constructing Code Coverage Labels
Ian Lynagh's avatar
Ian Lynagh committed
670
mkHpcTicksLabel :: Module -> CLabel
andy@galois.com's avatar
andy@galois.com committed
671 672
mkHpcTicksLabel                = HpcTicksLabel

673 674

-- Constructing labels used for dynamic linking
675
mkDynamicLinkerLabel :: DynamicLinkerLabelInfo -> CLabel -> CLabel
676
mkDynamicLinkerLabel            = DynamicLinkerLabel
677 678 679

dynamicLinkerLabelInfo :: CLabel -> Maybe (DynamicLinkerLabelInfo, CLabel)
dynamicLinkerLabelInfo (DynamicLinkerLabel info lbl) = Just (info, lbl)
680 681
dynamicLinkerLabelInfo _        = Nothing

682
mkPicBaseLabel :: CLabel
683
mkPicBaseLabel                  = PicBaseLabel
684

685 686

-- Constructing miscellaneous other labels
687
mkDeadStripPreventer :: CLabel -> CLabel
688
mkDeadStripPreventer lbl        = DeadStripPreventer lbl
689 690

mkStringLitLabel :: Unique -> CLabel
691
mkStringLitLabel                = StringLitLabel
692 693

mkAsmTempLabel :: Uniquable a => a -> CLabel
694
mkAsmTempLabel a                = AsmTempLabel (getUnique a)
695

Peter Wortmann's avatar
Peter Wortmann committed
696 697 698 699 700
mkAsmTempDerivedLabel :: CLabel -> FastString -> CLabel
mkAsmTempDerivedLabel = AsmTempDerivedLabel

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

702 703 704 705 706
-- | Construct a label for a DWARF Debug Information Entity (DIE)
-- describing another symbol.
mkAsmTempDieLabel :: CLabel -> CLabel
mkAsmTempDieLabel l = mkAsmTempDerivedLabel l (fsLit "_die")

707
-- -----------------------------------------------------------------------------
708 709
-- Convert between different kinds of label

710 711
toClosureLbl :: CLabel -> CLabel
toClosureLbl (IdLabel n c _) = IdLabel n c Closure
712
toClosureLbl (CmmLabel m str _) = CmmLabel m str CmmClosure
713 714 715
toClosureLbl l = pprPanic "toClosureLbl" (ppr l)

toSlowEntryLbl :: CLabel -> CLabel
716 717
toSlowEntryLbl (IdLabel n _ BlockInfoTable)
  = pprPanic "toSlowEntryLbl" (ppr n)
718 719 720 721 722 723
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
724
toEntryLbl (IdLabel n _ BlockInfoTable)  = mkLocalBlockLabel (nameUnique n)
725
                              -- See Note [Proc-point local block entry-point].
726 727 728 729 730 731 732 733 734 735 736 737
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)
738

nfrisby's avatar
nfrisby committed
739 740 741 742
hasHaskellName :: CLabel -> Maybe Name
hasHaskellName (IdLabel n _ _) = Just n
hasHaskellName _               = Nothing

743
-- -----------------------------------------------------------------------------
nfrisby's avatar
nfrisby committed
744
-- Does a CLabel's referent itself refer to a CAF?
745
hasCAF :: CLabel -> Bool
nfrisby's avatar
nfrisby committed
746
hasCAF (IdLabel _ _ RednCounts) = False -- Note [ticky for LNE]
747 748
hasCAF (IdLabel _ MayHaveCafRefs _) = True
hasCAF _                            = False
749

nfrisby's avatar
nfrisby committed
750 751 752 753 754
-- 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
755
-- GHC.Cmm.Info.Build.cafTransfers would consider such a ticky label
nfrisby's avatar
nfrisby committed
756 757 758 759 760 761 762 763 764 765 766 767
-- 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.
768

769 770
-- -----------------------------------------------------------------------------
-- Does a CLabel need declaring before use or not?
771
--
772
-- See wiki:commentary/compiler/backends/ppr-c#prototypes
773 774 775

needsCDecl :: CLabel -> Bool
  -- False <=> it's pre-declared; don't bother
776
  -- don't bother declaring Bitmap labels, we always make sure
777
  -- they are defined before use.
778
needsCDecl (SRTLabel _)                 = True
779 780
needsCDecl (LargeBitmapLabel _)         = False
needsCDecl (IdLabel _ _ _)              = True
781
needsCDecl (LocalBlockLabel _)          = True
782

783 784
needsCDecl (StringLitLabel _)           = False
needsCDecl (AsmTempLabel _)             = False
Peter Wortmann's avatar
Peter Wortmann committed
785
needsCDecl (AsmTempDerivedLabel _ _)    = False
786 787 788 789 790
needsCDecl (RtsLabel _)                 = False

needsCDecl (CmmLabel pkgId _ _)
        -- Prototypes for labels defined in the runtime system are imported
        --      into HC files via includes/Stg.h.
791
        | pkgId == rtsUnitId         = False
792 793 794 795 796 797 798

        -- 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
799
needsCDecl (HpcTicksLabel _)            = True
Ian Lynagh's avatar
Ian Lynagh committed
800 801 802
needsCDecl (DynamicLinkerLabel {})      = panic "needsCDecl DynamicLinkerLabel"
needsCDecl PicBaseLabel                 = panic "needsCDecl PicBaseLabel"
needsCDecl (DeadStripPreventer {})      = panic "needsCDecl DeadStripPreventer"
803

804 805 806 807 808
-- | 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
809

810

811
-- | Check whether a label corresponds to a C function that has
812
--      a prototype in a system header somewhere, or is built-in
813
--      to the C compiler. For these labels we avoid generating our
814
--      own C prototypes.
815
isMathFun :: CLabel -> Bool
816
isMathFun (ForeignLabel fs _ _ _)       = fs `elementOfUniqSet` math_funs
817 818
isMathFun _ = False

Ian Lynagh's avatar
Ian Lynagh committed
819
math_funs :: UniqSet FastString
820
math_funs = mkUniqSet [
821 822 823 824 825 826 827 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
        -- _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"),
897 898 899 900 901 902
        (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")
903
    ]
904

905
-- -----------------------------------------------------------------------------
906
-- | Is a CLabel visible outside this object file or not?
907 908 909
--      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.
910
externallyVisibleCLabel :: CLabel -> Bool -- not C "static"
911 912
externallyVisibleCLabel (StringLitLabel _)      = False
externallyVisibleCLabel (AsmTempLabel _)        = False
Peter Wortmann's avatar
Peter Wortmann committed
913
externallyVisibleCLabel (AsmTempDerivedLabel _ _)= False
914
externallyVisibleCLabel (RtsLabel _)            = True
915
externallyVisibleCLabel (LocalBlockLabel _)     = False
916 917 918 919 920
externallyVisibleCLabel (CmmLabel _ _ _)        = True
externallyVisibleCLabel (ForeignLabel{})        = True
externallyVisibleCLabel (IdLabel name _ info)   = isExternalName name && externallyVisibleIdLabel info
externallyVisibleCLabel (CC_Label _)            = True
externallyVisibleCLabel (CCS_Label _)           = True
921
externallyVisibleCLabel (DynamicLinkerLabel _ _)  = False
922
externallyVisibleCLabel (HpcTicksLabel _)       = True
923
externallyVisibleCLabel (LargeBitmapLabel _)    = False
924
externallyVisibleCLabel (SRTLabel _)            = False
Ian Lynagh's avatar
Ian Lynagh committed
925 926
externallyVisibleCLabel (PicBaseLabel {}) = panic "externallyVisibleCLabel PicBaseLabel"
externallyVisibleCLabel (DeadStripPreventer {}) = panic "externallyVisibleCLabel DeadStripPreventer"
927

batterseapower's avatar
batterseapower committed
928
externallyVisibleIdLabel :: IdLabelInfo -> Bool
929 930
externallyVisibleIdLabel LocalInfoTable  = False
externallyVisibleIdLabel LocalEntry      = False
931
externallyVisibleIdLabel BlockInfoTable  = False
932
externallyVisibleIdLabel _               = True
batterseapower's avatar
batterseapower committed
933

934
-- -----------------------------------------------------------------------------
935
-- Finding the "type" of a CLabel
936 937 938 939

-- For generating correct types in label declarations:

data CLabelType
940 941 942
  = CodeLabel   -- Address of some executable instructions
  | DataLabel   -- Address of data, not a GC ptr
  | GcPtrLabel  -- Address of a (presumably static) GC object
943 944 945

isCFunctionLabel :: CLabel -> Bool
isCFunctionLabel lbl = case labelType lbl of
946 947
                        CodeLabel -> True
                        _other    -> False
948 949 950

isGcPtrLabel :: CLabel -> Bool
isGcPtrLabel lbl = case labelType lbl of
951 952
                        GcPtrLabel -> True
                        _other     -> False
953

954 955 956

-- | Work out the general type of data at the address of this label
--    whether it be code, data, or static GC object.
957
labelType :: CLabel -> CLabelType
958
labelType (IdLabel _ _ info)                    = idInfoLabelType info
959
labelType (CmmLabel _ _ CmmData)                = DataLabel
960
labelType (CmmLabel _ _ CmmClosure)             = GcPtrLabel
961 962 963
labelType (CmmLabel _ _ CmmCode)                = CodeLabel
labelType (CmmLabel _ _ CmmInfo)                = DataLabel
labelType (CmmLabel _ _ CmmEntry)               = CodeLabel
964
labelType (CmmLabel _ _ CmmPrimCall)            = CodeLabel
965 966
labelType (CmmLabel _ _ CmmRetInfo)             = DataLabel
labelType (CmmLabel _ _ CmmRet)                 = CodeLabel
967 968
labelType (RtsLabel (RtsSelectorInfoTable _ _)) = DataLabel
labelType (RtsLabel (RtsApInfoTable _ _))       = DataLabel
969
labelType (RtsLabel (RtsApFast _))              = CodeLabel
970 971
labelType (RtsLabel _)                          = DataLabel
labelType (LocalBlockLabel _)                   = CodeLabel
972
labelType (SRTLabel _)                          = DataLabel
973 974 975 976 977 978 979 980 981 982 983
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
984
labelType (LargeBitmapLabel _)                  = DataLabel
985

Ian Lynagh's avatar
Ian Lynagh committed
986
idInfoLabelType :: IdLabelInfo -> CLabelType
987
idInfoLabelType info =
988
  case info of
989 990
    InfoTable     -> DataLabel
    LocalInfoTable -> DataLabel
991
    BlockInfoTable -> DataLabel
992
    Closure       -> GcPtrLabel
993
    ConInfoTable  -> DataLabel
994
    ClosureTable  -> DataLabel
995
    RednCounts    -> DataLabel
996
    Bytes         -> DataLabel
997
    _             -> CodeLabel
998 999 1000 1001


-- -----------------------------------------------------------------------------

1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
-- | 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?
--
1020 1021 1022 1023
-- 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.
1024 1025
labelDynamic :: DynFlags -> Module -> CLabel -> Bool
labelDynamic dflags this_mod lbl =
1026
  case lbl of
1027
   -- is the RTS in a DLL or not?
Simon Marlow's avatar
Simon Marlow committed
1028
   RtsLabel _ ->
1029
     externalDynamicRefs && (this_pkg /= rtsUnitId)
1030

Simon Marlow's avatar
Simon Marlow committed
1031
   IdLabel n _ _ ->
Sylvain Henry's avatar
Sylvain Henry committed
1032
     isDynLinkName dflags this_mod n
1033

daniel.is.fischer's avatar
daniel.is.fischer committed
1034
   -- When compiling in the "dyn" way, each package is to be linked into
Ian Lynagh's avatar
Ian Lynagh committed
1035
   -- its own shared library.
1036
   CmmLabel pkg _ _
Ian Lynagh's avatar
Ian Lynagh committed
1037
    | os == OSMinGW32 ->
1038
       externalDynamicRefs && (this_pkg /= pkg)
Ian Lynagh's avatar
Ian Lynagh committed
1039
    | otherwise ->
Simon Marlow's avatar
Simon Marlow committed
1040
       gopt Opt_ExternalDynamicRefs dflags
Ian Lynagh's avatar
Ian Lynagh committed
1041

1042 1043
   LocalBlockLabel _    -> False

Ian Lynagh's avatar
Ian Lynagh committed
1044 1045 1046 1047 1048 1049 1050