Module header tidyup, phase 1
[ghc-hetmet.git] / compiler / codeGen / CgInfoTbls.hs
1 -----------------------------------------------------------------------------
2 --
3 -- Building info tables.
4 --
5 -- (c) The University of Glasgow 2004-2006
6 --
7 -----------------------------------------------------------------------------
8
9 module CgInfoTbls (
10         emitClosureCodeAndInfoTable,
11         emitInfoTableAndCode,
12         dataConTagZ,
13         getSRTInfo,
14         emitDirectReturnTarget, emitAlgReturnTarget,
15         emitDirectReturnInstr, emitVectoredReturnInstr,
16         mkRetInfoTable,
17         mkStdInfoTable,
18         stdInfoTableSizeB,
19         mkFunGenInfoExtraBits,
20         entryCode, closureInfoPtr,
21         getConstrTag,
22         infoTable, infoTableClosureType,
23         infoTablePtrs, infoTableNonPtrs,
24         funInfoTable,
25         retVec
26   ) where
27
28
29 #include "HsVersions.h"
30
31 import ClosureInfo
32 import SMRep
33 import CgBindery
34 import CgCallConv
35 import CgUtils
36 import CgMonad
37
38 import CmmUtils
39 import Cmm
40 import MachOp
41 import CLabel
42 import StgSyn
43 import Name
44 import DataCon
45 import Unique
46 import DynFlags
47 import StaticFlags
48
49 import ListSetOps
50 import Maybes
51 import Constants
52
53 -------------------------------------------------------------------------
54 --
55 --      Generating the info table and code for a closure
56 --
57 -------------------------------------------------------------------------
58
59 -- Here we make a concrete info table, represented as a list of CmmAddr
60 -- (it can't be simply a list of Word, because the SRT field is
61 -- represented by a label+offset expression).
62
63 -- With tablesNextToCode, the layout is
64 --      <reversed variable part>
65 --      <normal forward StgInfoTable, but without 
66 --              an entry point at the front>
67 --      <code>
68 --
69 -- Without tablesNextToCode, the layout of an info table is
70 --      <entry label>
71 --      <normal forward rest of StgInfoTable>
72 --      <forward variable part>
73 --
74 --      See includes/InfoTables.h
75
76 emitClosureCodeAndInfoTable :: ClosureInfo -> [LocalReg] -> CgStmts -> Code
77 emitClosureCodeAndInfoTable cl_info args body
78  = do   { ty_descr_lit <- 
79                 if opt_SccProfilingOn 
80                    then mkStringCLit (closureTypeDescr cl_info)
81                    else return (mkIntCLit 0)
82         ; cl_descr_lit <- 
83                 if opt_SccProfilingOn 
84                    then mkStringCLit cl_descr_string
85                    else return (mkIntCLit 0)
86         ; let std_info = mkStdInfoTable ty_descr_lit cl_descr_lit 
87                                         cl_type srt_len layout_lit
88
89         ; blks <- cgStmtsToBlocks body
90         ; emitInfoTableAndCode info_lbl std_info extra_bits args blks }
91   where
92     info_lbl  = infoTableLabelFromCI cl_info
93
94     cl_descr_string = closureValDescr cl_info
95     cl_type = smRepClosureTypeInt (closureSMRep cl_info)
96
97     srt = closureSRT cl_info         
98     needs_srt = needsSRT srt
99
100     mb_con = isConstrClosure_maybe  cl_info
101     is_con = isJust mb_con
102
103     (srt_label,srt_len)
104         = case mb_con of
105             Just con -> -- Constructors don't have an SRT
106                         -- We keep the *zero-indexed* tag in the srt_len
107                         -- field of the info table. 
108                         (mkIntCLit 0, fromIntegral (dataConTagZ con)) 
109
110             Nothing  -> -- Not a constructor
111                         srtLabelAndLength srt info_lbl
112
113     ptrs       = closurePtrsSize cl_info
114     nptrs      = size - ptrs
115     size       = closureNonHdrSize cl_info
116     layout_lit = packHalfWordsCLit ptrs nptrs
117
118     extra_bits
119         | is_fun    = fun_extra_bits
120         | is_con    = []
121         | needs_srt = [srt_label]
122         | otherwise = []
123
124     maybe_fun_stuff = closureFunInfo cl_info
125     is_fun = isJust maybe_fun_stuff
126     (Just (arity, arg_descr)) = maybe_fun_stuff
127
128     fun_extra_bits
129         | ArgGen liveness <- arg_descr
130         = [ fun_amode,
131             srt_label,
132             makeRelativeRefTo info_lbl $ mkLivenessCLit liveness, 
133             slow_entry ]
134         | needs_srt = [fun_amode, srt_label]
135         | otherwise = [fun_amode]
136
137     slow_entry = makeRelativeRefTo info_lbl (CmmLabel slow_entry_label)
138     slow_entry_label = mkSlowEntryLabel (closureName cl_info)
139
140     fun_amode = packHalfWordsCLit fun_type arity
141     fun_type  = argDescrType arg_descr
142
143 -- We keep the *zero-indexed* tag in the srt_len field of the info
144 -- table of a data constructor.
145 dataConTagZ :: DataCon -> ConTagZ
146 dataConTagZ con = dataConTag con - fIRST_TAG
147
148 -- A low-level way to generate the variable part of a fun-style info table.
149 -- (must match fun_extra_bits above).  Used by the C-- parser.
150 mkFunGenInfoExtraBits :: Int -> Int -> CmmLit -> CmmLit -> CmmLit -> [CmmLit]
151 mkFunGenInfoExtraBits fun_type arity srt_label liveness slow_entry
152   = [ packHalfWordsCLit fun_type arity,
153       srt_label,
154       liveness,
155       slow_entry ]
156
157 -------------------------------------------------------------------------
158 --
159 --      Generating the info table and code for a return point
160 --
161 -------------------------------------------------------------------------
162
163 --      Here's the layout of a return-point info table
164 --
165 -- Tables next to code:
166 --
167 --                      <reversed vector table>
168 --                      <srt slot>
169 --                      <standard info table>
170 --      ret-addr -->    <entry code (if any)>
171 --
172 -- Not tables-next-to-code:
173 --
174 --      ret-addr -->    <ptr to entry code>
175 --                      <standard info table>
176 --                      <srt slot>
177 --                      <forward vector table>
178 --
179 --  * The vector table is only present for vectored returns
180 --
181 --  * The SRT slot is only there if either
182 --      (a) there is SRT info to record, OR
183 --      (b) if the return is vectored
184 --   The latter (b) is necessary so that the vector is in a
185 --   predictable place
186
187 vectorSlot :: CmmExpr -> CmmExpr -> CmmExpr
188 -- Get the vector slot from the info pointer
189 vectorSlot info_amode zero_indexed_tag
190   | tablesNextToCode 
191   = cmmOffsetExprW (cmmOffsetW info_amode (- (stdInfoTableSizeW + 2)))
192                    (cmmNegate zero_indexed_tag)
193         -- The "2" is one for the SRT slot, and one more 
194         -- to get to the first word of the vector
195
196   | otherwise 
197   = cmmOffsetExprW (cmmOffsetW info_amode (stdInfoTableSizeW + 2))
198                    zero_indexed_tag
199         -- The "2" is one for the entry-code slot and one for the SRT slot
200
201 retVec :: CmmExpr -> CmmExpr -> CmmExpr
202 -- Get a return vector from the info pointer
203 retVec info_amode zero_indexed_tag
204   = let slot = vectorSlot info_amode zero_indexed_tag
205 #ifdef x86_64_TARGET_ARCH
206         tableEntry = CmmMachOp (MO_S_Conv I32 I64) [CmmLoad slot I32]
207         -- offsets are 32-bits on x86-64, due to the inability of
208         -- the tools to handle 64-bit PC-relative relocations.  See also
209         -- PprMach.pprDataItem, and InfoTables.h:OFFSET_FIELD().
210 #else
211         tableEntry = CmmLoad slot wordRep
212 #endif
213     in if tablesNextToCode
214            then CmmMachOp (MO_Add wordRep) [tableEntry, info_amode]
215            else tableEntry
216            
217 emitReturnTarget
218    :: Name
219    -> CgStmts                   -- The direct-return code (if any)
220                                 --      (empty for vectored returns)
221    -> [CmmLit]                  -- Vector of return points 
222                                 --      (empty for non-vectored returns)
223    -> SRT
224    -> FCode CLabel
225 emitReturnTarget name stmts vector srt
226   = do  { live_slots <- getLiveStackSlots
227         ; liveness   <- buildContLiveness name live_slots
228         ; srt_info   <- getSRTInfo name srt
229
230         ; let
231               cl_type = case (null vector, isBigLiveness liveness) of
232                          (True,  True)  -> rET_BIG
233                          (True,  False) -> rET_SMALL
234                          (False, True)  -> rET_VEC_BIG
235                          (False, False) -> rET_VEC_SMALL
236  
237               (std_info, extra_bits) = 
238                    mkRetInfoTable info_lbl liveness srt_info cl_type vector
239
240         ; blks <- cgStmtsToBlocks stmts
241         ; emitInfoTableAndCode info_lbl std_info extra_bits args blks
242         ; return info_lbl }
243   where
244     args      = {- trace "emitReturnTarget: missing args" -} []
245     uniq      = getUnique name
246     info_lbl  = mkReturnInfoLabel uniq
247
248
249 mkRetInfoTable
250   :: CLabel             -- info label
251   -> Liveness           -- liveness
252   -> C_SRT              -- SRT Info
253   -> Int                -- type (eg. rET_SMALL)
254   -> [CmmLit]           -- vector
255   -> ([CmmLit],[CmmLit])
256 mkRetInfoTable info_lbl liveness srt_info cl_type vector
257   =  (std_info, extra_bits)
258   where
259         (srt_label, srt_len) = srtLabelAndLength srt_info info_lbl
260  
261         srt_slot | need_srt  = [srt_label]
262                  | otherwise = []
263
264         need_srt = needsSRT srt_info || not (null vector)
265                 -- If there's a vector table then we must allocate
266                 -- an SRT slot, so that the vector table is at a 
267                 -- known offset from the info pointer
268  
269         liveness_lit = makeRelativeRefTo info_lbl $ mkLivenessCLit liveness
270         std_info = mkStdInfoTable zeroCLit zeroCLit cl_type srt_len liveness_lit
271         extra_bits = srt_slot ++ map (makeRelativeRefTo info_lbl) vector
272
273
274 emitDirectReturnTarget
275    :: Name
276    -> CgStmts           -- The direct-return code
277    -> SRT
278    -> FCode CLabel
279 emitDirectReturnTarget name code srt
280   = emitReturnTarget name code [] srt
281
282 emitAlgReturnTarget
283         :: Name                         -- Just for its unique
284         -> [(ConTagZ, CgStmts)]         -- Tagged branches
285         -> Maybe CgStmts                -- Default branch (if any)
286         -> SRT                          -- Continuation's SRT
287         -> CtrlReturnConvention
288         -> FCode (CLabel, SemiTaggingStuff)
289
290 emitAlgReturnTarget name branches mb_deflt srt ret_conv
291   = case ret_conv of
292       UnvectoredReturn fam_sz -> do     
293         { blks <- getCgStmts $
294                     emitSwitch tag_expr branches mb_deflt 0 (fam_sz - 1)
295                 -- NB: tag_expr is zero-based
296         ; lbl <- emitDirectReturnTarget name blks srt 
297         ; return (lbl, Nothing) }
298                 -- Nothing: the internal branches in the switch don't have
299                 -- global labels, so we can't use them at the 'call site'
300
301       VectoredReturn fam_sz -> do
302         { let tagged_lbls = zip (map fst branches) $
303                             map (CmmLabel . mkAltLabel uniq . fst) branches
304               deflt_lbl | isJust mb_deflt = CmmLabel $ mkDefaultLabel uniq
305                         | otherwise       = mkIntCLit 0
306         ; let vector = [ assocDefault deflt_lbl tagged_lbls i 
307                        | i <- [0..fam_sz-1]]
308         ; lbl <- emitReturnTarget name noCgStmts vector srt 
309         ; mapFCs emit_alt branches
310         ; emit_deflt mb_deflt
311         ; return (lbl, Just (tagged_lbls, deflt_lbl)) }
312   where
313     uniq = getUnique name 
314     tag_expr = getConstrTag (CmmReg nodeReg)
315
316     emit_alt :: (Int, CgStmts) -> FCode (Int, CmmLit)
317         -- Emit the code for the alternative as a top-level
318         -- code block returning a label for it
319     emit_alt (tag, stmts) = do   { let lbl = mkAltLabel uniq tag
320                                  ; blks <- cgStmtsToBlocks stmts
321                                  ; emitProc [] lbl [] blks
322                                  ; return (tag, CmmLabel lbl) }
323
324     emit_deflt (Just stmts) = do { let lbl = mkDefaultLabel uniq
325                                  ; blks <- cgStmtsToBlocks stmts
326                                  ; emitProc [] lbl [] blks
327                                  ; return (CmmLabel lbl) }
328     emit_deflt Nothing = return (mkIntCLit 0)
329                 -- Nothing case: the simplifier might have eliminated a case
330                 --               so we may have e.g. case xs of 
331                 --                                       [] -> e
332                 -- In that situation the default should never be taken, 
333                 -- so we just use a NULL pointer
334
335 --------------------------------
336 emitDirectReturnInstr :: Code
337 emitDirectReturnInstr 
338   = do  { info_amode <- getSequelAmode
339         ; stmtC (CmmJump (entryCode info_amode) []) }
340
341 emitVectoredReturnInstr :: CmmExpr      -- _Zero-indexed_ constructor tag
342                         -> Code
343 emitVectoredReturnInstr zero_indexed_tag
344   = do  { info_amode <- getSequelAmode
345                 -- HACK! assign info_amode to a temp, because retVec
346                 -- uses it twice and the NCG doesn't have any CSE yet.
347                 -- Only do this for the NCG, because gcc is too stupid
348                 -- to optimise away the extra tmp (grrr).
349         ; dflags <- getDynFlags
350         ; x <- if hscTarget dflags == HscAsm
351                    then do z <- newTemp wordRep
352                            stmtC (CmmAssign z info_amode)
353                            return (CmmReg z)
354                    else
355                         return info_amode
356         ; let target = retVec x zero_indexed_tag
357         ; stmtC (CmmJump target []) }
358
359
360 -------------------------------------------------------------------------
361 --
362 --      Generating a standard info table
363 --
364 -------------------------------------------------------------------------
365
366 -- The standard bits of an info table.  This part of the info table
367 -- corresponds to the StgInfoTable type defined in InfoTables.h.
368 --
369 -- Its shape varies with ticky/profiling/tables next to code etc
370 -- so we can't use constant offsets from Constants
371
372 mkStdInfoTable
373    :: CmmLit            -- closure type descr (profiling)
374    -> CmmLit            -- closure descr (profiling)
375    -> Int               -- closure type
376    -> StgHalfWord       -- SRT length
377    -> CmmLit            -- layout field
378    -> [CmmLit]
379
380 mkStdInfoTable type_descr closure_descr cl_type srt_len layout_lit
381  =      -- Parallel revertible-black hole field
382     prof_info
383         -- Ticky info (none at present)
384         -- Debug info (none at present)
385  ++ [layout_lit, type_lit]
386
387  where  
388     prof_info 
389         | opt_SccProfilingOn = [type_descr, closure_descr]
390         | otherwise          = []
391
392     type_lit = packHalfWordsCLit cl_type srt_len
393         
394 stdInfoTableSizeW :: WordOff
395 -- The size of a standard info table varies with profiling/ticky etc,
396 -- so we can't get it from Constants
397 -- It must vary in sync with mkStdInfoTable
398 stdInfoTableSizeW
399   = size_fixed + size_prof
400   where
401     size_fixed = 2      -- layout, type
402     size_prof | opt_SccProfilingOn = 2
403               | otherwise          = 0
404
405 stdInfoTableSizeB = stdInfoTableSizeW * wORD_SIZE :: ByteOff
406
407 stdSrtBitmapOffset :: ByteOff
408 -- Byte offset of the SRT bitmap half-word which is 
409 -- in the *higher-addressed* part of the type_lit
410 stdSrtBitmapOffset = stdInfoTableSizeB - hALF_WORD_SIZE
411
412 stdClosureTypeOffset :: ByteOff
413 -- Byte offset of the closure type half-word 
414 stdClosureTypeOffset = stdInfoTableSizeB - wORD_SIZE
415
416 stdPtrsOffset, stdNonPtrsOffset :: ByteOff
417 stdPtrsOffset    = stdInfoTableSizeB - 2*wORD_SIZE
418 stdNonPtrsOffset = stdInfoTableSizeB - 2*wORD_SIZE + hALF_WORD_SIZE
419
420 -------------------------------------------------------------------------
421 --
422 --      Accessing fields of an info table
423 --
424 -------------------------------------------------------------------------
425
426 closureInfoPtr :: CmmExpr -> CmmExpr
427 -- Takes a closure pointer and returns the info table pointer
428 closureInfoPtr e = CmmLoad e wordRep
429
430 entryCode :: CmmExpr -> CmmExpr
431 -- Takes an info pointer (the first word of a closure)
432 -- and returns its entry code
433 entryCode e | tablesNextToCode = e
434             | otherwise        = CmmLoad e wordRep
435
436 getConstrTag :: CmmExpr -> CmmExpr
437 -- Takes a closure pointer, and return the *zero-indexed*
438 -- constructor tag obtained from the info table
439 -- This lives in the SRT field of the info table
440 -- (constructors don't need SRTs).
441 getConstrTag closure_ptr 
442   = CmmMachOp (MO_U_Conv halfWordRep wordRep) [infoTableConstrTag info_table]
443   where
444     info_table = infoTable (closureInfoPtr closure_ptr)
445
446 infoTable :: CmmExpr -> CmmExpr
447 -- Takes an info pointer (the first word of a closure)
448 -- and returns a pointer to the first word of the standard-form
449 -- info table, excluding the entry-code word (if present)
450 infoTable info_ptr
451   | tablesNextToCode = cmmOffsetB info_ptr (- stdInfoTableSizeB)
452   | otherwise        = cmmOffsetW info_ptr 1    -- Past the entry code pointer
453
454 infoTableConstrTag :: CmmExpr -> CmmExpr
455 -- Takes an info table pointer (from infoTable) and returns the constr tag
456 -- field of the info table (same as the srt_bitmap field)
457 infoTableConstrTag = infoTableSrtBitmap
458
459 infoTableSrtBitmap :: CmmExpr -> CmmExpr
460 -- Takes an info table pointer (from infoTable) and returns the srt_bitmap
461 -- field of the info table
462 infoTableSrtBitmap info_tbl
463   = CmmLoad (cmmOffsetB info_tbl stdSrtBitmapOffset) halfWordRep
464
465 infoTableClosureType :: CmmExpr -> CmmExpr
466 -- Takes an info table pointer (from infoTable) and returns the closure type
467 -- field of the info table.
468 infoTableClosureType info_tbl 
469   = CmmLoad (cmmOffsetB info_tbl stdClosureTypeOffset) halfWordRep
470
471 infoTablePtrs :: CmmExpr -> CmmExpr
472 infoTablePtrs info_tbl 
473   = CmmLoad (cmmOffsetB info_tbl stdPtrsOffset) halfWordRep
474
475 infoTableNonPtrs :: CmmExpr -> CmmExpr
476 infoTableNonPtrs info_tbl 
477   = CmmLoad (cmmOffsetB info_tbl stdNonPtrsOffset) halfWordRep
478
479 funInfoTable :: CmmExpr -> CmmExpr
480 -- Takes the info pointer of a function,
481 -- and returns a pointer to the first word of the StgFunInfoExtra struct
482 -- in the info table.
483 funInfoTable info_ptr
484   | tablesNextToCode
485   = cmmOffsetB info_ptr (- stdInfoTableSizeB - sIZEOF_StgFunInfoExtraRev)
486   | otherwise
487   = cmmOffsetW info_ptr (1 + stdInfoTableSizeW)
488                                 -- Past the entry code pointer
489
490 -------------------------------------------------------------------------
491 --
492 --      Emit the code for a closure (or return address)
493 --      and its associated info table
494 --
495 -------------------------------------------------------------------------
496
497 -- The complication here concerns whether or not we can
498 -- put the info table next to the code
499
500 emitInfoTableAndCode 
501         :: CLabel               -- Label of info table
502         -> [CmmLit]             -- ...its invariant part
503         -> [CmmLit]             -- ...and its variant part
504         -> [LocalReg]           -- ...args
505         -> [CmmBasicBlock]      -- ...and body
506         -> Code
507
508 emitInfoTableAndCode info_lbl std_info extra_bits args blocks
509   | tablesNextToCode    -- Reverse the extra_bits; and emit the top-level proc
510   = emitProc (reverse extra_bits ++ std_info) 
511              entry_lbl args blocks
512         -- NB: the info_lbl is discarded
513
514   | null blocks -- No actual code; only the info table is significant
515   =             -- Use a zero place-holder in place of the 
516                 -- entry-label in the info table
517     emitRODataLits info_lbl (zeroCLit : std_info ++ extra_bits)
518
519   | otherwise   -- Separately emit info table (with the function entry 
520   =             -- point as first entry) and the entry code 
521     do  { emitDataLits info_lbl (CmmLabel entry_lbl : std_info ++ extra_bits)
522         ; emitProc [] entry_lbl args blocks }
523
524   where
525         entry_lbl = infoLblToEntryLbl info_lbl
526
527 -------------------------------------------------------------------------
528 --
529 --      Static reference tables
530 --
531 -------------------------------------------------------------------------
532
533 -- There is just one SRT for each top level binding; all the nested
534 -- bindings use sub-sections of this SRT.  The label is passed down to
535 -- the nested bindings via the monad.
536
537 getSRTInfo :: Name -> SRT -> FCode C_SRT
538 getSRTInfo id NoSRT = return NoC_SRT
539 getSRTInfo id (SRT off len bmp)
540   | len > hALF_WORD_SIZE_IN_BITS || bmp == [fromIntegral srt_escape]
541   = do  { srt_lbl <- getSRTLabel
542         ; let srt_desc_lbl = mkSRTDescLabel id
543         ; emitRODataLits srt_desc_lbl
544                    ( cmmLabelOffW srt_lbl off
545                    : mkWordCLit (fromIntegral len)
546                    : map mkWordCLit bmp)
547         ; return (C_SRT srt_desc_lbl 0 srt_escape) }
548
549   | otherwise 
550   = do  { srt_lbl <- getSRTLabel
551         ; return (C_SRT srt_lbl off (fromIntegral (head bmp))) }
552                 -- The fromIntegral converts to StgHalfWord
553
554 srt_escape = (-1) :: StgHalfWord
555
556 srtLabelAndLength :: C_SRT -> CLabel -> (CmmLit, StgHalfWord)
557 srtLabelAndLength NoC_SRT _             
558   = (zeroCLit, 0)
559 srtLabelAndLength (C_SRT lbl off bitmap) info_lbl
560   = (makeRelativeRefTo info_lbl $ cmmLabelOffW lbl off, bitmap)
561
562 -------------------------------------------------------------------------
563 --
564 --      Position independent code
565 --
566 -------------------------------------------------------------------------
567 -- In order to support position independent code, we mustn't put absolute
568 -- references into read-only space. Info tables in the tablesNextToCode
569 -- case must be in .text, which is read-only, so we doctor the CmmLits
570 -- to use relative offsets instead.
571
572 -- Note that this is done even when the -fPIC flag is not specified,
573 -- as we want to keep binary compatibility between PIC and non-PIC.
574
575 makeRelativeRefTo :: CLabel -> CmmLit -> CmmLit
576         
577 makeRelativeRefTo info_lbl (CmmLabel lbl)
578   | tablesNextToCode
579   = CmmLabelDiffOff lbl info_lbl 0
580 makeRelativeRefTo info_lbl (CmmLabelOff lbl off)
581   | tablesNextToCode
582   = CmmLabelDiffOff lbl info_lbl off
583 makeRelativeRefTo _ lit = lit