136814ab26dd9076eca6bf76a23dd0e7ea129cc1
[ghc-hetmet.git] / ghc / compiler / codeGen / CgTailCall.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 %********************************************************
5 %*                                                      *
6 \section[CgTailCall]{Tail calls: converting @StgApps@}
7 %*                                                      *
8 %********************************************************
9
10 \begin{code}
11 #include "HsVersions.h"
12
13 module CgTailCall (
14         cgTailCall,
15         performReturn,
16         mkStaticAlgReturnCode, mkDynamicAlgReturnCode,
17         mkPrimReturnCode,
18
19         tailCallBusiness
20     ) where
21
22 IMP_Ubiq(){-uitous-}
23
24 import CgMonad
25 import AbsCSyn
26
27 import AbsCUtils        ( mkAbstractCs, mkAbsCStmts, getAmodeRep )
28 import CgBindery        ( getArgAmodes, getCAddrMode, getCAddrModeAndInfo )
29 import CgRetConv        ( dataReturnConvPrim, dataReturnConvAlg,
30                           ctrlReturnConvAlg, CtrlReturnConvention(..),
31                           DataReturnConvention(..)
32                         )
33 import CgStackery       ( adjustRealSps, mkStkAmodes )
34 import CgUsages         ( getSpARelOffset )
35 import CLabel           ( mkStdUpdCodePtrVecLabel, mkConUpdCodePtrVecLabel )
36 import ClosureInfo      ( nodeMustPointToIt,
37                           getEntryConvention, EntryConvention(..),
38                           LambdaFormInfo
39                         )
40 import CmdLineOpts      ( opt_DoSemiTagging )
41 import HeapOffs         ( zeroOff, SYN_IE(VirtualSpAOffset) )
42 import Id               ( idType, dataConTyCon, dataConTag,
43                           fIRST_TAG
44                         )
45 import Literal          ( mkMachInt )
46 import Maybes           ( assocMaybe )
47 import PrimRep          ( PrimRep(..) )
48 import StgSyn           ( SYN_IE(StgArg), GenStgArg(..), SYN_IE(StgLiveVars) )
49 import Type             ( isPrimType )
50 import Util             ( zipWithEqual, panic, assertPanic )
51 \end{code}
52
53 %************************************************************************
54 %*                                                                      *
55 \subsection[tailcall-doc]{Documentation}
56 %*                                                                      *
57 %************************************************************************
58
59 \begin{code}
60 cgTailCall :: StgArg -> [StgArg] -> StgLiveVars -> Code
61 \end{code}
62
63 Here's the code we generate for a tail call.  (NB there may be no
64 arguments, in which case this boils down to just entering a variable.)
65
66 \begin{itemize}
67 \item   Adjust the stack ptr to \tr{tailSp + #args}.
68 \item   Put args in the top locations of the resulting stack.
69 \item   Make Node point to the function closure.
70 \item   Enter the function closure.
71 \end{itemize}
72
73 Things to be careful about:
74 \begin{itemize}
75 \item   Don't overwrite stack locations before you have finished with
76         them (remember you need the function and the as-yet-unmoved
77         arguments).
78 \item   Preferably, generate no code to replace x by x on the stack (a
79         common situation in tail-recursion).
80 \item   Adjust the stack high water mark appropriately.
81 \end{itemize}
82
83 \begin{code}
84 cgTailCall (StgConArg con) args live_vars
85   = panic "cgTailCall StgConArg"        -- Only occur in argument positions
86 \end{code}
87
88 Literals are similar to constructors; they return by putting
89 themselves in an appropriate register and returning to the address on
90 top of the B stack.
91
92 \begin{code}
93 cgTailCall (StgLitArg lit) [] live_vars
94   = performPrimReturn (CLit lit) live_vars
95 \end{code}
96
97 Treat unboxed locals exactly like literals (above) except use the addr
98 mode for the local instead of (CLit lit) in the assignment.
99
100 Case for unboxed @Ids@ first:
101 \begin{code}
102 cgTailCall atom@(StgVarArg fun) [] live_vars
103   | isPrimType (idType fun)
104   = getCAddrMode fun `thenFC` \ amode ->
105     performPrimReturn amode live_vars
106 \end{code}
107
108 The general case (@fun@ is boxed):
109 \begin{code}
110 cgTailCall (StgVarArg fun) args live_vars = performTailCall fun args live_vars
111 \end{code}
112
113 %************************************************************************
114 %*                                                                      *
115 \subsection[return-and-tail-call]{Return and tail call}
116 %*                                                                      *
117 %************************************************************************
118
119 ADR-HACK
120
121   A quick bit of hacking to try to solve my void#-leaking blues...
122
123   I think I'm getting bitten by this stuff because code like
124
125   \begin{pseudocode}
126           case ds.s12 :: IoWorld of {
127               -- lvs: [ds.s12]; rhs lvs: []; uniq: c0
128             IoWorld ds.s13# -> ds.s13#;
129           } :: Universe#
130   \end{pseudocode}
131
132   causes me to try to allocate a register to return the result in.  The
133   hope is that the following will avoid such problems (and that Will
134   will do this in a cleaner way when he hits the same problem).
135
136 KCAH-RDA
137
138 \begin{code}
139 performPrimReturn :: CAddrMode  -- The thing to return
140                   -> StgLiveVars
141                   -> Code
142
143 performPrimReturn amode live_vars
144   = let
145         kind = getAmodeRep amode
146         ret_reg = dataReturnConvPrim kind
147
148         assign_possibly = case kind of
149           VoidRep -> AbsCNop
150           kind -> (CAssign (CReg ret_reg) amode)
151     in
152     performReturn assign_possibly mkPrimReturnCode live_vars
153
154 mkPrimReturnCode :: Sequel -> Code
155 mkPrimReturnCode (UpdateCode _) = panic "mkPrimReturnCode: Upd"
156 mkPrimReturnCode sequel         = sequelToAmode sequel  `thenFC` \ dest_amode ->
157                                   absC (CReturn dest_amode DirectReturn)
158                                   -- Direct, no vectoring
159
160 -- All constructor arguments in registers; Node and InfoPtr are set.
161 -- All that remains is
162 --      (a) to set TagReg, if necessary
163 --      (b) to set InfoPtr to the info ptr, if necessary
164 --      (c) to do the right sort of jump.
165
166 mkStaticAlgReturnCode :: Id             -- The constructor
167                       -> Maybe CLabel   -- The info ptr, if it isn't already set
168                       -> Sequel         -- where to return to
169                       -> Code
170
171 mkStaticAlgReturnCode con maybe_info_lbl sequel
172   =     -- Generate profiling code if necessary
173     (case return_convention of
174         VectoredReturn sz -> profCtrC SLIT("VEC_RETURN") [mkIntCLit sz]
175         other             -> nopC
176     )                                   `thenC`
177
178         -- Set tag if necessary
179         -- This is done by a macro, because if we are short of registers
180         -- we don't set TagReg; instead the continuation gets the tag
181         -- by indexing off the info ptr
182     (case return_convention of
183
184         UnvectoredReturn no_of_constrs
185          | no_of_constrs > 1
186                 -> absC (CMacroStmt SET_TAG [mkIntCLit zero_indexed_tag])
187
188         other   -> nopC
189     )                                   `thenC`
190
191         -- Generate the right jump or return
192     (case sequel of
193         UpdateCode _ -> -- Ha!  We know the constructor,
194                         -- so we can go direct to the correct
195                         -- update code for that constructor
196
197                                 -- Set the info pointer, and jump
198                         set_info_ptr            `thenC`
199                         absC (CJump (CLbl update_label CodePtrRep))
200
201         CaseAlts _ (Just (alts, _)) ->  -- Ho! We know the constructor so
202                                         -- we can go right to the alternative
203
204                         -- No need to set info ptr when returning to a
205                         -- known join point. After all, the code at
206                         -- the destination knows what constructor it
207                         -- is going to handle.
208
209                         case assocMaybe alts tag of
210                            Just (alt_absC, join_lbl) -> absC (CJump (CLbl join_lbl CodePtrRep))
211                            Nothing                   -> panic "mkStaticAlgReturnCode: default"
212                                 -- The Nothing case should never happen; it's the subject
213                                 -- of a wad of special-case code in cgReturnCon
214
215         other ->        -- OnStack, or (CaseAlts) ret_amode Nothing)
216                         -- Set the info pointer, and jump
217                     set_info_ptr                `thenC`
218                     sequelToAmode sequel        `thenFC` \ ret_amode ->
219                     absC (CReturn ret_amode return_info)
220     )
221
222   where
223     tag               = dataConTag   con
224     tycon             = dataConTyCon con
225     return_convention = ctrlReturnConvAlg tycon
226     zero_indexed_tag  = tag - fIRST_TAG       -- Adjust tag to be zero-indexed
227                                               -- cf AbsCUtils.mkAlgAltsCSwitch
228
229     update_label
230       = case (dataReturnConvAlg con) of
231           ReturnInHeap   -> mkStdUpdCodePtrVecLabel tycon tag
232           ReturnInRegs _ -> mkConUpdCodePtrVecLabel tycon tag
233
234     return_info = case return_convention of
235                         UnvectoredReturn _ -> DirectReturn
236                         VectoredReturn _   -> StaticVectoredReturn zero_indexed_tag
237
238     set_info_ptr = case maybe_info_lbl of
239                         Nothing       -> nopC
240                         Just info_lbl -> absC (CAssign (CReg infoptr) (CLbl info_lbl DataPtrRep))
241
242
243 mkDynamicAlgReturnCode :: TyCon -> CAddrMode -> Sequel -> Code
244
245 mkDynamicAlgReturnCode tycon dyn_tag sequel
246   = case ctrlReturnConvAlg tycon of
247         VectoredReturn sz ->
248
249                 profCtrC SLIT("VEC_RETURN") [mkIntCLit sz] `thenC`
250                 sequelToAmode sequel            `thenFC` \ ret_addr ->
251                 absC (CReturn ret_addr (DynamicVectoredReturn dyn_tag))
252
253         UnvectoredReturn no_of_constrs ->
254
255                 -- Set tag if necessary
256                 -- This is done by a macro, because if we are short of registers
257                 -- we don't set TagReg; instead the continuation gets the tag
258                 -- by indexing off the info ptr
259                 (if no_of_constrs > 1 then
260                         absC (CMacroStmt SET_TAG [dyn_tag])
261                 else
262                         nopC
263                 )                       `thenC`
264
265
266                 sequelToAmode sequel            `thenFC` \ ret_addr ->
267                 -- Generate the right jump or return
268                 absC (CReturn ret_addr DirectReturn)
269 \end{code}
270
271 \begin{code}
272 performReturn :: AbstractC          -- Simultaneous assignments to perform
273               -> (Sequel -> Code)   -- The code to execute to actually do
274                                     -- the return, given an addressing mode
275                                     -- for the return address
276               -> StgLiveVars
277               -> Code
278
279 performReturn sim_assts finish_code live_vars
280   = getEndOfBlockInfo   `thenFC` \ (EndOfBlockInfo args_spa args_spb sequel) ->
281
282         -- Do the simultaneous assignments,
283     doSimAssts args_spa live_vars sim_assts     `thenC`
284
285         -- Adjust stack pointers
286     adjustRealSps args_spa args_spb     `thenC`
287
288         -- Do the return
289     finish_code sequel          -- "sequel" is `robust' in that it doesn't
290                                 -- depend on stk-ptr values
291 \end{code}
292
293 \begin{code}
294 performTailCall :: Id                   -- Function
295                 -> [StgArg]     -- Args
296                 -> StgLiveVars
297                 -> Code
298
299 performTailCall fun args live_vars
300   =     -- Get all the info we have about the function and args and go on to
301         -- the business end
302     getCAddrModeAndInfo fun     `thenFC` \ (fun_amode, lf_info) ->
303     getArgAmodes args           `thenFC` \ arg_amodes ->
304
305     tailCallBusiness
306                 fun fun_amode lf_info arg_amodes
307                 live_vars AbsCNop {- No pending assignments -}
308
309
310 tailCallBusiness :: Id -> CAddrMode     -- Function and its amode
311                  -> LambdaFormInfo      -- Info about the function
312                  -> [CAddrMode]         -- Arguments
313                  -> StgLiveVars -- Live in continuation
314
315                  -> AbstractC           -- Pending simultaneous assignments
316                                         -- *** GUARANTEED to contain only stack assignments.
317                                         --     In ptic, we don't need to look in here to
318                                         --     discover all live regs
319
320                  -> Code
321
322 tailCallBusiness fun fun_amode lf_info arg_amodes live_vars pending_assts
323   = nodeMustPointToIt lf_info                   `thenFC` \ node_points ->
324     getEntryConvention fun lf_info
325         (map getAmodeRep arg_amodes)            `thenFC` \ entry_conv ->
326
327     getEndOfBlockInfo   `thenFC` \ (EndOfBlockInfo args_spa args_spb sequel) ->
328
329     let
330         node_asst
331           = if node_points then
332                 CAssign (CReg node) fun_amode
333             else
334                 AbsCNop
335
336         (arg_regs, finish_code)
337           = case entry_conv of
338               ViaNode                     ->
339                 ([],
340                      mkAbstractCs [
341                         CCallProfCtrMacro SLIT("ENT_VIA_NODE") [],
342                         CJump (CMacroExpr CodePtrRep ENTRY_CODE [(CMacroExpr DataPtrRep INFO_PTR [CReg node])])
343                      ])
344               StdEntry lbl Nothing        -> ([], CJump (CLbl lbl CodePtrRep))
345               StdEntry lbl (Just itbl)    -> ([], CAssign (CReg infoptr) (CLbl itbl DataPtrRep)
346                                                      `mkAbsCStmts`
347                                                   CJump (CLbl lbl CodePtrRep))
348               DirectEntry lbl arity regs  ->
349                 (regs,   CJump (CLbl lbl CodePtrRep))
350
351         no_of_args = length arg_amodes
352
353         (reg_arg_amodes, stk_arg_amodes) = splitAt (length arg_regs) arg_amodes
354             -- We get some stk_arg_amodes if (a) no regs, or (b) args beyond arity
355
356         reg_arg_assts
357           = mkAbstractCs (zipWithEqual "assign_to_reg2" assign_to_reg arg_regs reg_arg_amodes)
358
359         assign_to_reg reg_id amode = CAssign (CReg reg_id) amode
360     in
361     case fun_amode of
362       CJoinPoint join_spa join_spb ->  -- Ha!  A let-no-escape thingy
363
364           ASSERT(not (args_spa > join_spa) || (args_spb > join_spb))
365               -- If ASSERTion fails: Oops: the join point has *lower*
366               -- stack ptrs than the continuation Note that we take
367               -- the SpB point without the return address here.  The
368               -- return address is put on by the let-no-escapey thing
369               -- when it finishes.
370
371           mkStkAmodes join_spa join_spb stk_arg_amodes
372                       `thenFC` \ (final_spa, final_spb, stk_arg_assts) ->
373
374                 -- Do the simultaneous assignments,
375           doSimAssts join_spa live_vars
376                 (mkAbstractCs [pending_assts, reg_arg_assts, stk_arg_assts])
377                         `thenC`
378
379                 -- Adjust stack ptrs
380           adjustRealSps final_spa final_spb     `thenC`
381
382                 -- Jump to join point
383           absC finish_code
384
385       _ -> -- else: not a let-no-escape (the common case)
386
387                 -- Make instruction to save return address
388             loadRetAddrIntoRetReg sequel        `thenFC` \ ret_asst ->
389
390             mkStkAmodes args_spa args_spb stk_arg_amodes
391                                                 `thenFC`
392                             \ (final_spa, final_spb, stk_arg_assts) ->
393
394                 -- The B-stack space for the pushed return addess, with any args pushed
395                 -- on top, is recorded in final_spb.
396
397                 -- Do the simultaneous assignments,
398             doSimAssts args_spa live_vars
399                 (mkAbstractCs [pending_assts, node_asst, ret_asst,
400                                reg_arg_assts, stk_arg_assts])
401                                                 `thenC`
402
403                 -- Final adjustment of stack pointers
404             adjustRealSps final_spa final_spb   `thenC`
405
406                 -- Now decide about semi-tagging
407             let
408                 semi_tagging_on = opt_DoSemiTagging
409             in
410             case (semi_tagging_on, arg_amodes, node_points, sequel) of
411
412         --
413         -- *************** The semi-tagging case ***************
414         --
415               (   True,            [],          True,        CaseAlts _ (Just (st_alts, maybe_deflt_join_details))) ->
416
417                 -- Whoppee!  Semi-tagging rules OK!
418                 -- (a) semi-tagging is switched on
419                 -- (b) there are no arguments,
420                 -- (c) Node points to the closure
421                 -- (d) we have a case-alternative sequel with
422                 --      some visible alternatives
423
424                 -- Why is test (c) necessary?
425                 -- Usually Node will point to it at this point, because we're
426                 -- scrutinsing something which is either a thunk or a
427                 -- constructor.
428                 -- But not always!  The example I came across is when we have
429                 -- a top-level Double:
430                 --      lit.3 = D# 3.000
431                 --      ... (case lit.3 of ...) ...
432                 -- Here, lit.3 is built as a re-entrant thing, which you must enter.
433                 -- (OK, the simplifier should have eliminated this, but it's
434                 --  easy to deal with the case anyway.)
435                 let
436                     join_details_to_code (load_regs_and_profiling_code, join_lbl)
437                         = load_regs_and_profiling_code          `mkAbsCStmts`
438                           CJump (CLbl join_lbl CodePtrRep)
439
440                     semi_tagged_alts = [ (mkMachInt (toInteger (tag - fIRST_TAG)),
441                                           join_details_to_code join_details)
442                                        | (tag, join_details) <- st_alts
443                                        ]
444
445                     enter_jump
446                       -- Enter Node (we know infoptr will have the info ptr in it)!
447                       = mkAbstractCs [
448                         CCallProfCtrMacro SLIT("RET_SEMI_FAILED")
449                                         [CMacroExpr IntRep INFO_TAG [CReg infoptr]],
450                         CJump (CMacroExpr CodePtrRep ENTRY_CODE [CReg infoptr]) ]
451                 in
452                         -- Final switch
453                 absC (mkAbstractCs [
454                             CAssign (CReg infoptr)
455                                     (CVal (NodeRel zeroOff) DataPtrRep),
456
457                             case maybe_deflt_join_details of
458                                 Nothing ->
459                                     CSwitch (CMacroExpr IntRep INFO_TAG [CReg infoptr])
460                                         (semi_tagged_alts)
461                                         (enter_jump)
462                                 Just (_, details) ->
463                                     CSwitch (CMacroExpr IntRep EVAL_TAG [CReg infoptr])
464                                      [(mkMachInt 0, enter_jump)]
465                                      (CSwitch
466                                          (CMacroExpr IntRep INFO_TAG [CReg infoptr])
467                                          (semi_tagged_alts)
468                                          (join_details_to_code details))
469                 ])
470
471         --
472         -- *************** The non-semi-tagging case ***************
473         --
474               other -> absC finish_code
475 \end{code}
476
477 \begin{code}
478 loadRetAddrIntoRetReg :: Sequel -> FCode AbstractC
479
480 loadRetAddrIntoRetReg InRetReg
481   = returnFC AbsCNop  -- Return address already there
482
483 loadRetAddrIntoRetReg sequel
484   = sequelToAmode sequel      `thenFC` \ amode ->
485     returnFC (CAssign (CReg RetReg) amode)
486
487 \end{code}
488
489 %************************************************************************
490 %*                                                                      *
491 \subsection[doSimAssts]{@doSimAssts@}
492 %*                                                                      *
493 %************************************************************************
494
495 @doSimAssts@ happens at the end of every block of code.
496 They are separate because we sometimes do some jiggery-pokery in between.
497
498 \begin{code}
499 doSimAssts :: VirtualSpAOffset  -- tail_spa: SpA as seen by continuation
500            -> StgLiveVars       -- Live in continuation
501            -> AbstractC
502            -> Code
503
504 doSimAssts tail_spa live_vars sim_assts
505   =     -- Do the simultaneous assignments
506     absC (CSimultaneous sim_assts)      `thenC`
507
508         -- Stub any unstubbed slots; the only live variables are indicated in
509         -- the end-of-block info in the monad
510     nukeDeadBindings live_vars          `thenC`
511     getUnstubbedAStackSlots tail_spa    `thenFC` \ a_slots ->
512         -- Passing in tail_spa here should actually be redundant, because
513         -- the stack should be trimmed (by nukeDeadBindings) to
514         -- exactly the tail_spa position anyhow.
515
516         -- Emit code to stub dead regs; this only generates actual
517         -- machine instructions in in the DEBUG version
518         -- *** NOT DONE YET ***
519
520     (if (null a_slots)
521      then nopC
522      else profCtrC SLIT("A_STK_STUB") [mkIntCLit (length a_slots)]      `thenC`
523           mapCs stub_A_slot a_slots
524     )
525   where
526     stub_A_slot :: VirtualSpAOffset -> Code
527     stub_A_slot offset = getSpARelOffset offset         `thenFC` \ spa_rel ->
528                          absC (CAssign  (CVal spa_rel PtrRep)
529                                         (CReg StkStubReg))
530 \end{code}