[project @ 2001-09-04 18:29:20 by ken]
[ghc-hetmet.git] / ghc / compiler / absCSyn / CLabel.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 % $Id: CLabel.lhs,v 1.47 2001/09/04 18:29:20 ken Exp $
5 %
6 \section[CLabel]{@CLabel@: Information to make C Labels}
7
8 \begin{code}
9 module CLabel (
10         CLabel, -- abstract type
11
12         mkClosureLabel,
13         mkSRTLabel,
14         mkInfoTableLabel,
15         mkStdEntryLabel,
16         mkFastEntryLabel,
17         mkConEntryLabel,
18         mkStaticConEntryLabel,
19         mkRednCountsLabel,
20         mkConInfoTableLabel,
21         mkStaticInfoTableLabel,
22         mkApEntryLabel,
23         mkApInfoTableLabel,
24
25         mkReturnPtLabel,
26         mkReturnInfoLabel,
27         mkVecTblLabel,
28         mkAltLabel,
29         mkDefaultLabel,
30         mkBitmapLabel,
31
32         mkClosureTblLabel,
33
34         mkAsmTempLabel,
35
36         mkModuleInitLabel,
37
38         mkErrorStdEntryLabel,
39
40         mkStgUpdatePAPLabel,
41         mkSplitMarkerLabel,
42         mkUpdInfoLabel,
43         mkSeqInfoLabel,
44         mkIndInfoLabel,
45         mkIndStaticInfoLabel,
46         mkRtsGCEntryLabel,
47         mkMainRegTableLabel,
48         mkCharlikeClosureLabel,
49         mkIntlikeClosureLabel,
50         mkMAP_FROZEN_infoLabel,
51         mkEMPTY_MVAR_infoLabel,
52
53         mkTopTickyCtrLabel,
54         mkBlackHoleInfoTableLabel,
55         mkCAFBlackHoleInfoTableLabel,
56         mkSECAFBlackHoleInfoTableLabel,
57         mkRtsPrimOpLabel,
58
59         moduleRegdLabel,
60
61         mkSelectorInfoLabel,
62         mkSelectorEntryLabel,
63
64         mkForeignLabel,
65
66         mkCC_Label, mkCCS_Label,
67         
68         needsCDecl, isAsmTemp, externallyVisibleCLabel,
69
70         CLabelType(..), labelType, labelDynamic,
71
72         pprCLabel
73 #if ! OMIT_NATIVE_CODEGEN
74         , pprCLabel_asm
75 #endif
76     ) where
77
78
79 #include "HsVersions.h"
80
81 #if ! OMIT_NATIVE_CODEGEN
82 import {-# SOURCE #-} MachMisc ( underscorePrefix, fmtAsmLbl )
83 #endif
84
85 import CmdLineOpts      ( opt_Static, opt_DoTickyProfiling )
86 import CStrings         ( pp_cSEP )
87 import DataCon          ( ConTag )
88 import Module           ( moduleName, moduleNameFS, 
89                           Module, isHomeModule )
90 import Name             ( Name, getName, isDllName, isExternallyVisibleName )
91 import TyCon            ( TyCon )
92 import Unique           ( pprUnique, Unique )
93 import PrimOp           ( PrimOp )
94 import CostCentre       ( CostCentre, CostCentreStack )
95 import Outputable
96 \end{code}
97
98 things we want to find out:
99
100 * should the labelled things be declared "static" (visible only in this file)?
101
102 * should it be declared "const" (read-only text space)?
103
104 * does it need declarations at all? (v common Prelude things are pre-declared)
105
106 * what type does it have? (for generating accurate enough C declarations
107   so that the C compiler won't complain).
108
109 \begin{code}
110 data CLabel
111   = IdLabel                     -- A family of labels related to the
112         Name                    -- definition of a particular Id
113         IdLabelInfo
114
115   | DataConLabel                -- Ditto data constructors
116         Name
117         DataConLabelInfo
118
119   | CaseLabel                   -- A family of labels related to a particular case expression
120         Unique                  -- Unique says which case expression
121         CaseLabelInfo
122
123   | TyConLabel TyCon            -- currently only one kind of TyconLabel,
124                                 -- a 'Closure Table'.
125
126   | AsmTempLabel    Unique
127
128   | ModuleInitLabel Module
129
130   | RtsLabel        RtsLabelInfo
131
132   | ForeignLabel FAST_STRING Bool  -- a 'C' (or otherwise foreign) label
133                                    -- Bool <=> is dynamic
134
135   | CC_Label CostCentre
136   | CCS_Label CostCentreStack
137
138   deriving (Eq, Ord)
139 \end{code}
140
141 \begin{code}
142 data IdLabelInfo
143   = Closure             -- Label for (static???) closure
144
145   | SRT                 -- Static reference table
146
147   | InfoTbl             -- Info table for a closure; always read-only
148
149   | EntryStd            -- Thunk, or "slow", code entry point
150
151   | EntryFast Int       -- entry pt when no arg satisfaction chk needed;
152                         -- Int is the arity of the function (to be
153                         -- encoded into the name)
154
155                         -- Ticky-ticky counting
156   | RednCounts          -- Label of place to keep reduction-count info for 
157                         -- this Id
158   deriving (Eq, Ord)
159
160 data DataConLabelInfo
161   = ConEntry            -- the only kind of entry pt for constructors
162   | ConInfoTbl          -- corresponding info table
163   | StaticConEntry      -- static constructor entry point
164   | StaticInfoTbl       -- corresponding info table
165   deriving (Eq, Ord)
166
167 data CaseLabelInfo
168   = CaseReturnPt
169   | CaseReturnInfo
170   | CaseVecTbl
171   | CaseAlt ConTag
172   | CaseDefault
173   | CaseBitmap
174   deriving (Eq, Ord)
175
176 data RtsLabelInfo
177   = RtsShouldNeverHappenCode
178
179   | RtsBlackHoleInfoTbl FAST_STRING  -- black hole with info table name
180
181   | RtsUpdInfo                  -- upd_frame_info
182   | RtsSeqInfo                  -- seq_frame_info
183   | RtsGCEntryLabel String      -- a heap check fail handler, eg  stg_chk_2
184   | RtsMainRegTable             -- MainRegTable (??? Capabilities wurble ???)
185   | Rts_Closure String          -- misc rts closures, eg CHARLIKE_closure
186   | Rts_Info String             -- misc rts itbls, eg MUT_ARR_PTRS_FROZEN_info
187   | Rts_Code String             -- misc rts code
188
189   | RtsSelectorInfoTbl Bool{-updatable-} Int{-offset-}  -- Selector thunks
190   | RtsSelectorEntry   Bool{-updatable-} Int{-offset-}
191
192   | RtsApInfoTbl Bool{-updatable-} Int{-arity-}         -- AP thunks
193   | RtsApEntry   Bool{-updatable-} Int{-arity-}
194
195   | RtsPrimOp PrimOp
196
197   | RtsTopTickyCtr
198
199   | RtsModuleRegd
200
201   deriving (Eq, Ord)
202
203 -- Label Type: for generating C declarations.
204
205 data CLabelType
206   = InfoTblType
207   | ClosureType
208   | VecTblType
209   | ClosureTblType
210   | CodeType
211   | DataType
212 \end{code}
213
214 \begin{code}
215 mkClosureLabel          id              = IdLabel id  Closure
216 mkSRTLabel              id              = IdLabel id  SRT
217 mkInfoTableLabel        id              = IdLabel id  InfoTbl
218 mkStdEntryLabel         id              = IdLabel id  EntryStd
219 mkFastEntryLabel        id arity        = ASSERT(arity > 0)
220                                           IdLabel id  (EntryFast arity)
221
222 mkRednCountsLabel       id              = IdLabel id  RednCounts
223
224 mkStaticInfoTableLabel  con             = DataConLabel con StaticInfoTbl
225 mkConInfoTableLabel     con             = DataConLabel con ConInfoTbl
226 mkConEntryLabel         con             = DataConLabel con ConEntry
227 mkStaticConEntryLabel   con             = DataConLabel con StaticConEntry
228
229
230 mkReturnPtLabel uniq            = CaseLabel uniq CaseReturnPt
231 mkReturnInfoLabel uniq          = CaseLabel uniq CaseReturnInfo
232 mkVecTblLabel   uniq            = CaseLabel uniq CaseVecTbl
233 mkAltLabel      uniq tag        = CaseLabel uniq (CaseAlt tag)
234 mkDefaultLabel  uniq            = CaseLabel uniq CaseDefault
235 mkBitmapLabel   uniq            = CaseLabel uniq CaseBitmap
236
237 mkClosureTblLabel tycon         = TyConLabel tycon
238
239 mkAsmTempLabel                  = AsmTempLabel
240
241 mkModuleInitLabel               = ModuleInitLabel
242
243         -- Some fixed runtime system labels
244
245 mkErrorStdEntryLabel            = RtsLabel RtsShouldNeverHappenCode
246 mkStgUpdatePAPLabel             = RtsLabel (Rts_Code "stg_update_PAP")
247 mkSplitMarkerLabel              = RtsLabel (Rts_Code "__stg_split_marker")
248 mkUpdInfoLabel                  = RtsLabel RtsUpdInfo
249 mkSeqInfoLabel                  = RtsLabel RtsSeqInfo
250 mkIndInfoLabel                  = RtsLabel (Rts_Info "stg_IND_info")
251 mkIndStaticInfoLabel            = RtsLabel (Rts_Info "stg_IND_STATIC_info")
252 mkRtsGCEntryLabel str           = RtsLabel (RtsGCEntryLabel str)
253 mkMainRegTableLabel             = RtsLabel RtsMainRegTable
254 mkCharlikeClosureLabel          = RtsLabel (Rts_Closure "stg_CHARLIKE_closure")
255 mkIntlikeClosureLabel           = RtsLabel (Rts_Closure "stg_INTLIKE_closure")
256 mkMAP_FROZEN_infoLabel          = RtsLabel (Rts_Info "stg_MUT_ARR_PTRS_FROZEN_info")
257 mkEMPTY_MVAR_infoLabel          = RtsLabel (Rts_Info "stg_EMPTY_MVAR_info")
258
259 mkTopTickyCtrLabel              = RtsLabel RtsTopTickyCtr
260 mkBlackHoleInfoTableLabel       = RtsLabel (RtsBlackHoleInfoTbl SLIT("stg_BLACKHOLE_info"))
261 mkCAFBlackHoleInfoTableLabel    = RtsLabel (RtsBlackHoleInfoTbl SLIT("stg_CAF_BLACKHOLE_info"))
262 mkSECAFBlackHoleInfoTableLabel  = if opt_DoTickyProfiling then
263                                     RtsLabel (RtsBlackHoleInfoTbl SLIT("stg_SE_CAF_BLACKHOLE_info"))
264                                   else  -- RTS won't have info table unless -ticky is on
265                                     panic "mkSECAFBlackHoleInfoTableLabel requires -ticky"
266 mkRtsPrimOpLabel primop         = RtsLabel (RtsPrimOp primop)
267
268 moduleRegdLabel                 = RtsLabel RtsModuleRegd
269
270 mkSelectorInfoLabel  upd off    = RtsLabel (RtsSelectorInfoTbl upd off)
271 mkSelectorEntryLabel upd off    = RtsLabel (RtsSelectorEntry   upd off)
272
273 mkApInfoTableLabel  upd off     = RtsLabel (RtsApInfoTbl upd off)
274 mkApEntryLabel upd off          = RtsLabel (RtsApEntry   upd off)
275
276         -- Foreign labels
277
278 mkForeignLabel :: FAST_STRING -> Bool -> CLabel
279 mkForeignLabel str is_dynamic   = ForeignLabel str is_dynamic
280
281         -- Cost centres etc.
282
283 mkCC_Label      cc              = CC_Label cc
284 mkCCS_Label     ccs             = CCS_Label ccs
285 \end{code}
286
287 \begin{code}
288 needsCDecl :: CLabel -> Bool    -- False <=> it's pre-declared; don't bother
289 isAsmTemp  :: CLabel -> Bool    -- is a local temporary for native code generation
290 externallyVisibleCLabel :: CLabel -> Bool -- not C "static"
291 \end{code}
292
293 @needsCDecl@ is @True@ unless the thing is a deeply-@PreludeCore@-ish
294 object.  {\em Also:} No need to spit out labels for things generated
295 by the flattener (in @AbsCUtils@)---it is careful to ensure references
296 to them are always backwards.  These are return-point and vector-table
297 labels.
298
299 Declarations for (non-prelude) @Id@-based things are needed because of
300 mutual recursion.
301
302 Declarations for direct return points are needed, because they may be
303 let-no-escapes, which can be recursive.
304
305 \begin{code}
306 needsCDecl (IdLabel _ _)                = True
307 needsCDecl (CaseLabel _ CaseReturnPt)   = True
308 needsCDecl (DataConLabel _ _)           = True
309 needsCDecl (TyConLabel _)               = True
310 needsCDecl (ModuleInitLabel _)          = True
311
312 needsCDecl (CaseLabel _ _)              = False
313 needsCDecl (AsmTempLabel _)             = False
314 needsCDecl (RtsLabel _)                 = False
315 needsCDecl (ForeignLabel _ _)           = False
316 needsCDecl (CC_Label _)                 = False
317 needsCDecl (CCS_Label _)                = False
318 \end{code}
319
320 Whether the label is an assembler temporary:
321
322 \begin{code}
323 isAsmTemp (AsmTempLabel _) = True
324 isAsmTemp _                = False
325 \end{code}
326
327 C ``static'' or not...
328 From the point of view of the code generator, a name is
329 externally visible if it has to be declared as exported
330 in the .o file's symbol table; that is, made non-static.
331
332 \begin{code}
333 externallyVisibleCLabel (DataConLabel _ _) = True
334 externallyVisibleCLabel (TyConLabel tc)    = True
335 externallyVisibleCLabel (CaseLabel _ _)    = False
336 externallyVisibleCLabel (AsmTempLabel _)   = False
337 externallyVisibleCLabel (ModuleInitLabel _)= True
338 externallyVisibleCLabel (RtsLabel RtsModuleRegd) = False --hack
339 externallyVisibleCLabel (RtsLabel _)       = True
340 externallyVisibleCLabel (ForeignLabel _ _) = True
341 externallyVisibleCLabel (IdLabel id _)     = isExternallyVisibleName id
342 externallyVisibleCLabel (CC_Label _)       = False -- not strictly true
343 externallyVisibleCLabel (CCS_Label _)      = False -- not strictly true
344 \end{code}
345
346 For generating correct types in label declarations...
347
348 \begin{code}
349 labelType :: CLabel -> CLabelType
350 labelType (RtsLabel (RtsBlackHoleInfoTbl _))  = InfoTblType
351 labelType (RtsLabel (RtsSelectorInfoTbl _ _)) = InfoTblType
352 labelType (RtsLabel (RtsApInfoTbl _ _))       = InfoTblType
353 labelType (RtsLabel RtsUpdInfo)               = InfoTblType
354 labelType (CaseLabel _ CaseReturnInfo)        = InfoTblType
355 labelType (CaseLabel _ CaseReturnPt)          = CodeType
356 labelType (CaseLabel _ CaseVecTbl)            = VecTblType
357 labelType (TyConLabel _)                      = ClosureTblType
358 labelType (ModuleInitLabel _ )                = CodeType
359
360 labelType (IdLabel _ info) = 
361   case info of
362     InfoTbl       -> InfoTblType
363     Closure       -> ClosureType
364     _             -> CodeType
365
366 labelType (DataConLabel _ info) = 
367   case info of
368      ConInfoTbl    -> InfoTblType
369      StaticInfoTbl -> InfoTblType
370      _             -> CodeType
371
372 labelType _        = DataType
373 \end{code}
374
375 When referring to data in code, we need to know whether
376 that data resides in a DLL or not. [Win32 only.]
377 @labelDynamic@ returns @True@ if the label is located
378 in a DLL, be it a data reference or not.
379
380 \begin{code}
381 labelDynamic :: CLabel -> Bool
382 labelDynamic lbl = 
383   case lbl of
384    -- The special case for RtsShouldNeverHappenCode is because the associated address is
385    -- NULL, i.e. not a DLL entry point
386    RtsLabel RtsShouldNeverHappenCode -> False
387    RtsLabel _        -> not opt_Static  -- i.e., is the RTS in a DLL or not?
388    IdLabel n k       -> isDllName n
389    DataConLabel n k  -> isDllName n
390    TyConLabel tc     -> isDllName (getName tc)
391    ForeignLabel _ d  -> d
392    ModuleInitLabel m -> (not opt_Static) && (not (isHomeModule m))
393    _                 -> False
394 \end{code}
395
396
397 OLD?: These GRAN functions are needed for spitting out GRAN_FETCH() at the
398 right places. It is used to detect when the abstractC statement of an
399 CCodeBlock actually contains the code for a slow entry point.  -- HWL
400
401 We need at least @Eq@ for @CLabels@, because we want to avoid
402 duplicate declarations in generating C (see @labelSeenTE@ in
403 @PprAbsC@).
404
405 -----------------------------------------------------------------------------
406 Printing out CLabels.
407
408 Convention:
409
410       <name>_<type>
411
412 where <name> is <Module>_<name> for external names and <unique> for
413 internal names. <type> is one of the following:
414
415          info                   Info table
416          srt                    Static reference table
417          entry                  Entry code
418          ret                    Direct return address    
419          vtbl                   Vector table
420          <n>_alt                Case alternative (tag n)
421          dflt                   Default case alternative
422          btm                    Large bitmap vector
423          closure                Static closure
424          con_entry              Dynamic Constructor entry code
425          con_info               Dynamic Constructor info table
426          static_entry           Static Constructor entry code
427          static_info            Static Constructor info table
428          sel_info               Selector info table
429          sel_entry              Selector entry code
430          cc                     Cost centre
431          ccs                    Cost centre stack
432
433 \begin{code}
434 -- specialised for PprAsm: saves lots of arg passing in NCG
435 #if ! OMIT_NATIVE_CODEGEN
436 pprCLabel_asm = pprCLabel
437 #endif
438
439 pprCLabel :: CLabel -> SDoc
440
441 #if ! OMIT_NATIVE_CODEGEN
442 pprCLabel (AsmTempLabel u)
443   = text (fmtAsmLbl (show u))
444 #endif
445
446 pprCLabel lbl = 
447 #if ! OMIT_NATIVE_CODEGEN
448     getPprStyle $ \ sty ->
449     if asmStyle sty && underscorePrefix then
450        pp_cSEP <> pprCLbl lbl
451     else
452 #endif
453        pprCLbl lbl
454
455 pprCLbl (CaseLabel u CaseReturnPt)
456   = hcat [pprUnique u, pp_cSEP, ptext SLIT("ret")]
457 pprCLbl (CaseLabel u CaseReturnInfo)
458   = hcat [pprUnique u, pp_cSEP, ptext SLIT("info")]
459 pprCLbl (CaseLabel u CaseVecTbl)
460   = hcat [pprUnique u, pp_cSEP, ptext SLIT("vtbl")]
461 pprCLbl (CaseLabel u (CaseAlt tag))
462   = hcat [pprUnique u, pp_cSEP, int tag, pp_cSEP, ptext SLIT("alt")]
463 pprCLbl (CaseLabel u CaseDefault)
464   = hcat [pprUnique u, pp_cSEP, ptext SLIT("dflt")]
465 pprCLbl (CaseLabel u CaseBitmap)
466   = hcat [pprUnique u, pp_cSEP, ptext SLIT("btm")]
467
468 pprCLbl (RtsLabel RtsShouldNeverHappenCode) = ptext SLIT("NULL")
469 -- used to be stg_error_entry but Windows can't have DLL entry points as static
470 -- initialisers, and besides, this ShouldNeverHappen, right?
471
472 pprCLbl (RtsLabel RtsUpdInfo)            = ptext SLIT("stg_upd_frame_info")
473 pprCLbl (RtsLabel RtsSeqInfo)            = ptext SLIT("stg_seq_frame_info")
474 pprCLbl (RtsLabel RtsMainRegTable)       = ptext SLIT("MainRegTable")
475 pprCLbl (RtsLabel (RtsGCEntryLabel str)) = text str
476 pprCLbl (RtsLabel (Rts_Closure str))     = text str
477 pprCLbl (RtsLabel (Rts_Info str))        = text str
478 pprCLbl (RtsLabel (Rts_Code str))        = text str
479
480 pprCLbl (RtsLabel RtsTopTickyCtr) = ptext SLIT("top_ct")
481
482 pprCLbl (RtsLabel (RtsBlackHoleInfoTbl info)) = ptext info
483
484 pprCLbl (RtsLabel (RtsSelectorInfoTbl upd_reqd offset))
485   = hcat [ptext SLIT("stg_sel_"), text (show offset),
486                 ptext (if upd_reqd 
487                         then SLIT("_upd_info") 
488                         else SLIT("_noupd_info"))
489         ]
490
491 pprCLbl (RtsLabel (RtsSelectorEntry upd_reqd offset))
492   = hcat [ptext SLIT("stg_sel_"), text (show offset),
493                 ptext (if upd_reqd 
494                         then SLIT("_upd_entry") 
495                         else SLIT("_noupd_entry"))
496         ]
497
498 pprCLbl (RtsLabel (RtsApInfoTbl upd_reqd arity))
499   = hcat [ptext SLIT("stg_ap_"), text (show arity),
500                 ptext (if upd_reqd 
501                         then SLIT("_upd_info") 
502                         else SLIT("_noupd_info"))
503         ]
504
505 pprCLbl (RtsLabel (RtsApEntry upd_reqd arity))
506   = hcat [ptext SLIT("stg_ap_"), text (show arity),
507                 ptext (if upd_reqd 
508                         then SLIT("_upd_entry") 
509                         else SLIT("_noupd_entry"))
510         ]
511
512 pprCLbl (RtsLabel (RtsPrimOp primop)) 
513   = ppr primop <> ptext SLIT("_fast")
514
515 pprCLbl (RtsLabel RtsModuleRegd)
516   = ptext SLIT("module_registered")
517
518 pprCLbl (ForeignLabel str _)
519   = ptext str
520
521 pprCLbl (TyConLabel tc)
522   = hcat [ppr tc, pp_cSEP, ptext SLIT("closure_tbl")]
523
524 pprCLbl (IdLabel      id  flavor) = ppr id <> ppIdFlavor flavor
525 pprCLbl (DataConLabel con flavor) = ppr con <> ppConFlavor flavor
526
527 pprCLbl (CC_Label cc)           = ppr cc
528 pprCLbl (CCS_Label ccs)         = ppr ccs
529
530 pprCLbl (ModuleInitLabel mod)   
531    = ptext SLIT("__stginit_") <> ptext (moduleNameFS (moduleName mod))
532
533 ppIdFlavor :: IdLabelInfo -> SDoc
534
535 ppIdFlavor x = pp_cSEP <>
536                (case x of
537                        Closure          -> ptext SLIT("closure")
538                        SRT              -> ptext SLIT("srt")
539                        InfoTbl          -> ptext SLIT("info")
540                        EntryStd         -> ptext SLIT("entry")
541                        EntryFast arity  -> --false:ASSERT (arity > 0)
542                                            (<>) (ptext SLIT("fast")) (int arity)
543                        RednCounts       -> ptext SLIT("ct")
544                       )
545
546 ppConFlavor x = pp_cSEP <>
547                 (case x of
548                        ConEntry         -> ptext SLIT("con_entry")
549                        ConInfoTbl       -> ptext SLIT("con_info")
550                        StaticConEntry   -> ptext SLIT("static_entry")
551                        StaticInfoTbl    -> ptext SLIT("static_info")
552                 )
553 \end{code}
554