CLabel.hs 52.3 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 CLabel (
Ian Lynagh's avatar
Ian Lynagh committed
12
13
14
15
16
        CLabel, -- abstract type
        ForeignLabelSource(..),
        pprDebugCLabel,

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

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

33
34
        mkBlockInfoTableLabel,

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

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

Ian Lynagh's avatar
Ian Lynagh committed
43
44
45
46
47
        mkSplitMarkerLabel,
        mkDirty_MUT_VAR_Label,
        mkUpdInfoLabel,
        mkBHUpdInfoLabel,
        mkIndStaticInfoLabel,
48
        mkMainCapabilityLabel,
Ian Lynagh's avatar
Ian Lynagh committed
49
        mkMAP_FROZEN_infoLabel,
50
        mkMAP_FROZEN0_infoLabel,
Ian Lynagh's avatar
Ian Lynagh committed
51
        mkMAP_DIRTY_infoLabel,
52
53
54
        mkSMAP_FROZEN_infoLabel,
        mkSMAP_FROZEN0_infoLabel,
        mkSMAP_DIRTY_infoLabel,
Ben Gamari's avatar
Ben Gamari committed
55
        mkBadAlignmentLabel,
56
        mkArrWords_infoLabel,
57

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

63
        mkSelectorInfoLabel,
Ian Lynagh's avatar
Ian Lynagh committed
64
        mkSelectorEntryLabel,
65

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

Ian Lynagh's avatar
Ian Lynagh committed
74
        mkRtsApFastLabel,
75

76
77
        mkPrimCallLabel,

Ian Lynagh's avatar
Ian Lynagh committed
78
        mkForeignLabel,
79
        addLabelSize,
80

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

88
89
90
        DynamicLinkerLabelInfo(..),
        mkDynamicLinkerLabel,
        dynamicLinkerLabelInfo,
Ian Lynagh's avatar
Ian Lynagh committed
91

92
        mkPicBaseLabel,
93
        mkDeadStripPreventer,
94

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

97
        hasCAF,
98
        needsCDecl, maybeLocalBlockLabel, externallyVisibleCLabel,
99
        isMathFun,
Ian Lynagh's avatar
Ian Lynagh committed
100
        isCFunctionLabel, isGcPtrLabel, labelDynamic,
101
102

        -- * Conversions
103
        toClosureLbl, toSlowEntryLbl, toEntryLbl, toInfoLbl, hasHaskellName,
104

105
        pprCLabel
106
107
    ) where

108
109
#include "HsVersions.h"

110
111
import GhcPrelude

