CLabel.hs 62.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
{-# LANGUAGE CPP #-}
10
{-# LANGUAGE BangPatterns #-}
11
{-# LANGUAGE LambdaCase #-}
Sylvain Henry's avatar
Sylvain Henry committed
12 13 14
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}

15

16
module GHC.Cmm.CLabel (
Ian Lynagh's avatar
Ian Lynagh committed
17
        CLabel, -- abstract type
18
        NeedExternDecl (..),
Ian Lynagh's avatar
Ian Lynagh committed
19
        ForeignLabelSource(..),
20
        DynamicLinkerLabelInfo(..),
Ian Lynagh's avatar
Ian Lynagh committed
21

22
        -- * Constructors
Ian Lynagh's avatar
Ian Lynagh committed
23
        mkClosureLabel,
24
        mkSRTLabel,
Ian Lynagh's avatar
Ian Lynagh committed
25 26 27 28 29 30 31
        mkInfoTableLabel,
        mkEntryLabel,
        mkRednCountsLabel,
        mkConInfoTableLabel,
        mkApEntryLabel,
        mkApInfoTableLabel,
        mkClosureTableLabel,
32
        mkBytesLabel,
Ian Lynagh's avatar
Ian Lynagh committed
33

34
        mkLocalBlockLabel,
Ian Lynagh's avatar
Ian Lynagh committed
35 36 37 38
        mkLocalClosureLabel,
        mkLocalInfoTableLabel,
        mkLocalClosureTableLabel,

39 40
        mkBlockInfoTableLabel,

Ian Lynagh's avatar
Ian Lynagh committed
41 42 43 44
        mkBitmapLabel,
        mkStringLitLabel,

        mkAsmTempLabel,
Peter Wortmann's avatar
Peter Wortmann committed
45 46
        mkAsmTempDerivedLabel,
        mkAsmTempEndLabel,
47
        mkAsmTempDieLabel,
48

Ian Lynagh's avatar
Ian Lynagh committed
49
        mkDirty_MUT_VAR_Label,
50
        mkNonmovingWriteBarrierEnabledLabel,
Ian Lynagh's avatar
Ian Lynagh committed
51 52 53
        mkUpdInfoLabel,
        mkBHUpdInfoLabel,
        mkIndStaticInfoLabel,
54
        mkMainCapabilityLabel,
55 56
        mkMAP_FROZEN_CLEAN_infoLabel,
        mkMAP_FROZEN_DIRTY_infoLabel,
Ian Lynagh's avatar
Ian Lynagh committed
57
        mkMAP_DIRTY_infoLabel,
58 59
        mkSMAP_FROZEN_CLEAN_infoLabel,
        mkSMAP_FROZEN_DIRTY_infoLabel,
60
        mkSMAP_DIRTY_infoLabel,
Ben Gamari's avatar
Ben Gamari committed
61
        mkBadAlignmentLabel,
62
        mkArrWords_infoLabel,
63
        mkSRTInfoLabel,
64

Ian Lynagh's avatar
Ian Lynagh committed
65
        mkTopTickyCtrLabel,
66
        mkCAFBlackHoleInfoTableLabel,
Ian Lynagh's avatar
Ian Lynagh committed
67
        mkRtsPrimOpLabel,
nfrisby's avatar
nfrisby committed
68
        mkRtsSlowFastTickyCtrLabel,
69

70
        mkSelectorInfoLabel,
Ian Lynagh's avatar
Ian Lynagh committed
71 72 73 74 75 76 77
        mkSelectorEntryLabel,
        mkCmmInfoLabel,
        mkCmmEntryLabel,
        mkCmmRetInfoLabel,
        mkCmmRetLabel,
        mkCmmCodeLabel,
        mkCmmDataLabel,
78
        mkRtsCmmDataLabel,
79
        mkCmmClosureLabel,
Ian Lynagh's avatar
Ian Lynagh committed
80
        mkRtsApFastLabel,
81
        mkPrimCallLabel,
Ian Lynagh's avatar
Ian Lynagh committed
82
        mkForeignLabel,
83 84
        mkCCLabel,
        mkCCSLabel,
85 86
        mkDynamicLinkerLabel,
        mkPicBaseLabel,
87
        mkDeadStripPreventer,
andy@galois.com's avatar
andy@galois.com committed
88 89
        mkHpcTicksLabel,

90
        -- * Predicates
91
        hasCAF,
92 93 94
        needsCDecl,
        maybeLocalBlockLabel,
        externallyVisibleCLabel,
95
        isMathFun,
96 97 98 99 100 101 102 103 104 105 106 107 108 109
        isCFunctionLabel,
        isGcPtrLabel,
        labelDynamic,
        isLocalCLabel,
        mayRedirectTo,
        isInfoTableLabel,
        isConInfoTableLabel,
        isIdLabel,
        isTickyLabel,
        hasHaskellName,
        isBytesLabel,
        isForeignLabel,
        isSomeRODataLabel,
        isStaticClosureLabel,
110 111

        -- * Conversions
112 113 114 115
        toClosureLbl,
        toSlowEntryLbl,
        toEntryLbl,
        toInfoLbl,
116

117 118 119 120 121 122 123 124 125
        -- * Pretty-printing
        LabelStyle (..),
        pprDebugCLabel,
        pprCLabel,

        -- * Others
        dynamicLinkerLabelInfo,
        addLabelSize,
        foreignLabelStdcallInfo
126 127
    ) where

128 129
#include "HsVersions.h"

130
import GHC.Prelude
131

Sylvain Henry's avatar
Sylvain Henry committed
132 133
import GHC.Types.Id.Info
import GHC.Types.Basic
134
import {-# SOURCE #-} GHC.Cmm.BlockId (BlockId, mkBlockId)
135
import GHC.Unit.Types
Sylvain Henry's avatar
Sylvain Henry committed
136 137
import GHC.Types.Name
import GHC.Types.Unique
Sylvain Henry's avatar
Sylvain Henry committed
138
import GHC.Builtin.PrimOps
Sylvain Henry's avatar
Sylvain Henry committed
139
import GHC.Types.CostCentre
140
import GHC.Utils.Outputable
141
import GHC.Utils.Panic
142
import GHC.Data.FastString
Sylvain Henry's avatar
Sylvain Henry committed
143
import GHC.Driver.Session
John Ericson's avatar
John Ericson committed
144
import GHC.Platform
Sylvain Henry's avatar
Sylvain Henry committed
145
import GHC.Types.Unique.Set
146
import GHC.Utils.Misc
Sylvain Henry's avatar
Sylvain Henry committed
147
import GHC.Core.Ppr ( {- instances -} )
148
import GHC.CmmToAsm.Config
149 150 151 152

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

Ben Gamari's avatar
Ben Gamari committed
153 154
{- |
  'CLabel' is an abstract type that supports the following operations:
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172

  - 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
173 174 175 176 177 178

  CLabel usage is a bit messy in GHC as they are used in a number of different
  contexts:

  - By the C-- AST to identify labels

179
  - By the unregisterised C code generator (\"PprC\") for naming functions (hence
Ben Gamari's avatar
Ben Gamari committed
180 181 182 183 184 185 186 187 188 189 190 191
    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.
192 193 194
-}

data CLabel
195
  = -- | A label related to the definition of a particular Id or Con in a .hs file.
Ian Lynagh's avatar
Ian Lynagh committed
196 197
    IdLabel
        Name
198
        CafInfo
199
        IdLabelInfo             -- ^ encodes the suffix of the label
Ian Lynagh's avatar
Ian Lynagh committed
200

201
  -- | A label from a .cmm file that is not associated with a .hs level Id.
Ian Lynagh's avatar
Ian Lynagh committed
202
  | CmmLabel
203 204 205 206
        UnitId                  -- ^ what package the label belongs to.
        NeedExternDecl          -- ^ does the label need an "extern .." declaration
        FastString              -- ^ identifier giving the prefix of the label
        CmmLabelInfo            -- ^ encodes the suffix of the label
207 208 209

  -- | A label with a baked-in \/ algorithmically generated name that definitely
  --    comes from the RTS. The code for it must compile into libHSrts.a \/ libHSrts.so
Ian Lynagh's avatar
Ian Lynagh committed
210
  --    If it doesn't have an algorithmically generated name then use a CmmLabel
211
  --    instead and give it an appropriate UnitId argument.
Ian Lynagh's avatar
Ian Lynagh committed
212 213
  | RtsLabel
        RtsLabelInfo
214

215 216 217 218 219 220 221 222
  -- | 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

223 224
  -- | A 'C' (or otherwise foreign) label.
  --
Ian Lynagh's avatar
Ian Lynagh committed
225
  | ForeignLabel
226
        FastString              -- ^ name of the imported label.
Ian Lynagh's avatar
Ian Lynagh committed
227

228
        (Maybe Int)             -- ^ possible '@n' suffix for stdcall functions
Ian Lynagh's avatar
Ian Lynagh committed
229 230
                                -- When generating C, the '@n' suffix is omitted, but when
                                -- generating assembler we must add it to the label.
231

232
        ForeignLabelSource      -- ^ what package the foreign label is in.
233

234 235
        FunctionOrData

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

Ben Gamari's avatar
Ben Gamari committed
241 242
  -- | 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
243 244
  | AsmTempDerivedLabel
        CLabel
245
        FastString              -- ^ suffix
Peter Wortmann's avatar
Peter Wortmann committed
246

247
  | StringLitLabel
Ian Lynagh's avatar
Ian Lynagh committed
248
        {-# UNPACK #-} !Unique
249

250 251 252
  | CC_Label  CostCentre
  | CCS_Label CostCentreStack

Ian Lynagh's avatar
Ian Lynagh committed
253 254 255

  -- | These labels are generated and used inside the NCG only.
  --    They are special variants of a label used for dynamic linking
256
  --    see module "GHC.CmmToAsm.PIC" for details.
257
  | DynamicLinkerLabel DynamicLinkerLabelInfo CLabel
Ian Lynagh's avatar
Ian Lynagh committed
258 259 260 261

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

266 267
  -- | A label before an info table to prevent excessive dead-stripping on darwin
  | DeadStripPreventer CLabel
268

269

270 271
  -- | Per-module table of tick locations
  | HpcTicksLabel Module
272

273
  -- | Static reference table
274
  | SRTLabel
275 276
        {-# UNPACK #-} !Unique

277 278
  -- | A bitmap (function or case return)
  | LargeBitmapLabel
279 280
        {-# UNPACK #-} !Unique

niteria's avatar
niteria committed
281 282
  deriving Eq

283 284 285 286
isIdLabel :: CLabel -> Bool
isIdLabel IdLabel{} = True
isIdLabel _ = False

287 288 289 290 291 292
-- Used in SRT analysis. See Note [Ticky labels in SRT analysis] in
-- GHC.Cmm.Info.Build.
isTickyLabel :: CLabel -> Bool
isTickyLabel (IdLabel _ _ RednCounts) = True
isTickyLabel _ = False

293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
-- | Indicate if "GHC.CmmToC" has to generate an extern declaration for the
-- label (e.g. "extern StgWordArray(foo)").  The type is fixed to StgWordArray.
--
-- Symbols from the RTS don't need "extern" declarations because they are
-- exposed via "includes/Stg.h" with the appropriate type. See 'needsCDecl'.
--
-- The fixed StgWordArray type led to "conflicting types" issues with user
-- provided Cmm files (not in the RTS) that declare data of another type (#15467
-- and test for #17920).  Hence the Cmm parser considers that labels in data
-- sections don't need the "extern" declaration (just add one explicitly if you
-- need it).
--
-- See https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/compiler/backends/ppr-c#prototypes
-- for why extern declaration are needed at all.
newtype NeedExternDecl
   = NeedExternDecl Bool
   deriving (Ord,Eq)

niteria's avatar
niteria committed
311 312 313 314 315 316 317 318 319 320
-- 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
321
  compare (CmmLabel a1 b1 c1 d1) (CmmLabel a2 b2 c2 d2) =
niteria's avatar
niteria committed
322 323
    compare a1 a2 `thenCmp`
    compare b1 b2 `thenCmp`
324
    uniqCompareFS c1 c2 `thenCmp`
325
    compare d1 d2
niteria's avatar
niteria committed
326
  compare (RtsLabel a1) (RtsLabel a2) = compare a1 a2
327
  compare (LocalBlockLabel u1) (LocalBlockLabel u2) = nonDetCmpUnique u1 u2
niteria's avatar
niteria committed
328
  compare (ForeignLabel a1 b1 c1 d1) (ForeignLabel a2 b2 c2 d2) =
329
    uniqCompareFS a1 a2 `thenCmp`
niteria's avatar
niteria committed
330 331 332 333 334 335
    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`
336
    uniqCompareFS b1 b2
niteria's avatar
niteria committed
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
  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
361 362
  compare LocalBlockLabel{} _ = LT
  compare _ LocalBlockLabel{} = GT
niteria's avatar
niteria committed
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
  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
385 386 387 388 389

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

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

392
   -- | Label is in some external, system package that doesn't also
Ian Lynagh's avatar
Ian Lynagh committed
393 394 395 396
   --   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
397

398
   -- | Label is in the package currently being compiled.
Ian Lynagh's avatar
Ian Lynagh committed
399 400 401 402
   --   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.
403
   | ForeignLabelInThisPackage
Ian Lynagh's avatar
Ian Lynagh committed
404 405

   deriving (Eq, Ord)
406 407 408


-- | For debugging problems with the CLabel representation.
Ian Lynagh's avatar
Ian Lynagh committed
409 410
--      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.
411
--
412
pprDebugCLabel :: Platform -> CLabel -> SDoc
413 414 415 416 417 418 419 420
pprDebugCLabel platform lbl = pprCLabel platform AsmStyle lbl <> parens extra
   where
      extra = case lbl of
         IdLabel _ _ info
            -> text "IdLabel" <> whenPprDebug (text ":" <> text (show info))

         CmmLabel pkg _ext _name _info
            -> text "CmmLabel" <+> ppr pkg
421

422 423
         RtsLabel{}
            -> text "RtsLabel"
424

425 426
         ForeignLabel _name mSuffix src funOrData
             -> text "ForeignLabel" <+> ppr mSuffix <+> ppr src <+> ppr funOrData
427

428
         _  -> text "other CLabel"
429 430


431
data IdLabelInfo
Ian Lynagh's avatar
Ian Lynagh committed
432
  = Closure             -- ^ Label for closure
433
  | InfoTable           -- ^ Info tables for closures; always read-only
Ian Lynagh's avatar
Ian Lynagh committed
434
  | Entry               -- ^ Entry point
435
  | Slow                -- ^ Slow entry point
436

437 438 439 440
  | 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
441

Ian Lynagh's avatar
Ian Lynagh committed
442 443
  | ConEntry            -- ^ Constructor entry point
  | ConInfoTable        -- ^ Corresponding info table
444

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

447 448
  | Bytes               -- ^ Content of a string literal. See
                        -- Note [Bytes label].
449 450 451
  | BlockInfoTable      -- ^ Like LocalInfoTable but for a proc-point block
                        -- instead of a closure entry-point.
                        -- See Note [Proc-point local block entry-point].
452

453
  deriving (Eq, Ord, Show)
454 455 456


data RtsLabelInfo
457 458
  = RtsSelectorInfoTable Bool{-updatable-} Int{-offset-}  -- ^ Selector thunks
  | RtsSelectorEntry     Bool{-updatable-} Int{-offset-}
459

460 461
  | RtsApInfoTable       Bool{-updatable-} Int{-arity-}    -- ^ AP thunks
  | RtsApEntry           Bool{-updatable-} Int{-arity-}
462

463 464
  | RtsPrimOp            PrimOp
  | RtsApFast            NonDetFastString    -- ^ _fast versions of generic apply
nfrisby's avatar
nfrisby committed
465
  | RtsSlowFastTickyCtr String
466

467
  deriving (Eq,Ord)
468

469 470

-- | What type of Cmm label we're dealing with.
Ian Lynagh's avatar
Ian Lynagh committed
471 472
--      Determines the suffix appended to the name when a CLabel.CmmLabel
--      is pretty printed.
473
data CmmLabelInfo
474
  = CmmInfo                     -- ^ misc rts info tables,      suffix _info
Ian Lynagh's avatar
Ian Lynagh committed
475 476 477
  | CmmEntry                    -- ^ misc rts entry points,     suffix _entry
  | CmmRetInfo                  -- ^ misc rts ret info tables,  suffix _info
  | CmmRet                      -- ^ misc rts return points,    suffix _ret
478
  | CmmData                     -- ^ misc rts data bits, eg CHARLIKE_closure
Ian Lynagh's avatar
Ian Lynagh committed
479
  | CmmCode                     -- ^ misc rts code
480
  | CmmClosure                  -- ^ closures eg CHARLIKE_closure
Ian Lynagh's avatar
Ian Lynagh committed
481
  | CmmPrimCall                 -- ^ a prim call to some hand written Cmm code
482 483
  deriving (Eq, Ord)

484
data DynamicLinkerLabelInfo
Ian Lynagh's avatar
Ian Lynagh committed
485 486 487 488 489
  = CodeStub                    -- MachO: Lfoo$stub, ELF: foo@plt
  | SymbolPtr                   -- MachO: Lfoo$non_lazy_ptr, Windows: __imp_foo
  | GotSymbolPtr                -- ELF: foo@got
  | GotSymbolOffset             -- ELF: foo@gotoff

490
  deriving (Eq, Ord)
Ian Lynagh's avatar
Ian Lynagh committed
491

492

493 494
-- -----------------------------------------------------------------------------
-- Constructing CLabels
495
-- -----------------------------------------------------------------------------
496

Ian Lynagh's avatar
Ian Lynagh committed
497
-- Constructing IdLabels
498
-- These are always local:
499

500 501
mkSRTLabel     :: Unique -> CLabel
mkSRTLabel u = SRTLabel u
502

nfrisby's avatar
nfrisby committed
503
mkRednCountsLabel :: Name -> CLabel
504
mkRednCountsLabel name = IdLabel name NoCafRefs RednCounts  -- Note [ticky for LNE]
505 506

-- These have local & (possibly) external variants:
Ian Lynagh's avatar
Ian Lynagh committed
507 508 509
mkLocalClosureLabel      :: Name -> CafInfo -> CLabel
mkLocalInfoTableLabel    :: Name -> CafInfo -> CLabel
mkLocalClosureTableLabel :: Name -> CafInfo -> CLabel
510
mkLocalClosureLabel   !name !c  = IdLabel name  c Closure
511
mkLocalInfoTableLabel   name c  = IdLabel name  c LocalInfoTable
512 513
mkLocalClosureTableLabel name c = IdLabel name  c ClosureTable

Ian Lynagh's avatar
Ian Lynagh committed
514 515 516 517 518
mkClosureLabel              :: Name -> CafInfo -> CLabel
mkInfoTableLabel            :: Name -> CafInfo -> CLabel
mkEntryLabel                :: Name -> CafInfo -> CLabel
mkClosureTableLabel         :: Name -> CafInfo -> CLabel
mkConInfoTableLabel         :: Name -> CafInfo -> CLabel
519
mkBytesLabel                :: Name -> CLabel
520
mkClosureLabel name         c     = IdLabel name c Closure
521
mkInfoTableLabel name       c     = IdLabel name c InfoTable
522
mkEntryLabel name           c     = IdLabel name c Entry
523
mkClosureTableLabel name    c     = IdLabel name c ClosureTable
524
mkConInfoTableLabel name    c     = IdLabel name c ConInfoTable
525
mkBytesLabel name                 = IdLabel name NoCafRefs Bytes
526

527 528 529 530
mkBlockInfoTableLabel :: Name -> CafInfo -> CLabel
mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable
                               -- See Note [Proc-point local block entry-point].

531
-- Constructing Cmm Labels
532 533 534
mkDirty_MUT_VAR_Label,
    mkNonmovingWriteBarrierEnabledLabel,
    mkUpdInfoLabel,
Ian Lynagh's avatar
Ian Lynagh committed
535
    mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel,
536 537
    mkMAP_FROZEN_CLEAN_infoLabel, mkMAP_FROZEN_DIRTY_infoLabel,
    mkMAP_DIRTY_infoLabel,
538 539 540
    mkArrWords_infoLabel,
    mkTopTickyCtrLabel,
    mkCAFBlackHoleInfoTableLabel,
541
    mkSMAP_FROZEN_CLEAN_infoLabel, mkSMAP_FROZEN_DIRTY_infoLabel,
Ben Gamari's avatar
Ben Gamari committed
542
    mkSMAP_DIRTY_infoLabel, mkBadAlignmentLabel :: CLabel
543
mkDirty_MUT_VAR_Label           = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction
544
mkNonmovingWriteBarrierEnabledLabel
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
                                = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "nonmoving_write_barrier_enabled") CmmData
mkUpdInfoLabel                  = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_upd_frame")         CmmInfo
mkBHUpdInfoLabel                = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_bh_upd_frame" )     CmmInfo
mkIndStaticInfoLabel            = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_IND_STATIC")        CmmInfo
mkMainCapabilityLabel           = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "MainCapability")        CmmData
mkMAP_FROZEN_CLEAN_infoLabel    = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_MUT_ARR_PTRS_FROZEN_CLEAN") CmmInfo
mkMAP_FROZEN_DIRTY_infoLabel    = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_MUT_ARR_PTRS_FROZEN_DIRTY") CmmInfo
mkMAP_DIRTY_infoLabel           = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_MUT_ARR_PTRS_DIRTY") CmmInfo
mkTopTickyCtrLabel              = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "top_ct")                CmmData
mkCAFBlackHoleInfoTableLabel    = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_CAF_BLACKHOLE")     CmmInfo
mkArrWords_infoLabel            = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_ARR_WORDS")         CmmInfo
mkSMAP_FROZEN_CLEAN_infoLabel   = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN_CLEAN") CmmInfo
mkSMAP_FROZEN_DIRTY_infoLabel   = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN_DIRTY") CmmInfo
mkSMAP_DIRTY_infoLabel          = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_SMALL_MUT_ARR_PTRS_DIRTY") CmmInfo
mkBadAlignmentLabel             = CmmLabel rtsUnitId (NeedExternDecl False) (fsLit "stg_badAlignment")      CmmEntry
560

561
mkSRTInfoLabel :: Int -> CLabel
562
mkSRTInfoLabel n = CmmLabel rtsUnitId (NeedExternDecl False) lbl CmmInfo
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
 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"

584
-----
585
mkCmmInfoLabel,   mkCmmEntryLabel, mkCmmRetInfoLabel, mkCmmRetLabel,
586
  mkCmmCodeLabel, mkCmmClosureLabel
Sylvain Henry's avatar
Sylvain Henry committed
587
        :: UnitId -> FastString -> CLabel
588

589 590 591 592 593 594 595 596 597 598 599 600 601 602
mkCmmDataLabel    :: UnitId -> NeedExternDecl -> FastString -> CLabel
mkRtsCmmDataLabel :: FastString -> CLabel

mkCmmInfoLabel       pkg str     = CmmLabel pkg (NeedExternDecl True) str CmmInfo
mkCmmEntryLabel      pkg str     = CmmLabel pkg (NeedExternDecl True) str CmmEntry
mkCmmRetInfoLabel    pkg str     = CmmLabel pkg (NeedExternDecl True) str CmmRetInfo
mkCmmRetLabel        pkg str     = CmmLabel pkg (NeedExternDecl True) str CmmRet
mkCmmCodeLabel       pkg str     = CmmLabel pkg (NeedExternDecl True) str CmmCode
mkCmmClosureLabel    pkg str     = CmmLabel pkg (NeedExternDecl True) str CmmClosure
mkCmmDataLabel       pkg ext str = CmmLabel pkg ext  str CmmData
mkRtsCmmDataLabel    str         = CmmLabel rtsUnitId (NeedExternDecl False)  str CmmData
                                    -- RTS symbols don't need "GHC.CmmToC" to
                                    -- generate \"extern\" declaration (they are
                                    -- exposed via includes/Stg.h)
603

604 605
mkLocalBlockLabel :: Unique -> CLabel
mkLocalBlockLabel u = LocalBlockLabel u
606 607

-- Constructing RtsLabels
Ian Lynagh's avatar
Ian Lynagh committed
608
mkRtsPrimOpLabel :: PrimOp -> CLabel
609
mkRtsPrimOpLabel primop = RtsLabel (RtsPrimOp primop)
610

611 612 613
mkSelectorInfoLabel :: Platform -> Bool -> Int -> CLabel
mkSelectorInfoLabel platform upd offset =
   ASSERT(offset >= 0 && offset <= pc_MAX_SPEC_SELECTEE_SIZE (platformConstants platform))
614
   RtsLabel (RtsSelectorInfoTable upd offset)
615

616 617 618
mkSelectorEntryLabel :: Platform -> Bool -> Int -> CLabel
mkSelectorEntryLabel platform upd offset =
   ASSERT(offset >= 0 && offset <= pc_MAX_SPEC_SELECTEE_SIZE (platformConstants platform))
619 620
   RtsLabel (RtsSelectorEntry upd offset)

621 622 623
mkApInfoTableLabel :: Platform -> Bool -> Int -> CLabel
mkApInfoTableLabel platform upd arity =
   ASSERT(arity > 0 && arity <= pc_MAX_SPEC_AP_SIZE (platformConstants platform))
624 625
   RtsLabel (RtsApInfoTable upd arity)

626 627 628
mkApEntryLabel :: Platform -> Bool -> Int -> CLabel
mkApEntryLabel platform upd arity =
   ASSERT(arity > 0 && arity <= pc_MAX_SPEC_AP_SIZE (platformConstants platform))
629
   RtsLabel (RtsApEntry upd arity)
630

631

632
-- A call to some primitive hand written Cmm code
633
mkPrimCallLabel :: PrimCall -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
634
mkPrimCallLabel (PrimCall str pkg)
635
        = CmmLabel (toUnitId pkg) (NeedExternDecl True) str CmmPrimCall
636

637

638
-- Constructing ForeignLabels
639

640
-- | Make a foreign label
Ian Lynagh's avatar
Ian Lynagh committed
641 642 643 644 645 646
mkForeignLabel
        :: FastString           -- name
        -> Maybe Int            -- size prefix
        -> ForeignLabelSource   -- what package it's in
        -> FunctionOrData
        -> CLabel
647

648
mkForeignLabel = ForeignLabel
649 650 651


-- | Update the label size field in a ForeignLabel
652
addLabelSize :: CLabel -> Int -> CLabel
653 654
addLabelSize (ForeignLabel str _ src  fod) sz
    = ForeignLabel str (Just sz) src fod
655
addLabelSize label _
656
    = label
657

658 659 660 661 662
-- | Whether label is a top-level string literal
isBytesLabel :: CLabel -> Bool
isBytesLabel (IdLabel _ _ Bytes) = True
isBytesLabel _lbl = False

663 664 665 666 667
-- | Whether label is a non-haskell label (defined in C code)
isForeignLabel :: CLabel -> Bool
isForeignLabel (ForeignLabel _ _ _ _) = True
isForeignLabel _lbl = False

668 669 670 671 672
-- | 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
673
isStaticClosureLabel (CmmLabel _ _ _ CmmClosure) = True
674 675 676 677 678 679 680 681 682
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
683
isSomeRODataLabel (IdLabel _ _ BlockInfoTable) = True
684
-- info table defined in cmm (.cmm)
685
isSomeRODataLabel (CmmLabel _ _ _ CmmInfo) = True
686 687
isSomeRODataLabel _lbl = False

688 689 690 691 692 693 694 695 696 697 698 699 700
-- | 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

701
-- | Get the label size field from a ForeignLabel
702
foreignLabelStdcallInfo :: CLabel -> Maybe Int
703
foreignLabelStdcallInfo (ForeignLabel _ info _ _) = info
704 705
foreignLabelStdcallInfo _lbl = Nothing

706

707
-- Constructing Large*Labels
Ian Lynagh's avatar
Ian Lynagh committed
708
mkBitmapLabel   :: Unique -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
709
mkBitmapLabel   uniq            = LargeBitmapLabel uniq
710 711

-- Constructing Cost Center Labels
Ian Lynagh's avatar
Ian Lynagh committed
712 713
mkCCLabel  :: CostCentre      -> CLabel
mkCCSLabel :: CostCentreStack -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
714 715
mkCCLabel           cc          = CC_Label cc
mkCCSLabel          ccs         = CCS_Label ccs
716

Ian Lynagh's avatar
Ian Lynagh committed
717
mkRtsApFastLabel :: FastString -> CLabel
718
mkRtsApFastLabel str = RtsLabel (RtsApFast (NonDetFastString str))
719

nfrisby's avatar
nfrisby committed
720 721
mkRtsSlowFastTickyCtrLabel :: String -> CLabel
mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat)
722

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

724
-- Constructing Code Coverage Labels
Ian Lynagh's avatar
Ian Lynagh committed
725
mkHpcTicksLabel :: Module -> CLabel
andy@galois.com's avatar
andy@galois.com committed
726 727
mkHpcTicksLabel                = HpcTicksLabel

728 729

-- Constructing labels used for dynamic linking
730
mkDynamicLinkerLabel :: DynamicLinkerLabelInfo -> CLabel -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
731
mkDynamicLinkerLabel            = DynamicLinkerLabel
732 733 734

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

737
mkPicBaseLabel :: CLabel
Ian Lynagh's avatar
Ian Lynagh committed
738
mkPicBaseLabel                  = PicBaseLabel
739

740 741

-- Constructing miscellaneous other labels
742
mkDeadStripPreventer :: CLabel -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
743
mkDeadStripPreventer lbl        = DeadStripPreventer lbl
744 745

mkStringLitLabel :: Unique -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
746
mkStringLitLabel                = StringLitLabel
747 748

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

Peter Wortmann's avatar
Peter Wortmann committed
751 752 753 754 755
mkAsmTempDerivedLabel :: CLabel -> FastString -> CLabel
mkAsmTempDerivedLabel = AsmTempDerivedLabel

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

757 758 759 760 761
-- | Construct a label for a DWARF Debug Information Entity (DIE)
-- describing another symbol.
mkAsmTempDieLabel :: CLabel -> CLabel
mkAsmTempDieLabel l = mkAsmTempDerivedLabel l (fsLit "_die")

762
-- -----------------------------------------------------------------------------
763 764
-- Convert between different kinds of label

765 766 767 768
toClosureLbl :: Platform -> CLabel -> CLabel
toClosureLbl platform lbl = case lbl of
   IdLabel n c _        -> IdLabel n c Closure
   CmmLabel m ext str _ -> CmmLabel m ext str CmmClosure
769
   _                    -> pprPanic "toClosureLbl" (pprDebugCLabel platform lbl)
770 771 772 773 774

toSlowEntryLbl :: Platform -> CLabel -> CLabel
toSlowEntryLbl platform lbl = case lbl of
   IdLabel n _ BlockInfoTable -> pprPanic "toSlowEntryLbl" (ppr n)
   IdLabel n c _              -> IdLabel n c Slow
775
   _                          -> pprPanic "toSlowEntryLbl" (pprDebugCLabel platform lbl)
776 777 778 779 780 781 782 783 784 785

toEntryLbl :: Platform -> CLabel -> CLabel
toEntryLbl platform lbl = case lbl of
   IdLabel n c LocalInfoTable    -> IdLabel n c LocalEntry
   IdLabel n c ConInfoTable      -> IdLabel n c ConEntry
   IdLabel n _ BlockInfoTable    -> mkLocalBlockLabel (nameUnique n)
                   -- See Note [Proc-point local block entry-point].
   IdLabel n c _                 -> IdLabel n c Entry
   CmmLabel m ext str CmmInfo    -> CmmLabel m ext str CmmEntry
   CmmLabel m ext str CmmRetInfo -> CmmLabel m ext str CmmRet
786
   _                             -> pprPanic "toEntryLbl" (pprDebugCLabel platform lbl)
787 788 789 790 791 792 793 794

toInfoLbl :: Platform -> CLabel -> CLabel
toInfoLbl platform lbl = case lbl of
   IdLabel n c LocalEntry      -> IdLabel n c LocalInfoTable
   IdLabel n c ConEntry        -> IdLabel n c ConInfoTable
   IdLabel n c _               -> IdLabel n c InfoTable
   CmmLabel m ext str CmmEntry -> CmmLabel m ext str CmmInfo
   CmmLabel m ext str CmmRet   -> CmmLabel m ext str CmmRetInfo
795
   _                           -> pprPanic "CLabel.toInfoLbl" (pprDebugCLabel platform lbl)
796

nfrisby's avatar
nfrisby committed
797 798 799 800
hasHaskellName :: CLabel -> Maybe Name
hasHaskellName (IdLabel n _ _) = Just n
hasHaskellName _               = Nothing

801
-- -----------------------------------------------------------------------------
nfrisby's avatar
nfrisby committed
802
-- Does a CLabel's referent itself refer to a CAF?
803
hasCAF :: CLabel -> Bool
nfrisby's avatar
nfrisby committed
804
hasCAF (IdLabel _ _ RednCounts) = False -- Note [ticky for LNE]
805 806
hasCAF (IdLabel _ MayHaveCafRefs _) = True
hasCAF _                            = False
807

nfrisby's avatar
nfrisby committed
808 809 810 811 812
-- 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
813
-- GHC.Cmm.Info.Build.cafTransfers would consider such a ticky label
nfrisby's avatar
nfrisby committed
814 815 816 817 818 819 820 821 822 823 824 825
-- 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.
826

827 828
-- -----------------------------------------------------------------------------
-- Does a CLabel need declaring before use or not?
829
--
830
-- See wiki:commentary/compiler/backends/ppr-c#prototypes
831 832 833

needsCDecl :: CLabel -> Bool
  -- False <=> it's pre-declared; don't bother
834
  -- don't bother declaring Bitmap labels, we always make sure
835
  -- they are defined before use.
836
needsCDecl (SRTLabel _)                 = True
Ian Lynagh's avatar
Ian Lynagh committed
837 838
needsCDecl (LargeBitmapLabel _)         = False
needsCDecl (IdLabel _ _ _)              = True
839
needsCDecl (LocalBlockLabel _)          = True
840

Ian Lynagh's avatar
Ian Lynagh committed
841 842
needsCDecl (StringLitLabel _)           = False
needsCDecl (AsmTempLabel _)             = False
Peter Wortmann's avatar
Peter Wortmann committed
843
needsCDecl (AsmTempDerivedLabel _ _)    = False
Ian Lynagh's avatar
Ian Lynagh committed
844 845
needsCDecl (RtsLabel _)                 = False

846 847 848 849
needsCDecl (CmmLabel pkgId (NeedExternDecl external) _ _)
        -- local labels mustn't have it
        | not external                  = False

Ian Lynagh's avatar
Ian Lynagh committed
850 851
        -- Prototypes for labels defined in the runtime system are imported
        --      into HC files via includes/Stg.h.
852
        | pkgId == rtsUnitId            = False
Ian Lynagh's avatar
Ian Lynagh committed
853 854 855 856 857 858 859

        -- 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
860
needsCDecl (HpcTicksLabel _)            = True
Ian Lynagh's avatar
Ian Lynagh committed
861 862 863
needsCDecl (DynamicLinkerLabel {})      = panic "needsCDecl DynamicLinkerLabel"
needsCDecl PicBaseLabel                 = panic "needsCDecl PicBaseLabel"
needsCDecl (DeadStripPreventer {})      = panic "needsCDecl DeadStripPreventer"
864

865 866 867 868 869
-- | 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