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