Fix description and type profiling
[ghc-hetmet.git] / compiler / cmm / CmmInfo.hs
1 module CmmInfo (
2   cmmToRawCmm,
3   mkInfoTable
4 ) where
5
6 #include "HsVersions.h"
7
8 import Cmm
9 import CmmUtils
10 import PprCmm
11
12 import CLabel
13 import MachOp
14
15 import Bitmap
16 import ClosureInfo
17 import CgInfoTbls
18 import CgCallConv
19 import CgUtils
20 import SMRep
21
22 import Constants
23 import StaticFlags
24 import DynFlags
25 import Unique
26 import UniqSupply
27 import Panic
28
29 import Data.Bits
30
31 cmmToRawCmm :: [Cmm] -> IO [RawCmm]
32 cmmToRawCmm cmm = do
33   info_tbl_uniques <- mkSplitUniqSupply 'i'
34   return $ zipWith raw_cmm (listSplitUniqSupply info_tbl_uniques) cmm
35     where
36       raw_cmm uniq_supply (Cmm procs) =
37           Cmm $ concat $ zipWith mkInfoTable (uniqsFromSupply uniq_supply) procs
38
39 -- Make a concrete info table, represented as a list of CmmStatic
40 -- (it can't be simply a list of Word, because the SRT field is
41 -- represented by a label+offset expression).
42 --
43 -- With tablesNextToCode, the layout is
44 --      <reversed variable part>
45 --      <normal forward StgInfoTable, but without 
46 --              an entry point at the front>
47 --      <code>
48 --
49 -- Without tablesNextToCode, the layout of an info table is
50 --      <entry label>
51 --      <normal forward rest of StgInfoTable>
52 --      <forward variable part>
53 --
54 --      See includes/InfoTables.h
55 --
56 -- For return-points these are as follows
57 --
58 -- Tables next to code:
59 --
60 --                      <srt slot>
61 --                      <standard info table>
62 --      ret-addr -->    <entry code (if any)>
63 --
64 -- Not tables-next-to-code:
65 --
66 --      ret-addr -->    <ptr to entry code>
67 --                      <standard info table>
68 --                      <srt slot>
69 --
70 --  * The SRT slot is only there if there is SRT info to record
71
72 mkInfoTable :: Unique -> CmmTop -> [RawCmmTop]
73 mkInfoTable uniq (CmmData sec dat) = [CmmData sec dat]
74 mkInfoTable uniq (CmmProc (CmmInfo _ _ info) entry_label arguments blocks) =
75     case info of
76       -- | Code without an info table.  Easy.
77       CmmNonInfoTable -> [CmmProc [] entry_label arguments blocks]
78
79       CmmInfoTable (ProfilingInfo ty_prof cl_prof) type_tag type_info ->
80           let info_label = entryLblToInfoLbl entry_label
81               ty_prof' = if tablesNextToCode
82                          then makeRelativeRefTo info_label ty_prof
83                          else                              ty_prof
84               cl_prof' = if tablesNextToCode
85                          then makeRelativeRefTo info_label cl_prof
86                          else                              cl_prof
87           in case type_info of
88           -- | A function entry point.
89           FunInfo (ptrs, nptrs) srt fun_type fun_arity pap_bitmap slow_entry ->
90               mkInfoTableAndCode info_label std_info fun_extra_bits entry_label
91                                  arguments blocks
92             where
93               fun_extra_bits =
94                  [packHalfWordsCLit fun_type fun_arity] ++
95                  case pap_bitmap of
96                  ArgGen liveness ->
97                      (if null srt_label then [mkIntCLit 0] else srt_label) ++
98                      [makeRelativeRefTo info_label $ mkLivenessCLit liveness,
99                       makeRelativeRefTo info_label slow_entry]
100                  _ -> srt_label
101               std_info = mkStdInfoTable ty_prof' cl_prof' type_tag srt_bitmap
102                                         layout
103               (srt_label, srt_bitmap) = mkSRTLit info_label srt
104               layout = packHalfWordsCLit ptrs nptrs
105
106           -- | A constructor.
107           ConstrInfo (ptrs, nptrs) con_tag descr ->
108               mkInfoTableAndCode info_label std_info [con_name] entry_label
109                                  arguments blocks
110               where
111                 std_info = mkStdInfoTable ty_prof' cl_prof' type_tag con_tag layout
112                 con_name = makeRelativeRefTo info_label descr
113                 layout = packHalfWordsCLit ptrs nptrs
114
115           -- | A thunk.
116           ThunkInfo (ptrs, nptrs) srt ->
117               mkInfoTableAndCode info_label std_info srt_label entry_label
118                                  arguments blocks
119               where
120                 std_info = mkStdInfoTable ty_prof' cl_prof' type_tag srt_bitmap layout
121                 (srt_label, srt_bitmap) = mkSRTLit info_label srt
122                 layout = packHalfWordsCLit ptrs nptrs
123
124           -- | A selector thunk.
125           ThunkSelectorInfo offset srt ->
126               mkInfoTableAndCode info_label std_info [{- no SRT -}] entry_label
127                                  arguments blocks
128               where
129                 std_info = mkStdInfoTable ty_prof' cl_prof' type_tag 0 (mkWordCLit offset)
130
131           -- A continuation/return-point.
132           ContInfo stack_layout srt ->
133               liveness_data ++
134               mkInfoTableAndCode info_label std_info srt_label entry_label
135                                  arguments blocks
136               where
137                 std_info = mkStdInfoTable ty_prof' cl_prof' maybe_big_type_tag srt_bitmap
138                                           (makeRelativeRefTo info_label liveness_lit)
139                 (liveness_lit, liveness_data, liveness_tag) =
140                     mkLiveness uniq stack_layout
141                 maybe_big_type_tag = if type_tag == rET_SMALL
142                                      then liveness_tag
143                                      else type_tag
144                 (srt_label, srt_bitmap) = mkSRTLit info_label srt
145
146 -- Handle the differences between tables-next-to-code
147 -- and not tables-next-to-code
148 mkInfoTableAndCode :: CLabel
149                    -> [CmmLit]
150                    -> [CmmLit]
151                    -> CLabel
152                    -> CmmFormals
153                    -> [CmmBasicBlock]
154                    -> [RawCmmTop]
155 mkInfoTableAndCode info_lbl std_info extra_bits entry_lbl args blocks
156   | tablesNextToCode    -- Reverse the extra_bits; and emit the top-level proc
157   = [CmmProc (map CmmStaticLit (reverse extra_bits ++ std_info))
158              entry_lbl args blocks]
159
160   | null blocks -- No actual code; only the info table is significant
161   =             -- Use a zero place-holder in place of the 
162                 -- entry-label in the info table
163     [mkRODataLits info_lbl (zeroCLit : std_info ++ extra_bits)]
164
165   | otherwise   -- Separately emit info table (with the function entry 
166   =             -- point as first entry) and the entry code 
167     [CmmProc [] entry_lbl args blocks,
168      mkDataLits info_lbl (CmmLabel entry_lbl : std_info ++ extra_bits)]
169
170 mkSRTLit :: CLabel
171          -> C_SRT
172          -> ([CmmLit],    -- srt_label
173              StgHalfWord) -- srt_bitmap
174 mkSRTLit info_label NoC_SRT = ([], 0)
175 mkSRTLit info_label (C_SRT lbl off bitmap) =
176     ([makeRelativeRefTo info_label (cmmLabelOffW lbl off)], bitmap)
177
178 -------------------------------------------------------------------------
179 --
180 --              Build a liveness mask for the stack layout
181 --
182 -------------------------------------------------------------------------
183
184 -- There are four kinds of things on the stack:
185 --
186 --      - pointer variables (bound in the environment)
187 --      - non-pointer variables (bound in the environment)
188 --      - free slots (recorded in the stack free list)
189 --      - non-pointer data slots (recorded in the stack free list)
190 --
191 -- The first two are represented with a 'Just' of a 'LocalReg'.
192 -- The last two with one or more 'Nothing' constructors.
193 -- Each 'Nothing' represents one used word.
194 --
195 -- The head of the stack layout is the top of the stack and
196 -- the least-significant bit.
197
198 -- TODO: refactor to use utility functions
199 -- TODO: combine with CgCallConv.mkLiveness (see comment there)
200 mkLiveness :: Unique
201            -> [Maybe LocalReg]
202            -> (CmmLit,           -- ^ The bitmap (literal value or label)
203                [RawCmmTop],      -- ^ Large bitmap CmmData if needed
204                ClosureTypeTag)   -- ^ rET_SMALL or rET_BIG
205 mkLiveness uniq live =
206   if length bits > mAX_SMALL_BITMAP_SIZE
207     -- does not fit in one word
208     then (CmmLabel big_liveness, [data_lits], rET_BIG)
209     -- fits in one word
210     else (mkWordCLit small_liveness, [], rET_SMALL)
211   where
212     mkBits [] = []
213     mkBits (reg:regs) = take sizeW bits ++ mkBits regs where
214         sizeW = case reg of
215                   Nothing -> 1
216                   Just r -> (machRepByteWidth (localRegRep r) + wORD_SIZE - 1)
217                             `quot` wORD_SIZE
218                             -- number of words, rounded up
219         bits = repeat $ is_non_ptr reg -- True <=> Non Ptr
220
221     is_non_ptr Nothing = True
222     is_non_ptr (Just reg) =
223         case localRegGCFollow reg of
224           KindNonPtr -> True
225           KindPtr -> False
226
227     bits :: [Bool]
228     bits = mkBits live
229
230     bitmap :: Bitmap
231     bitmap = mkBitmap bits
232
233     small_bitmap = case bitmap of 
234                    []  -> 0
235                    [b] -> fromIntegral b
236                    _   -> panic "mkLiveness"
237     small_liveness =
238         fromIntegral (length bits) .|. (small_bitmap `shiftL` bITMAP_BITS_SHIFT)
239
240     big_liveness = mkBitmapLabel uniq
241     lits = mkWordCLit (fromIntegral (length bits)) : map mkWordCLit bitmap
242     data_lits = mkRODataLits big_liveness lits
243
244 -------------------------------------------------------------------------
245 --
246 --      Generating a standard info table
247 --
248 -------------------------------------------------------------------------
249
250 -- The standard bits of an info table.  This part of the info table
251 -- corresponds to the StgInfoTable type defined in InfoTables.h.
252 --
253 -- Its shape varies with ticky/profiling/tables next to code etc
254 -- so we can't use constant offsets from Constants
255
256 mkStdInfoTable
257    :: CmmLit            -- closure type descr (profiling)
258    -> CmmLit            -- closure descr (profiling)
259    -> StgHalfWord       -- closure type
260    -> StgHalfWord       -- SRT length
261    -> CmmLit            -- layout field
262    -> [CmmLit]
263
264 mkStdInfoTable type_descr closure_descr cl_type srt_len layout_lit
265  =      -- Parallel revertible-black hole field
266     prof_info
267         -- Ticky info (none at present)
268         -- Debug info (none at present)
269  ++ [layout_lit, type_lit]
270
271  where  
272     prof_info 
273         | opt_SccProfilingOn = [type_descr, closure_descr]
274         | otherwise          = []
275
276     type_lit = packHalfWordsCLit cl_type srt_len