Change the strategy to determine dynamic data access
[ghc-hetmet.git] / compiler / codeGen / CgTailCall.lhs
1 %
2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 %
5 % Code generation for tail calls.
6
7 \begin{code}
8 module CgTailCall (
9         cgTailCall, performTailCall,
10         performReturn, performPrimReturn,
11         returnUnboxedTuple, ccallReturnUnboxedTuple,
12         pushUnboxedTuple,
13         tailCallPrimOp,
14
15         pushReturnAddress
16     ) where
17
18 #include "HsVersions.h"
19
20 import CgMonad
21 import CgBindery
22 import CgInfoTbls
23 import CgCallConv
24 import CgStackery
25 import CgHeapery
26 import CgUtils
27 import CgTicky
28 import ClosureInfo
29 import SMRep
30 import MachOp
31 import Cmm      
32 import CmmUtils
33 import CLabel
34 import Type
35 import Id
36 import StgSyn
37 import PrimOp
38 import Outputable
39
40 import Control.Monad
41
42 -----------------------------------------------------------------------------
43 -- Tail Calls
44
45 cgTailCall :: Id -> [StgArg] -> Code
46
47 -- Here's the code we generate for a tail call.  (NB there may be no
48 -- arguments, in which case this boils down to just entering a variable.)
49 -- 
50 --    * Put args in the top locations of the stack.
51 --    * Adjust the stack ptr
52 --    * Make R1 point to the function closure if necessary.
53 --    * Perform the call.
54 --
55 -- Things to be careful about:
56 --
57 --    * Don't overwrite stack locations before you have finished with
58 --      them (remember you need the function and the as-yet-unmoved
59 --      arguments).
60 --    * Preferably, generate no code to replace x by x on the stack (a
61 --      common situation in tail-recursion).
62 --    * Adjust the stack high water mark appropriately.
63 -- 
64 -- Treat unboxed locals exactly like literals (above) except use the addr
65 -- mode for the local instead of (CLit lit) in the assignment.
66
67 cgTailCall fun args
68   = do  { fun_info <- getCgIdInfo fun
69
70         ; if isUnLiftedType (idType fun)
71           then  -- Primitive return
72                 ASSERT( null args )
73             do  { fun_amode <- idInfoToAmode fun_info
74                 ; performPrimReturn (cgIdInfoArgRep fun_info) fun_amode } 
75
76           else -- Normal case, fun is boxed
77             do  { arg_amodes <- getArgAmodes args
78                 ; performTailCall fun_info arg_amodes noStmts }
79         }
80                 
81
82 -- -----------------------------------------------------------------------------
83 -- The guts of a tail-call
84
85 performTailCall 
86         :: CgIdInfo             -- The function
87         -> [(CgRep,CmmExpr)]    -- Args
88         -> CmmStmts             -- Pending simultaneous assignments
89                                 --  *** GUARANTEED to contain only stack assignments.
90         -> Code
91
92 performTailCall fun_info arg_amodes pending_assts
93   | Just join_sp <- maybeLetNoEscape fun_info
94   =        -- A let-no-escape is slightly different, because we
95            -- arrange the stack arguments into pointers and non-pointers
96            -- to make the heap check easier.  The tail-call sequence
97            -- is very similar to returning an unboxed tuple, so we
98            -- share some code.
99      do { (final_sp, arg_assts) <- pushUnboxedTuple join_sp arg_amodes
100         ; emitSimultaneously (pending_assts `plusStmts` arg_assts)
101         ; let lbl = enterReturnPtLabel (idUnique (cgIdInfoId fun_info))
102         ; doFinalJump final_sp True {- Is LNE -} (jumpToLbl lbl) }
103
104   | otherwise
105   = do  { fun_amode <- idInfoToAmode fun_info
106         ; let assignSt  = CmmAssign nodeReg fun_amode
107               node_asst = oneStmt assignSt
108               opt_node_asst | nodeMustPointToIt lf_info = node_asst
109                             | otherwise                 = noStmts
110         ; EndOfBlockInfo sp _ <- getEndOfBlockInfo
111         ; this_pkg <- getThisPackage
112
113         ; case (getCallMethod fun_name lf_info (length arg_amodes)) of
114
115             -- Node must always point to things we enter
116             EnterIt -> do
117                 { emitSimultaneously (node_asst `plusStmts` pending_assts) 
118                 ; let target     = entryCode (closureInfoPtr (CmmReg nodeReg))
119                       enterClosure = stmtC (CmmJump target [])
120                       -- If this is a scrutinee
121                       -- let's check if the closure is a constructor
122                       -- so we can directly jump to the alternatives switch
123                       -- statement.
124                       jumpInstr = getEndOfBlockInfo >>=
125                                   maybeSwitchOnCons enterClosure
126                 ; doFinalJump sp False jumpInstr }
127     
128             -- A function, but we have zero arguments.  It is already in WHNF,
129             -- so we can just return it.  
130             -- As with any return, Node must point to it.
131             ReturnIt -> do
132                 { emitSimultaneously (node_asst `plusStmts` pending_assts)
133                 ; doFinalJump sp False emitReturnInstr }
134     
135             -- A real constructor.  Don't bother entering it, 
136             -- just do the right sort of return instead.
137             -- As with any return, Node must point to it.
138             ReturnCon con -> do
139                 { emitSimultaneously (node_asst `plusStmts` pending_assts)
140                 ; doFinalJump sp False emitReturnInstr }
141
142             JumpToIt lbl -> do
143                 { emitSimultaneously (opt_node_asst `plusStmts` pending_assts)
144                 ; doFinalJump sp False (jumpToLbl lbl) }
145     
146             -- A slow function call via the RTS apply routines
147             -- Node must definitely point to the thing
148             SlowCall -> do 
149                 {  when (not (null arg_amodes)) $ do
150                    { if (isKnownFun lf_info) 
151                         then tickyKnownCallTooFewArgs
152                         else tickyUnknownCall
153                    ; tickySlowCallPat (map fst arg_amodes) 
154                    }
155
156                 ; let (apply_lbl, args, extra_args) 
157                         = constructSlowCall arg_amodes
158
159                 ; directCall sp apply_lbl args extra_args 
160                         (node_asst `plusStmts` pending_assts)
161
162                 }
163     
164             -- A direct function call (possibly with some left-over arguments)
165             DirectEntry lbl arity -> do
166                 { if arity == length arg_amodes
167                         then tickyKnownCallExact
168                         else do tickyKnownCallExtraArgs
169                                 tickySlowCallPat (map fst (drop arity arg_amodes))
170
171                 ; let
172                      -- The args beyond the arity go straight on the stack
173                      (arity_args, extra_args) = splitAt arity arg_amodes
174      
175                 ; directCall sp lbl arity_args extra_args
176                         (opt_node_asst `plusStmts` pending_assts)
177                 }
178         }
179   where
180     fun_name  = idName (cgIdInfoId fun_info)
181     lf_info   = cgIdInfoLF fun_info
182     untag_node = CmmAssign nodeReg (cmmUntag (CmmReg nodeReg))
183     -- Test if closure is a constructor
184     maybeSwitchOnCons enterClosure eob
185               | EndOfBlockInfo _ (CaseAlts lbl _ _) <- eob
186               = do { is_constr <- newLabelC
187                    -- Is the pointer tagged?
188                    -- Yes, jump to switch statement
189                    ; stmtC (CmmCondBranch (cmmIsTagged (CmmReg nodeReg)) 
190                                 is_constr)
191                    -- No, enter the closure.
192                    ; enterClosure
193                    ; labelC is_constr
194                    ; stmtC (CmmJump (CmmLit (CmmLabel lbl)) [])
195                    }
196 {-
197               -- This is a scrutinee for a case expression
198               -- so let's see if we can directly inspect the closure
199               | EndOfBlockInfo _ (CaseAlts lbl _ _ _) <- eob
200               = do { no_cons <- newLabelC
201                    -- Both the NCG and gcc optimize away the temp
202                    ; z <- newTemp  wordRep
203                    ; stmtC (CmmAssign z tag_expr)
204                    ; let tag = CmmReg z
205                    -- Is the closure a cons?
206                    ; stmtC (CmmCondBranch (cond1 tag) no_cons)
207                    ; stmtC (CmmCondBranch (cond2 tag) no_cons)
208                    -- Yes, jump to switch statement
209                    ; stmtC (CmmJump (CmmLit (CmmLabel lbl)) [])
210                    ; labelC no_cons
211                    -- No, enter the closure.
212                    ; enterClosure
213                    }
214 -}
215               -- No case expression involved, enter the closure.
216               | otherwise
217               = do { stmtC untag_node
218                    ; enterClosure
219                    }
220         where
221           --cond1 tag  = cmmULtWord tag lowCons
222           -- More efficient than the above?
223           tag_expr   = cmmGetClosureType (CmmReg nodeReg)
224           cond1 tag  = cmmEqWord tag (CmmLit (mkIntCLit 0))
225           cond2 tag  = cmmUGtWord tag highCons
226           lowCons    = CmmLit (mkIntCLit 1)
227             -- CONSTR
228           highCons   = CmmLit (mkIntCLit 8)
229             -- CONSTR_NOCAF_STATIC (from ClosureType.h)
230
231
232 untagCmmAssign (CmmAssign r cmmExpr) = CmmAssign r (cmmUntag cmmExpr)
233 untagCmmAssign stmt                  = stmt
234
235 directCall sp lbl args extra_args assts = do
236   let
237         -- First chunk of args go in registers
238         (reg_arg_amodes, stk_args) = assignCallRegs args
239      
240         -- Any "extra" arguments are placed in frames on the
241         -- stack after the other arguments.
242         slow_stk_args = slowArgs extra_args
243
244         reg_assts = assignToRegs reg_arg_amodes
245   --
246   (final_sp, stk_assts) <- mkStkAmodes sp (stk_args ++ slow_stk_args)
247
248   emitSimultaneously (reg_assts     `plusStmts`
249                       stk_assts     `plusStmts`
250                       assts)
251
252   doFinalJump final_sp False (jumpToLbl lbl)
253
254 -- -----------------------------------------------------------------------------
255 -- The final clean-up before we do a jump at the end of a basic block.
256 -- This code is shared by tail-calls and returns.
257
258 doFinalJump :: VirtualSpOffset -> Bool -> Code -> Code 
259 doFinalJump final_sp is_let_no_escape jump_code
260   = do  { -- Adjust the high-water mark if necessary
261           adjustStackHW final_sp
262
263         -- Push a return address if necessary (after the assignments
264         -- above, in case we clobber a live stack location)
265         --
266         -- DONT push the return address when we're about to jump to a
267         -- let-no-escape: the final tail call in the let-no-escape
268         -- will do this.
269         ; eob <- getEndOfBlockInfo
270         ; whenC (not is_let_no_escape) (pushReturnAddress eob)
271
272             -- Final adjustment of Sp/Hp
273         ; adjustSpAndHp final_sp
274
275             -- and do the jump
276         ; jump_code }
277
278 -- ----------------------------------------------------------------------------
279 -- A general return (just a special case of doFinalJump, above)
280
281 performReturn :: Code   -- The code to execute to actually do the return
282               -> Code
283
284 performReturn finish_code
285   = do  { EndOfBlockInfo args_sp sequel <- getEndOfBlockInfo
286         ; doFinalJump args_sp False{-not a LNE-} finish_code }
287
288 -- ----------------------------------------------------------------------------
289 -- Primitive Returns
290 -- Just load the return value into the right register, and return.
291
292 performPrimReturn :: CgRep -> CmmExpr   -- The thing to return
293                   -> Code
294 performPrimReturn rep amode
295   =  do { whenC (not (isVoidArg rep))
296                 (stmtC (CmmAssign ret_reg amode))
297         ; performReturn emitReturnInstr }
298   where
299     ret_reg = dataReturnConvPrim rep
300
301 -- ---------------------------------------------------------------------------
302 -- Unboxed tuple returns
303
304 -- These are a bit like a normal tail call, except that:
305 --
306 --   - The tail-call target is an info table on the stack
307 --
308 --   - We separate stack arguments into pointers and non-pointers,
309 --     to make it easier to leave things in a sane state for a heap check.
310 --     This is OK because we can never partially-apply an unboxed tuple,
311 --     unlike a function.  The same technique is used when calling
312 --     let-no-escape functions, because they also can't be partially
313 --     applied.
314
315 returnUnboxedTuple :: [(CgRep, CmmExpr)] -> Code
316 returnUnboxedTuple amodes
317   = do  { eob@(EndOfBlockInfo args_sp sequel) <- getEndOfBlockInfo
318         ; tickyUnboxedTupleReturn (length amodes)
319         ; (final_sp, assts) <- pushUnboxedTuple args_sp amodes
320         ; emitSimultaneously assts
321         ; doFinalJump final_sp False{-not a LNE-} emitReturnInstr }
322
323 pushUnboxedTuple :: VirtualSpOffset             -- Sp at which to start pushing
324                  -> [(CgRep, CmmExpr)]          -- amodes of the components
325                  -> FCode (VirtualSpOffset,     -- final Sp
326                            CmmStmts)            -- assignments (regs+stack)
327
328 pushUnboxedTuple sp [] 
329   = return (sp, noStmts)
330 pushUnboxedTuple sp amodes
331   = do  { let   (reg_arg_amodes, stk_arg_amodes) = assignReturnRegs amodes
332         
333                 -- separate the rest of the args into pointers and non-pointers
334                 (ptr_args, nptr_args) = separateByPtrFollowness stk_arg_amodes
335                 reg_arg_assts = assignToRegs reg_arg_amodes
336                 
337             -- push ptrs, then nonptrs, on the stack
338         ; (ptr_sp,   ptr_assts)  <- mkStkAmodes sp ptr_args
339         ; (final_sp, nptr_assts) <- mkStkAmodes ptr_sp nptr_args
340
341         ; returnFC (final_sp,
342                     reg_arg_assts `plusStmts` 
343                     ptr_assts `plusStmts` nptr_assts) }
344     
345                   
346 -- -----------------------------------------------------------------------------
347 -- Returning unboxed tuples.  This is mainly to support _ccall_GC_, where
348 -- we want to do things in a slightly different order to normal:
349 -- 
350 --              - push return address
351 --              - adjust stack pointer
352 --              - r = call(args...)
353 --              - assign regs for unboxed tuple (usually just R1 = r)
354 --              - return to continuation
355 -- 
356 -- The return address (i.e. stack frame) must be on the stack before
357 -- doing the call in case the call ends up in the garbage collector.
358 -- 
359 -- Sadly, the information about the continuation is lost after we push it
360 -- (in order to avoid pushing it again), so we end up doing a needless
361 -- indirect jump (ToDo).
362
363 ccallReturnUnboxedTuple :: [(CgRep, CmmExpr)] -> Code -> Code
364 ccallReturnUnboxedTuple amodes before_jump
365   = do  { eob@(EndOfBlockInfo args_sp _) <- getEndOfBlockInfo
366
367         -- Push a return address if necessary
368         ; pushReturnAddress eob
369         ; setEndOfBlockInfo (EndOfBlockInfo args_sp OnStack)
370             (do { adjustSpAndHp args_sp
371                 ; before_jump
372                 ; returnUnboxedTuple amodes })
373     }
374
375 -- -----------------------------------------------------------------------------
376 -- Calling an out-of-line primop
377
378 tailCallPrimOp :: PrimOp -> [StgArg] -> Code
379 tailCallPrimOp op args
380  = do   {       -- We're going to perform a normal-looking tail call, 
381                 -- except that *all* the arguments will be in registers.
382                 -- Hence the ASSERT( null leftovers )
383           arg_amodes <- getArgAmodes args
384         ; let (arg_regs, leftovers) = assignPrimOpCallRegs arg_amodes
385               jump_to_primop = jumpToLbl (mkRtsPrimOpLabel op)
386
387         ; ASSERT(null leftovers) -- no stack-resident args
388           emitSimultaneously (assignToRegs arg_regs)
389
390         ; EndOfBlockInfo args_sp _ <- getEndOfBlockInfo
391         ; doFinalJump args_sp False{-not a LNE-} jump_to_primop }
392
393 -- -----------------------------------------------------------------------------
394 -- Return Addresses
395
396 -- We always push the return address just before performing a tail call
397 -- or return.  The reason we leave it until then is because the stack
398 -- slot that the return address is to go into might contain something
399 -- useful.
400 -- 
401 -- If the end of block info is 'CaseAlts', then we're in the scrutinee of a
402 -- case expression and the return address is still to be pushed.
403 -- 
404 -- There are cases where it doesn't look necessary to push the return
405 -- address: for example, just before doing a return to a known
406 -- continuation.  However, the continuation will expect to find the
407 -- return address on the stack in case it needs to do a heap check.
408
409 pushReturnAddress :: EndOfBlockInfo -> Code
410
411 pushReturnAddress (EndOfBlockInfo args_sp sequel@(CaseAlts lbl _ _))
412   = do  { sp_rel <- getSpRelOffset args_sp
413         ; stmtC (CmmStore sp_rel (mkLblExpr lbl)) }
414
415 pushReturnAddress _ = nopC
416
417 -- -----------------------------------------------------------------------------
418 -- Misc.
419
420 jumpToLbl :: CLabel -> Code
421 -- Passes no argument to the destination procedure
422 jumpToLbl lbl = stmtC (CmmJump (CmmLit (CmmLabel lbl)) [{- No args -}])
423
424 assignToRegs :: [(CmmExpr, GlobalReg)] -> CmmStmts
425 assignToRegs reg_args 
426   = mkStmts [ CmmAssign (CmmGlobal reg_id) expr
427             | (expr, reg_id) <- reg_args ] 
428 \end{code}
429
430
431 %************************************************************************
432 %*                                                                      *
433 \subsection[CgStackery-adjust]{Adjusting the stack pointers}
434 %*                                                                      *
435 %************************************************************************
436
437 This function adjusts the stack and heap pointers just before a tail
438 call or return.  The stack pointer is adjusted to its final position
439 (i.e. to point to the last argument for a tail call, or the activation
440 record for a return).  The heap pointer may be moved backwards, in
441 cases where we overallocated at the beginning of the basic block (see
442 CgCase.lhs for discussion).
443
444 These functions {\em do not} deal with high-water-mark adjustment.
445 That's done by functions which allocate stack space.
446
447 \begin{code}
448 adjustSpAndHp :: VirtualSpOffset        -- New offset for Arg stack ptr
449               -> Code
450 adjustSpAndHp newRealSp 
451   = do  { -- Adjust stack, if necessary.
452           -- NB: the conditional on the monad-carried realSp
453           --     is out of line (via codeOnly), to avoid a black hole
454         ; new_sp <- getSpRelOffset newRealSp
455         ; checkedAbsC (CmmAssign spReg new_sp)  -- Will generate no code in the case
456         ; setRealSp newRealSp                   -- where realSp==newRealSp
457
458           -- Adjust heap.  The virtual heap pointer may be less than the real Hp
459           -- because the latter was advanced to deal with the worst-case branch
460           -- of the code, and we may be in a better-case branch.  In that case,
461           -- move the real Hp *back* and retract some ticky allocation count.
462         ; hp_usg <- getHpUsage
463         ; let rHp = realHp hp_usg
464               vHp = virtHp hp_usg
465         ; new_hp <- getHpRelOffset vHp
466         ; checkedAbsC (CmmAssign hpReg new_hp)  -- Generates nothing when vHp==rHp
467         ; tickyAllocHeap (vHp - rHp)            -- ...ditto
468         ; setRealHp vHp
469         }
470 \end{code}