CLabel.lhs 16.9 KB
Newer Older
1
%
2
3
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
4
% $Id: CLabel.lhs,v 1.55 2002/09/13 15:02:26 simonpj Exp $
5
%
6
\section[CLabel]{@CLabel@: Information to make C Labels}
7
8

\begin{code}
9
module CLabel (
10
11
12
	CLabel,	-- abstract type

	mkClosureLabel,
13
	mkSRTLabel,
14
15
16
17
18
19
	mkInfoTableLabel,
	mkStdEntryLabel,
	mkFastEntryLabel,
	mkConEntryLabel,
	mkStaticConEntryLabel,
	mkRednCountsLabel,
20
	mkConInfoTableLabel,
21
	mkStaticInfoTableLabel,
22
23
	mkApEntryLabel,
	mkApInfoTableLabel,
24
25

	mkReturnPtLabel,
26
	mkReturnInfoLabel,
27
28
29
	mkVecTblLabel,
	mkAltLabel,
	mkDefaultLabel,
30
31
32
	mkBitmapLabel,

	mkClosureTblLabel,
33
34
35

	mkAsmTempLabel,

36
	mkModuleInitLabel,
37
	mkPlainModuleInitLabel,
38

39
	mkErrorStdEntryLabel,
40
41

	mkStgUpdatePAPLabel,
42
	mkSplitMarkerLabel,
43
	mkUpdInfoLabel,
44
45
46
47
	mkSeqInfoLabel,
	mkIndInfoLabel,
	mkIndStaticInfoLabel,
	mkRtsGCEntryLabel,
48
        mkMainCapabilityLabel,
49
50
51
	mkCharlikeClosureLabel,
	mkIntlikeClosureLabel,
	mkMAP_FROZEN_infoLabel,
52
        mkEMPTY_MVAR_infoLabel,
53

54
	mkTopTickyCtrLabel,
55
	mkBlackHoleInfoTableLabel,
56
57
        mkCAFBlackHoleInfoTableLabel,
        mkSECAFBlackHoleInfoTableLabel,
58
59
	mkRtsPrimOpLabel,

60
61
	moduleRegdLabel,

62
63
	mkSelectorInfoLabel,
	mkSelectorEntryLabel,
64

65
66
	mkForeignLabel,

67
68
	mkCC_Label, mkCCS_Label,
	
69
	needsCDecl, isAsmTemp, externallyVisibleCLabel,
70

sof's avatar
sof committed
71
	CLabelType(..), labelType, labelDynamic,
72

73
	pprCLabel
74
75
    ) where

sof's avatar
sof committed
76

77
#include "HsVersions.h"
sof's avatar
sof committed
78

