2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1994
4 \section[CgUpdate]{Manipulating update frames}
7 #include "HsVersions.h"
10 pushUpdateFrame -- OLD: , evalPushRCCFrame
17 import CgCompInfo ( sTD_UF_SIZE, cON_UF_SIZE,
18 sCC_STD_UF_SIZE, sCC_CON_UF_SIZE,
19 spARelToInt, spBRelToInt
21 import CgStackery ( allocUpdateFrame )
23 import CmdLineOpts ( GlobalSwitch(..) )
28 %********************************************************
30 %* Setting up update frames *
32 %********************************************************
33 \subsection[setting-update-frames]{Setting up update frames}
35 @pushUpdateFrame@ $updatee$ pushes a general update frame which
36 points to $updatee$ as the thing to be updated. It is only used
37 when a thunk has just been entered, so the (real) stack pointers
38 are guaranteed to be nicely aligned with the top of stack.
39 @pushUpdateFrame@ adjusts the virtual and tail stack pointers
40 to reflect the frame pushed.
43 pushUpdateFrame :: CAddrMode -> CAddrMode -> Code -> Code
45 pushUpdateFrame updatee vector code
46 = isSwitchSetC SccProfilingOn `thenFC` \ profiling_on ->
48 -- frame_size *includes* the return address
49 frame_size = if profiling_on
53 getEndOfBlockInfo `thenFC` \ eob_info ->
54 ASSERT(case eob_info of { EndOfBlockInfo _ _ InRetReg -> True; _ -> False})
55 allocUpdateFrame frame_size vector (\ _ ->
57 -- Emit the push macro
58 absC (CMacroStmt PUSH_STD_UPD_FRAME [
60 int_CLit0, -- Known to be zero because we have just
61 int_CLit0 -- entered a thunk
66 int_CLit0 = mkIntCLit 0 -- out here to avoid pushUpdateFrame CAF (sigh)
68 {- ---------------------
69 What actually happens is something like this; but it got macro-ised
71 = pushOnBStack (CReg CurCostCentre) `thenFC` \ _ ->
72 pushOnBStack (CReg SuA) `thenFC` \ _ ->
73 pushOnBStack (CReg SuB) `thenFC` \ _ ->
74 pushOnBStack updatee `thenFC` \ _ ->
75 pushOnBStack (CLabel sTD_UPD_RET_VEC_LABEL CodePtrKind) `thenFC` \ _ ->
77 -- MAKE SuA, SuB POINT TO TOP OF A,B STACKS
78 -- Remember, SpB hasn't yet been incremented to account for the
79 -- 4-word update frame which has been pushed.
80 -- This code seems crude, but effective...
81 absC (AbsCStmts (CAssign (CReg SuA) (CReg SpA))
82 (CAssign (CReg SuB) (CAddr (SpBRel 0 4))))
83 -------------------------- -}
86 @evalPushRCCFrame@ pushes a frame to restore the cost centre, and
87 deallocates stuff from the A and B stack if evaluation profiling. No
88 actual update is required so no closure to update is passed.
89 @evalPushRCCFrame@ is called for an @scc@ expression and on entry to a
90 single-entry thunk: no update reqd but cost centre manipulation is.
95 evalPushRCCFrame :: Bool -> Code -> Code
97 evalPushRCCFrame prim code
98 = isSwitchSetC SccProfiling_Eval `thenFC` \ eval_profiling ->
100 if (not eval_profiling) then
104 -- Find out how many words of stack must will be
105 -- deallocated at the end of the basic block
106 -- As we push stuff onto the B stack we must make the
107 -- RCC frame dealocate the B stack words
109 -- We dont actually push things onto the A stack so we
110 -- can treat the A stack as if these words were not there
111 -- i.e. we subtract them from the A stack offset
112 -- They will be popped by the current block of code
114 -- Tell downstream code about the update frame on the B stack
117 (panic "pushEvalRCCFrame: mkRestoreCostCentreLbl")
118 (\ (old_args_spa, old_args_spb, upd_frame_offset) ->
120 getSpARelOffset old_args_spa `thenFC` \ old_args_spa_rel ->
121 getSpBRelOffset upd_frame_offset `thenFC` \ upd_frame_rel ->
123 let b_wds_to_pop = upd_frame_offset - old_args_spb
126 -- Allocate enough space on the B stack for the frame
130 "PUSH_RCC_FRAME_RETURN"
132 "PUSH_RCC_FRAME_VECTOR")
134 mkIntCLit (spARelToInt old_args_spa_rel),
135 {- Place on A stack to ``draw the line'' -}
136 mkIntCLit (spBRelToInt upd_frame_rel),
137 {- Ditto B stk. The update frame is pushed starting
140 {- Number of words of A below the line, which must be
141 popped to get to the tail-call position -}
142 mkIntCLit b_wds_to_pop
149 -- If we actually pushed things onto the A stack we have
150 -- to arrange for the RCC frame to pop these as well
151 -- Would need to tell downstream code about the update frame
152 -- both the A and B stacks