Fix for function info tables: the SRT field cannot be omitted if there are fields...
[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 info entry_label arguments blocks) =
75     case info of
76       -- | Code without an info table.  Easy.
77       CmmNonInfo _ -> [CmmProc [] entry_label arguments blocks]
78
79       -- | A function entry point.
80       CmmInfo (ProfilingInfo ty_prof cl_prof) _ type_tag
81               (FunInfo (ptrs, nptrs) srt fun_type fun_arity
82                        pap_bitmap slow_entry) ->
83           mkInfoTableAndCode info_label std_info fun_extra_bits entry_label
84                              arguments blocks
85           where
86             fun_extra_bits =
87                [packHalfWordsCLit fun_type fun_arity] ++
88                case pap_bitmap of
89                  ArgGen liveness ->
90                      (if null srt_label then [mkIntCLit 0] else srt_label) ++
91                      [makeRelativeRefTo info_label $ mkLivenessCLit liveness,
92                       makeRelativeRefTo info_label slow_entry]
93                  _ -> srt_label
94             std_info = mkStdInfoTable ty_prof cl_prof type_tag srt_bitmap layout
95             info_label = entryLblToInfoLbl entry_label
96             (srt_label, srt_bitmap) = mkSRTLit info_label srt
97             layout = packHalfWordsCLit ptrs nptrs
98
99       -- | A constructor.
100       CmmInfo (ProfilingInfo ty_prof cl_prof) _ type_tag
101               (ConstrInfo (ptrs, nptrs) con_tag descr) ->
102           mkInfoTableAndCode info_label std_info [con_name] entry_label
103                              arguments blocks
104           where
105             std_info = mkStdInfoTable ty_prof cl_prof type_tag con_tag layout
106             info_label = entryLblToInfoLbl entry_label
107             con_name = makeRelativeRefTo info_label descr
108             layout = packHalfWordsCLit ptrs nptrs
109
110       -- | A thunk.
111       CmmInfo (ProfilingInfo ty_prof cl_prof) _ type_tag
112               (ThunkInfo (ptrs, nptrs) srt) ->
113           mkInfoTableAndCode info_label std_info srt_label entry_label
114                              arguments blocks
115           where
116             std_info = mkStdInfoTable ty_prof cl_prof type_tag srt_bitmap layout
117             info_label = entryLblToInfoLbl entry_label
118             (srt_label, srt_bitmap) = mkSRTLit info_label srt
119             layout = packHalfWordsCLit ptrs nptrs
120
121       -- | A selector thunk.
122       CmmInfo (ProfilingInfo ty_prof cl_prof) _ type_tag
123               (ThunkSelectorInfo offset srt) ->
124           mkInfoTableAndCode info_label std_info [{- no SRT -}] entry_label
125                              arguments blocks
126           where
127             std_info = mkStdInfoTable ty_prof cl_prof type_tag 0 (mkWordCLit offset)
128             info_label = entryLblToInfoLbl entry_label
129
130       -- A continuation/return-point.
131       CmmInfo (ProfilingInfo ty_prof cl_prof) _ type_tag (ContInfo stack_layout srt) ->
132           liveness_data ++
133           mkInfoTableAndCode info_label std_info srt_label entry_label
134                              arguments blocks
135           where
136             std_info = mkStdInfoTable ty_prof cl_prof maybe_big_type_tag srt_bitmap
137                                       (makeRelativeRefTo info_label liveness_lit)
138             info_label = entryLblToInfoLbl entry_label
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     [mkDataLits info_lbl (CmmLabel entry_lbl : std_info ++ extra_bits),
168      CmmProc [] entry_lbl args blocks]
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) `quot` wORD_SIZE
217         bits = repeat $ is_non_ptr reg -- True <=> Non Ptr
218
219     is_non_ptr Nothing = True
220     is_non_ptr (Just reg) =
221         case localRegGCFollow reg of
222           KindNonPtr -> True
223           KindPtr -> False
224
225     bits :: [Bool]
226     bits = mkBits live
227
228     bitmap :: Bitmap
229     bitmap = mkBitmap bits
230
231     small_bitmap = case bitmap of 
232                    []  -> 0
233                    [b] -> fromIntegral b
234                    _   -> panic "mkLiveness"
235     small_liveness =
236         fromIntegral (length bits) .|. (small_bitmap `shiftL` bITMAP_BITS_SHIFT)
237
238     big_liveness = mkBitmapLabel uniq
239     lits = mkWordCLit (fromIntegral (length bits)) : map mkWordCLit bitmap
240     data_lits = mkRODataLits big_liveness lits
241
242 -------------------------------------------------------------------------
243 --
244 --      Generating a standard info table
245 --
246 -------------------------------------------------------------------------
247
248 -- The standard bits of an info table.  This part of the info table
249 -- corresponds to the StgInfoTable type defined in InfoTables.h.
250 --
251 -- Its shape varies with ticky/profiling/tables next to code etc
252 -- so we can't use constant offsets from Constants
253
254 mkStdInfoTable
255    :: CmmLit            -- closure type descr (profiling)
256    -> CmmLit            -- closure descr (profiling)
257    -> StgHalfWord       -- closure type
258    -> StgHalfWord       -- SRT length
259    -> CmmLit            -- layout field
260    -> [CmmLit]
261
262 mkStdInfoTable type_descr closure_descr cl_type srt_len layout_lit
263  =      -- Parallel revertible-black hole field
264     prof_info
265         -- Ticky info (none at present)
266         -- Debug info (none at present)
267  ++ [layout_lit, type_lit]
268
269  where  
270     prof_info 
271         | opt_SccProfilingOn = [type_descr, closure_descr]
272         | otherwise          = []
273
274     type_lit = packHalfWordsCLit cl_type srt_len