112
import IdInfo
113
import BasicTypes
114
import {-# SOURCE #-} BlockId (BlockId, mkBlockId)
Simon Marlow's avatar
Simon Marlow committed
115
116
117
118
119
120
121
import Packages
import Module
import Name
import Unique
import PrimOp
import Config
import CostCentre
122
123
import Outputable
import FastString
124
import DynFlags
Ian Lynagh's avatar
Ian Lynagh committed
125
import Platform
126
import UniqSet
127
import Util
Peter Wortmann's avatar
Peter Wortmann committed
128
import PprCore ( {- instances -} )
129
130
131
132
133

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

{-
134
  | CLabel is an abstract type that supports the following operations:
135
136
137
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.
-}

data CLabel
156
  = -- | A label related to the definition of a particular Id or Con in a .hs file.
Ian Lynagh's avatar
Ian Lynagh committed
157
158
    IdLabel
        Name
159
        CafInfo
Ian Lynagh's avatar
Ian Lynagh committed
160
161
        IdLabelInfo             -- encodes the suffix of the label

162
  -- | A label from a .cmm file that is not associated with a .hs level Id.
Ian Lynagh's avatar
Ian Lynagh committed
163
  | CmmLabel
164
        UnitId               -- what package the label belongs to.
Ian Lynagh's avatar
Ian Lynagh committed
165
166
        FastString              -- identifier giving the prefix of the label
        CmmLabelInfo            -- encodes the suffix of the label
167
168
169

  -- | 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
170
  --    If it doesn't have an algorithmically generated name then use a CmmLabel
171
  --    instead and give it an appropriate UnitId argument.
Ian Lynagh's avatar
Ian Lynagh committed
172
173
  | RtsLabel
        RtsLabelInfo
174

175
176
177
178
179
180
181
182
  -- | 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

183
184
  -- | A 'C' (or otherwise foreign) label.
  --
Ian Lynagh's avatar
Ian Lynagh committed
185
186
187
188
189
190
  | 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.
191

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

194
195
        FunctionOrData

196
  -- | Local temporary label used for native (or LLVM) code generation
Ian Lynagh's avatar
Ian Lynagh committed
197
198
  | AsmTempLabel
        {-# UNPACK #-} !Unique
199

Peter Wortmann's avatar
Peter Wortmann committed
200
201
202
203
  | AsmTempDerivedLabel
        CLabel
        FastString              -- suffix

204
  | StringLitLabel
Ian Lynagh's avatar
Ian Lynagh committed
205
        {-# UNPACK #-} !Unique
206

207
208
209
  | CC_Label  CostCentre
  | CCS_Label CostCentreStack

Ian Lynagh's avatar
Ian Lynagh committed
210
211
212

  -- | These labels are generated and used inside the NCG only.
  --    They are special variants of a label used for dynamic linking
213
  --    see module PositionIndependentCode for details.
214
  | DynamicLinkerLabel DynamicLinkerLabelInfo CLabel
Ian Lynagh's avatar
Ian Lynagh committed
215
216
217
218

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

223
224
  -- | A label before an info table to prevent excessive dead-stripping on darwin
  | DeadStripPreventer CLabel
225

226

227
228
  -- | Per-module table of tick locations
  | HpcTicksLabel Module
229

230
  -- | Static reference table
231
  | SRTLabel !Unique
232

233
234
  -- | Label of an StgLargeSRT
  | LargeSRTLabel
235
236
        {-# UNPACK #-} !Unique

237
238
  -- | A bitmap (function or case return)
  | LargeBitmapLabel
239
240
        {-# UNPACK #-} !Unique

niteria's avatar
niteria committed
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  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
258
  compare (LocalBlockLabel u1) (LocalBlockLabel u2) = nonDetCmpUnique u1 u2
niteria's avatar
niteria committed
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
  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 (LargeSRTLabel u1) (LargeSRTLabel 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
294
295
  compare LocalBlockLabel{} _ = LT
  compare _ LocalBlockLabel{} = GT
niteria's avatar
niteria committed
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{} _ = 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
  compare LargeSRTLabel{} _ = LT
  compare _ LargeSRTLabel{} = GT
320
321
322
323
324

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

   -- | Label is in a named package
325
   = ForeignLabelInPackage      UnitId
Ian Lynagh's avatar
Ian Lynagh committed
326

327
   -- | Label is in some external, system package that doesn't also
Ian Lynagh's avatar
Ian Lynagh committed
328
329
330
331
   --   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
332
333

   -- | Label is in the package currenly being compiled.
Ian Lynagh's avatar
Ian Lynagh committed
334
335
336
337
   --   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.
338
   | ForeignLabelInThisPackage
Ian Lynagh's avatar
Ian Lynagh committed
339
340

   deriving (Eq, Ord)
341
342
343


-- | For debugging problems with the CLabel representation.
Ian Lynagh's avatar
Ian Lynagh committed
344
345
--      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.
346
--
347
348
pprDebugCLabel :: CLabel -> SDoc
pprDebugCLabel lbl
349
 = case lbl of
350
351
        IdLabel _ _ info-> ppr lbl <> (parens $ text "IdLabel"
                                       <> whenPprDebug (text ":" <> text (show info)))
Ian Lynagh's avatar
Ian Lynagh committed
352
        CmmLabel pkg _name _info
Ian Lynagh's avatar
Ian Lynagh committed
353
         -> ppr lbl <> (parens $ text "CmmLabel" <+> ppr pkg)
354

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

Ian Lynagh's avatar
Ian Lynagh committed
357
        ForeignLabel _name mSuffix src funOrData
Ian Lynagh's avatar
Ian Lynagh committed
358
            -> ppr lbl <> (parens $ text "ForeignLabel"
Ian Lynagh's avatar
Ian Lynagh committed
359
360
361
                                <+> ppr mSuffix
                                <+> ppr src
                                <+> ppr funOrData)
362

363
        _               -> ppr lbl <> (parens $ text "other CLabel")
364
365


366
data IdLabelInfo
Ian Lynagh's avatar
Ian Lynagh committed
367
  = Closure             -- ^ Label for closure
368
369
370
  | SRT                 -- ^ Static reference table (TODO: could be removed
                        -- with the old code generator, but might be needed
                        -- when we implement the New SRT Plan)
371
  | InfoTable           -- ^ Info tables for closures; always read-only
Ian Lynagh's avatar
Ian Lynagh committed
372
  | Entry               -- ^ Entry point
373
  | Slow                -- ^ Slow entry point
374

375
376
377
378
  | 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
379

Ian Lynagh's avatar
Ian Lynagh committed
380
381
  | ConEntry            -- ^ Constructor entry point
  | ConInfoTable        -- ^ Corresponding info table
382

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

385
386
  | Bytes               -- ^ Content of a string literal. See
                        -- Note [Bytes label].
387
388
389
  | BlockInfoTable      -- ^ Like LocalInfoTable but for a proc-point block
                        -- instead of a closure entry-point.
                        -- See Note [Proc-point local block entry-point].
390

391
  deriving (Eq, Ord, Show)
392
393
394


data RtsLabelInfo
395
396
  = RtsSelectorInfoTable Bool{-updatable-} Int{-offset-}  -- ^ Selector thunks
  | RtsSelectorEntry     Bool{-updatable-} Int{-offset-}
397

398
399
  | RtsApInfoTable       Bool{-updatable-} Int{-arity-}    -- ^ AP thunks
  | RtsApEntry           Bool{-updatable-} Int{-arity-}
400
401

  | RtsPrimOp PrimOp
Ian Lynagh's avatar
Ian Lynagh committed
402
  | RtsApFast     FastString    -- ^ _fast versions of generic apply
nfrisby's avatar
nfrisby committed
403
  | RtsSlowFastTickyCtr String
404
405

  deriving (Eq, Ord)
406
407
  -- NOTE: Eq on LitString compares the pointer only, so this isn't
  -- a real equality.
408

409
410

-- | What type of Cmm label we're dealing with.
Ian Lynagh's avatar
Ian Lynagh committed
411
412
--      Determines the suffix appended to the name when a CLabel.CmmLabel
--      is pretty printed.
413
data CmmLabelInfo
414
  = CmmInfo                     -- ^ misc rts info tables,      suffix _info
Ian Lynagh's avatar
Ian Lynagh committed
415
416
417
  | CmmEntry                    -- ^ misc rts entry points,     suffix _entry
  | CmmRetInfo                  -- ^ misc rts ret info tables,  suffix _info
  | CmmRet                      -- ^ misc rts return points,    suffix _ret
418
  | CmmData                     -- ^ misc rts data bits, eg CHARLIKE_closure
Ian Lynagh's avatar
Ian Lynagh committed
419
  | CmmCode                     -- ^ misc rts code
420
  | CmmClosure                  -- ^ closures eg CHARLIKE_closure
Ian Lynagh's avatar
Ian Lynagh committed
421
  | CmmPrimCall                 -- ^ a prim call to some hand written Cmm code
422
423
  deriving (Eq, Ord)

424
data DynamicLinkerLabelInfo
Ian Lynagh's avatar
Ian Lynagh committed
425
426
427
428
429
  = CodeStub                    -- MachO: Lfoo$stub, ELF: foo@plt
  | SymbolPtr                   -- MachO: Lfoo$non_lazy_ptr, Windows: __imp_foo
  | GotSymbolPtr                -- ELF: foo@got
  | GotSymbolOffset             -- ELF: foo@gotoff

430
  deriving (Eq, Ord)
Ian Lynagh's avatar
Ian Lynagh committed
431

432

433
434
-- -----------------------------------------------------------------------------
-- Constructing CLabels
435
-- -----------------------------------------------------------------------------
436

Ian Lynagh's avatar
Ian Lynagh committed
437
-- Constructing IdLabels
438
-- These are always local:
439

440
441
mkTopSRTLabel     :: Unique -> CLabel
mkTopSRTLabel u = SRTLabel u
442

nfrisby's avatar
nfrisby committed
443
444
445
mkRednCountsLabel :: Name -> CLabel
mkRednCountsLabel       name    =
  IdLabel name NoCafRefs RednCounts  -- Note [ticky for LNE]
446
447

-- These have local & (possibly) external variants:
Ian Lynagh's avatar
Ian Lynagh committed
448
449
450
mkLocalClosureLabel      :: Name -> CafInfo -> CLabel
mkLocalInfoTableLabel    :: Name -> CafInfo -> CLabel
mkLocalClosureTableLabel :: Name -> CafInfo -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
451
mkLocalClosureLabel     name c  = IdLabel name  c Closure
452
mkLocalInfoTableLabel   name c  = IdLabel name  c LocalInfoTable
453
454
mkLocalClosureTableLabel name c = IdLabel name  c ClosureTable

Ian Lynagh's avatar
Ian Lynagh committed
455
456
457
458
459
mkClosureLabel              :: Name -> CafInfo -> CLabel
mkInfoTableLabel            :: Name -> CafInfo -> CLabel
mkEntryLabel                :: Name -> CafInfo -> CLabel
mkClosureTableLabel         :: Name -> CafInfo -> CLabel
mkConInfoTableLabel         :: Name -> CafInfo -> CLabel
460
mkBytesLabel                :: Name -> CLabel
461
mkClosureLabel name         c     = IdLabel name c Closure
462
mkInfoTableLabel name       c     = IdLabel name c InfoTable
463
mkEntryLabel name           c     = IdLabel name c Entry
464
mkClosureTableLabel name    c     = IdLabel name c ClosureTable
465
mkConInfoTableLabel name    c     = IdLabel name c ConInfoTable
466
mkBytesLabel name                 = IdLabel name NoCafRefs Bytes
467

468
469
470
471
mkBlockInfoTableLabel :: Name -> CafInfo -> CLabel
mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable
                               -- See Note [Proc-point local block entry-point].

472
-- Constructing Cmm Labels
473
mkDirty_MUT_VAR_Label, mkSplitMarkerLabel, mkUpdInfoLabel,
Ian Lynagh's avatar
Ian Lynagh committed
474
    mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel,
475
    mkMAP_FROZEN_infoLabel, mkMAP_FROZEN0_infoLabel, mkMAP_DIRTY_infoLabel,
476
477
478
479
    mkArrWords_infoLabel,
    mkTopTickyCtrLabel,
    mkCAFBlackHoleInfoTableLabel,
    mkSMAP_FROZEN_infoLabel, mkSMAP_FROZEN0_infoLabel,
Ben Gamari's avatar
Ben Gamari committed
480
    mkSMAP_DIRTY_infoLabel, mkBadAlignmentLabel :: CLabel
481
mkDirty_MUT_VAR_Label           = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction
482
483
484
485
486
487
488
489
490
491
492
493
494
495
mkSplitMarkerLabel              = CmmLabel rtsUnitId (fsLit "__stg_split_marker")    CmmCode
mkUpdInfoLabel                  = CmmLabel rtsUnitId (fsLit "stg_upd_frame")         CmmInfo
mkBHUpdInfoLabel                = CmmLabel rtsUnitId (fsLit "stg_bh_upd_frame" )     CmmInfo
mkIndStaticInfoLabel            = CmmLabel rtsUnitId (fsLit "stg_IND_STATIC")        CmmInfo
mkMainCapabilityLabel           = CmmLabel rtsUnitId (fsLit "MainCapability")        CmmData
mkMAP_FROZEN_infoLabel          = CmmLabel rtsUnitId (fsLit "stg_MUT_ARR_PTRS_FROZEN") CmmInfo
mkMAP_FROZEN0_infoLabel         = CmmLabel rtsUnitId (fsLit "stg_MUT_ARR_PTRS_FROZEN0") CmmInfo
mkMAP_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
mkSMAP_FROZEN_infoLabel         = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN") CmmInfo
mkSMAP_FROZEN0_infoLabel        = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_FROZEN0") CmmInfo
mkSMAP_DIRTY_infoLabel          = CmmLabel rtsUnitId (fsLit "stg_SMALL_MUT_ARR_PTRS_DIRTY") CmmInfo
Ben Gamari's avatar
Ben Gamari committed
496
mkBadAlignmentLabel             = CmmLabel rtsUnitId (fsLit "stg_badAlignment")      CmmEntry
497
498

-----
499
mkCmmInfoLabel,   mkCmmEntryLabel, mkCmmRetInfoLabel, mkCmmRetLabel,
500
  mkCmmCodeLabel, mkCmmDataLabel,  mkCmmClosureLabel
501
        :: UnitId -> FastString -> CLabel
502

Ian Lynagh's avatar
Ian Lynagh committed
503
504
505
506
507
508
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
509
mkCmmClosureLabel   pkg str     = CmmLabel pkg str CmmClosure
510

511
512
mkLocalBlockLabel :: Unique -> CLabel
mkLocalBlockLabel u = LocalBlockLabel u
513
514

-- Constructing RtsLabels
Ian Lynagh's avatar
Ian Lynagh committed
515
mkRtsPrimOpLabel :: PrimOp -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
516
mkRtsPrimOpLabel primop         = RtsLabel (RtsPrimOp primop)
517

Ian Lynagh's avatar
Ian Lynagh committed
518
519
mkSelectorInfoLabel  :: Bool -> Int -> CLabel
mkSelectorEntryLabel :: Bool -> Int -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
520
521
mkSelectorInfoLabel  upd off    = RtsLabel (RtsSelectorInfoTable upd off)
mkSelectorEntryLabel upd off    = RtsLabel (RtsSelectorEntry     upd off)
522

Ian Lynagh's avatar
Ian Lynagh committed
523
524
mkApInfoTableLabel :: Bool -> Int -> CLabel
mkApEntryLabel     :: Bool -> Int -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
525
526
mkApInfoTableLabel   upd off    = RtsLabel (RtsApInfoTable       upd off)
mkApEntryLabel       upd off    = RtsLabel (RtsApEntry           upd off)
527

528

529
-- A call to some primitive hand written Cmm code
530
mkPrimCallLabel :: PrimCall -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
531
532
mkPrimCallLabel (PrimCall str pkg)
        = CmmLabel pkg str CmmPrimCall
533

534

535
-- Constructing ForeignLabels
536

537
-- | Make a foreign label
Ian Lynagh's avatar
Ian Lynagh committed
538
539
540
541
542
543
mkForeignLabel
        :: FastString           -- name
        -> Maybe Int            -- size prefix
        -> ForeignLabelSource   -- what package it's in
        -> FunctionOrData
        -> CLabel
544
545
546
547
548
549

mkForeignLabel str mb_sz src fod
    = ForeignLabel str mb_sz src  fod


-- | Update the label size field in a ForeignLabel
550
addLabelSize :: CLabel -> Int -> CLabel
551
552
addLabelSize (ForeignLabel str _ src  fod) sz
    = ForeignLabel str (Just sz) src fod
553
addLabelSize label _
554
    = label
555

556
557
558
559
560
-- | Whether label is a top-level string literal
isBytesLabel :: CLabel -> Bool
isBytesLabel (IdLabel _ _ Bytes) = True
isBytesLabel _lbl = False

561
562
563
564
565
-- | Whether label is a non-haskell label (defined in C code)
isForeignLabel :: CLabel -> Bool
isForeignLabel (ForeignLabel _ _ _ _) = True
isForeignLabel _lbl = False

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
-- | 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
581
isSomeRODataLabel (IdLabel _ _ BlockInfoTable) = True
582
583
584
585
586
587
588
-- static reference tables defined in haskell (.hs)
isSomeRODataLabel (IdLabel _ _ SRT) = True
isSomeRODataLabel (SRTLabel _) = True
-- info table defined in cmm (.cmm)
isSomeRODataLabel (CmmLabel _ _ CmmInfo) = True
isSomeRODataLabel _lbl = False

589
-- | Get the label size field from a ForeignLabel
590
foreignLabelStdcallInfo :: CLabel -> Maybe Int
591
foreignLabelStdcallInfo (ForeignLabel _ info _ _) = info
592
593
foreignLabelStdcallInfo _lbl = Nothing

594

595
-- Constructing Large*Labels
Ian Lynagh's avatar
Ian Lynagh committed
596
597
mkLargeSRTLabel :: Unique -> CLabel
mkBitmapLabel   :: Unique -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
598
599
mkLargeSRTLabel uniq            = LargeSRTLabel uniq
mkBitmapLabel   uniq            = LargeBitmapLabel uniq
600
601

-- Constructing Cost Center Labels
Ian Lynagh's avatar
Ian Lynagh committed
602
603
mkCCLabel  :: CostCentre      -> CLabel
mkCCSLabel :: CostCentreStack -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
604
605
mkCCLabel           cc          = CC_Label cc
mkCCSLabel          ccs         = CCS_Label ccs
606

Ian Lynagh's avatar
Ian Lynagh committed
607
mkRtsApFastLabel :: FastString -> CLabel
608
609
mkRtsApFastLabel str = RtsLabel (RtsApFast str)

nfrisby's avatar
nfrisby committed
610
611
mkRtsSlowFastTickyCtrLabel :: String -> CLabel
mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat)
612

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

614
-- Constructing Code Coverage Labels
Ian Lynagh's avatar
Ian Lynagh committed
615
mkHpcTicksLabel :: Module -> CLabel
andy@galois.com's avatar
andy@galois.com committed
616
617
mkHpcTicksLabel                = HpcTicksLabel

618
619

-- Constructing labels used for dynamic linking
620
mkDynamicLinkerLabel :: DynamicLinkerLabelInfo -> CLabel -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
621
mkDynamicLinkerLabel            = DynamicLinkerLabel
622
623
624

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

627
mkPicBaseLabel :: CLabel
Ian Lynagh's avatar
Ian Lynagh committed
628
mkPicBaseLabel                  = PicBaseLabel
629

630
631

-- Constructing miscellaneous other labels
632
mkDeadStripPreventer :: CLabel -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
633
mkDeadStripPreventer lbl        = DeadStripPreventer lbl
634
635

mkStringLitLabel :: Unique -> CLabel
Ian Lynagh's avatar
Ian Lynagh committed
636
mkStringLitLabel                = StringLitLabel
637
638

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

Peter Wortmann's avatar
Peter Wortmann committed
641
642
643
644
645
mkAsmTempDerivedLabel :: CLabel -> FastString -> CLabel
mkAsmTempDerivedLabel = AsmTempDerivedLabel

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

647
648
649
650
651
-- | Construct a label for a DWARF Debug Information Entity (DIE)
-- describing another symbol.
mkAsmTempDieLabel :: CLabel -> CLabel
mkAsmTempDieLabel l = mkAsmTempDerivedLabel l (fsLit "_die")

652
-- -----------------------------------------------------------------------------
653
654
-- Convert between different kinds of label

655
toClosureLbl :: CLabel -> CLabel
656
657
toClosureLbl (IdLabel n _ BlockInfoTable)
  = pprPanic "toClosureLbl: BlockInfoTable" (ppr n)
658
toClosureLbl (IdLabel n c _) = IdLabel n c Closure
659
toClosureLbl (CmmLabel m str _) = CmmLabel m str CmmClosure
660
661
662
toClosureLbl l = pprPanic "toClosureLbl" (ppr l)

toSlowEntryLbl :: CLabel -> CLabel
663
664
toSlowEntryLbl (IdLabel n _ BlockInfoTable)
  = pprPanic "toSlowEntryLbl" (ppr n)
665
666
667
668
669
670
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
671
toEntryLbl (IdLabel n _ BlockInfoTable)  = mkLocalBlockLabel (nameUnique n)
672
                              -- See Note [Proc-point local block entry-point].
673
674
675
676
677
678
679
680
681
682
683
684
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)
685

nfrisby's avatar
nfrisby committed
686
687
688
689
hasHaskellName :: CLabel -> Maybe Name
hasHaskellName (IdLabel n _ _) = Just n
hasHaskellName _               = Nothing

690
-- -----------------------------------------------------------------------------
nfrisby's avatar
nfrisby committed
691
-- Does a CLabel's referent itself refer to a CAF?
692
hasCAF :: CLabel -> Bool
nfrisby's avatar
nfrisby committed
693
hasCAF (IdLabel _ _ RednCounts) = False -- Note [ticky for LNE]
694
695
hasCAF (IdLabel _ MayHaveCafRefs _) = True
hasCAF _                            = False
696

nfrisby's avatar
nfrisby committed
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
-- 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
-- CmmBuildInfoTables.cafTransfers would consider such a ticky label
-- 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.
715

716
717
-- -----------------------------------------------------------------------------
-- Does a CLabel need declaring before use or not?
718
719
--
-- See wiki:Commentary/Compiler/Backends/PprC#Prototypes
720
721
722

needsCDecl :: CLabel -> Bool
  -- False <=> it's pre-declared; don't bother
723
  -- don't bother declaring Bitmap labels, we always make sure
724
  -- they are defined before use.
725
needsCDecl (SRTLabel _)                 = True
Ian Lynagh's avatar
Ian Lynagh committed
726
727
728
needsCDecl (LargeSRTLabel _)            = False
needsCDecl (LargeBitmapLabel _)         = False
needsCDecl (IdLabel _ _ _)              = True
729
needsCDecl (LocalBlockLabel _)          = True
730

Ian Lynagh's avatar
Ian Lynagh committed
731
732
needsCDecl (StringLitLabel _)           = False
needsCDecl (AsmTempLabel _)             = False
Peter Wortmann's avatar
Peter Wortmann committed
733
needsCDecl (AsmTempDerivedLabel _ _)    = False
Ian Lynagh's avatar
Ian Lynagh committed
734
735
736
737
738
needsCDecl (RtsLabel _)                 = False

needsCDecl (CmmLabel pkgId _ _)
        -- Prototypes for labels defined in the runtime system are imported
        --      into HC files via includes/Stg.h.
739
        | pkgId == rtsUnitId         = False
Ian Lynagh's avatar
Ian Lynagh committed
740
741
742
743
744
745
746

        -- 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
747
needsCDecl (HpcTicksLabel _)            = True
Ian Lynagh's avatar
Ian Lynagh committed
748
749
750
needsCDecl (DynamicLinkerLabel {})      = panic "needsCDecl DynamicLinkerLabel"
needsCDecl PicBaseLabel                 = panic "needsCDecl PicBaseLabel"
needsCDecl (DeadStripPreventer {})      = panic "needsCDecl DeadStripPreventer"
751

752
753
754
755
756
-- | 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
757

758

Ian Lynagh's avatar
Ian Lynagh committed
759
-- | Check whether a label corresponds to a C function that has
760
--      a prototype in a system header somehere, or is built-in
761
--      to the C compiler. For these labels we avoid generating our
762
--      own C prototypes.
763
isMathFun :: CLabel -> Bool
Ian Lynagh's avatar
Ian Lynagh committed
764
isMathFun (ForeignLabel fs _ _ _)       = fs `elementOfUniqSet` math_funs
765
766
isMathFun _ = False

Ian Lynagh's avatar
Ian Lynagh committed
767
math_funs :: UniqSet FastString
768
math_funs = mkUniqSet [
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
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
        -- _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"),
845
846
847
848
849
850
        (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")
851
    ]
852

853
-- -----------------------------------------------------------------------------
854
-- | Is a CLabel visible outside this object file or not?
Ian Lynagh's avatar
Ian Lynagh committed
855
856
857
--      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.
858
externallyVisibleCLabel :: CLabel -> Bool -- not C "static"
Ian Lynagh's avatar
Ian Lynagh committed
859
860
externallyVisibleCLabel (StringLitLabel _)      = False
externallyVisibleCLabel (AsmTempLabel _)        = False
Peter Wortmann's avatar
Peter Wortmann committed
861
externallyVisibleCLabel (AsmTempDerivedLabel _ _)= False
862
externallyVisibleCLabel (RtsLabel _)            = True
863
externallyVisibleCLabel (LocalBlockLabel _)     = False
Ian Lynagh's avatar
Ian Lynagh committed
864
865
866
867
868
externallyVisibleCLabel (CmmLabel _ _ _)        = True
externallyVisibleCLabel (ForeignLabel{})        = True
externallyVisibleCLabel (IdLabel name _ info)   = isExternalName name && externallyVisibleIdLabel info
externallyVisibleCLabel (CC_Label _)            = True
externallyVisibleCLabel (CCS_Label _)           = True
869
externallyVisibleCLabel (DynamicLinkerLabel _ _)  = False
Ian Lynagh's avatar
Ian Lynagh committed
870
externallyVisibleCLabel (HpcTicksLabel _)       = True
871
externallyVisibleCLabel (LargeBitmapLabel _)    = False
872
externallyVisibleCLabel (SRTLabel _)            = False
Ian Lynagh's avatar
Ian Lynagh committed
873
externallyVisibleCLabel (LargeSRTLabel _)       = False
Ian Lynagh's avatar
Ian Lynagh committed
874
875
externallyVisibleCLabel (PicBaseLabel {}) = panic "externallyVisibleCLabel PicBaseLabel"
externallyVisibleCLabel (DeadStripPreventer {}) = panic "externallyVisibleCLabel DeadStripPreventer"
876

batterseapower's avatar
batterseapower committed
877
externallyVisibleIdLabel :: IdLabelInfo -> Bool
878
externallyVisibleIdLabel SRT             = False
879
880
externallyVisibleIdLabel LocalInfoTable  = False
externallyVisibleIdLabel LocalEntry      = False
881
externallyVisibleIdLabel BlockInfoTable  = False
882
externallyVisibleIdLabel _               = True
batterseapower's avatar
batterseapower committed
883

884
-- -----------------------------------------------------------------------------
Ian Lynagh's avatar
Ian Lynagh committed
885
-- Finding the "type" of a CLabel
886
887
888
889

-- For generating correct types in label declarations:

data CLabelType
Ian Lynagh's avatar
Ian Lynagh committed
890
891
892
  = CodeLabel   -- Address of some executable instructions
  | DataLabel   -- Address of data, not a GC ptr
  | GcPtrLabel  -- Address of a (presumably static) GC object
893
894
895

isCFunctionLabel :: CLabel -> Bool
isCFunctionLabel lbl = case labelType lbl of
Ian Lynagh's avatar
Ian Lynagh committed
896
897
                        CodeLabel -> True
                        _other    -> False
898
899
900

isGcPtrLabel :: CLabel -> Bool
isGcPtrLabel lbl = case labelType lbl of
Ian Lynagh's avatar
Ian Lynagh committed
901
902
                        GcPtrLabel -> True
                        _other     -> False
903

904
905
906

-- | Work out the general type of data at the address of this label
--    whether it be code, data, or static GC object.
907
labelType :: CLabel -> CLabelType
908
labelType (IdLabel _ _ info)                    = idInfoLabelType info
Ian Lynagh's avatar
Ian Lynagh committed
909
labelType (CmmLabel _ _ CmmData)                = DataLabel
910
labelType (CmmLabel _ _ CmmClosure)             = GcPtrLabel
Ian Lynagh's avatar
Ian Lynagh committed
911
912
913
labelType (CmmLabel _ _ CmmCode)                = CodeLabel
labelType (CmmLabel _ _ CmmInfo)                = DataLabel
labelType (CmmLabel _ _ CmmEntry)               = CodeLabel
914
labelType (CmmLabel _ _ CmmPrimCall)            = CodeLabel
Ian Lynagh's avatar
Ian Lynagh committed
915
916
labelType (CmmLabel _ _ CmmRetInfo)             = DataLabel
labelType (CmmLabel _ _ CmmRet)                 = CodeLabel
917
918
labelType (RtsLabel (RtsSelectorInfoTable _ _)) = DataLabel
labelType (RtsLabel (RtsApInfoTable _ _))       = DataLabel
919
labelType (RtsLabel (RtsApFast _))              = CodeLabel
920
921
labelType (RtsLabel _)                          = DataLabel
labelType (LocalBlockLabel _)                   = CodeLabel
922
labelType (SRTLabel _)                          = DataLabel
923
924
925
926
927
928
929
930
931
932
933
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
934
935
labelType (LargeSRTLabel _)                     = DataLabel
labelType (LargeBitmapLabel _)                  = DataLabel
936

Ian Lynagh's avatar
Ian Lynagh committed
937
idInfoLabelType :: IdLabelInfo -> CLabelType
938
idInfoLabelType info =
939
  case info of
940
941
    InfoTable     -> DataLabel
    LocalInfoTable -> DataLabel
942
    BlockInfoTable -> DataLabel
943
    Closure       -> GcPtrLabel
944
    ConInfoTable  -> DataLabel
945
    ClosureTable  -> DataLabel
946
    RednCounts    -> DataLabel
947
    Bytes         -> DataLabel
Ian Lynagh's avatar
Ian Lynagh committed
948
    _             -> CodeLabel
949
950
951
952
953
954
955
956
957
958


-- -----------------------------------------------------------------------------
-- Does a CLabel need dynamic linkage?

-- When referring to data in code, we need to know whether
-- that data resides in a DLL or not. [Win32 only.]
-- @labelDynamic@ returns @True@ if the label is located
-- in a DLL, be it a data reference or not.

959
960
labelDynamic :: DynFlags -> Module -> CLabel -> Bool
labelDynamic dflags this_mod lbl =
961
  case lbl of
962
   -- is the RTS in a DLL or not?
thomie's avatar
thomie committed
963
   RtsLabel _           -> (WayDyn `elem` ways dflags) && (this_pkg /= rtsUnitId)
964

965
   IdLabel n _ _        -> isDllName dflags this_mod n
966

daniel.is.fischer's avatar
daniel.is.fischer committed
967
   -- When compiling in the "dyn" way, each package is to be linked into
Ian Lynagh's avatar
Ian Lynagh committed
968
   -- its own shared library.
969
   CmmLabel pkg _ _
Ian Lynagh's avatar
Ian Lynagh committed
970
    | os == OSMinGW32 ->
thomie's avatar
thomie committed
971
       (WayDyn `elem` ways dflags) && (this_pkg /= pkg)
Ian Lynagh's avatar
Ian Lynagh committed
972
973
974
    | otherwise ->
       True

975
976
   LocalBlockLabel _    -> False

Ian Lynagh's avatar
Ian Lynagh committed
977
978
979
980
981
982
983
984
985
986
987
988
989
990
   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 ->
thomie's avatar
thomie committed
991
                (WayDyn `elem` ways dflags) && (this_pkg /= pkgId)
Ian Lynagh's avatar
Ian Lynagh committed
992
993
994
995
996

       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
997

thomie's avatar
thomie committed
998
   HpcTicksLabel m        -> (WayDyn `elem` ways dflags) && this_mod /= m
rwbarton's avatar
rwbarton committed
999

1000
   -- Note that DynamicLinkerLabels do NOT require dynamic linking themselves.
Ian Lynagh's avatar
Ian Lynagh committed
1001
   _                 -> False
1002
1003
1004
  where
    os = platformOS (targetPlatform dflags)
    this_pkg = moduleUnitId this_mod
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017


-----------------------------------------------------------------------------
-- Printing out CLabels.

{-
Convention:

      <name>_<type>

where <name> is <Module>_<name> for external names and <unique> for
internal names. <type> is one of the following: