Revert "Add new mbmi and mbmi2 compiler flags"
[ghc.git] / compiler / cmm / CmmInfo.hs
1 {-# LANGUAGE CPP #-}
2 module CmmInfo (
3 mkEmptyContInfoTable,
4 cmmToRawCmm,
5 mkInfoTable,
6 srtEscape,
7
8 -- info table accessors
9 closureInfoPtr,
10 entryCode,
11 getConstrTag,
12 cmmGetClosureType,
13 infoTable,
14 infoTableConstrTag,
15 infoTableSrtBitmap,
16 infoTableClosureType,
17 infoTablePtrs,
18 infoTableNonPtrs,
19 funInfoTable,
20 funInfoArity,
21
22 -- info table sizes and offsets
23 stdInfoTableSizeW,
24 fixedInfoTableSizeW,
25 profInfoTableSizeW,
26 maxStdInfoTableSizeW,
27 maxRetInfoTableSizeW,
28 stdInfoTableSizeB,
29 conInfoTableSizeB,
30 stdSrtBitmapOffset,
31 stdClosureTypeOffset,
32 stdPtrsOffset, stdNonPtrsOffset,
33 ) where
34
35 #include "HsVersions.h"
36
37 import GhcPrelude
38
39 import Cmm
40 import CmmUtils
41 import CLabel
42 import SMRep
43 import Bitmap
44 import Stream (Stream)
45 import qualified Stream
46 import Hoopl.Collections
47
48 import Maybes
49 import DynFlags
50 import Panic
51 import UniqSupply
52 import MonadUtils
53 import Util
54 import Outputable
55
56 import Data.Bits
57 import Data.Word
58
59 -- When we split at proc points, we need an empty info table.
60 mkEmptyContInfoTable :: CLabel -> CmmInfoTable
61 mkEmptyContInfoTable info_lbl
62 = CmmInfoTable { cit_lbl = info_lbl
63 , cit_rep = mkStackRep []
64 , cit_prof = NoProfilingInfo
65 , cit_srt = NoC_SRT }
66
67 cmmToRawCmm :: DynFlags -> Stream IO CmmGroup ()
68 -> IO (Stream IO RawCmmGroup ())
69 cmmToRawCmm dflags cmms
70 = do { uniqs <- mkSplitUniqSupply 'i'
71 ; let do_one uniqs cmm = do
72 case initUs uniqs $ concatMapM (mkInfoTable dflags) cmm of
73 (b,uniqs') -> return (uniqs',b)
74 -- NB. strictness fixes a space leak. DO NOT REMOVE.
75 ; return (Stream.mapAccumL do_one uniqs cmms >> return ())
76 }
77
78 -- Make a concrete info table, represented as a list of CmmStatic
79 -- (it can't be simply a list of Word, because the SRT field is
80 -- represented by a label+offset expression).
81 --
82 -- With tablesNextToCode, the layout is
83 -- <reversed variable part>
84 -- <normal forward StgInfoTable, but without
85 -- an entry point at the front>
86 -- <code>
87 --
88 -- Without tablesNextToCode, the layout of an info table is
89 -- <entry label>
90 -- <normal forward rest of StgInfoTable>
91 -- <forward variable part>
92 --
93 -- See includes/rts/storage/InfoTables.h
94 --
95 -- For return-points these are as follows
96 --
97 -- Tables next to code:
98 --
99 -- <srt slot>
100 -- <standard info table>
101 -- ret-addr --> <entry code (if any)>
102 --
103 -- Not tables-next-to-code:
104 --
105 -- ret-addr --> <ptr to entry code>
106 -- <standard info table>
107 -- <srt slot>
108 --
109 -- * The SRT slot is only there if there is SRT info to record
110
111 mkInfoTable :: DynFlags -> CmmDecl -> UniqSM [RawCmmDecl]
112 mkInfoTable _ (CmmData sec dat)
113 = return [CmmData sec dat]
114
115 mkInfoTable dflags proc@(CmmProc infos entry_lbl live blocks)
116 --
117 -- in the non-tables-next-to-code case, procs can have at most a
118 -- single info table associated with the entry label of the proc.
119 --
120 | not (tablesNextToCode dflags)
121 = case topInfoTable proc of -- must be at most one
122 -- no info table
123 Nothing ->
124 return [CmmProc mapEmpty entry_lbl live blocks]
125
126 Just info@CmmInfoTable { cit_lbl = info_lbl } -> do
127 (top_decls, (std_info, extra_bits)) <-
128 mkInfoTableContents dflags info Nothing
129 let
130 rel_std_info = map (makeRelativeRefTo dflags info_lbl) std_info
131 rel_extra_bits = map (makeRelativeRefTo dflags info_lbl) extra_bits
132 --
133 -- Separately emit info table (with the function entry
134 -- point as first entry) and the entry code
135 --
136 return (top_decls ++
137 [CmmProc mapEmpty entry_lbl live blocks,
138 mkRODataLits info_lbl
139 (CmmLabel entry_lbl : rel_std_info ++ rel_extra_bits)])
140
141 --
142 -- With tables-next-to-code, we can have many info tables,
143 -- associated with some of the BlockIds of the proc. For each info
144 -- table we need to turn it into CmmStatics, and collect any new
145 -- CmmDecls that arise from doing so.
146 --
147 | otherwise
148 = do
149 (top_declss, raw_infos) <-
150 unzip `fmap` mapM do_one_info (mapToList (info_tbls infos))
151 return (concat top_declss ++
152 [CmmProc (mapFromList raw_infos) entry_lbl live blocks])
153
154 where
155 do_one_info (lbl,itbl) = do
156 (top_decls, (std_info, extra_bits)) <-
157 mkInfoTableContents dflags itbl Nothing
158 let
159 info_lbl = cit_lbl itbl
160 rel_std_info = map (makeRelativeRefTo dflags info_lbl) std_info
161 rel_extra_bits = map (makeRelativeRefTo dflags info_lbl) extra_bits
162 --
163 return (top_decls, (lbl, Statics info_lbl $ map CmmStaticLit $
164 reverse rel_extra_bits ++ rel_std_info))
165
166 -----------------------------------------------------
167 type InfoTableContents = ( [CmmLit] -- The standard part
168 , [CmmLit] ) -- The "extra bits"
169 -- These Lits have *not* had mkRelativeTo applied to them
170
171 mkInfoTableContents :: DynFlags
172 -> CmmInfoTable
173 -> Maybe Int -- Override default RTS type tag?
174 -> UniqSM ([RawCmmDecl], -- Auxiliary top decls
175 InfoTableContents) -- Info tbl + extra bits
176
177 mkInfoTableContents dflags
178 info@(CmmInfoTable { cit_lbl = info_lbl
179 , cit_rep = smrep
180 , cit_prof = prof
181 , cit_srt = srt })
182 mb_rts_tag
183 | RTSRep rts_tag rep <- smrep
184 = mkInfoTableContents dflags info{cit_rep = rep} (Just rts_tag)
185 -- Completely override the rts_tag that mkInfoTableContents would
186 -- otherwise compute, with the rts_tag stored in the RTSRep
187 -- (which in turn came from a handwritten .cmm file)
188
189 | StackRep frame <- smrep
190 = do { (prof_lits, prof_data) <- mkProfLits dflags prof
191 ; let (srt_label, srt_bitmap) = mkSRTLit dflags srt
192 ; (liveness_lit, liveness_data) <- mkLivenessBits dflags frame
193 ; let
194 std_info = mkStdInfoTable dflags prof_lits rts_tag srt_bitmap liveness_lit
195 rts_tag | Just tag <- mb_rts_tag = tag
196 | null liveness_data = rET_SMALL -- Fits in extra_bits
197 | otherwise = rET_BIG -- Does not; extra_bits is
198 -- a label
199 ; return (prof_data ++ liveness_data, (std_info, srt_label)) }
200
201 | HeapRep _ ptrs nonptrs closure_type <- smrep
202 = do { let layout = packIntsCLit dflags ptrs nonptrs
203 ; (prof_lits, prof_data) <- mkProfLits dflags prof
204 ; let (srt_label, srt_bitmap) = mkSRTLit dflags srt
205 ; (mb_srt_field, mb_layout, extra_bits, ct_data)
206 <- mk_pieces closure_type srt_label
207 ; let std_info = mkStdInfoTable dflags prof_lits
208 (mb_rts_tag `orElse` rtsClosureType smrep)
209 (mb_srt_field `orElse` srt_bitmap)
210 (mb_layout `orElse` layout)
211 ; return (prof_data ++ ct_data, (std_info, extra_bits)) }
212 where
213 mk_pieces :: ClosureTypeInfo -> [CmmLit]
214 -> UniqSM ( Maybe StgHalfWord -- Override the SRT field with this
215 , Maybe CmmLit -- Override the layout field with this
216 , [CmmLit] -- "Extra bits" for info table
217 , [RawCmmDecl]) -- Auxiliary data decls
218 mk_pieces (Constr con_tag con_descr) _no_srt -- A data constructor
219 = do { (descr_lit, decl) <- newStringLit con_descr
220 ; return ( Just (toStgHalfWord dflags (fromIntegral con_tag))
221 , Nothing, [descr_lit], [decl]) }
222
223 mk_pieces Thunk srt_label
224 = return (Nothing, Nothing, srt_label, [])
225
226 mk_pieces (ThunkSelector offset) _no_srt
227 = return (Just (toStgHalfWord dflags 0), Just (mkWordCLit dflags (fromIntegral offset)), [], [])
228 -- Layout known (one free var); we use the layout field for offset
229
230 mk_pieces (Fun arity (ArgSpec fun_type)) srt_label
231 = do { let extra_bits = packIntsCLit dflags fun_type arity : srt_label
232 ; return (Nothing, Nothing, extra_bits, []) }
233
234 mk_pieces (Fun arity (ArgGen arg_bits)) srt_label
235 = do { (liveness_lit, liveness_data) <- mkLivenessBits dflags arg_bits
236 ; let fun_type | null liveness_data = aRG_GEN
237 | otherwise = aRG_GEN_BIG
238 extra_bits = [ packIntsCLit dflags fun_type arity
239 , srt_lit, liveness_lit, slow_entry ]
240 ; return (Nothing, Nothing, extra_bits, liveness_data) }
241 where
242 slow_entry = CmmLabel (toSlowEntryLbl info_lbl)
243 srt_lit = case srt_label of
244 [] -> mkIntCLit dflags 0
245 (lit:_rest) -> ASSERT( null _rest ) lit
246
247 mk_pieces other _ = pprPanic "mk_pieces" (ppr other)
248
249 mkInfoTableContents _ _ _ = panic "mkInfoTableContents" -- NonInfoTable dealt with earlier
250
251 packIntsCLit :: DynFlags -> Int -> Int -> CmmLit
252 packIntsCLit dflags a b = packHalfWordsCLit dflags
253 (toStgHalfWord dflags (fromIntegral a))
254 (toStgHalfWord dflags (fromIntegral b))
255
256
257 mkSRTLit :: DynFlags
258 -> C_SRT
259 -> ([CmmLit], -- srt_label, if any
260 StgHalfWord) -- srt_bitmap
261 mkSRTLit dflags NoC_SRT = ([], toStgHalfWord dflags 0)
262 mkSRTLit dflags (C_SRT lbl off bitmap) = ([cmmLabelOffW dflags lbl off], bitmap)
263
264
265 -------------------------------------------------------------------------
266 --
267 -- Lay out the info table and handle relative offsets
268 --
269 -------------------------------------------------------------------------
270
271 -- This function takes
272 -- * the standard info table portion (StgInfoTable)
273 -- * the "extra bits" (StgFunInfoExtraRev etc.)
274 -- * the entry label
275 -- * the code
276 -- and lays them out in memory, producing a list of RawCmmDecl
277
278 -------------------------------------------------------------------------
279 --
280 -- Position independent code
281 --
282 -------------------------------------------------------------------------
283 -- In order to support position independent code, we mustn't put absolute
284 -- references into read-only space. Info tables in the tablesNextToCode
285 -- case must be in .text, which is read-only, so we doctor the CmmLits
286 -- to use relative offsets instead.
287
288 -- Note that this is done even when the -fPIC flag is not specified,
289 -- as we want to keep binary compatibility between PIC and non-PIC.
290
291 makeRelativeRefTo :: DynFlags -> CLabel -> CmmLit -> CmmLit
292
293 makeRelativeRefTo dflags info_lbl (CmmLabel lbl)
294 | tablesNextToCode dflags
295 = CmmLabelDiffOff lbl info_lbl 0
296 makeRelativeRefTo dflags info_lbl (CmmLabelOff lbl off)
297 | tablesNextToCode dflags
298 = CmmLabelDiffOff lbl info_lbl off
299 makeRelativeRefTo _ _ lit = lit
300
301
302 -------------------------------------------------------------------------
303 --
304 -- Build a liveness mask for the stack layout
305 --
306 -------------------------------------------------------------------------
307
308 -- There are four kinds of things on the stack:
309 --
310 -- - pointer variables (bound in the environment)
311 -- - non-pointer variables (bound in the environment)
312 -- - free slots (recorded in the stack free list)
313 -- - non-pointer data slots (recorded in the stack free list)
314 --
315 -- The first two are represented with a 'Just' of a 'LocalReg'.
316 -- The last two with one or more 'Nothing' constructors.
317 -- Each 'Nothing' represents one used word.
318 --
319 -- The head of the stack layout is the top of the stack and
320 -- the least-significant bit.
321
322 mkLivenessBits :: DynFlags -> Liveness -> UniqSM (CmmLit, [RawCmmDecl])
323 -- ^ Returns:
324 -- 1. The bitmap (literal value or label)
325 -- 2. Large bitmap CmmData if needed
326
327 mkLivenessBits dflags liveness
328 | n_bits > mAX_SMALL_BITMAP_SIZE dflags -- does not fit in one word
329 = do { uniq <- getUniqueM
330 ; let bitmap_lbl = mkBitmapLabel uniq
331 ; return (CmmLabel bitmap_lbl,
332 [mkRODataLits bitmap_lbl lits]) }
333
334 | otherwise -- Fits in one word
335 = return (mkStgWordCLit dflags bitmap_word, [])
336 where
337 n_bits = length liveness
338
339 bitmap :: Bitmap
340 bitmap = mkBitmap dflags liveness
341
342 small_bitmap = case bitmap of
343 [] -> toStgWord dflags 0
344 [b] -> b
345 _ -> panic "mkLiveness"
346 bitmap_word = toStgWord dflags (fromIntegral n_bits)
347 .|. (small_bitmap `shiftL` bITMAP_BITS_SHIFT dflags)
348
349 lits = mkWordCLit dflags (fromIntegral n_bits)
350 : map (mkStgWordCLit dflags) bitmap
351 -- The first word is the size. The structure must match
352 -- StgLargeBitmap in includes/rts/storage/InfoTable.h
353
354 -------------------------------------------------------------------------
355 --
356 -- Generating a standard info table
357 --
358 -------------------------------------------------------------------------
359
360 -- The standard bits of an info table. This part of the info table
361 -- corresponds to the StgInfoTable type defined in
362 -- includes/rts/storage/InfoTables.h.
363 --
364 -- Its shape varies with ticky/profiling/tables next to code etc
365 -- so we can't use constant offsets from Constants
366
367 mkStdInfoTable
368 :: DynFlags
369 -> (CmmLit,CmmLit) -- Closure type descr and closure descr (profiling)
370 -> Int -- Closure RTS tag
371 -> StgHalfWord -- SRT length
372 -> CmmLit -- layout field
373 -> [CmmLit]
374
375 mkStdInfoTable dflags (type_descr, closure_descr) cl_type srt_len layout_lit
376 = -- Parallel revertible-black hole field
377 prof_info
378 -- Ticky info (none at present)
379 -- Debug info (none at present)
380 ++ [layout_lit, type_lit]
381
382 where
383 prof_info
384 | gopt Opt_SccProfilingOn dflags = [type_descr, closure_descr]
385 | otherwise = []
386
387 type_lit = packHalfWordsCLit dflags (toStgHalfWord dflags (fromIntegral cl_type)) srt_len
388
389 -------------------------------------------------------------------------
390 --
391 -- Making string literals
392 --
393 -------------------------------------------------------------------------
394
395 mkProfLits :: DynFlags -> ProfilingInfo -> UniqSM ((CmmLit,CmmLit), [RawCmmDecl])
396 mkProfLits dflags NoProfilingInfo = return ((zeroCLit dflags, zeroCLit dflags), [])
397 mkProfLits _ (ProfilingInfo td cd)
398 = do { (td_lit, td_decl) <- newStringLit td
399 ; (cd_lit, cd_decl) <- newStringLit cd
400 ; return ((td_lit,cd_lit), [td_decl,cd_decl]) }
401
402 newStringLit :: [Word8] -> UniqSM (CmmLit, GenCmmDecl CmmStatics info stmt)
403 newStringLit bytes
404 = do { uniq <- getUniqueM
405 ; return (mkByteStringCLit (mkStringLitLabel uniq) bytes) }
406
407
408 -- Misc utils
409
410 -- | Value of the srt field of an info table when using an StgLargeSRT
411 srtEscape :: DynFlags -> StgHalfWord
412 srtEscape dflags = toStgHalfWord dflags (-1)
413
414 -------------------------------------------------------------------------
415 --
416 -- Accessing fields of an info table
417 --
418 -------------------------------------------------------------------------
419
420 -- | Wrap a 'CmmExpr' in an alignment check when @-falignment-sanitisation@ is
421 -- enabled.
422 wordAligned :: DynFlags -> CmmExpr -> CmmExpr
423 wordAligned dflags e
424 | gopt Opt_AlignmentSanitisation dflags
425 = CmmMachOp (MO_AlignmentCheck (wORD_SIZE dflags) (wordWidth dflags)) [e]
426 | otherwise
427 = e
428
429 closureInfoPtr :: DynFlags -> CmmExpr -> CmmExpr
430 -- Takes a closure pointer and returns the info table pointer
431 closureInfoPtr dflags e =
432 CmmLoad (wordAligned dflags e) (bWord dflags)
433
434 entryCode :: DynFlags -> CmmExpr -> CmmExpr
435 -- Takes an info pointer (the first word of a closure)
436 -- and returns its entry code
437 entryCode dflags e
438 | tablesNextToCode dflags = e
439 | otherwise = CmmLoad e (bWord dflags)
440
441 getConstrTag :: DynFlags -> CmmExpr -> CmmExpr
442 -- Takes a closure pointer, and return the *zero-indexed*
443 -- constructor tag obtained from the info table
444 -- This lives in the SRT field of the info table
445 -- (constructors don't need SRTs).
446 getConstrTag dflags closure_ptr
447 = CmmMachOp (MO_UU_Conv (halfWordWidth dflags) (wordWidth dflags)) [infoTableConstrTag dflags info_table]
448 where
449 info_table = infoTable dflags (closureInfoPtr dflags closure_ptr)
450
451 cmmGetClosureType :: DynFlags -> CmmExpr -> CmmExpr
452 -- Takes a closure pointer, and return the closure type
453 -- obtained from the info table
454 cmmGetClosureType dflags closure_ptr
455 = CmmMachOp (MO_UU_Conv (halfWordWidth dflags) (wordWidth dflags)) [infoTableClosureType dflags info_table]
456 where
457 info_table = infoTable dflags (closureInfoPtr dflags closure_ptr)
458
459 infoTable :: DynFlags -> CmmExpr -> CmmExpr
460 -- Takes an info pointer (the first word of a closure)
461 -- and returns a pointer to the first word of the standard-form
462 -- info table, excluding the entry-code word (if present)
463 infoTable dflags info_ptr
464 | tablesNextToCode dflags = cmmOffsetB dflags info_ptr (- stdInfoTableSizeB dflags)
465 | otherwise = cmmOffsetW dflags info_ptr 1 -- Past the entry code pointer
466
467 infoTableConstrTag :: DynFlags -> CmmExpr -> CmmExpr
468 -- Takes an info table pointer (from infoTable) and returns the constr tag
469 -- field of the info table (same as the srt_bitmap field)
470 infoTableConstrTag = infoTableSrtBitmap
471
472 infoTableSrtBitmap :: DynFlags -> CmmExpr -> CmmExpr
473 -- Takes an info table pointer (from infoTable) and returns the srt_bitmap
474 -- field of the info table
475 infoTableSrtBitmap dflags info_tbl
476 = CmmLoad (cmmOffsetB dflags info_tbl (stdSrtBitmapOffset dflags)) (bHalfWord dflags)
477
478 infoTableClosureType :: DynFlags -> CmmExpr -> CmmExpr
479 -- Takes an info table pointer (from infoTable) and returns the closure type
480 -- field of the info table.
481 infoTableClosureType dflags info_tbl
482 = CmmLoad (cmmOffsetB dflags info_tbl (stdClosureTypeOffset dflags)) (bHalfWord dflags)
483
484 infoTablePtrs :: DynFlags -> CmmExpr -> CmmExpr
485 infoTablePtrs dflags info_tbl
486 = CmmLoad (cmmOffsetB dflags info_tbl (stdPtrsOffset dflags)) (bHalfWord dflags)
487
488 infoTableNonPtrs :: DynFlags -> CmmExpr -> CmmExpr
489 infoTableNonPtrs dflags info_tbl
490 = CmmLoad (cmmOffsetB dflags info_tbl (stdNonPtrsOffset dflags)) (bHalfWord dflags)
491
492 funInfoTable :: DynFlags -> CmmExpr -> CmmExpr
493 -- Takes the info pointer of a function,
494 -- and returns a pointer to the first word of the StgFunInfoExtra struct
495 -- in the info table.
496 funInfoTable dflags info_ptr
497 | tablesNextToCode dflags
498 = cmmOffsetB dflags info_ptr (- stdInfoTableSizeB dflags - sIZEOF_StgFunInfoExtraRev dflags)
499 | otherwise
500 = cmmOffsetW dflags info_ptr (1 + stdInfoTableSizeW dflags)
501 -- Past the entry code pointer
502
503 -- Takes the info pointer of a function, returns the function's arity
504 funInfoArity :: DynFlags -> CmmExpr -> CmmExpr
505 funInfoArity dflags iptr
506 = cmmToWord dflags (cmmLoadIndex dflags rep fun_info (offset `div` rep_bytes))
507 where
508 fun_info = funInfoTable dflags iptr
509 rep = cmmBits (widthFromBytes rep_bytes)
510
511 (rep_bytes, offset)
512 | tablesNextToCode dflags = ( pc_REP_StgFunInfoExtraRev_arity pc
513 , oFFSET_StgFunInfoExtraRev_arity dflags )
514 | otherwise = ( pc_REP_StgFunInfoExtraFwd_arity pc
515 , oFFSET_StgFunInfoExtraFwd_arity dflags )
516
517 pc = sPlatformConstants (settings dflags)
518
519 -----------------------------------------------------------------------------
520 --
521 -- Info table sizes & offsets
522 --
523 -----------------------------------------------------------------------------
524
525 stdInfoTableSizeW :: DynFlags -> WordOff
526 -- The size of a standard info table varies with profiling/ticky etc,
527 -- so we can't get it from Constants
528 -- It must vary in sync with mkStdInfoTable
529 stdInfoTableSizeW dflags
530 = fixedInfoTableSizeW
531 + if gopt Opt_SccProfilingOn dflags
532 then profInfoTableSizeW
533 else 0
534
535 fixedInfoTableSizeW :: WordOff
536 fixedInfoTableSizeW = 2 -- layout, type
537
538 profInfoTableSizeW :: WordOff
539 profInfoTableSizeW = 2
540
541 maxStdInfoTableSizeW :: WordOff
542 maxStdInfoTableSizeW =
543 1 {- entry, when !tablesNextToCode -}
544 + fixedInfoTableSizeW
545 + profInfoTableSizeW
546
547 maxRetInfoTableSizeW :: WordOff
548 maxRetInfoTableSizeW =
549 maxStdInfoTableSizeW
550 + 1 {- srt label -}
551
552 stdInfoTableSizeB :: DynFlags -> ByteOff
553 stdInfoTableSizeB dflags = stdInfoTableSizeW dflags * wORD_SIZE dflags
554
555 stdSrtBitmapOffset :: DynFlags -> ByteOff
556 -- Byte offset of the SRT bitmap half-word which is
557 -- in the *higher-addressed* part of the type_lit
558 stdSrtBitmapOffset dflags = stdInfoTableSizeB dflags - hALF_WORD_SIZE dflags
559
560 stdClosureTypeOffset :: DynFlags -> ByteOff
561 -- Byte offset of the closure type half-word
562 stdClosureTypeOffset dflags = stdInfoTableSizeB dflags - wORD_SIZE dflags
563
564 stdPtrsOffset, stdNonPtrsOffset :: DynFlags -> ByteOff
565 stdPtrsOffset dflags = stdInfoTableSizeB dflags - 2 * wORD_SIZE dflags
566 stdNonPtrsOffset dflags = stdInfoTableSizeB dflags - 2 * wORD_SIZE dflags + hALF_WORD_SIZE dflags
567
568 conInfoTableSizeB :: DynFlags -> Int
569 conInfoTableSizeB dflags = stdInfoTableSizeB dflags + wORD_SIZE dflags