79
#if ! OMIT_NATIVE_CODEGEN
sof's avatar
sof committed
80
import {-# SOURCE #-} MachMisc ( underscorePrefix, fmtAsmLbl )
81
#endif
82

83
import CmdLineOpts      ( opt_Static, opt_DoTickyProfiling )
84
import CStrings		( pp_cSEP )
85
86
import DataCon		( ConTag )
import Module		( moduleName, moduleNameFS, 
87
			  Module, isHomeModule )
88
import Name		( Name, getName, isDllName, isExternalName )
89
import TyCon		( TyCon )
90
import Unique		( pprUnique, Unique )
91
import PrimOp		( PrimOp )
92
import CostCentre	( CostCentre, CostCentreStack )
93
import Outputable
94
import FastString
95
96
97
98
99
100
101
102
103
104
\end{code}

things we want to find out:

* should the labelled things be declared "static" (visible only in this file)?

* should it be declared "const" (read-only text space)?

* does it need declarations at all? (v common Prelude things are pre-declared)

105
106
107
* what type does it have? (for generating accurate enough C declarations
  so that the C compiler won't complain).

108
109
\begin{code}
data CLabel
110
  = IdLabel	    		-- A family of labels related to the
111
112
	Name			-- definition of a particular Id
	IdLabelInfo
113

114
115
116
  | DataConLabel		-- Ditto data constructors
	Name
	DataConLabelInfo
117
118
119
120
121

  | CaseLabel			-- A family of labels related to a particular case expression
	Unique			-- Unique says which case expression
	CaseLabelInfo

122
123
124
  | TyConLabel TyCon		-- currently only one kind of TyconLabel,
				-- a 'Closure Table'.

125
126
  | AsmTempLabel    Unique

127
128
129
  | ModuleInitLabel 
	Module			-- the module name
	String			-- its "way"
130
131
132
133
134
	-- at some point we might want some kind of version number in
	-- the module init label, to guard against compiling modules in
	-- the wrong order.  We can't use the interface file version however,
	-- because we don't always recompile modules which depend on a module
	-- whose version has changed.
135
136

  | PlainModuleInitLabel Module	 -- without the vesrion & way info
137

138
139
  | RtsLabel	    RtsLabelInfo

140
  | ForeignLabel FastString Bool  -- a 'C' (or otherwise foreign) label
141
142
				   -- Bool <=> is dynamic

143
144
  | CC_Label CostCentre
  | CCS_Label CostCentreStack
145

146
  deriving (Eq, Ord)
147
148
149
150
151
\end{code}

\begin{code}
data IdLabelInfo
  = Closure		-- Label for (static???) closure
152
153

  | SRT                 -- Static reference table
154
155
156

  | InfoTbl		-- Info table for a closure; always read-only

157
158
  | EntryStd		-- Thunk, or "slow", code entry point

159
160
161
162
  | EntryFast Int	-- entry pt when no arg satisfaction chk needed;
			-- Int is the arity of the function (to be
			-- encoded into the name)

163
164
165
166
167
168
169
			-- Ticky-ticky counting
  | RednCounts		-- Label of place to keep reduction-count info for 
			-- this Id
  deriving (Eq, Ord)

data DataConLabelInfo
  = ConEntry		-- the only kind of entry pt for constructors
170
171
  | ConInfoTbl		-- corresponding info table
  | StaticConEntry  	-- static constructor entry point
172
173
174
  | StaticInfoTbl   	-- corresponding info table
  deriving (Eq, Ord)

175
data CaseLabelInfo
176
  = CaseReturnPt
177
  | CaseReturnInfo
178
179
180
  | CaseVecTbl
  | CaseAlt ConTag
  | CaseDefault
181
  | CaseBitmap
182
183
184
185
186
  deriving (Eq, Ord)

data RtsLabelInfo
  = RtsShouldNeverHappenCode

187
  | RtsBlackHoleInfoTbl FastString  -- black hole with info table name
188

189
190
191
  | RtsUpdInfo            	-- upd_frame_info
  | RtsSeqInfo			-- seq_frame_info
  | RtsGCEntryLabel String 	-- a heap check fail handler, eg  stg_chk_2
192
  | RtsMainCapability           -- MainCapability
193
194
  | Rts_Closure String		-- misc rts closures, eg CHARLIKE_closure
  | Rts_Info String		-- misc rts itbls, eg MUT_ARR_PTRS_FROZEN_info
195
  | Rts_Code String		-- misc rts code
196
197
198
199
200
201
202
203

  | RtsSelectorInfoTbl Bool{-updatable-} Int{-offset-}	-- Selector thunks
  | RtsSelectorEntry   Bool{-updatable-} Int{-offset-}

  | RtsApInfoTbl Bool{-updatable-} Int{-arity-}	        -- AP thunks
  | RtsApEntry   Bool{-updatable-} Int{-arity-}

  | RtsPrimOp PrimOp
204

205
206
  | RtsTopTickyCtr

207
208
  | RtsModuleRegd

209
  deriving (Eq, Ord)
210
211
212
213
214
215
216

-- Label Type: for generating C declarations.

data CLabelType
  = InfoTblType
  | ClosureType
  | VecTblType
217
  | ClosureTblType
218
219
  | CodeType
  | DataType
220
221
222
\end{code}

\begin{code}
223
224
225
226
mkClosureLabel	      	id 		= IdLabel id  Closure
mkSRTLabel		id		= IdLabel id  SRT
mkInfoTableLabel      	id 		= IdLabel id  InfoTbl
mkStdEntryLabel	      	id 		= IdLabel id  EntryStd
227
mkFastEntryLabel      	id arity	= ASSERT(arity > 0)
228
229
230
231
232
233
234
235
236
					  IdLabel id  (EntryFast arity)

mkRednCountsLabel     	id		= IdLabel id  RednCounts

mkStaticInfoTableLabel  con		= DataConLabel con StaticInfoTbl
mkConInfoTableLabel     con		= DataConLabel con ConInfoTbl
mkConEntryLabel	      	con		= DataConLabel con ConEntry
mkStaticConEntryLabel 	con		= DataConLabel con StaticConEntry

237
238

mkReturnPtLabel uniq		= CaseLabel uniq CaseReturnPt
239
mkReturnInfoLabel uniq		= CaseLabel uniq CaseReturnInfo
240
241
242
mkVecTblLabel   uniq		= CaseLabel uniq CaseVecTbl
mkAltLabel      uniq tag	= CaseLabel uniq (CaseAlt tag)
mkDefaultLabel  uniq 		= CaseLabel uniq CaseDefault
243
244
245
mkBitmapLabel   uniq		= CaseLabel uniq CaseBitmap

mkClosureTblLabel tycon		= TyConLabel tycon
246
247
248

mkAsmTempLabel 			= AsmTempLabel

249
mkModuleInitLabel		= ModuleInitLabel
250
mkPlainModuleInitLabel		= PlainModuleInitLabel
251

252
253
	-- Some fixed runtime system labels

rrt's avatar
rrt committed
254
mkErrorStdEntryLabel 		= RtsLabel RtsShouldNeverHappenCode
255
mkStgUpdatePAPLabel		= RtsLabel (Rts_Code "stg_update_PAP")
256
mkSplitMarkerLabel		= RtsLabel (Rts_Code "__stg_split_marker")
257
mkUpdInfoLabel			= RtsLabel RtsUpdInfo
258
mkSeqInfoLabel			= RtsLabel RtsSeqInfo
259
260
mkIndInfoLabel			= RtsLabel (Rts_Info "stg_IND_info")
mkIndStaticInfoLabel		= RtsLabel (Rts_Info "stg_IND_STATIC_info")
261
mkRtsGCEntryLabel str		= RtsLabel (RtsGCEntryLabel str)
262
mkMainCapabilityLabel		= RtsLabel RtsMainCapability
263
264
265
mkCharlikeClosureLabel		= RtsLabel (Rts_Closure "stg_CHARLIKE_closure")
mkIntlikeClosureLabel		= RtsLabel (Rts_Closure "stg_INTLIKE_closure")
mkMAP_FROZEN_infoLabel		= RtsLabel (Rts_Info "stg_MUT_ARR_PTRS_FROZEN_info")
266
mkEMPTY_MVAR_infoLabel		= RtsLabel (Rts_Info "stg_EMPTY_MVAR_info")
267

268
mkTopTickyCtrLabel		= RtsLabel RtsTopTickyCtr
269
270
mkBlackHoleInfoTableLabel	= RtsLabel (RtsBlackHoleInfoTbl FSLIT("stg_BLACKHOLE_info"))
mkCAFBlackHoleInfoTableLabel	= RtsLabel (RtsBlackHoleInfoTbl FSLIT("stg_CAF_BLACKHOLE_info"))
271
mkSECAFBlackHoleInfoTableLabel	= if opt_DoTickyProfiling then
272
                                    RtsLabel (RtsBlackHoleInfoTbl FSLIT("stg_SE_CAF_BLACKHOLE_info"))
273
274
                                  else  -- RTS won't have info table unless -ticky is on
                                    panic "mkSECAFBlackHoleInfoTableLabel requires -ticky"
275
276
mkRtsPrimOpLabel primop		= RtsLabel (RtsPrimOp primop)

277
278
moduleRegdLabel			= RtsLabel RtsModuleRegd

279
280
281
282
283
284
mkSelectorInfoLabel  upd off	= RtsLabel (RtsSelectorInfoTbl upd off)
mkSelectorEntryLabel upd off	= RtsLabel (RtsSelectorEntry   upd off)

mkApInfoTableLabel  upd off	= RtsLabel (RtsApInfoTbl upd off)
mkApEntryLabel upd off		= RtsLabel (RtsApEntry   upd off)

285
286
	-- Foreign labels

287
mkForeignLabel :: FastString -> Bool -> CLabel
288
289
mkForeignLabel str is_dynamic	= ForeignLabel str is_dynamic

290
291
292
293
	-- Cost centres etc.

mkCC_Label	cc		= CC_Label cc
mkCCS_Label	ccs		= CCS_Label ccs
294
295
296
297
298
299
300
301
302
303
\end{code}

\begin{code}
needsCDecl :: CLabel -> Bool	-- False <=> it's pre-declared; don't bother
isAsmTemp  :: CLabel -> Bool    -- is a local temporary for native code generation
externallyVisibleCLabel :: CLabel -> Bool -- not C "static"
\end{code}

@needsCDecl@ is @True@ unless the thing is a deeply-@PreludeCore@-ish
object.  {\em Also:} No need to spit out labels for things generated
304
by the flattener (in @AbsCUtils@)---it is careful to ensure references
305
306
307
308
309
310
to them are always backwards.  These are return-point and vector-table
labels.

Declarations for (non-prelude) @Id@-based things are needed because of
mutual recursion.

311
312
Declarations for direct return points are needed, because they may be
let-no-escapes, which can be recursive.
313

314
315
316
317
\begin{code}
needsCDecl (IdLabel _ _)		= True
needsCDecl (CaseLabel _ CaseReturnPt)	= True
needsCDecl (DataConLabel _ _)		= True
318
needsCDecl (TyConLabel _)		= True
319
needsCDecl (ModuleInitLabel _ _)	= True
320
needsCDecl (PlainModuleInitLabel _)	= True
321

rrt's avatar
rrt committed
322
needsCDecl (CaseLabel _ _)		= False
323
324
needsCDecl (AsmTempLabel _)		= False
needsCDecl (RtsLabel _)			= False
325
needsCDecl (ForeignLabel _ _)		= False
326
327
needsCDecl (CC_Label _)			= False
needsCDecl (CCS_Label _)		= False
328
329
330
\end{code}

Whether the label is an assembler temporary:
331

332
333
334
335
336
337
\begin{code}
isAsmTemp (AsmTempLabel _) = True
isAsmTemp _ 	    	   = False
\end{code}

C ``static'' or not...
338
From the point of view of the code generator, a name is
339
340
341
342
343
344
345
346
externally visible if it has to be declared as exported
in the .o file's symbol table; that is, made non-static.

\begin{code}
externallyVisibleCLabel (DataConLabel _ _) = True
externallyVisibleCLabel (TyConLabel tc)    = True
externallyVisibleCLabel (CaseLabel _ _)	   = False
externallyVisibleCLabel (AsmTempLabel _)   = False
347
externallyVisibleCLabel (ModuleInitLabel _ _)= True
348
externallyVisibleCLabel (PlainModuleInitLabel _)= True
349
externallyVisibleCLabel (RtsLabel RtsModuleRegd) = False --hack
350
externallyVisibleCLabel (RtsLabel _)	   = True
351
externallyVisibleCLabel (ForeignLabel _ _) = True
352
externallyVisibleCLabel (IdLabel id _)     = isExternalName id
353
354
355
356
357
externallyVisibleCLabel (CC_Label _)	   = False -- not strictly true
externallyVisibleCLabel (CCS_Label _)	   = False -- not strictly true
\end{code}

For generating correct types in label declarations...
358

359
\begin{code}
360
labelType :: CLabel -> CLabelType
361
labelType (RtsLabel (RtsBlackHoleInfoTbl _))  = InfoTblType
362
363
labelType (RtsLabel (RtsSelectorInfoTbl _ _)) = InfoTblType
labelType (RtsLabel (RtsApInfoTbl _ _))       = InfoTblType
364
labelType (RtsLabel RtsUpdInfo)       	      = InfoTblType
365
labelType (RtsLabel (Rts_Info _))             = InfoTblType
366
367
368
labelType (CaseLabel _ CaseReturnInfo)        = InfoTblType
labelType (CaseLabel _ CaseReturnPt)	      = CodeType
labelType (CaseLabel _ CaseVecTbl)            = VecTblType
369
labelType (TyConLabel _)		      = ClosureTblType
370
labelType (ModuleInitLabel _ _)               = CodeType
371
labelType (PlainModuleInitLabel _)            = CodeType
372
373
374
375
376
377
378
379
380
381
382
383
384
385

labelType (IdLabel _ info) = 
  case info of
    InfoTbl       -> InfoTblType
    Closure	  -> ClosureType
    _		  -> CodeType

labelType (DataConLabel _ info) = 
  case info of
     ConInfoTbl    -> InfoTblType
     StaticInfoTbl -> InfoTblType
     _		   -> CodeType

labelType _        = DataType
386
387
\end{code}

sof's avatar
sof committed
388
389
390
391
392
393
394
395
396
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.

\begin{code}
labelDynamic :: CLabel -> Bool
labelDynamic lbl = 
  case lbl of
rrt's avatar
rrt committed
397
398
399
400
401
402
403
404
   -- The special case for RtsShouldNeverHappenCode is because the associated address is
   -- NULL, i.e. not a DLL entry point
   RtsLabel RtsShouldNeverHappenCode -> False
   RtsLabel _  	     -> not opt_Static  -- i.e., is the RTS in a DLL or not?
   IdLabel n k       -> isDllName n
   DataConLabel n k  -> isDllName n
   TyConLabel tc     -> isDllName (getName tc)
   ForeignLabel _ d  -> d
405
   ModuleInitLabel m _  -> (not opt_Static) && (not (isHomeModule m))
406
   PlainModuleInitLabel m -> (not opt_Static) && (not (isHomeModule m))
rrt's avatar
rrt committed
407
   _ 		     -> False
sof's avatar
sof committed
408
409
410
\end{code}


411
OLD?: These GRAN functions are needed for spitting out GRAN_FETCH() at the
412
413
414
415
416
417
418
right places. It is used to detect when the abstractC statement of an
CCodeBlock actually contains the code for a slow entry point.  -- HWL

We need at least @Eq@ for @CLabels@, because we want to avoid
duplicate declarations in generating C (see @labelSeenTE@ in
@PprAbsC@).

419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
-----------------------------------------------------------------------------
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:

	 info			Info table
	 srt			Static reference table
	 entry			Entry code
	 ret			Direct return address	 
	 vtbl			Vector table
	 <n>_alt		Case alternative (tag n)
	 dflt			Default case alternative
	 btm			Large bitmap vector
	 closure		Static closure
	 con_entry		Dynamic Constructor entry code
	 con_info		Dynamic Constructor info table
	 static_entry		Static Constructor entry code
	 static_info		Static Constructor info table
	 sel_info		Selector info table
	 sel_entry		Selector entry code
444
445
	 cc			Cost centre
	 ccs			Cost centre stack
446

447
\begin{code}
448
pprCLabel :: CLabel -> SDoc
449

450
#if ! OMIT_NATIVE_CODEGEN
451
pprCLabel (AsmTempLabel u)
452
  = text (fmtAsmLbl (show u))
453
#endif
454

455
456
457
pprCLabel lbl = 
#if ! OMIT_NATIVE_CODEGEN
    getPprStyle $ \ sty ->
458
459
460
    if asmStyle sty && underscorePrefix then
       pp_cSEP <> pprCLbl lbl
    else
461
#endif
462
463
464
       pprCLbl lbl

pprCLbl (CaseLabel u CaseReturnPt)
465
466
467
  = hcat [pprUnique u, pp_cSEP, ptext SLIT("ret")]
pprCLbl (CaseLabel u CaseReturnInfo)
  = hcat [pprUnique u, pp_cSEP, ptext SLIT("info")]
468
pprCLbl (CaseLabel u CaseVecTbl)
469
  = hcat [pprUnique u, pp_cSEP, ptext SLIT("vtbl")]
470
pprCLbl (CaseLabel u (CaseAlt tag))
471
  = hcat [pprUnique u, pp_cSEP, int tag, pp_cSEP, ptext SLIT("alt")]
472
pprCLbl (CaseLabel u CaseDefault)
473
474
475
476
  = hcat [pprUnique u, pp_cSEP, ptext SLIT("dflt")]
pprCLbl (CaseLabel u CaseBitmap)
  = hcat [pprUnique u, pp_cSEP, ptext SLIT("btm")]

rrt's avatar
rrt committed
477
478
479
pprCLbl (RtsLabel RtsShouldNeverHappenCode) = ptext SLIT("NULL")
-- used to be stg_error_entry but Windows can't have DLL entry points as static
-- initialisers, and besides, this ShouldNeverHappen, right?
480

481
482
pprCLbl (RtsLabel RtsUpdInfo)            = ptext SLIT("stg_upd_frame_info")
pprCLbl (RtsLabel RtsSeqInfo)            = ptext SLIT("stg_seq_frame_info")
483
pprCLbl (RtsLabel RtsMainCapability)     = ptext SLIT("MainCapability")
484
485
486
487
pprCLbl (RtsLabel (RtsGCEntryLabel str)) = text str
pprCLbl (RtsLabel (Rts_Closure str))     = text str
pprCLbl (RtsLabel (Rts_Info str))        = text str
pprCLbl (RtsLabel (Rts_Code str))        = text str
488

489
490
pprCLbl (RtsLabel RtsTopTickyCtr) = ptext SLIT("top_ct")

491
pprCLbl (RtsLabel (RtsBlackHoleInfoTbl info)) = ftext info
492

493
pprCLbl (RtsLabel (RtsSelectorInfoTbl upd_reqd offset))
494
  = hcat [ptext SLIT("stg_sel_"), text (show offset),
495
496
497
498
		ptext (if upd_reqd 
			then SLIT("_upd_info") 
			else SLIT("_noupd_info"))
	]
499

500
pprCLbl (RtsLabel (RtsSelectorEntry upd_reqd offset))
501
  = hcat [ptext SLIT("stg_sel_"), text (show offset),
502
503
504
505
506
507
		ptext (if upd_reqd 
			then SLIT("_upd_entry") 
			else SLIT("_noupd_entry"))
	]

pprCLbl (RtsLabel (RtsApInfoTbl upd_reqd arity))
508
  = hcat [ptext SLIT("stg_ap_"), text (show arity),
509
510
511
512
513
514
		ptext (if upd_reqd 
			then SLIT("_upd_info") 
			else SLIT("_noupd_info"))
	]

pprCLbl (RtsLabel (RtsApEntry upd_reqd arity))
515
  = hcat [ptext SLIT("stg_ap_"), text (show arity),
516
517
518
519
520
521
		ptext (if upd_reqd 
			then SLIT("_upd_entry") 
			else SLIT("_noupd_entry"))
	]

pprCLbl (RtsLabel (RtsPrimOp primop)) 
522
  = ppr primop <> ptext SLIT("_fast")
523

524
525
526
pprCLbl (RtsLabel RtsModuleRegd)
  = ptext SLIT("module_registered")

527
pprCLbl (ForeignLabel str _)
528
  = ftext str
529

530
531
532
533
534
535
536
537
538
pprCLbl (TyConLabel tc)
  = hcat [ppr tc, pp_cSEP, ptext SLIT("closure_tbl")]

pprCLbl (IdLabel      id  flavor) = ppr id <> ppIdFlavor flavor
pprCLbl (DataConLabel con flavor) = ppr con <> ppConFlavor flavor

pprCLbl (CC_Label cc) 		= ppr cc
pprCLbl (CCS_Label ccs) 	= ppr ccs

539
pprCLbl (ModuleInitLabel mod way)	
540
   = ptext SLIT("__stginit_") <> ftext (moduleNameFS (moduleName mod))
541
	<> char '_' <> text way
542
543

pprCLbl (PlainModuleInitLabel mod)	
544
   = ptext SLIT("__stginit_") <> ftext (moduleNameFS (moduleName mod))
545

546
547
548
549
ppIdFlavor :: IdLabelInfo -> SDoc

ppIdFlavor x = pp_cSEP <>
	       (case x of
sof's avatar
sof committed
550
		       Closure	    	-> ptext SLIT("closure")
551
		       SRT		-> ptext SLIT("srt")
sof's avatar
sof committed
552
553
		       InfoTbl	    	-> ptext SLIT("info")
		       EntryStd	    	-> ptext SLIT("entry")
554
		       EntryFast arity	-> --false:ASSERT (arity > 0)
sof's avatar
sof committed
555
					   (<>) (ptext SLIT("fast")) (int arity)
556
557
558
559
560
		       RednCounts	-> ptext SLIT("ct")
		      )

ppConFlavor x = pp_cSEP <>
	     	(case x of
sof's avatar
sof committed
561
562
563
564
		       ConEntry	    	-> ptext SLIT("con_entry")
		       ConInfoTbl    	-> ptext SLIT("con_info")
		       StaticConEntry  	-> ptext SLIT("static_entry")
		       StaticInfoTbl 	-> ptext SLIT("static_info")
565
		)
566
\end{code}
567