[project @ 2002-02-14 11:56:03 by njn]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgClosure.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 % $Id: CgClosure.lhs,v 1.55 2002/02/14 11:56:03 njn Exp $
5 %
6 \section[CgClosure]{Code generation for closures}
7
8 This module provides the support code for @StgToAbstractC@ to deal
9 with {\em closures} on the RHSs of let(rec)s.  See also
10 @CgCon@, which deals with constructors.
11
12 \begin{code}
13 module CgClosure ( cgTopRhsClosure, 
14                    cgStdRhsClosure, 
15                    cgRhsClosure, 
16                    closureCodeBody ) where
17
18 #include "HsVersions.h"
19
20 import {-# SOURCE #-} CgExpr ( cgExpr )
21
22 import CgMonad
23 import AbsCSyn
24 import StgSyn
25
26 import AbsCUtils        ( mkAbstractCs, getAmodeRep )
27 import CgBindery        ( getCAddrMode, getArgAmodes,
28                           getCAddrModeAndInfo, bindNewToNode,
29                           bindNewToStack,
30                           bindNewToReg, bindArgsToRegs,
31                           stableAmodeIdInfo, heapIdInfo, CgIdInfo
32                         )
33 import CgUpdate         ( pushUpdateFrame )
34 import CgHeapery        ( allocDynClosure, 
35                           fetchAndReschedule, yield,  -- HWL
36                           fastEntryChecks, thunkChecks
37                         )
38 import CgStackery       ( mkTaggedVirtStkOffsets, freeStackSlots )
39 import CgUsages         ( adjustSpAndHp, setRealAndVirtualSp, getVirtSp,
40                           getSpRelOffset, getHpRelOffset
41                         )
42 import CLabel           ( CLabel, mkClosureLabel, mkFastEntryLabel,
43                           mkRednCountsLabel, mkInfoTableLabel
44                         )
45 import ClosureInfo      -- lots and lots of stuff
46 import CmdLineOpts      ( opt_GranMacros, opt_SccProfilingOn, opt_DoTickyProfiling )
47 import CostCentre       
48 import Id               ( Id, idName, idType, idPrimRep )
49 import Name             ( Name, isLocalName )
50 import Module           ( Module, pprModule )
51 import ListSetOps       ( minusList )
52 import PrimRep          ( PrimRep(..) )
53 import PprType          ( showTypeCategory )
54 import Util             ( isIn, splitAtList )
55 import CmdLineOpts      ( opt_SccProfilingOn )
56 import Outputable
57
58 import Name             ( nameOccName )
59 import OccName          ( occNameFS )
60 import FastTypes        ( iBox )
61 \end{code}
62
63 %********************************************************
64 %*                                                      *
65 \subsection[closures-no-free-vars]{Top-level closures}
66 %*                                                      *
67 %********************************************************
68
69 For closures bound at top level, allocate in static space.
70 They should have no free variables.
71
72 \begin{code}
73 cgTopRhsClosure :: Id
74                 -> CostCentreStack      -- Optional cost centre annotation
75                 -> StgBinderInfo
76                 -> SRT
77                 -> [Id]         -- Args
78                 -> StgExpr
79                 -> LambdaFormInfo
80                 -> FCode (Id, CgIdInfo)
81
82 cgTopRhsClosure id ccs binder_info srt args body lf_info
83   = 
84     -- LAY OUT THE OBJECT
85     getSRTInfo srt              `thenFC` \ srt_info ->
86     let
87         name          = idName id
88         closure_info  = layOutStaticNoFVClosure name lf_info srt_info
89         closure_label = mkClosureLabel name
90         cg_id_info    = stableAmodeIdInfo id (CLbl closure_label PtrRep) lf_info
91     in
92
93         -- BUILD THE OBJECT (IF NECESSARY)
94     (
95      ({- if staticClosureRequired name binder_info lf_info
96       then -}
97         absC (mkStaticClosure closure_info ccs [] True)
98       {- else
99         nopC -}
100      )
101                                                         `thenC`
102
103         -- GENERATE THE INFO TABLE (IF NECESSARY)
104     forkClosureBody (closureCodeBody binder_info closure_info
105                                          ccs args body)
106
107     ) `thenC`
108
109     returnFC (id, cg_id_info)
110
111 \end{code}
112
113 %********************************************************
114 %*                                                      *
115 \subsection[non-top-level-closures]{Non top-level closures}
116 %*                                                      *
117 %********************************************************
118
119 For closures with free vars, allocate in heap.
120
121 \begin{code}
122 cgStdRhsClosure
123         :: Id
124         -> CostCentreStack      -- Optional cost centre annotation
125         -> StgBinderInfo
126         -> [Id]                 -- Free vars
127         -> [Id]                 -- Args
128         -> StgExpr
129         -> LambdaFormInfo
130         -> [StgArg]             -- payload
131         -> FCode (Id, CgIdInfo)
132
133 cgStdRhsClosure binder cc binder_info fvs args body lf_info payload
134                 -- AHA!  A STANDARD-FORM THUNK
135   = (
136         -- LAY OUT THE OBJECT
137     getArgAmodes payload                        `thenFC` \ amodes ->
138     let
139         (closure_info, amodes_w_offsets)
140           = layOutDynClosure (idName binder) getAmodeRep amodes lf_info NoC_SRT
141                 -- No SRT for a standard-form closure
142
143         (use_cc, blame_cc) = chooseDynCostCentres cc args fvs body
144     in
145         -- BUILD THE OBJECT
146     allocDynClosure closure_info use_cc blame_cc amodes_w_offsets
147     )
148                 `thenFC` \ heap_offset ->
149
150         -- RETURN
151     returnFC (binder, heapIdInfo binder heap_offset lf_info)
152 \end{code}
153
154 Here's the general case.
155
156 \begin{code}
157 cgRhsClosure    :: Id
158                 -> CostCentreStack      -- Optional cost centre annotation
159                 -> StgBinderInfo
160                 -> SRT
161                 -> [Id]                 -- Free vars
162                 -> [Id]                 -- Args
163                 -> StgExpr
164                 -> LambdaFormInfo
165                 -> FCode (Id, CgIdInfo)
166
167 cgRhsClosure binder cc binder_info srt fvs args body lf_info
168   = (
169         -- LAY OUT THE OBJECT
170         --
171         -- If the binder is itself a free variable, then don't store
172         -- it in the closure.  Instead, just bind it to Node on entry.
173         -- NB we can be sure that Node will point to it, because we
174         -- havn't told mkClosureLFInfo about this; so if the binder
175         -- *was* a free var of its RHS, mkClosureLFInfo thinks it *is*
176         -- stored in the closure itself, so it will make sure that
177         -- Node points to it...
178     let
179         is_elem        = isIn "cgRhsClosure"
180
181         binder_is_a_fv = binder `is_elem` fvs
182         reduced_fvs    = if binder_is_a_fv
183                          then fvs `minusList` [binder]
184                          else fvs
185     in
186     mapFCs getCAddrModeAndInfo reduced_fvs      `thenFC` \ fvs_w_amodes_and_info ->
187     getSRTInfo srt                              `thenFC` \ srt_info ->
188     let
189         closure_info :: ClosureInfo
190         bind_details :: [((Id, CAddrMode, LambdaFormInfo), VirtualHeapOffset)]
191
192         (closure_info, bind_details)
193           = layOutDynClosure (idName binder) get_kind
194                              fvs_w_amodes_and_info lf_info srt_info
195
196         bind_fv ((id, _, lf_info), offset) = bindNewToNode id offset lf_info
197
198         amodes_w_offsets = [(amode,offset) | ((_,amode,_), offset) <- bind_details]
199
200         get_kind (id, _, _) = idPrimRep id
201     in
202         -- BUILD ITS INFO TABLE AND CODE
203     forkClosureBody (
204                 -- Bind the fvs
205             mapCs bind_fv bind_details `thenC`
206
207                 -- Bind the binder itself, if it is a free var
208             (if binder_is_a_fv then
209                 bindNewToReg binder node lf_info
210             else
211                 nopC)                                   `thenC`
212
213                 -- Compile the body
214             closureCodeBody binder_info closure_info cc args body
215     )   `thenC`
216
217         -- BUILD THE OBJECT
218     let
219         (use_cc, blame_cc) = chooseDynCostCentres cc args fvs body
220     in
221     allocDynClosure closure_info use_cc blame_cc amodes_w_offsets
222     )           `thenFC` \ heap_offset ->
223
224         -- RETURN
225     returnFC (binder, heapIdInfo binder heap_offset lf_info)
226 \end{code}
227
228 %************************************************************************
229 %*                                                                      *
230 \subsection[code-for-closures]{The code for closures}
231 %*                                                                      *
232 %************************************************************************
233
234 \begin{code}
235 closureCodeBody :: StgBinderInfo
236                 -> ClosureInfo     -- Lots of information about this closure
237                 -> CostCentreStack -- Optional cost centre attached to closure
238                 -> [Id]
239                 -> StgExpr
240                 -> Code
241 \end{code}
242
243 There are two main cases for the code for closures.  If there are {\em
244 no arguments}, then the closure is a thunk, and not in normal form.
245 So it should set up an update frame (if it is shared).  Also, it has
246 no argument satisfaction check, so fast and slow entry-point labels
247 are the same.
248
249 \begin{code}
250 closureCodeBody binder_info closure_info cc [] body
251   = -- thunks cannot have a primitive type!
252     getAbsC body_code   `thenFC` \ body_absC ->
253     moduleName          `thenFC` \ mod_name ->
254
255     absC (CClosureInfoAndCode closure_info body_absC Nothing
256                               (cl_descr mod_name))
257   where
258     cl_descr mod_name = closureDescription mod_name (closureName closure_info)
259
260     body_label   = entryLabelFromCI closure_info
261     
262     is_box  = case body of { StgApp fun [] -> True; _ -> False }
263
264     ticky_ent_lit = if (isStaticClosure closure_info)
265                     then SLIT("TICK_ENT_STATIC_THK")
266                     else SLIT("TICK_ENT_DYN_THK")
267
268     body_code   = profCtrC ticky_ent_lit []                     `thenC`
269                   -- node always points when profiling, so this is ok:
270                   ldvEnter                                      `thenC`
271                   thunkWrapper closure_info body_label (
272                         -- We only enter cc after setting up update so
273                         -- that cc of enclosing scope will be recorded
274                         -- in update frame CAF/DICT functions will be
275                         -- subsumed by this enclosing cc
276                     enterCostCentreCode closure_info cc IsThunk is_box `thenC`
277                     cgExpr body
278                   )
279
280 \end{code}
281
282 If there is {\em at least one argument}, then this closure is in
283 normal form, so there is no need to set up an update frame.  On the
284 other hand, we do have to check that there are enough args, and
285 perform an update if not!
286
287 The Macros for GrAnSim are produced at the beginning of the
288 argSatisfactionCheck (by calling fetchAndReschedule).  There info if
289 Node points to closure is available. -- HWL
290
291 \begin{code}
292 closureCodeBody binder_info closure_info cc all_args body
293   = getEntryConvention name lf_info
294                        (map idPrimRep all_args)         `thenFC` \ entry_conv ->
295
296     -- get the current virtual Sp (it might not be zero, eg. if we're
297     -- compiling a let-no-escape).
298     getVirtSp `thenFC` \vSp ->
299
300     let
301         -- Figure out what is needed and what isn't
302
303         -- SDM: need everything for now in case the heap/stack check refers
304         -- to it. (ToDo)
305         slow_code_needed   = True 
306                    --slowFunEntryCodeRequired name binder_info entry_conv
307         info_table_needed  = True
308                    --funInfoTableRequired name binder_info lf_info
309
310         -- Arg mapping for standard (slow) entry point; all args on stack,
311         -- with tagging.
312         (sp_all_args, arg_offsets, _)
313            = mkTaggedVirtStkOffsets vSp idPrimRep all_args
314
315         -- Arg mapping for the fast entry point; as many args as poss in
316         -- registers; the rest on the stack
317         --      arg_regs are the registers used for arg passing
318         --      stk_args are the args which are passed on the stack
319         --
320         -- Args passed on the stack are tagged, but the tags may not
321         -- actually be present (just gaps) if the function is called 
322         -- by jumping directly to the fast entry point.
323         --
324         arg_regs = case entry_conv of
325                 DirectEntry lbl arity regs -> regs
326                 other                      -> []  -- "(HWL ignored; no args passed in regs)"
327
328         (reg_args, stk_args) = splitAtList arg_regs all_args
329
330         (sp_stk_args, stk_offsets, stk_tags)
331           = mkTaggedVirtStkOffsets vSp idPrimRep stk_args
332
333         -- HWL; Note: empty list of live regs in slow entry code
334         -- Old version (reschedule combined with heap check);
335         -- see argSatisfactionCheck for new version
336         --slow_entry_code = forceHeapCheck [node] True slow_entry_code'
337         --                where node = UnusedReg PtrRep 1
338         --slow_entry_code = forceHeapCheck [] True slow_entry_code'
339
340         slow_entry_code
341           = profCtrC slow_ticky_ent_lit [
342                     CLbl ticky_ctr_label DataPtrRep
343             ] `thenC`
344
345             -- Bind args, and record expected position of stk ptrs
346             mapCs bindNewToStack arg_offsets                `thenC`
347             setRealAndVirtualSp sp_all_args                 `thenC`
348
349             argSatisfactionCheck closure_info   arg_regs            `thenC`
350
351             -- OK, so there are enough args.  Now we need to stuff as
352             -- many of them in registers as the fast-entry code
353             -- expects. Note that the zipWith will give up when it hits
354             -- the end of arg_regs.
355
356             mapFCs getCAddrMode all_args            `thenFC` \ stk_amodes ->
357             absC (mkAbstractCs (zipWith assign_to_reg arg_regs stk_amodes)) 
358                                                             `thenC`
359
360             -- Now adjust real stack pointers (no need to adjust Hp,
361             -- but call this function for convenience).
362             adjustSpAndHp sp_stk_args                   `thenC`
363
364             absC (CFallThrough (CLbl fast_label CodePtrRep))
365
366         assign_to_reg reg_id amode = CAssign (CReg reg_id) amode
367
368         -- HWL
369         -- Old version (reschedule combined with heap check);
370         -- see argSatisfactionCheck for new version
371         -- fast_entry_code = forceHeapCheck [] True fast_entry_code'
372
373         fast_entry_code = do
374                 mod_name <- moduleName
375                 profCtrC SLIT("TICK_CTR") [ 
376                         CLbl ticky_ctr_label DataPtrRep,
377                         mkCString (_PK_ (ppr_for_ticky_name mod_name name)),
378                         mkIntCLit stg_arity,    -- total # of args
379                         mkIntCLit sp_stk_args,  -- # passed on stk
380                         mkCString (_PK_ (map (showTypeCategory . idType) all_args))
381                         ] 
382                 let prof = 
383                         profCtrC fast_ticky_ent_lit [
384                                 CLbl ticky_ctr_label DataPtrRep
385                         ] 
386
387 -- Nuked for now; see comment at end of file
388 --                  CString (_PK_ (show_wrapper_name wrapper_maybe)),
389 --                  CString (_PK_ (show_wrapper_arg_kinds wrapper_maybe))
390
391
392                 -- Bind args to regs/stack as appropriate, and
393                 -- record expected position of sps.
394                 bindArgsToRegs reg_args arg_regs                    
395                 mapCs bindNewToStack stk_offsets                    
396                 setRealAndVirtualSp sp_stk_args             
397
398                 -- free up the stack slots containing tags
399                 freeStackSlots (map fst stk_tags)
400
401                 -- Enter the closures cc, if required
402                 enterCostCentreCode closure_info cc IsFunction False
403
404                 -- Do the business
405                 funWrapper closure_info arg_regs stk_tags info_label 
406                         (prof >> cgExpr body)
407     in
408
409     setTickyCtrLabel ticky_ctr_label (
410
411         -- Make a labelled code-block for the slow and fast entry code
412       forkAbsC (if slow_code_needed then slow_entry_code else absC AbsCNop)
413                                 `thenFC` \ slow_abs_c ->
414       forkAbsC fast_entry_code  `thenFC` \ fast_abs_c ->
415       moduleName                `thenFC` \ mod_name ->
416
417         -- Now either construct the info table, or put the fast code in alone
418         -- (We never have slow code without an info table)
419         -- XXX probably need the info table and slow entry code in case of
420         -- a heap check failure.
421       absC (
422        if info_table_needed then
423           CClosureInfoAndCode closure_info slow_abs_c (Just fast_abs_c)
424                         (cl_descr mod_name)
425        else
426         CCodeBlock fast_label fast_abs_c
427        )
428     )
429   where
430     ticky_ctr_label = mkRednCountsLabel name
431
432     (slow_ticky_ent_lit, fast_ticky_ent_lit) = 
433         if (isStaticClosure closure_info)
434         then (SLIT("TICK_ENT_STATIC_FUN_STD"), SLIT("TICK_ENT_STATIC_FUN_DIRECT"))
435         else (SLIT("TICK_ENT_DYN_FUN_STD"), SLIT("TICK_ENT_DYN_FUN_DIRECT"))
436         
437     stg_arity = length all_args
438     lf_info = closureLFInfo closure_info
439
440     cl_descr mod_name = closureDescription mod_name name
441
442         -- Manufacture labels
443     name       = closureName closure_info
444     fast_label = mkFastEntryLabel name stg_arity
445     info_label = mkInfoTableLabel name
446
447
448 -- When printing the name of a thing in a ticky file, we want to
449 -- give the module name even for *local* things.   We print
450 -- just "x (M)" rather that "M.x" to distinguish them from the global kind.
451 ppr_for_ticky_name mod_name name
452   | isLocalName name = showSDocDebug (ppr name <+> (parens (ppr mod_name)))
453   | otherwise        = showSDocDebug (ppr name)
454 \end{code}
455
456 For lexically scoped profiling we have to load the cost centre from
457 the closure entered, if the costs are not supposed to be inherited.
458 This is done immediately on entering the fast entry point.
459
460 Load current cost centre from closure, if not inherited.
461 Node is guaranteed to point to it, if profiling and not inherited.
462
463 \begin{code}
464 data IsThunk = IsThunk | IsFunction -- Bool-like, local
465 -- #ifdef DEBUG
466         deriving Eq
467 -- #endif
468
469 enterCostCentreCode 
470    :: ClosureInfo -> CostCentreStack
471    -> IsThunk
472    -> Bool      -- is_box: this closure is a special box introduced by SCCfinal
473    -> Code
474
475 enterCostCentreCode closure_info ccs is_thunk is_box
476   = if not opt_SccProfilingOn then
477         nopC
478     else
479         ASSERT2(not (noCCSAttached ccs), ppr (closureName closure_info) <+> ppr ccs)
480
481         if isSubsumedCCS ccs then
482             ASSERT(isToplevClosure closure_info)
483             ASSERT(is_thunk == IsFunction)
484             costCentresC SLIT("ENTER_CCS_FSUB") []
485  
486         else if isDerivedFromCurrentCCS ccs then 
487             if re_entrant && not is_box
488                 then costCentresC SLIT("ENTER_CCS_FCL") [CReg node]
489                 else costCentresC SLIT("ENTER_CCS_TCL") [CReg node]
490
491         else if isCafCCS ccs then
492             ASSERT(isToplevClosure closure_info)
493             ASSERT(is_thunk == IsThunk)
494                 -- might be a PAP, in which case we want to subsume costs
495             if re_entrant
496                 then costCentresC SLIT("ENTER_CCS_FSUB") []
497                 else costCentresC SLIT("ENTER_CCS_CAF") c_ccs
498
499         else panic "enterCostCentreCode"
500
501    where
502         c_ccs = [mkCCostCentreStack ccs]
503         re_entrant = closureReEntrant closure_info
504 \end{code}
505
506 %************************************************************************
507 %*                                                                      *
508 \subsubsection[pre-closure-code-stuff]{Pre-closure-code code}
509 %*                                                                      *
510 %************************************************************************
511
512 The argument-satisfaction check code is placed after binding
513 the arguments to their stack locations. Hence, the virtual stack
514 pointer is pointing after all the args, and virtual offset 1 means
515 the base of frame and hence most distant arg.  Hence
516 virtual offset 0 is just beyond the most distant argument; the
517 relative offset of this word tells how many words of arguments
518 are expected.
519
520 \begin{code}
521 argSatisfactionCheck :: ClosureInfo -> [MagicId] {-GRAN-} -> Code
522
523 argSatisfactionCheck closure_info arg_regs
524
525   = nodeMustPointToIt (closureLFInfo closure_info)   `thenFC` \ node_points ->
526
527 --      let
528 --         emit_gran_macros = opt_GranMacros
529 --      in
530
531     -- HWL  ngo' ngoq:
532     -- absC (CMacroStmt GRAN_FETCH [])                  `thenC`
533     -- forceHeapCheck [] node_points (absC AbsCNop)                     `thenC`
534     --(if opt_GranMacros
535     --  then if node_points 
536     --         then fetchAndReschedule  arg_regs node_points 
537     --         else yield arg_regs node_points
538     --  else absC AbsCNop)                       `thenC`
539
540         getSpRelOffset 0        `thenFC` \ (SpRel sp) ->
541         let
542             off     = iBox sp
543             rel_arg = mkIntCLit off
544         in
545         ASSERT(off /= 0)
546         if node_points then
547             absC (CMacroStmt ARGS_CHK [rel_arg]) -- node already points
548         else
549             absC (CMacroStmt ARGS_CHK_LOAD_NODE [rel_arg, set_Node_to_this])
550   where
551     -- We must tell the arg-satis macro whether Node is pointing to
552     -- the closure or not.  If it isn't so pointing, then we give to
553     -- the macro the (static) address of the closure.
554
555     set_Node_to_this = CLbl (closureLabelFromCI closure_info) PtrRep
556 \end{code}
557
558 %************************************************************************
559 %*                                                                      *
560 \subsubsection[closure-code-wrappers]{Wrappers around closure code}
561 %*                                                                      *
562 %************************************************************************
563
564 \begin{code}
565 thunkWrapper:: ClosureInfo -> CLabel -> Code -> Code
566 thunkWrapper closure_info lbl thunk_code
567   =     -- Stack and heap overflow checks
568     nodeMustPointToIt (closureLFInfo closure_info) `thenFC` \ node_points ->
569
570     -- HWL: insert macros for GrAnSim; 2 versions depending on liveness of node
571     -- (we prefer fetchAndReschedule-style context switches to yield ones)
572     (if opt_GranMacros
573        then if node_points 
574               then fetchAndReschedule [] node_points 
575               else yield [] node_points
576        else absC AbsCNop)                       `thenC`
577
578         -- stack and/or heap checks
579     thunkChecks lbl node_points (
580
581         -- Overwrite with black hole if necessary
582     blackHoleIt closure_info node_points  `thenC`
583
584     setupUpdate closure_info (                  -- setupUpdate *encloses* the rest
585
586         -- Finally, do the business
587     thunk_code
588     ))
589
590 funWrapper :: ClosureInfo       -- Closure whose code body this is
591            -> [MagicId]         -- List of argument registers (if any)
592            -> [(VirtualSpOffset,Int)] -- tagged stack slots
593            -> CLabel            -- info table for heap check ret.
594            -> Code              -- Body of function being compiled
595            -> Code
596 funWrapper closure_info arg_regs stk_tags info_label fun_body
597   =     -- Stack overflow check
598     nodeMustPointToIt (closureLFInfo closure_info)  `thenFC` \ node_points ->
599
600     -- enter for Ldv profiling
601     (if node_points then ldvEnter else nopC)        `thenC`
602
603     (if opt_GranMacros
604        then yield arg_regs node_points
605        else absC AbsCNop)                           `thenC`
606
607         -- heap and/or stack checks
608     fastEntryChecks arg_regs stk_tags info_label node_points (
609
610         -- Finally, do the business
611     fun_body
612     )
613 \end{code}
614
615
616 %************************************************************************
617 %*                                                                      *
618 \subsubsubsection[update-and-BHs]{Update and black-hole wrappers}
619 %*                                                                      *
620 %************************************************************************
621
622
623 \begin{code}
624 blackHoleIt :: ClosureInfo -> Bool -> Code      -- Only called for closures with no args
625
626 blackHoleIt closure_info node_points
627   = if blackHoleOnEntry closure_info && node_points
628     then
629         let
630           info_label = infoTableLabelFromCI closure_info
631           args = [ CLbl info_label DataPtrRep ]
632         in
633         absC (if closureSingleEntry(closure_info) then
634                 CMacroStmt UPD_BH_SINGLE_ENTRY args
635               else
636                 CMacroStmt UPD_BH_UPDATABLE args)
637     else
638         nopC
639 \end{code}
640
641 \begin{code}
642 setupUpdate :: ClosureInfo -> Code -> Code      -- Only called for closures with no args
643         -- Nota Bene: this function does not change Node (even if it's a CAF),
644         -- so that the cost centre in the original closure can still be
645         -- extracted by a subsequent ENTER_CC_TCL
646
647 -- I've tidied up the code for this function, but it should still do the same as
648 -- it did before (modulo ticky stuff).  KSW 1999-04.
649 setupUpdate closure_info code
650  = if closureReEntrant closure_info
651    then
652      code
653    else
654      case (closureUpdReqd closure_info, isStaticClosure closure_info) of
655        (False,False) -> profCtrC SLIT("TICK_UPDF_OMITTED") [] `thenC`
656                         code
657        (False,True ) -> (if opt_DoTickyProfiling
658                          then
659                          -- blackhole the SE CAF
660                            link_caf seCafBlackHoleClosureInfo `thenFC` \ _ -> nopC
661                          else
662                            nopC)                                                       `thenC`
663                         profCtrC SLIT("TICK_UPD_CAF_BH_SINGLE_ENTRY") [mkCString cl_name] `thenC`
664                         profCtrC SLIT("TICK_UPDF_OMITTED") []                           `thenC`
665                         code
666        (True ,False) -> pushUpdateFrame (CReg node) code
667        (True ,True ) -> -- blackhole the (updatable) CAF:
668                         link_caf cafBlackHoleClosureInfo           `thenFC` \ update_closure ->
669                         profCtrC SLIT("TICK_UPD_CAF_BH_UPDATABLE") [mkCString cl_name]    `thenC`
670                         pushUpdateFrame update_closure code
671  where
672    cl_name :: FAST_STRING
673    cl_name  = (occNameFS . nameOccName . closureName) closure_info
674
675    link_caf :: (ClosureInfo -> ClosureInfo)  -- function yielding BH closure_info
676             -> FCode CAddrMode               -- Returns amode for closure to be updated
677    link_caf bhCI
678      = -- To update a CAF we must allocate a black hole, link the CAF onto the
679        -- CAF list, then update the CAF to point to the fresh black hole.
680        -- This function returns the address of the black hole, so it can be
681        -- updated with the new value when available.
682
683              -- Alloc black hole specifying CC_HDR(Node) as the cost centre
684        let
685            use_cc   = CMacroExpr PtrRep CCS_HDR [nodeReg]
686            blame_cc = use_cc
687        in
688        allocDynClosure (bhCI closure_info) use_cc blame_cc []  `thenFC` \ heap_offset ->
689        getHpRelOffset heap_offset                              `thenFC` \ hp_rel ->
690        let  amode = CAddr hp_rel
691        in
692        absC (CMacroStmt UPD_CAF [CReg node, amode])            `thenC`
693        returnFC amode
694 \end{code}
695
696 %************************************************************************
697 %*                                                                      *
698 \subsection[CgClosure-Description]{Profiling Closure Description.}
699 %*                                                                      *
700 %************************************************************************
701
702 For "global" data constructors the description is simply occurrence
703 name of the data constructor itself (see \ref{CgConTbls-info-tables}).
704
705 Otherwise it is determind by @closureDescription@ from the let
706 binding information.
707
708 \begin{code}
709 closureDescription :: Module            -- Module
710                    -> Name              -- Id of closure binding
711                    -> String
712
713         -- Not called for StgRhsCon which have global info tables built in
714         -- CgConTbls.lhs with a description generated from the data constructor
715
716 closureDescription mod_name name
717   = showSDoc (
718         hcat [char '<',
719                    pprModule mod_name,
720                    char '.',
721                    ppr name,
722                    char '>'])
723 \end{code}
724
725 \begin{code}
726 chooseDynCostCentres ccs args fvs body
727   = let
728         use_cc -- cost-centre we record in the object
729           = if currentOrSubsumedCCS ccs
730             then CReg CurCostCentre
731             else mkCCostCentreStack ccs
732
733         blame_cc -- cost-centre on whom we blame the allocation
734           = case (args, fvs, body) of
735               ([], _, StgApp fun [{-no args-}])
736                 -> mkCCostCentreStack overheadCCS
737               _ -> use_cc
738
739             -- if it's an utterly trivial RHS, then it must be
740             -- one introduced by boxHigherOrderArgs for profiling,
741             -- so we charge it to "OVERHEAD".
742
743             -- This looks like a HACK to me --SDM
744     in
745     (use_cc, blame_cc)
746 \end{code}