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