CLabel.hs 59.4 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 10
{-# LANGUAGE CPP #-}

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

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

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

32 33
        mkBlockInfoTableLabel,

34 35 36 37
        mkBitmapLabel,
        mkStringLitLabel,

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

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

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

63
        mkSelectorInfoLabel,
64
        mkSelectorEntryLabel,
65

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

74
        mkRtsApFastLabel,
75

76 77
        mkPrimCallLabel,

78
        mkForeignLabel,
79
        addLabelSize,
80

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

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

92
        mkPicBaseLabel,
93
        mkDeadStripPreventer,
94

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

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

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

107 108 109
        pprCLabel,
        isInfoTableLabel,
        isConInfoTableLabel
110 111
    ) where

112 113
#include "HsVersions.h"

114 115
import GhcPrelude

116
import IdInfo
117
import BasicTypes
118
import {-# SOURCE #-} GHC.Cmm.BlockId (BlockId, mkBlockId)
Simon Marlow's avatar
Simon Marlow committed
119 120 121 122 123 124
import Packages
import Module
import Name
import Unique
import PrimOp
import CostCentre
125 126
import Outputable
import FastString
127
import DynFlags
John Ericson's avatar
John Ericson committed
128
import GHC.Platform
129
import UniqSet
130
import Util
Peter Wortmann's avatar
Peter Wortmann committed
131
import PprCore ( {- instances -} )
132 133 134 135

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

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

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

  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.
175 176 177
-}

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

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

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

197 198 199 200 201 202 203 204
  -- | 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

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

214
        ForeignLabelSource      -- what package the foreign label is in.
215

216 217
        FunctionOrData

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

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

229
  | StringLitLabel
