Merging in the new codegen branch
[ghc-hetmet.git] / compiler / codeGen / StgCmmProf.hs
1 {-# OPTIONS -w #-}
2 -- Lots of missing type sigs etc
3
4 -----------------------------------------------------------------------------
5 --
6 -- Code generation for profiling
7 --
8 -- (c) The University of Glasgow 2004-2006
9 --
10 -----------------------------------------------------------------------------
11
12 module StgCmmProf (
13         initCostCentres, ccType, ccsType,
14         mkCCostCentre, mkCCostCentreStack,
15
16         -- Cost-centre Profiling
17         dynProfHdr, profDynAlloc, profAlloc, staticProfHdr, initUpdFrameProf,
18         enterCostCentre, enterCostCentrePAP, enterCostCentreThunk, 
19         chooseDynCostCentres, 
20         costCentreFrom, 
21         curCCS, curCCSAddr,
22         emitSetCCC, emitCCS,
23
24         saveCurrentCostCentre, restoreCurrentCostCentre,
25
26         -- Lag/drag/void stuff
27         ldvEnter, ldvEnterClosure, ldvRecordCreate
28   ) where
29
30 #include "HsVersions.h"
31 #include "MachDeps.h"
32  -- For WORD_SIZE_IN_BITS only.
33 #include "../includes/Constants.h"
34         -- For LDV_CREATE_MASK, LDV_STATE_USE
35         -- which are StgWords
36 #include "../includes/DerivedConstants.h"
37         -- For REP_xxx constants, which are MachReps
38
39 import StgCmmClosure
40 import StgCmmUtils
41 import StgCmmMonad
42 import SMRep
43
44 import MkZipCfgCmm
45 import Cmm
46 import TyCon    ( PrimRep(..) )
47 import CmmUtils
48 import CLabel
49
50 import Id
51 import qualified Module
52 import CostCentre
53 import StgSyn
54 import StaticFlags
55 import FastString
56 import Constants        -- Lots of field offsets
57 import Outputable
58
59 import Data.Maybe
60 import Data.Char
61 import Control.Monad
62
63 -----------------------------------------------------------------------------
64 --
65 -- Cost-centre-stack Profiling
66 --
67 -----------------------------------------------------------------------------
68
69 -- Expression representing the current cost centre stack
70 ccsType :: CmmType      -- Type of a cost-centre stack
71 ccsType = bWord
72
73 ccType :: CmmType       -- Type of a cost centre
74 ccType = bWord
75
76 curCCS :: CmmExpr
77 curCCS = CmmLoad curCCSAddr ccsType
78
79 -- Address of current CCS variable, for storing into
80 curCCSAddr :: CmmExpr
81 curCCSAddr = CmmLit (CmmLabel (mkRtsDataLabel (sLit "CCCS")))
82
83 mkCCostCentre :: CostCentre -> CmmLit
84 mkCCostCentre cc = CmmLabel (mkCCLabel cc)
85
86 mkCCostCentreStack :: CostCentreStack -> CmmLit
87 mkCCostCentreStack ccs = CmmLabel (mkCCSLabel ccs)
88
89 costCentreFrom :: CmmExpr       -- A closure pointer
90                -> CmmExpr       -- The cost centre from that closure
91 costCentreFrom cl = CmmLoad (cmmOffsetB cl oFFSET_StgHeader_ccs) ccsType
92
93 staticProfHdr :: CostCentreStack -> [CmmLit]
94 -- The profiling header words in a static closure
95 -- Was SET_STATIC_PROF_HDR
96 staticProfHdr ccs = ifProfilingL [mkCCostCentreStack ccs, 
97                                   staticLdvInit]
98
99 dynProfHdr :: CmmExpr -> [CmmExpr]
100 -- Profiling header words in a dynamic closure
101 dynProfHdr ccs = ifProfilingL [ccs, dynLdvInit]
102
103 initUpdFrameProf :: CmmExpr -> FCode ()
104 -- Initialise the profiling field of an update frame
105 initUpdFrameProf frame_amode 
106   = ifProfiling $       -- frame->header.prof.ccs = CCCS
107     emit (mkStore (cmmOffsetB frame_amode oFFSET_StgHeader_ccs) curCCS)
108         -- frame->header.prof.hp.rs = NULL (or frame-header.prof.hp.ldvw = 0) 
109         -- is unnecessary because it is not used anyhow.
110
111 ---------------------------------------------------------------------------
112 --      Saving and restoring the current cost centre
113 ---------------------------------------------------------------------------
114
115 {-      Note [Saving the current cost centre]
116         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
117 The current cost centre is like a global register.  Like other 
118 global registers, it's a caller-saves one.  But consider
119         case (f x) of (p,q) -> rhs
120 Since 'f' may set the cost centre, we must restore it 
121 before resuming rhs.  So we want code like this:
122         local_cc = CCC  -- save
123         r = f( x )
124         CCC = local_cc  -- restore
125 That is, we explicitly "save" the current cost centre in
126 a LocalReg, local_cc; and restore it after the call. The
127 C-- infrastructure will arrange to save local_cc across the
128 call. 
129
130 The same goes for join points;
131         let j x = join-stuff
132         in blah-blah
133 We want this kind of code:
134         local_cc = CCC  -- save
135         blah-blah
136      J: 
137         CCC = local_cc  -- restore
138 -}
139
140 saveCurrentCostCentre :: FCode (Maybe LocalReg)
141         -- Returns Nothing if profiling is off
142 saveCurrentCostCentre
143   | not opt_SccProfilingOn 
144   = return Nothing
145   | otherwise
146   = do  { local_cc <- newTemp ccType
147         ; emit (mkAssign (CmmLocal local_cc) curCCS)
148         ; return (Just local_cc) }
149
150 restoreCurrentCostCentre :: Maybe LocalReg -> FCode ()
151 restoreCurrentCostCentre Nothing 
152   = return ()
153 restoreCurrentCostCentre (Just local_cc)
154   = emit (mkStore curCCSAddr (CmmReg (CmmLocal local_cc)))
155
156
157 -------------------------------------------------------------------------------
158 -- Recording allocation in a cost centre
159 -------------------------------------------------------------------------------
160
161 -- | Record the allocation of a closure.  The CmmExpr is the cost
162 -- centre stack to which to attribute the allocation.
163 profDynAlloc :: ClosureInfo -> CmmExpr -> FCode ()
164 profDynAlloc cl_info ccs
165   = ifProfiling $
166     profAlloc (CmmLit (mkIntCLit (closureSize cl_info))) ccs
167
168 -- | Record the allocation of a closure (size is given by a CmmExpr)
169 -- The size must be in words, because the allocation counter in a CCS counts
170 -- in words.
171 profAlloc :: CmmExpr -> CmmExpr -> FCode ()
172 profAlloc words ccs
173   = ifProfiling $
174     emit (addToMemE alloc_rep
175                 (cmmOffsetB ccs oFFSET_CostCentreStack_mem_alloc)
176                 (CmmMachOp (MO_UU_Conv wordWidth (typeWidth alloc_rep)) $
177                   [CmmMachOp mo_wordSub [words, 
178                                          CmmLit (mkIntCLit profHdrSize)]]))
179                 -- subtract the "profiling overhead", which is the
180                 -- profiling header in a closure.
181  where 
182         alloc_rep =  REP_CostCentreStack_mem_alloc
183
184 -- ----------------------------------------------------------------------
185 -- Setting the cost centre in a new closure
186
187 chooseDynCostCentres :: CostCentreStack
188                      -> [Id]            -- Args
189                      -> StgExpr         -- Body
190                      -> FCode (CmmExpr, CmmExpr)
191 -- Called when alllcating a closure
192 -- Tells which cost centre to put in the object, and which
193 -- to blame the cost of allocation on
194 chooseDynCostCentres ccs args body = do
195   -- Cost-centre we record in the object
196   use_ccs <- emitCCS ccs
197
198   -- Cost-centre on whom we blame the allocation
199   let blame_ccs
200         | null args && isBox body = CmmLit (mkCCostCentreStack overheadCCS)
201         | otherwise               = use_ccs
202
203   return (use_ccs, blame_ccs)
204
205
206 -- Some CostCentreStacks are a sequence of pushes on top of CCCS.
207 -- These pushes must be performed before we can refer to the stack in
208 -- an expression.
209 emitCCS :: CostCentreStack -> FCode CmmExpr
210 emitCCS ccs = push_em (ccsExpr ccs') (reverse cc's)
211   where
212         (cc's, ccs') = decomposeCCS ccs
213
214         push_em ccs [] = return ccs
215         push_em ccs (cc:rest) = do
216           tmp <- newTemp ccsType        
217           pushCostCentre tmp ccs cc
218           push_em (CmmReg (CmmLocal tmp)) rest
219
220 ccsExpr :: CostCentreStack -> CmmExpr
221 ccsExpr ccs
222   | isCurrentCCS ccs = curCCS
223   | otherwise        = CmmLit (mkCCostCentreStack ccs)
224
225
226 isBox :: StgExpr -> Bool
227 -- If it's an utterly trivial RHS, then it must be
228 -- one introduced by boxHigherOrderArgs for profiling,
229 -- so we charge it to "OVERHEAD".
230 -- This looks like a GROSS HACK to me --SDM
231 isBox (StgApp fun []) = True
232 isBox other           = False
233
234
235 -- -----------------------------------------------------------------------
236 -- Setting the current cost centre on entry to a closure
237
238 -- For lexically scoped profiling we have to load the cost centre from
239 -- the closure entered, if the costs are not supposed to be inherited.
240 -- This is done immediately on entering the fast entry point.
241
242 -- Load current cost centre from closure, if not inherited.
243 -- Node is guaranteed to point to it, if profiling and not inherited.
244
245 enterCostCentre
246    :: ClosureInfo 
247    -> CostCentreStack
248    -> StgExpr   -- The RHS of the closure
249    -> FCode ()
250
251 -- We used to have a special case for bindings of form
252 --      f = g True
253 -- where g has arity 2.  The RHS is a thunk, but we don't
254 -- need to update it; and we want to subsume costs.
255 -- We don't have these sort of PAPs any more, so the special
256 -- case has gone away.
257
258 enterCostCentre closure_info ccs body
259   = ifProfiling $
260     ASSERT2(not (noCCSAttached ccs), ppr (closureName closure_info) <+> ppr ccs)
261     enter_cost_centre closure_info ccs body
262
263 enter_cost_centre closure_info ccs body
264   | isSubsumedCCS ccs
265   = ASSERT(isToplevClosure closure_info)
266     ASSERT(re_entrant)
267     enter_ccs_fsub
268         
269   | isDerivedFromCurrentCCS ccs
270   = do {
271         if re_entrant && not is_box
272           then
273                 enter_ccs_fun node_ccs
274           else
275                 emit (mkStore curCCSAddr node_ccs)
276
277         -- don't forget to bump the scc count.  This closure might have been
278         -- of the form   let x = _scc_ "x" e in ...x..., which the SCCfinal
279         -- pass has turned into simply  let x = e in ...x... and attached
280         -- the _scc_ as PushCostCentre(x,CCCS) on the x closure.  So that
281         -- we don't lose the scc counter, bump it in the entry code for x.
282         -- ToDo: for a multi-push we should really bump the counter for
283         -- each of the intervening CCSs, not just the top one.
284        ; when (not (isCurrentCCS ccs)) $
285                 emit (bumpSccCount curCCS)
286        }
287
288   | isCafCCS ccs
289   = ASSERT(isToplevClosure closure_info)
290     ASSERT(not re_entrant)
291     do  {       -- This is just a special case of the isDerivedFromCurrentCCS
292                 -- case above.  We could delete this, but it's a micro
293                 -- optimisation and saves a bit of code.
294           emit (mkStore curCCSAddr enc_ccs)
295         ; emit (bumpSccCount node_ccs)
296         }
297
298   | otherwise
299   = panic "enterCostCentre"
300   where
301     enc_ccs    = CmmLit (mkCCostCentreStack ccs)
302     re_entrant = closureReEntrant closure_info
303     node_ccs   = costCentreFrom (cmmOffsetB (CmmReg nodeReg) (-node_tag))
304     is_box     = isBox body
305
306     -- if this is a function, then node will be tagged; we must subract the tag
307     node_tag = funTag closure_info
308
309 -- set the current CCS when entering a PAP
310 enterCostCentrePAP :: CmmExpr -> FCode ()
311 enterCostCentrePAP closure = 
312   ifProfiling $ do 
313     enter_ccs_fun (costCentreFrom closure)
314     enteringPAP 1
315   
316 enterCostCentreThunk :: CmmExpr -> FCode ()
317 enterCostCentreThunk closure = 
318   ifProfiling $ do 
319     emit $ mkStore curCCSAddr (costCentreFrom closure)
320
321 enter_ccs_fun stack = emitRtsCall (sLit "EnterFunCCS") [(stack,AddrHint)] False
322                         -- ToDo: vols
323
324 enter_ccs_fsub = enteringPAP 0
325
326 -- When entering a PAP, EnterFunCCS is called by both the PAP entry
327 -- code and the function entry code; we don't want the function's
328 -- entry code to also update CCCS in the event that it was called via
329 -- a PAP, so we set the flag entering_PAP to indicate that we are
330 -- entering via a PAP.
331 enteringPAP :: Integer -> FCode ()
332 enteringPAP n
333   = emit (mkStore (CmmLit (CmmLabel (mkRtsDataLabel (sLit "entering_PAP"))))
334                   (CmmLit (CmmInt n cIntWidth)))
335
336 ifProfiling :: FCode () -> FCode ()
337 ifProfiling code
338   | opt_SccProfilingOn = code
339   | otherwise          = nopC
340
341 ifProfilingL :: [a] -> [a]
342 ifProfilingL xs
343   | opt_SccProfilingOn = xs
344   | otherwise          = []
345
346
347 ---------------------------------------------------------------
348 --      Initialising Cost Centres & CCSs
349 ---------------------------------------------------------------
350
351 initCostCentres :: CollectedCCs -> FCode CmmAGraph
352 -- Emit the declarations, and return code to register them
353 initCostCentres (local_CCs, ___extern_CCs, singleton_CCSs)
354   = getCode $ whenC opt_SccProfilingOn $
355     do  { mapM_ emitCostCentreDecl local_CCs
356         ; mapM_ emitCostCentreStackDecl  singleton_CCSs 
357         ; emit $ catAGraphs $ map mkRegisterCC local_CCs
358         ; emit $ catAGraphs $ map mkRegisterCCS singleton_CCSs }
359
360
361 emitCostCentreDecl :: CostCentre -> FCode ()
362 emitCostCentreDecl cc = do 
363   { label <- mkStringCLit (costCentreUserName cc)
364   ; modl  <- mkStringCLit (Module.moduleNameString 
365                                (Module.moduleName (cc_mod cc)))
366                 -- All cost centres will be in the main package, since we
367                 -- don't normally use -auto-all or add SCCs to other packages.
368                 -- Hence don't emit the package name in the module here.
369   ; let lits = [ zero,          -- StgInt ccID,
370                  label, -- char *label,
371                  modl,  -- char *module,
372                  zero,  -- StgWord time_ticks
373                  zero64,        -- StgWord64 mem_alloc
374                  subsumed, -- StgInt is_caf
375                  zero   -- struct _CostCentre *link
376                ] 
377   ; emitDataLits (mkCCLabel cc) lits
378   }
379   where
380         subsumed | isCafCC cc = mkIntCLit (ord 'c')  -- 'c' == is a CAF
381                  | otherwise  = mkIntCLit (ord 'B')  -- 'B' == is boring
382
383 emitCostCentreStackDecl :: CostCentreStack -> FCode ()
384 emitCostCentreStackDecl ccs 
385   = case maybeSingletonCCS ccs of
386         Just cc -> emitDataLits (mkCCSLabel ccs) (mk_lits cc)
387         Nothing -> pprPanic "emitCostCentreStackDecl" (ppr ccs)
388   where
389      mk_lits cc = zero : 
390                   mkCCostCentre cc : 
391                   replicate (sizeof_ccs_words - 2) zero
392         -- Note: to avoid making any assumptions about how the
393         -- C compiler (that compiles the RTS, in particular) does
394         -- layouts of structs containing long-longs, simply
395         -- pad out the struct with zero words until we hit the
396         -- size of the overall struct (which we get via DerivedConstants.h)
397
398 zero = mkIntCLit 0
399 zero64 = CmmInt 0 W64
400
401 sizeof_ccs_words :: Int
402 sizeof_ccs_words 
403     -- round up to the next word.
404   | ms == 0   = ws
405   | otherwise = ws + 1
406   where
407    (ws,ms) = SIZEOF_CostCentreStack `divMod` wORD_SIZE
408
409 -- ---------------------------------------------------------------------------
410 -- Registering CCs and CCSs
411
412 --   (cc)->link = CC_LIST;
413 --   CC_LIST = (cc);
414 --   (cc)->ccID = CC_ID++;
415
416 mkRegisterCC :: CostCentre -> CmmAGraph
417 mkRegisterCC cc
418   = withTemp cInt $ \tmp -> 
419     catAGraphs [
420      mkStore (cmmOffsetB cc_lit oFFSET_CostCentre_link)
421                  (CmmLoad cC_LIST bWord),
422      mkStore cC_LIST cc_lit,
423      mkAssign (CmmLocal tmp) (CmmLoad cC_ID cInt),
424      mkStore (cmmOffsetB cc_lit oFFSET_CostCentre_ccID) (CmmReg (CmmLocal tmp)),
425      mkStore cC_ID (cmmRegOffB (CmmLocal tmp) 1)
426    ]
427   where
428         cc_lit = CmmLit (CmmLabel (mkCCLabel cc))
429
430 --  (ccs)->prevStack = CCS_LIST;
431 --  CCS_LIST = (ccs);
432 --  (ccs)->ccsID = CCS_ID++;
433
434 mkRegisterCCS :: CostCentreStack -> CmmAGraph
435 mkRegisterCCS ccs
436   = withTemp cInt $ \ tmp ->
437     catAGraphs [
438      mkStore (cmmOffsetB ccs_lit oFFSET_CostCentreStack_prevStack) 
439                         (CmmLoad cCS_LIST bWord),
440      mkStore cCS_LIST ccs_lit,
441      mkAssign (CmmLocal tmp) (CmmLoad cCS_ID cInt),
442      mkStore (cmmOffsetB ccs_lit oFFSET_CostCentreStack_ccsID) (CmmReg (CmmLocal tmp)),
443      mkStore cCS_ID (cmmRegOffB (CmmLocal tmp) 1)
444    ]
445   where
446     ccs_lit = CmmLit (CmmLabel (mkCCSLabel ccs))
447
448
449 cC_LIST = CmmLit (CmmLabel (mkRtsDataLabel (sLit "CC_LIST")))
450 cC_ID   = CmmLit (CmmLabel (mkRtsDataLabel (sLit "CC_ID")))
451
452 cCS_LIST = CmmLit (CmmLabel (mkRtsDataLabel (sLit "CCS_LIST")))
453 cCS_ID   = CmmLit (CmmLabel (mkRtsDataLabel (sLit "CCS_ID")))
454
455 -- ---------------------------------------------------------------------------
456 -- Set the current cost centre stack
457
458 emitSetCCC :: CostCentre -> FCode ()
459 emitSetCCC cc
460   | not opt_SccProfilingOn = nopC
461   | otherwise = do 
462     tmp <- newTemp ccsType -- TODO FIXME NOW
463     ASSERT( sccAbleCostCentre cc )
464       pushCostCentre tmp curCCS cc
465     emit (mkStore curCCSAddr (CmmReg (CmmLocal tmp)))
466     when (isSccCountCostCentre cc) $ 
467          emit (bumpSccCount curCCS)
468
469 pushCostCentre :: LocalReg -> CmmExpr -> CostCentre -> FCode ()
470 pushCostCentre result ccs cc
471   = emitRtsCallWithResult result AddrHint
472         (sLit "PushCostCentre") [(ccs,AddrHint), 
473                                 (CmmLit (mkCCostCentre cc), AddrHint)]
474         False
475
476 bumpSccCount :: CmmExpr -> CmmAGraph
477 bumpSccCount ccs
478   = addToMem REP_CostCentreStack_scc_count
479          (cmmOffsetB ccs oFFSET_CostCentreStack_scc_count) 1
480
481 -----------------------------------------------------------------------------
482 --
483 --              Lag/drag/void stuff
484 --
485 -----------------------------------------------------------------------------
486
487 --
488 -- Initial value for the LDV field in a static closure
489 --
490 staticLdvInit :: CmmLit
491 staticLdvInit = zeroCLit
492
493 --
494 -- Initial value of the LDV field in a dynamic closure
495 --
496 dynLdvInit :: CmmExpr
497 dynLdvInit =     -- (era << LDV_SHIFT) | LDV_STATE_CREATE  
498   CmmMachOp mo_wordOr [
499       CmmMachOp mo_wordShl [loadEra, CmmLit (mkIntCLit lDV_SHIFT) ],
500       CmmLit (mkWordCLit lDV_STATE_CREATE)
501   ]
502         
503 --
504 -- Initialise the LDV word of a new closure
505 --
506 ldvRecordCreate :: CmmExpr -> FCode ()
507 ldvRecordCreate closure = emit $ mkStore (ldvWord closure) dynLdvInit
508
509 --
510 -- Called when a closure is entered, marks the closure as having been "used".
511 -- The closure is not an 'inherently used' one.
512 -- The closure is not IND or IND_OLDGEN because neither is considered for LDV
513 -- profiling.
514 --
515 ldvEnterClosure :: ClosureInfo -> FCode ()
516 ldvEnterClosure closure_info = ldvEnter (cmmOffsetB (CmmReg nodeReg) (-tag))
517   where tag = funTag closure_info
518         -- don't forget to substract node's tag
519   
520 ldvEnter :: CmmExpr -> FCode ()
521 -- Argument is a closure pointer
522 ldvEnter cl_ptr
523   = ifProfiling $
524      -- if (era > 0) {
525      --    LDVW((c)) = (LDVW((c)) & LDV_CREATE_MASK) |
526      --                era | LDV_STATE_USE }
527     emit (mkCmmIfThenElse (CmmMachOp mo_wordUGt [loadEra, CmmLit zeroCLit])
528                 (mkStore ldv_wd new_ldv_wd)
529                 mkNop)
530   where
531         -- don't forget to substract node's tag
532     ldv_wd = ldvWord cl_ptr
533     new_ldv_wd = cmmOrWord (cmmAndWord (CmmLoad ldv_wd bWord)
534                                        (CmmLit (mkWordCLit lDV_CREATE_MASK)))
535                  (cmmOrWord loadEra (CmmLit (mkWordCLit lDV_STATE_USE)))
536
537 loadEra :: CmmExpr 
538 loadEra = CmmMachOp (MO_UU_Conv cIntWidth wordWidth)
539           [CmmLoad (mkLblExpr (mkRtsDataLabel (sLit "era"))) cInt]
540
541 ldvWord :: CmmExpr -> CmmExpr
542 -- Takes the address of a closure, and returns 
543 -- the address of the LDV word in the closure
544 ldvWord closure_ptr = cmmOffsetB closure_ptr oFFSET_StgHeader_ldvw
545
546 -- LDV constants, from ghc/includes/Constants.h
547 lDV_SHIFT        = (LDV_SHIFT :: Int)
548 --lDV_STATE_MASK   = (LDV_STATE_MASK :: StgWord)
549 lDV_CREATE_MASK  = (LDV_CREATE_MASK :: StgWord)
550 --lDV_LAST_MASK    = (LDV_LAST_MASK :: StgWord)
551 lDV_STATE_CREATE = (LDV_STATE_CREATE :: StgWord)
552 lDV_STATE_USE    = (LDV_STATE_USE :: StgWord)
553