230
        {-# UNPACK #-} !Unique
231

232 233 234
  | CC_Label  CostCentre
  | CCS_Label CostCentreStack

235 236 237

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

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

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

251

252 253
  -- | Per-module table of tick locations
  | HpcTicksLabel Module
254

255
  -- | Static reference table
256
  | SRTLabel
257 258
        {-# UNPACK #-} !Unique

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

niteria's avatar
niteria committed
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
  deriving Eq

-- This is laborious, but necessary. We can't derive Ord because
-- Unique doesn't have an Ord instance. Note nonDetCmpUnique in the
-- implementation. See Note [No Ord for Unique]
-- This is non-deterministic but we do not currently support deterministic
-- code-generation. See Note [Unique Determinism and code generation]
instance Ord CLabel where
  compare (IdLabel a1 b1 c1) (IdLabel a2 b2 c2) =
    compare a1 a2 `thenCmp`
    compare b1 b2 `thenCmp`
    compare c1 c2
  compare (CmmLabel a1 b1 c1) (CmmLabel a2 b2 c2) =
    compare a1 a2 `thenCmp`
    compare b1 b2 `thenCmp`
    compare c1 c2
  compare (RtsLabel a1) (RtsLabel a2) = compare a1 a2
280
  compare (LocalBlockLabel u1) (LocalBlockLabel u2) = nonDetCmpUnique u1 u2
niteria's avatar
niteria committed
281 282 283 284 285 286 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
  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
314 315
  compare LocalBlockLabel{} _ = LT
  compare _ LocalBlockLabel{} = GT
niteria's avatar
niteria committed
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
  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
338 339 340 341 342

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

   -- | Label is in a named package
343
   = ForeignLabelInPackage      UnitId
344

345
   -- | Label is in some external, system package that doesn't also
346 347 348 349
   --   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
350

351
   -- | Label is in the package currently being compiled.
352 353 354 355
   --   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.
356
   | ForeignLabelInThisPackage
357 358

   deriving (Eq, Ord)
359 360 361


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

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

Ian Lynagh's avatar
Ian Lynagh committed
375
        ForeignLabel _name mSuffix src funOrData
Ian Lynagh's avatar
Ian Lynagh committed
376
            -> ppr lbl <> (parens $ text "ForeignLabel"
377 378 379
                                <+> ppr mSuffix
                                <+> ppr src
                                <+> ppr funOrData)
380

381
        _               -> ppr lbl <> (parens $ text "other CLabel")
382 383


384
data IdLabelInfo
385
  = Closure             -- ^ Label for closure
386
  | InfoTable           -- ^ Info tables for closures; always read-only
387
  | Entry               -- ^ Entry point
388
  | Slow                -- ^ Slow entry point
389

390 391 392 393
  | 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
394

395 396
  | ConEntry            -- ^ Constructor entry point
  | ConInfoTable        -- ^ Corresponding info table
397

398
  | ClosureTable        -- ^ Table of closures for Enum tycons
399

400 401
  | Bytes               -- ^ Content of a string literal. See
                        -- Note [Bytes label].
402 403 404
  | BlockInfoTable      -- ^ Like LocalInfoTable but for a proc-point block
                        -- instead of a closure entry-point.
                        -- See Note [Proc-point local block entry-point].
405

406
  deriving (Eq, Ord, Show)
407 408 409


data RtsLabelInfo
410 411
  = RtsSelectorInfoTable Bool{-updatable-} Int{-offset-}  -- ^ Selector thunks
  | RtsSelectorEntry     Bool{-updatable-} Int{-offset-}
412

413 414
  | RtsApInfoTable       Bool{-updatable-} Int{-arity-}    -- ^ AP thunks
  | RtsApEntry           Bool{-updatable-} Int{-arity-}
415 416

  | RtsPrimOp PrimOp
417
  | RtsApFast     FastString    -- ^ _fast versions of generic apply
nfrisby's avatar
nfrisby committed
418
  | RtsSlowFastTickyCtr String
419 420

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

424 425

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

439
data DynamicLinkerLabelInfo
440 441 442 443 444
  = CodeStub                    -- MachO: Lfoo$stub, ELF: foo@plt
  | SymbolPtr                   -- MachO: Lfoo$non_lazy_ptr, Windows: __imp_foo
  | GotSymbolPtr                -- ELF: foo@got
  | GotSymbolOffset             -- ELF: foo@gotoff

445
  deriving (Eq, Ord)
446

447

448 449
-- -----------------------------------------------------------------------------
-- Constructing CLabels
450
-- -----------------------------------------------------------------------------
451

452
-- Constructing IdLabels
453
-- These are always local:
454

455 456
mkSRTLabel     :: Unique -> CLabel
mkSRTLabel u = SRTLabel u
457

nfrisby's avatar
nfrisby committed
458 459 460
mkRednCountsLabel :: Name -> CLabel
mkRednCountsLabel       name    =
  IdLabel name NoCafRefs RednCounts  -- Note [ticky for LNE]
461 462

-- These have local & (possibly) external variants:
Ian Lynagh's avatar
Ian Lynagh committed
463 464 465
mkLocalClosureLabel      :: Name -> CafInfo -> CLabel
mkLocalInfoTableLabel    :: Name -> CafInfo -> CLabel
mkLocalClosureTableLabel :: Name -> CafInfo -> CLabel
466
mkLocalClosureLabel     name c  = IdLabel name  c Closure
467
mkLocalInfoTableLabel   name c  = IdLabel name  c LocalInfoTable
468 469
mkLocalClosureTableLabel name c = IdLabel name  c ClosureTable

Ian Lynagh's avatar
Ian Lynagh committed
470 471 472 473 474
mkClosureLabel              :: Name -> CafInfo -> CLabel
mkInfoTableLabel            :: Name -> CafInfo -> CLabel
mkEntryLabel                :: Name -> CafInfo -> CLabel
mkClosureTableLabel         :: Name -> CafInfo -> CLabel
mkConInfoTableLabel         :: Name -> CafInfo -> CLabel
475
mkBytesLabel                :: Name -> CLabel
476
mkClosureLabel name         c     = IdLabel name c Closure
477
mkInfoTableLabel name       c     = IdLabel name c InfoTable
478
mkEntryLabel name           c     = IdLabel name c Entry
479
mkClosureTableLabel name    c     = IdLabel name c ClosureTable
480
mkConInfoTableLabel name    c     = IdLabel name c ConInfoTable
481
mkBytesLabel name                 = IdLabel name NoCafRefs Bytes
482

483 484 485 486
mkBlockInfoTableLabel :: Name -> CafInfo -> CLabel
mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable
                               -- See Note [Proc-point local block entry-point].

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

517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
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"

540
-----
541
mkCmmInfoLabel,   mkCmmEntryLabel, mkCmmRetInfoLabel, mkCmmRetLabel,
542
  mkCmmCodeLabel, mkCmmDataLabel,  mkCmmClosureLabel
543
        :: UnitId -> FastString -> CLabel
544

545 546 547 548 549 550
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
551
mkCmmClosureLabel   pkg str     = CmmLabel pkg str CmmClosure
552

553 554
mkLocalBlockLabel :: Unique -> CLabel
mkLocalBlockLabel u = LocalBlockLabel u
555 556

-- Constructing RtsLabels
Ian Lynagh's avatar
Ian Lynagh committed
557
mkRtsPrimOpLabel :: PrimOp -> CLabel
558
mkRtsPrimOpLabel primop         = RtsLabel (RtsPrimOp primop)
559

Ian Lynagh's avatar
Ian Lynagh committed
560 561
mkSelectorInfoLabel  :: Bool -> Int -> CLabel
mkSelectorEntryLabel :: Bool -> Int -> CLabel
562 563
mkSelectorInfoLabel  upd off    = RtsLabel (RtsSelectorInfoTable upd off)
mkSelectorEntryLabel upd off    = RtsLabel (RtsSelectorEntry     upd off)
564

Ian Lynagh's avatar
Ian Lynagh committed
565 566
mkApInfoTableLabel :: Bool -> Int -> CLabel
mkApEntryLabel     :: Bool -> Int -> CLabel
567 568
mkApInfoTableLabel   upd off    = RtsLabel (RtsApInfoTable       upd off)
mkApEntryLabel       upd off    = RtsLabel (RtsApEntry           upd off)
569

570

571
-- A call to some primitive hand written Cmm code
572
mkPrimCallLabel :: PrimCall -> CLabel
573 574
mkPrimCallLabel (PrimCall str pkg)
        = CmmLabel pkg str CmmPrimCall
575

576

577
-- Constructing ForeignLabels
578

579
-- | Make a foreign label
580 581 582 583 584 585
mkForeignLabel
        :: FastString           -- name
        -> Maybe Int            -- size prefix
        -> ForeignLabelSource   -- what package it's in
        -> FunctionOrData
        -> CLabel
586

587
mkForeignLabel = ForeignLabel
588 589 590


-- | Update the label size field in a ForeignLabel
591
addLabelSize :: CLabel -> Int -> CLabel
592 593
addLabelSize (ForeignLabel str _ src  fod) sz
    = ForeignLabel str (Just sz) src fod
594
addLabelSize label _
595
    = label
596

597 598 599 600 601
-- | Whether label is a top-level string literal
isBytesLabel :: CLabel -> Bool
isBytesLabel (IdLabel _ _ Bytes) = True
isBytesLabel _lbl = False

602 603 604 605 606
-- | Whether label is a non-haskell label (defined in C code)
isForeignLabel :: CLabel -> Bool
isForeignLabel (ForeignLabel _ _ _ _) = True
isForeignLabel _lbl = False

607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
-- | 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
622
isSomeRODataLabel (IdLabel _ _ BlockInfoTable) = True
623 624 625 626
-- info table defined in cmm (.cmm)
isSomeRODataLabel (CmmLabel _ _ CmmInfo) = True
isSomeRODataLabel _lbl = False

627 628 629 630 631 632 633 634 635 636 637 638 639
-- | 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

640
-- | Get the label size field from a ForeignLabel
641
foreignLabelStdcallInfo :: CLabel -> Maybe Int
642
foreignLabelStdcallInfo (ForeignLabel _ info _ _) = info
643 644
foreignLabelStdcallInfo _lbl = Nothing

645

646
-- Constructing Large*Labels
Ian Lynagh's avatar
Ian Lynagh committed
647
mkBitmapLabel   :: Unique -> CLabel
648
mkBitmapLabel   uniq            = LargeBitmapLabel uniq
649 650

-- Constructing Cost Center Labels
Ian Lynagh's avatar
Ian Lynagh committed
651 652
mkCCLabel  :: CostCentre      -> CLabel
mkCCSLabel :: CostCentreStack -> CLabel
653 654
mkCCLabel           cc          = CC_Label cc
mkCCSLabel          ccs         = CCS_Label ccs
655

Ian Lynagh's avatar
Ian Lynagh committed
656
mkRtsApFastLabel :: FastString -> CLabel
657 658
mkRtsApFastLabel str = RtsLabel (RtsApFast str)

nfrisby's avatar
nfrisby committed
659 660
mkRtsSlowFastTickyCtrLabel :: String -> CLabel
mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat)
661

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

663
-- Constructing Code Coverage Labels
Ian Lynagh's avatar
Ian Lynagh committed
664
mkHpcTicksLabel :: Module -> CLabel
andy@galois.com's avatar
andy@galois.com committed
665 666
mkHpcTicksLabel                = HpcTicksLabel

667 668

-- Constructing labels used for dynamic linking
669
mkDynamicLinkerLabel :: DynamicLinkerLabelInfo -> CLabel -> CLabel
670
mkDynamicLinkerLabel            = DynamicLinkerLabel
671 672 673

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

676
mkPicBaseLabel :: CLabel
677
mkPicBaseLabel                  = PicBaseLabel
678

679 680

-- Constructing miscellaneous other labels
681
mkDeadStripPreventer :: CLabel -> CLabel
682
mkDeadStripPreventer lbl        = DeadStripPreventer lbl
683 684

mkStringLitLabel :: Unique -> CLabel
685
mkStringLitLabel                = StringLitLabel
686 687

mkAsmTempLabel :: Uniquable a => a -> CLabel
688
mkAsmTempLabel a                = AsmTempLabel (getUnique a)
689

Peter Wortmann's avatar
Peter Wortmann committed
690 691 692 693 694
mkAsmTempDerivedLabel :: CLabel -> FastString -> CLabel
mkAsmTempDerivedLabel = AsmTempDerivedLabel

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

696 697 698 699 700
-- | Construct a label for a DWARF Debug Information Entity (DIE)
-- describing another symbol.
mkAsmTempDieLabel :: CLabel -> CLabel
mkAsmTempDieLabel l = mkAsmTempDerivedLabel l (fsLit "_die")

701
-- -----------------------------------------------------------------------------
702 703
-- Convert between different kinds of label

704 705
toClosureLbl :: CLabel -> CLabel
toClosureLbl (IdLabel n c _) = IdLabel n c Closure
706
toClosureLbl (CmmLabel m str _) = CmmLabel m str CmmClosure
707 708 709
toClosureLbl l = pprPanic "toClosureLbl" (ppr l)

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

nfrisby's avatar
nfrisby committed
733 734 735 736
hasHaskellName :: CLabel -> Maybe Name
hasHaskellName (IdLabel n _ _) = Just n
hasHaskellName _               = Nothing

737
-- -----------------------------------------------------------------------------
nfrisby's avatar
nfrisby committed
738
-- Does a CLabel's referent itself refer to a CAF?
739
hasCAF :: CLabel -> Bool
nfrisby's avatar
nfrisby committed
740
hasCAF (IdLabel _ _ RednCounts) = False -- Note [ticky for LNE]
741 742
hasCAF (IdLabel _ MayHaveCafRefs _) = True
hasCAF _                            = False
743

nfrisby's avatar
nfrisby committed
744 745 746 747 748
-- 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
749
-- GHC.Cmm.Info.Build.cafTransfers would consider such a ticky label
nfrisby's avatar
nfrisby committed
750 751 752 753 754 755 756 757 758 759 760 761
-- 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.
762

763 764
-- -----------------------------------------------------------------------------
-- Does a CLabel need declaring before use or not?
765
--
766
-- See wiki:commentary/compiler/backends/ppr-c#prototypes
767 768 769

needsCDecl :: CLabel -> Bool
  -- False <=> it's pre-declared; don't bother
770
  -- don't bother declaring Bitmap labels, we always make sure
771
  -- they are defined before use.
772
needsCDecl (SRTLabel _)                 = True
773 774
needsCDecl (LargeBitmapLabel _)         = False
needsCDecl (IdLabel _ _ _)              = True
775
needsCDecl (LocalBlockLabel _)          = True
776

777 778
needsCDecl (StringLitLabel _)           = False
needsCDecl (AsmTempLabel _)             = False
Peter Wortmann's avatar
Peter Wortmann committed
779
needsCDecl (AsmTempDerivedLabel _ _)    = False
780 781 782 783 784
needsCDecl (RtsLabel _)                 = False

needsCDecl (CmmLabel pkgId _ _)
        -- Prototypes for labels defined in the runtime system are imported
        --      into HC files via includes/Stg.h.
785
        | pkgId == rtsUnitId         = False
786 787 788 789 790 791 792

        -- 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
793
needsCDecl (HpcTicksLabel _)            = True
Ian Lynagh's avatar
Ian Lynagh committed
794 795 796
needsCDecl (DynamicLinkerLabel {})      = panic "needsCDecl DynamicLinkerLabel"
needsCDecl PicBaseLabel                 = panic "needsCDecl PicBaseLabel"
needsCDecl (DeadStripPreventer {})      = panic "needsCDecl DeadStripPreventer"
797

798 799 800 801 802
-- | 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
803

804

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

Ian Lynagh's avatar
Ian Lynagh committed
813
math_funs :: UniqSet FastString
814
math_funs = mkUniqSet [
815 816 817 818 819 820 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
        -- _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"),
891 892 893 894 895 896
        (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")
897
    ]
898

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

batterseapower's avatar
batterseapower committed
922
externallyVisibleIdLabel :: IdLabelInfo -> Bool
923 924
externallyVisibleIdLabel LocalInfoTable  = False
externallyVisibleIdLabel LocalEntry      = False
925
externallyVisibleIdLabel BlockInfoTable  = False
926
externallyVisibleIdLabel _               = True
batterseapower's avatar
batterseapower committed
927

928
-- -----------------------------------------------------------------------------
929
-- Finding the "type" of a CLabel
930 931 932 933

-- For generating correct types in label declarations:

data CLabelType
934 935 936
  = CodeLabel   -- Address of some executable instructions
  | DataLabel   -- Address of data, not a GC ptr
  | GcPtrLabel  -- Address of a (presumably static) GC object
937 938 939

isCFunctionLabel :: CLabel -> Bool
isCFunctionLabel lbl = case labelType lbl of
940 941
                        CodeLabel -> True
                        _other    -> False
942 943 944

isGcPtrLabel :: CLabel -> Bool
isGcPtrLabel lbl = case labelType lbl of
945 946
                        GcPtrLabel -> True
                        _other     -> False
947

948 949 950

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

Ian Lynagh's avatar
Ian Lynagh committed
980
idInfoLabelType :: IdLabelInfo -> CLabelType
981
idInfoLabelType info =
982
  case info of
983 984
    InfoTable     -> DataLabel
    LocalInfoTable -> DataLabel
985
    BlockInfoTable -> DataLabel
986
    Closure       -> GcPtrLabel
987
    ConInfoTable  -> DataLabel
988
    ClosureTable  -> DataLabel
989
    RednCounts    -> DataLabel
990
    Bytes         -> DataLabel
991
    _             -> CodeLabel
992 993 994 995


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

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

Simon Marlow's avatar
Simon Marlow committed
1025 1026
   IdLabel n _ _ ->
     isDllName dflags this_mod n
1027

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

1036 1037
   LocalBlockLabel _    -> False

Ian Lynagh's avatar
Ian Lynagh committed
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
   ForeignLabel _ _ source _  ->
       if os == OSMinGW32
       then case source of
            -- Foreign label is in some un-named foreign package (or DLL).
            ForeignLabelInExternalPackage -> True

            -- Foreign label is linked into the same package as the
            -- source file currently being compiled.
            ForeignLabelInThisPackage -> False

            -- Foreign label is in some named package.
            -- When compiling in the "dyn" way, each package is to be
            -- linked into its own DLL.
            ForeignLabelInPackage pkgId ->
1052
                externalDynamicRefs && (this_pkg /= pkgId)
Ian Lynagh's avatar
Ian Lynagh committed
1053 1054 1055 1056 1057

       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
1058

1059 1060 1061 1062 1063