305a28332d3b669f3eefe2c9de686c6ebeab93d2
[ghc-hetmet.git] / ghc / compiler / codeGen / CgCase.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 %********************************************************
5 %*                                                      *
6 \section[CgCase]{Converting @StgCase@ expressions}
7 %*                                                      *
8 %********************************************************
9
10 \begin{code}
11 module CgCase ( cgCase, saveVolatileVarsAndRegs ) where
12
13 #include "HsVersions.h"
14
15 import {-# SOURCE #-} CgExpr
16
17 import CgMonad
18 import StgSyn
19 import AbsCSyn
20
21 import AbsCUtils        ( mkAbstractCs, mkAbsCStmts, mkAlgAltsCSwitch,
22                           magicIdPrimRep, getAmodeRep
23                         )
24 import CgBindery        ( getVolatileRegs, getArgAmode, getArgAmodes,
25                           bindNewToReg, bindNewToTemp,
26                           bindNewPrimToAmode,
27                           rebindToAStack, rebindToBStack,
28                           getCAddrModeAndInfo, getCAddrModeIfVolatile,
29                           idInfoToAmode
30                         )
31 import CgCon            ( buildDynCon, bindConArgs )
32 import CgHeapery        ( heapCheck, yield )
33 import CgRetConv        ( dataReturnConvAlg, dataReturnConvPrim,
34                           ctrlReturnConvAlg,
35                           DataReturnConvention(..), CtrlReturnConvention(..),
36                           assignPrimOpResultRegs,
37                           makePrimOpArgsRobust
38                         )
39 import CgStackery       ( allocAStack, allocBStack, allocAStackTop, allocBStackTop )
40 import CgTailCall       ( tailCallBusiness, performReturn )
41 import CgUsages         ( getSpARelOffset, getSpBRelOffset, freeBStkSlot )
42 import CLabel           ( mkVecTblLabel, mkReturnPtLabel, mkDefaultLabel,
43                           mkAltLabel
44                         )
45 import ClosureInfo      ( mkConLFInfo, mkLFArgument, layOutDynCon )
46 import CmdLineOpts      ( opt_SccProfilingOn, opt_GranMacros )
47 import CostCentre       ( useCurrentCostCentre, CostCentre )
48 import HeapOffs         ( VirtualSpBOffset, VirtualHeapOffset )
49 import Id               ( idPrimRep, dataConTag, fIRST_TAG, ConTag,
50                           isDataCon, DataCon,
51                           idSetToList, GenId{-instance Uniquable,Eq-}, Id
52                         )
53 import Literal          ( Literal )
54 import Maybes           ( catMaybes )
55 import PrimOp           ( primOpCanTriggerGC, PrimOp(..),
56                           primOpStackRequired, StackRequirement(..)
57                         )
58 import PrimRep          ( getPrimRepSize, isFollowableRep, retPrimRepSize,
59                           PrimRep(..)
60                         )
61 import TyCon            ( isEnumerationTyCon )
62 import Type             ( typePrimRep,
63                           splitAlgTyConApp, splitAlgTyConApp_maybe,
64                           Type
65                         )
66 import Unique           ( Unique, Uniquable(..) )
67 import Util             ( sortLt, isIn, isn'tIn, zipEqual )
68 import Outputable
69 \end{code}
70
71 \begin{code}
72 data GCFlag
73   = GCMayHappen -- The scrutinee may involve GC, so everything must be
74                 -- tidy before the code for the scrutinee.
75
76   | NoGC        -- The scrutinee is a primitive value, or a call to a
77                 -- primitive op which does no GC.  Hence the case can
78                 -- be done inline, without tidying up first.
79 \end{code}
80
81 It is quite interesting to decide whether to put a heap-check
82 at the start of each alternative.  Of course we certainly have
83 to do so if the case forces an evaluation, or if there is a primitive
84 op which can trigger GC.
85
86 A more interesting situation is this:
87
88 \begin{verbatim}
89         !A!;
90         ...A...
91         case x# of
92           0#      -> !B!; ...B...
93           default -> !C!; ...C...
94 \end{verbatim}
95
96 where \tr{!x!} indicates a possible heap-check point. The heap checks
97 in the alternatives {\em can} be omitted, in which case the topmost
98 heapcheck will take their worst case into account.
99
100 In favour of omitting \tr{!B!}, \tr{!C!}:
101
102 \begin{itemize}
103 \item
104 {\em May} save a heap overflow test,
105         if ...A... allocates anything.  The other advantage
106         of this is that we can use relative addressing
107         from a single Hp to get at all the closures so allocated.
108 \item
109  No need to save volatile vars etc across the case
110 \end{itemize}
111
112 Against:
113
114 \begin{itemize}
115 \item
116    May do more allocation than reqd.  This sometimes bites us
117         badly.  For example, nfib (ha!)  allocates about 30\% more space if the
118         worst-casing is done, because many many calls to nfib are leaf calls
119         which don't need to allocate anything.
120
121         This never hurts us if there is only one alternative.
122 \end{itemize}
123
124
125 *** NOT YET DONE ***  The difficulty is that \tr{!B!}, \tr{!C!} need
126 to take account of what is live, and that includes all live volatile
127 variables, even if they also have stable analogues.  Furthermore, the
128 stack pointers must be lined up properly so that GC sees tidy stacks.
129 If these things are done, then the heap checks can be done at \tr{!B!} and
130 \tr{!C!} without a full save-volatile-vars sequence.
131
132 \begin{code}
133 cgCase  :: StgExpr
134         -> StgLiveVars
135         -> StgLiveVars
136         -> Unique
137         -> StgCaseAlts
138         -> Code
139 \end{code}
140
141 Several special cases for primitive operations.
142
143
144 \begin{code}
145 cgCase (StgPrim op args _) live_in_whole_case live_in_alts uniq alts
146   | not (primOpCanTriggerGC op)
147   =
148         -- Get amodes for the arguments and results
149     getPrimOpArgAmodes op args                  `thenFC` \ arg_amodes ->
150     let
151         result_amodes = getPrimAppResultAmodes uniq alts
152         liveness_mask = panic "cgCase: liveness of non-GC-ing primop touched\n"
153     in
154         -- Perform the operation
155     getVolatileRegs live_in_alts                        `thenFC` \ vol_regs ->
156
157     -- seq cannot happen here => no additional B Stack alloc
158
159     absC (COpStmt result_amodes op
160                  arg_amodes -- note: no liveness arg
161                  liveness_mask vol_regs)                `thenC`
162
163         -- Scrutinise the result
164     cgInlineAlts NoGC uniq alts
165
166   | otherwise   -- *Can* trigger GC
167   = getPrimOpArgAmodes op args  `thenFC` \ arg_amodes ->
168
169         -- Get amodes for the arguments and results, and assign to regs
170         -- (Can-trigger-gc primops guarantee to have their (nonRobust)
171         --  args in regs)
172     let
173         op_result_regs = assignPrimOpResultRegs op
174
175         op_result_amodes = map CReg op_result_regs
176
177         (op_arg_amodes, liveness_mask, arg_assts)
178           = makePrimOpArgsRobust op arg_amodes
179
180         liveness_arg  = mkIntCLit liveness_mask
181     in
182         -- Tidy up in case GC happens...
183
184         -- Nota Bene the use of live_in_whole_case in nukeDeadBindings.
185         -- Reason: the arg_assts computed above may refer to some stack slots
186         -- which are not live in the alts.  So we mustn't use those slots
187         -- to save volatile vars in!
188     nukeDeadBindings live_in_whole_case `thenC`
189     saveVolatileVars live_in_alts       `thenFC` \ volatile_var_save_assts ->
190
191     -- Allocate stack words for the prim-op itself,
192     -- these are guaranteed to be ON TOP OF the stack.
193     -- Currently this is used *only* by the seq# primitive op.
194     let 
195       (a_req,b_req) = case (primOpStackRequired op) of
196                            NoStackRequired        -> (0, 0)
197                            FixedStackRequired a b -> (a, b)
198                            VariableStackRequired  -> (0, 0) -- i.e. don't care
199     in
200     allocAStackTop a_req                `thenFC` \ a_slot ->
201     allocBStackTop b_req                `thenFC` \ b_slot ->
202
203     getEndOfBlockInfo                   `thenFC` \ eob_info@(EndOfBlockInfo args_spa args_spb sequel) ->
204     -- a_req and b_req allocate stack space that is taken care of by the
205     -- macros generated for the primops; thus, we there is no need to adjust
206     -- this part of the stacks later on (=> +a_req in EndOfBlockInfo)
207     -- currently all this is only used for SeqOp
208     forkEval (if True {- a_req==0 && b_req==0 -}
209                 then eob_info
210                 else (EndOfBlockInfo (args_spa+a_req) 
211                                      (args_spb+b_req) sequel)) nopC 
212              (
213               getAbsC (cgInlineAlts GCMayHappen uniq alts) `thenFC` \ abs_c ->
214               absC (CRetUnVector vtbl_label (CLabelledCode return_label abs_c))
215                                         `thenC`
216               returnFC (CaseAlts (CUnVecLbl return_label vtbl_label)
217                                  Nothing{-no semi-tagging-}))
218             `thenFC` \ new_eob_info ->
219
220         -- Record the continuation info
221     setEndOfBlockInfo new_eob_info (
222
223         -- Now "return" to the inline alternatives; this will get
224         -- compiled to a fall-through.
225     let
226         simultaneous_assts = arg_assts `mkAbsCStmts` volatile_var_save_assts
227
228         -- do_op_and_continue will be passed an amode for the continuation
229         do_op_and_continue sequel
230           = absC (COpStmt op_result_amodes
231                           op
232                           (pin_liveness op liveness_arg op_arg_amodes)
233                           liveness_mask
234                           [{-no vol_regs-}])
235                                         `thenC`
236
237             sequelToAmode sequel        `thenFC` \ dest_amode ->
238             absC (CReturn dest_amode DirectReturn)
239
240                 -- Note: we CJump even for algebraic data types,
241                 -- because cgInlineAlts always generates code, never a
242                 -- vector.
243     in
244     performReturn simultaneous_assts do_op_and_continue live_in_alts
245     )
246   where
247     -- for all PrimOps except ccalls, we pin the liveness info
248     -- on as the first "argument"
249     -- ToDo: un-duplicate?
250
251     pin_liveness (CCallOp _ _ _ _ _ _) _ args = args
252     pin_liveness other_op liveness_arg args
253       = liveness_arg :args
254
255     vtbl_label = mkVecTblLabel uniq
256     return_label = mkReturnPtLabel uniq
257
258 \end{code}
259
260 Another special case: scrutinising a primitive-typed variable.  No
261 evaluation required.  We don't save volatile variables, nor do we do a
262 heap-check in the alternatives.  Instead, the heap usage of the
263 alternatives is worst-cased and passed upstream.  This can result in
264 allocating more heap than strictly necessary, but it will sometimes
265 eliminate a heap check altogether.
266
267 \begin{code}
268 cgCase (StgApp v [] _) live_in_whole_case live_in_alts uniq (StgPrimAlts ty alts deflt)
269   = getArgAmode v               `thenFC` \ amode ->
270     cgPrimAltsGivenScrutinee NoGC amode alts deflt
271 \end{code}
272
273 Special case: scrutinising a non-primitive variable.
274 This can be done a little better than the general case, because
275 we can reuse/trim the stack slot holding the variable (if it is in one).
276
277 \begin{code}
278 cgCase (StgApp (StgVarArg fun) args _ {-lvs must be same as live_in_alts-})
279         live_in_whole_case live_in_alts uniq alts@(StgAlgAlts _ _ _)
280   =
281     getCAddrModeAndInfo fun             `thenFC` \ (fun_amode, lf_info) ->
282     getArgAmodes args                   `thenFC` \ arg_amodes ->
283
284         -- Squish the environment
285     nukeDeadBindings live_in_alts       `thenC`
286     saveVolatileVarsAndRegs live_in_alts
287                         `thenFC` \ (save_assts, alts_eob_info, maybe_cc_slot) ->
288
289     forkEval alts_eob_info
290              nopC (cgEvalAlts maybe_cc_slot uniq alts) `thenFC` \ scrut_eob_info ->
291     setEndOfBlockInfo scrut_eob_info  (
292       tailCallBusiness fun fun_amode lf_info arg_amodes live_in_alts save_assts
293     )
294
295 \end{code}
296
297 Finally, here is the general case.
298
299 \begin{code}
300 cgCase expr live_in_whole_case live_in_alts uniq alts
301   =     -- Figure out what volatile variables to save
302     nukeDeadBindings live_in_whole_case `thenC`
303     saveVolatileVarsAndRegs live_in_alts
304                         `thenFC` \ (save_assts, alts_eob_info, maybe_cc_slot) ->
305
306         -- Save those variables right now!
307     absC save_assts                     `thenC`
308
309     forkEval alts_eob_info
310         (nukeDeadBindings live_in_alts)
311         (cgEvalAlts maybe_cc_slot uniq alts) `thenFC` \ scrut_eob_info ->
312
313     setEndOfBlockInfo scrut_eob_info (cgExpr expr)
314 \end{code}
315
316 %************************************************************************
317 %*                                                                      *
318 \subsection[CgCase-primops]{Primitive applications}
319 %*                                                                      *
320 %************************************************************************
321
322 Get result amodes for a primitive operation, in the case wher GC can't happen.
323 The  amodes are returned in canonical order, ready for the prim-op!
324
325         Alg case: temporaries named as in the alternatives,
326                   plus (CTemp u) for the tag (if needed)
327         Prim case: (CTemp u)
328
329 This is all disgusting, because these amodes must be consistent with those
330 invented by CgAlgAlts.
331
332 \begin{code}
333 getPrimAppResultAmodes
334         :: Unique
335         -> StgCaseAlts
336         -> [CAddrMode]
337 \end{code}
338
339 \begin{code}
340 -- If there's an StgBindDefault which does use the bound
341 -- variable, then we can only handle it if the type involved is
342 -- an enumeration type.   That's important in the case
343 -- of comparisions:
344 --
345 --      case x ># y of
346 --        r -> f r
347 --
348 -- The only reason for the restriction to *enumeration* types is our
349 -- inability to invent suitable temporaries to hold the results;
350 -- Elaborating the CTemp addr mode to have a second uniq field
351 -- (which would simply count from 1) would solve the problem.
352 -- Anyway, cgInlineAlts is now capable of handling all cases;
353 -- it's only this function which is being wimpish.
354
355 getPrimAppResultAmodes uniq (StgAlgAlts ty alts (StgBindDefault _ True {- used -} _))
356   | isEnumerationTyCon spec_tycon = [tag_amode]
357   | otherwise                     = panic "getPrimAppResultAmodes: non-enumeration algebraic alternatives with default"
358   where
359     -- A temporary variable to hold the tag; this is unaffected by GC because
360     -- the heap-checks in the branches occur after the switch
361     tag_amode     = CTemp uniq IntRep
362     (spec_tycon, _, _) = splitAlgTyConApp ty
363
364 getPrimAppResultAmodes uniq (StgAlgAlts ty alts other_default)
365         -- Default is either StgNoDefault or StgBindDefault with unused binder
366   = case alts of
367         [_]     -> arg_amodes                   -- No need for a tag
368         other   -> tag_amode : arg_amodes
369   where
370     -- A temporary variable to hold the tag; this is unaffected by GC because
371     -- the heap-checks in the branches occur after the switch
372     tag_amode = CTemp uniq IntRep
373
374     -- Sort alternatives into canonical order; there must be a complete
375     -- set because there's no default case.
376     sorted_alts = sortLt lt alts
377     (con1,_,_,_) `lt` (con2,_,_,_) = dataConTag con1 < dataConTag con2
378
379     arg_amodes :: [CAddrMode]
380
381     -- Turn them into amodes
382     arg_amodes = concat (map mk_amodes sorted_alts)
383     mk_amodes (con, args, use_mask, rhs)
384       = [ CTemp (uniqueOf arg) (idPrimRep arg) | arg <- args ]
385 \end{code}
386
387 The situation is simpler for primitive
388 results, because there is only one!
389
390 \begin{code}
391 getPrimAppResultAmodes uniq (StgPrimAlts ty _ _)
392   = [CTemp uniq (typePrimRep ty)]
393 \end{code}
394
395
396 %************************************************************************
397 %*                                                                      *
398 \subsection[CgCase-alts]{Alternatives}
399 %*                                                                      *
400 %************************************************************************
401
402 @cgEvalAlts@ returns an addressing mode for a continuation for the
403 alternatives of a @case@, used in a context when there
404 is some evaluation to be done.
405
406 \begin{code}
407 cgEvalAlts :: Maybe VirtualSpBOffset    -- Offset of cost-centre to be restored, if any
408            -> Unique
409            -> StgCaseAlts
410            -> FCode Sequel              -- Any addr modes inside are guaranteed to be a label
411                                         -- so that we can duplicate it without risk of
412                                         -- duplicating code
413
414 cgEvalAlts cc_slot uniq (StgAlgAlts ty alts deflt)
415   =     -- Generate the instruction to restore cost centre, if any
416     restoreCurrentCostCentre cc_slot    `thenFC` \ cc_restore ->
417
418         -- Generate sequel info for use downstream
419         -- At the moment, we only do it if the type is vector-returnable.
420         -- Reason: if not, then it costs extra to label the
421         -- alternatives, because we'd get return code like:
422         --
423         --      switch TagReg { 0 : JMP(alt_1); 1 : JMP(alt_2) ..etc }
424         --
425         -- which is worse than having the alt code in the switch statement
426
427     let
428         (spec_tycon, _, _) = splitAlgTyConApp ty
429
430         use_labelled_alts
431           = case ctrlReturnConvAlg spec_tycon of
432               VectoredReturn _ -> True
433               _                -> False
434
435         semi_tagged_stuff
436           = if not use_labelled_alts then
437                 Nothing -- no semi-tagging info
438             else
439                 cgSemiTaggedAlts uniq alts deflt -- Just <something>
440     in
441     cgAlgAlts GCMayHappen uniq cc_restore use_labelled_alts ty alts deflt True
442                                         `thenFC` \ (tagged_alt_absCs, deflt_absC) ->
443
444     mkReturnVector uniq ty tagged_alt_absCs deflt_absC `thenFC` \ return_vec ->
445
446     returnFC (CaseAlts return_vec semi_tagged_stuff)
447
448 cgEvalAlts cc_slot uniq (StgPrimAlts ty alts deflt)
449   =     -- Generate the instruction to restore cost centre, if any
450     restoreCurrentCostCentre cc_slot                     `thenFC` \ cc_restore ->
451
452         -- Generate the switch
453     getAbsC (cgPrimAlts GCMayHappen uniq ty alts deflt)  `thenFC` \ abs_c ->
454
455         -- Generate the labelled block, starting with restore-cost-centre
456     absC (CRetUnVector vtbl_label
457          (CLabelledCode return_label (cc_restore `mkAbsCStmts` abs_c)))
458                                                          `thenC`
459         -- Return an amode for the block
460     returnFC (CaseAlts (CUnVecLbl return_label vtbl_label) Nothing{-no semi-tagging-})
461   where
462     vtbl_label = mkVecTblLabel uniq
463     return_label = mkReturnPtLabel uniq
464 \end{code}
465
466
467 \begin{code}
468 cgInlineAlts :: GCFlag -> Unique
469              -> StgCaseAlts
470              -> Code
471 \end{code}
472
473 HWL comment on {\em GrAnSim\/}  (adding GRAN_YIELDs for context switch): If
474 we  do  an inlining of the  case  no separate  functions  for returning are
475 created, so we don't have to generate a GRAN_YIELD in that case.  This info
476 must be  propagated  to cgAlgAltRhs (where the  GRAN_YIELD  macro might  be
477 emitted). Hence, the new Bool arg to cgAlgAltRhs.
478
479 First case: algebraic case, exactly one alternative, no default.
480 In this case the primitive op will not have set a temporary to the
481 tag, so we shouldn't generate a switch statment.  Instead we just
482 do the right thing.
483
484 \begin{code}
485 cgInlineAlts gc_flag uniq (StgAlgAlts ty [alt@(con,args,use_mask,rhs)] StgNoDefault)
486   = cgAlgAltRhs gc_flag con args use_mask rhs False{-no yield macro if alt gets inlined-}
487 \end{code}
488
489 Second case: algebraic case, several alternatives.
490 Tag is held in a temporary.
491
492 \begin{code}
493 cgInlineAlts gc_flag uniq (StgAlgAlts ty alts deflt)
494   = cgAlgAlts gc_flag uniq AbsCNop{-restore_cc-} False{-no semi-tagging-}
495                 ty alts deflt
496                 False{-don't emit yield-}  `thenFC` \ (tagged_alts, deflt_c) ->
497
498         -- Do the switch
499     absC (mkAlgAltsCSwitch tag_amode tagged_alts deflt_c)
500  where
501     -- A temporary variable to hold the tag; this is unaffected by GC because
502     -- the heap-checks in the branches occur after the switch
503     tag_amode = CTemp uniq IntRep
504 \end{code}
505
506 Third (real) case: primitive result type.
507
508 \begin{code}
509 cgInlineAlts gc_flag uniq (StgPrimAlts ty alts deflt)
510   = cgPrimAlts gc_flag uniq ty alts deflt
511 \end{code}
512
513
514 %************************************************************************
515 %*                                                                      *
516 \subsection[CgCase-alg-alts]{Algebraic alternatives}
517 %*                                                                      *
518 %************************************************************************
519
520 In @cgAlgAlts@, none of the binders in the alternatives are
521 assumed to be yet bound.
522
523 HWL comment on {\em GrAnSim\/} (adding GRAN_YIELDs for context switch): The
524 last   arg of  cgAlgAlts  indicates  if we  want  a context   switch at the
525 beginning of  each alternative. Normally we  want that. The  only exception
526 are inlined alternatives.
527
528 \begin{code}
529 cgAlgAlts :: GCFlag
530           -> Unique
531           -> AbstractC                          -- Restore-cost-centre instruction
532           -> Bool                               -- True <=> branches must be labelled
533           -> Type                               -- From the case statement
534           -> [(Id, [Id], [Bool], StgExpr)]      -- The alternatives
535           -> StgCaseDefault             -- The default
536           -> Bool                               -- Context switch at alts?
537           -> FCode ([(ConTag, AbstractC)],      -- The branches
538                     AbstractC                   -- The default case
539              )
540 \end{code}
541
542 The case with a default which has a binder is different.  We need to
543 pick all the constructors which aren't handled explicitly by an
544 alternative, and which return their results in registers, allocate
545 them explicitly in the heap, and jump to a join point for the default
546 case.
547
548 OLD:  All of this only works if a heap-check is required anyway, because
549 otherwise it isn't safe to allocate.
550
551 NEW (July 94): now false!  It should work regardless of gc_flag,
552 because of the extra_branches argument now added to forkAlts.
553
554 We put a heap-check at the join point, for the benefit of constructors
555 which don't need to do allocation. This means that ones which do need
556 to allocate may end up doing two heap-checks; but that's just too bad.
557 (We'd need two join labels otherwise.  ToDo.)
558
559 It's all pretty turgid anyway.
560
561 \begin{code}
562 cgAlgAlts gc_flag uniq restore_cc semi_tagging
563         ty alts deflt@(StgBindDefault binder True{-used-} _)
564         emit_yield{-should a yield macro be emitted?-}
565   = let
566         extra_branches :: [FCode (ConTag, AbstractC)]
567         extra_branches = catMaybes (map mk_extra_branch default_cons)
568
569         must_label_default = semi_tagging || not (null extra_branches)
570     in
571     forkAlts (map (cgAlgAlt gc_flag uniq restore_cc semi_tagging emit_yield) alts)
572              extra_branches
573              (cgAlgDefault  gc_flag uniq restore_cc must_label_default deflt emit_yield)
574   where
575
576     default_join_lbl = mkDefaultLabel uniq
577     jump_instruction = CJump (CLbl default_join_lbl CodePtrRep)
578
579     (spec_tycon, _, spec_cons) = splitAlgTyConApp ty
580
581     alt_cons = [ con | (con,_,_,_) <- alts ]
582
583     default_cons  = [ spec_con | spec_con <- spec_cons, -- In this type
584                                  spec_con `not_elem` alt_cons ] -- Not handled explicitly
585         where
586           not_elem = isn'tIn "cgAlgAlts"
587
588     -- (mk_extra_branch con) returns the a maybe for the extra branch for con.
589     -- The "maybe" is because con may return in heap, in which case there is
590     -- nothing to do. Otherwise, we have a special case for a nullary constructor,
591     -- but in the general case we do an allocation and heap-check.
592
593     mk_extra_branch :: DataCon -> (Maybe (FCode (ConTag, AbstractC)))
594
595     mk_extra_branch con
596       = ASSERT(isDataCon con)
597         case dataReturnConvAlg con of
598           ReturnInHeap    -> Nothing
599           ReturnInRegs rs -> Just (getAbsC (alloc_code rs) `thenFC` \ abs_c ->
600                                    returnFC (tag, abs_c)
601                                   )
602       where
603         lf_info         = mkConLFInfo con
604         tag             = dataConTag con
605
606         -- alloc_code generates code to allocate constructor con, whose args are
607         -- in the arguments to alloc_code, assigning the result to Node.
608         alloc_code :: [MagicId] -> Code
609
610         alloc_code regs
611           = possibleHeapCheck gc_flag regs False (
612                 buildDynCon binder useCurrentCostCentre con
613                                 (map CReg regs) (all zero_size regs)
614                                                 `thenFC` \ idinfo ->
615                 idInfoToAmode PtrRep idinfo     `thenFC` \ amode ->
616
617                 absC (CAssign (CReg node) amode) `thenC`
618                 absC jump_instruction
619             )
620           where
621             zero_size reg = getPrimRepSize (magicIdPrimRep reg) == 0
622 \end{code}
623
624 Now comes the general case
625
626 \begin{code}
627 cgAlgAlts gc_flag uniq restore_cc must_label_branches ty alts deflt
628         {- The deflt is either StgNoDefault or a BindDefault which doesn't use the binder -}
629           emit_yield{-should a yield macro be emitted?-}
630
631   = forkAlts (map (cgAlgAlt gc_flag uniq restore_cc must_label_branches emit_yield) alts)
632              [{- No "extra branches" -}]
633              (cgAlgDefault gc_flag uniq restore_cc must_label_branches deflt emit_yield)
634 \end{code}
635
636 \begin{code}
637 cgAlgDefault :: GCFlag
638              -> Unique -> AbstractC -> Bool -- turgid state...
639              -> StgCaseDefault      -- input
640              -> Bool
641              -> FCode AbstractC     -- output
642
643 cgAlgDefault gc_flag uniq restore_cc must_label_branch
644              StgNoDefault _
645   = returnFC AbsCNop
646
647 cgAlgDefault gc_flag uniq restore_cc must_label_branch
648              (StgBindDefault _ False{-binder not used-} rhs)
649              emit_yield{-should a yield macro be emitted?-}
650
651   = getAbsC (absC restore_cc `thenC`
652              let
653                 emit_gran_macros = opt_GranMacros
654              in
655              (if emit_gran_macros && emit_yield 
656                 then yield [] False 
657                 else absC AbsCNop)                            `thenC`     
658     -- liveness same as in possibleHeapCheck below
659              possibleHeapCheck gc_flag [] False (cgExpr rhs)) `thenFC` \ abs_c ->
660     let
661         final_abs_c | must_label_branch = CJump (CLabelledCode lbl abs_c)
662                     | otherwise         = abs_c
663     in
664     returnFC final_abs_c
665   where
666     lbl = mkDefaultLabel uniq
667
668
669 cgAlgDefault gc_flag uniq restore_cc must_label_branch
670              (StgBindDefault binder True{-binder used-} rhs)
671           emit_yield{-should a yield macro be emitted?-}
672
673   =     -- We have arranged that Node points to the thing, even
674         -- even if we return in registers
675     bindNewToReg binder node mkLFArgument `thenC`
676     getAbsC (absC restore_cc `thenC`
677              let
678                 emit_gran_macros = opt_GranMacros
679              in
680              (if emit_gran_macros && emit_yield
681                 then yield [node] False
682                 else absC AbsCNop)                            `thenC`     
683                 -- liveness same as in possibleHeapCheck below
684              possibleHeapCheck gc_flag [node] False (cgExpr rhs)
685         -- Node is live, but doesn't need to point at the thing itself;
686         -- it's ok for Node to point to an indirection or FETCH_ME
687         -- Hence no need to re-enter Node.
688     )                                   `thenFC` \ abs_c ->
689
690     let
691         final_abs_c | must_label_branch = CJump (CLabelledCode lbl abs_c)
692                     | otherwise         = abs_c
693     in
694     returnFC final_abs_c
695   where
696     lbl = mkDefaultLabel uniq
697
698 -- HWL comment on GrAnSim: GRAN_YIELDs needed; emitted in cgAlgAltRhs
699
700 cgAlgAlt :: GCFlag
701          -> Unique -> AbstractC -> Bool         -- turgid state
702          -> Bool                               -- Context switch at alts?
703          -> (Id, [Id], [Bool], StgExpr)
704          -> FCode (ConTag, AbstractC)
705
706 cgAlgAlt gc_flag uniq restore_cc must_label_branch 
707          emit_yield{-should a yield macro be emitted?-}
708          (con, args, use_mask, rhs)
709   = getAbsC (absC restore_cc `thenC`
710              cgAlgAltRhs gc_flag con args use_mask rhs 
711              emit_yield
712             ) `thenFC` \ abs_c -> 
713     let
714         final_abs_c | must_label_branch = CJump (CLabelledCode lbl abs_c)
715                     | otherwise         = abs_c
716     in
717     returnFC (tag, final_abs_c)
718   where
719     tag = dataConTag con
720     lbl = mkAltLabel uniq tag
721
722 cgAlgAltRhs :: GCFlag 
723             -> Id 
724             -> [Id] 
725             -> [Bool] 
726             -> StgExpr 
727             -> Bool              -- context switch?
728             -> Code
729 cgAlgAltRhs gc_flag con args use_mask rhs emit_yield
730   = let
731       (live_regs, node_reqd)
732         = case (dataReturnConvAlg con) of
733             ReturnInHeap      -> ([],                                             True)
734             ReturnInRegs regs -> ([reg | (reg,True) <- zipEqual "cgAlgAltRhs" regs use_mask], False)
735                                 -- Pick the live registers using the use_mask
736                                 -- Doing so is IMPORTANT, because with semi-tagging
737                                 -- enabled only the live registers will have valid
738                                 -- pointers in them.
739     in
740      let
741         emit_gran_macros = opt_GranMacros
742      in
743     (if emit_gran_macros && emit_yield
744       then yield live_regs node_reqd 
745       else absC AbsCNop)                                    `thenC`     
746     -- liveness same as in possibleHeapCheck below
747     possibleHeapCheck gc_flag live_regs node_reqd (
748     (case gc_flag of
749         NoGC        -> mapFCs bindNewToTemp args `thenFC` \ _ ->
750                        nopC
751         GCMayHappen -> bindConArgs con args
752     )   `thenC`
753     cgExpr rhs
754     )
755 \end{code}
756
757 %************************************************************************
758 %*                                                                      *
759 \subsection[CgCase-semi-tagged-alts]{The code to deal with sem-tagging}
760 %*                                                                      *
761 %************************************************************************
762
763 Turgid-but-non-monadic code to conjure up the required info from
764 algebraic case alternatives for semi-tagging.
765
766 \begin{code}
767 cgSemiTaggedAlts :: Unique
768                  -> [(Id, [Id], [Bool], StgExpr)]
769                  -> GenStgCaseDefault Id Id
770                  -> SemiTaggingStuff
771
772 cgSemiTaggedAlts uniq alts deflt
773   = Just (map st_alt alts, st_deflt deflt)
774   where
775     st_deflt StgNoDefault = Nothing
776
777     st_deflt (StgBindDefault binder binder_used _)
778       = Just (if binder_used then Just binder else Nothing,
779               (CCallProfCtrMacro SLIT("RET_SEMI_BY_DEFAULT") [], -- ToDo: monadise?
780                mkDefaultLabel uniq)
781              )
782
783     st_alt (con, args, use_mask, _)
784       = case (dataReturnConvAlg con) of
785
786           ReturnInHeap ->
787             -- Ha!  Nothing to do; Node already points to the thing
788             (con_tag,
789              (CCallProfCtrMacro SLIT("RET_SEMI_IN_HEAP") -- ToDo: monadise?
790                         [mkIntCLit (length args)], -- how big the thing in the heap is
791              join_label)
792             )
793
794           ReturnInRegs regs ->
795             -- We have to load the live registers from the constructor
796             -- pointed to by Node.
797             let
798                 (_, regs_w_offsets) = layOutDynCon con magicIdPrimRep regs
799
800                 used_regs = selectByMask use_mask regs
801
802                 used_regs_w_offsets = [ ro | ro@(reg,offset) <- regs_w_offsets,
803                                              reg `is_elem` used_regs]
804
805                 is_elem = isIn "cgSemiTaggedAlts"
806             in
807             (con_tag,
808              (mkAbstractCs [
809                 CCallProfCtrMacro SLIT("RET_SEMI_IN_REGS")  -- ToDo: macroise?
810                         [mkIntCLit (length regs_w_offsets),
811                          mkIntCLit (length used_regs_w_offsets)],
812                 CSimultaneous (mkAbstractCs (map move_to_reg used_regs_w_offsets))],
813               join_label))
814       where
815         con_tag     = dataConTag con
816         join_label  = mkAltLabel uniq con_tag
817
818     move_to_reg :: (MagicId, VirtualHeapOffset {-from Node-}) -> AbstractC
819     move_to_reg (reg, offset)
820       = CAssign (CReg reg) (CVal (NodeRel offset) (magicIdPrimRep reg))
821 \end{code}
822
823 %************************************************************************
824 %*                                                                      *
825 \subsection[CgCase-prim-alts]{Primitive alternatives}
826 %*                                                                      *
827 %************************************************************************
828
829 @cgPrimAlts@ generates a suitable @CSwitch@ for dealing with the
830 alternatives of a primitive @case@, given an addressing mode for the
831 thing to scrutinise.  It also keeps track of the maximum stack depth
832 encountered down any branch.
833
834 As usual, no binders in the alternatives are yet bound.
835
836 \begin{code}
837 cgPrimAlts :: GCFlag
838            -> Unique
839            -> Type
840            -> [(Literal, StgExpr)]      -- Alternatives
841            -> StgCaseDefault            -- Default
842            -> Code
843
844 cgPrimAlts gc_flag uniq ty alts deflt
845   = cgPrimAltsGivenScrutinee gc_flag scrutinee alts deflt
846  where
847     -- A temporary variable, or standard register, to hold the result
848     scrutinee = case gc_flag of
849                      NoGC        -> CTemp uniq kind
850                      GCMayHappen -> CReg (dataReturnConvPrim kind)
851
852     kind = typePrimRep ty
853
854
855 cgPrimAltsGivenScrutinee gc_flag scrutinee alts deflt
856   = forkAlts (map (cgPrimAlt gc_flag) alts)
857              [{- No "extra branches" -}]
858              (cgPrimDefault gc_flag scrutinee deflt) `thenFC` \ (alt_absCs, deflt_absC) ->
859     absC (CSwitch scrutinee alt_absCs deflt_absC)
860           -- CSwitch does sensible things with one or zero alternatives
861
862
863 cgPrimAlt :: GCFlag
864           -> (Literal, StgExpr)    -- The alternative
865           -> FCode (Literal, AbstractC) -- Its compiled form
866
867 cgPrimAlt gc_flag (lit, rhs)
868   = getAbsC rhs_code     `thenFC` \ absC ->
869     returnFC (lit,absC)
870   where
871     rhs_code = possibleHeapCheck gc_flag [] False (cgExpr rhs )
872
873 cgPrimDefault :: GCFlag
874               -> CAddrMode              -- Scrutinee
875               -> StgCaseDefault
876               -> FCode AbstractC
877
878 cgPrimDefault gc_flag scrutinee StgNoDefault
879   = panic "cgPrimDefault: No default in prim case"
880
881 cgPrimDefault gc_flag scrutinee (StgBindDefault _ False{-binder not used-} rhs)
882   = getAbsC (possibleHeapCheck gc_flag [] False (cgExpr rhs ))
883
884 cgPrimDefault gc_flag scrutinee (StgBindDefault binder True{-used-} rhs)
885   = getAbsC (possibleHeapCheck gc_flag regs False rhs_code)
886   where
887     regs = if isFollowableRep (getAmodeRep scrutinee) then
888               [node] else []
889
890     rhs_code = bindNewPrimToAmode binder scrutinee `thenC`
891                cgExpr rhs
892 \end{code}
893
894
895 %************************************************************************
896 %*                                                                      *
897 \subsection[CgCase-tidy]{Code for tidying up prior to an eval}
898 %*                                                                      *
899 %************************************************************************
900
901 \begin{code}
902 saveVolatileVarsAndRegs
903     :: StgLiveVars               -- Vars which should be made safe
904     -> FCode (AbstractC,              -- Assignments to do the saves
905        EndOfBlockInfo,                -- New sequel, recording where the return
906                                       -- address now is
907        Maybe VirtualSpBOffset)        -- Slot for current cost centre
908
909
910 saveVolatileVarsAndRegs vars
911   = saveVolatileVars vars     `thenFC` \ var_saves ->
912     saveCurrentCostCentre     `thenFC` \ (maybe_cc_slot, cc_save) ->
913     saveReturnAddress         `thenFC` \ (new_eob_info, ret_save) ->
914     returnFC (mkAbstractCs [var_saves, cc_save, ret_save],
915               new_eob_info,
916               maybe_cc_slot)
917
918
919 saveVolatileVars :: StgLiveVars -- Vars which should be made safe
920                  -> FCode AbstractC     -- Assignments to to the saves
921
922 saveVolatileVars vars
923   = save_em (idSetToList vars)
924   where
925     save_em [] = returnFC AbsCNop
926
927     save_em (var:vars)
928       = getCAddrModeIfVolatile var `thenFC` \ v ->
929         case v of
930             Nothing         -> save_em vars -- Non-volatile, so carry on
931
932
933             Just vol_amode  ->  -- Aha! It's volatile
934                                save_var var vol_amode   `thenFC` \ abs_c ->
935                                save_em vars             `thenFC` \ abs_cs ->
936                                returnFC (abs_c `mkAbsCStmts` abs_cs)
937
938     save_var var vol_amode
939       | isFollowableRep kind
940       = allocAStack                     `thenFC` \ a_slot ->
941         rebindToAStack var a_slot       `thenC`
942         getSpARelOffset a_slot          `thenFC` \ spa_rel ->
943         returnFC (CAssign (CVal spa_rel kind) vol_amode)
944       | otherwise
945       = allocBStack (getPrimRepSize kind)       `thenFC` \ b_slot ->
946         rebindToBStack var b_slot       `thenC`
947         getSpBRelOffset b_slot          `thenFC` \ spb_rel ->
948         returnFC (CAssign (CVal spb_rel kind) vol_amode)
949       where
950         kind = getAmodeRep vol_amode
951
952 saveReturnAddress :: FCode (EndOfBlockInfo, AbstractC)
953 saveReturnAddress
954   = getEndOfBlockInfo                `thenFC` \ eob_info@(EndOfBlockInfo vA vB sequel) ->
955
956       -- See if it is volatile
957     case sequel of
958       InRetReg ->     -- Yes, it's volatile
959                    allocBStack retPrimRepSize    `thenFC` \ b_slot ->
960                    getSpBRelOffset b_slot      `thenFC` \ spb_rel ->
961
962                    returnFC (EndOfBlockInfo vA vB (OnStack b_slot),
963                              CAssign (CVal spb_rel RetRep) (CReg RetReg))
964
965       UpdateCode _ ->   -- It's non-volatile all right, but we still need
966                         -- to allocate a B-stack slot for it, *solely* to make
967                         -- sure that update frames for different values do not
968                         -- appear adjacent on the B stack. This makes sure
969                         -- that B-stack squeezing works ok.
970                         -- See note below
971                    allocBStack retPrimRepSize    `thenFC` \ b_slot ->
972                    returnFC (eob_info, AbsCNop)
973
974       other ->           -- No, it's non-volatile, so do nothing
975                    returnFC (eob_info, AbsCNop)
976 \end{code}
977
978 Note about B-stack squeezing.  Consider the following:`
979
980         y = [...] \u [] -> ...
981         x = [y]   \u [] -> case y of (a,b) -> a
982
983 The code for x will push an update frame, and then enter y.  The code
984 for y will push another update frame.  If the B-stack-squeezer then
985 wakes up, it will see two update frames right on top of each other,
986 and will combine them.  This is WRONG, of course, because x's value is
987 not the same as y's.
988
989 The fix implemented above makes sure that we allocate an (unused)
990 B-stack slot before entering y.  You can think of this as holding the
991 saved value of RetAddr, which (after pushing x's update frame will be
992 some update code ptr).  The compiler is clever enough to load the
993 static update code ptr into RetAddr before entering ~a~, but the slot
994 is still there to separate the update frames.
995
996 When we save the current cost centre (which is done for lexical
997 scoping), we allocate a free B-stack location, and return (a)~the
998 virtual offset of the location, to pass on to the alternatives, and
999 (b)~the assignment to do the save (just as for @saveVolatileVars@).
1000
1001 \begin{code}
1002 saveCurrentCostCentre ::
1003         FCode (Maybe VirtualSpBOffset,  -- Where we decide to store it
1004                                         --   Nothing if not lexical CCs
1005                AbstractC)               -- Assignment to save it
1006                                         --   AbsCNop if not lexical CCs
1007
1008 saveCurrentCostCentre
1009   = let
1010         doing_profiling = opt_SccProfilingOn
1011     in
1012     if not doing_profiling then
1013         returnFC (Nothing, AbsCNop)
1014     else
1015         allocBStack (getPrimRepSize CostCentreRep) `thenFC` \ b_slot ->
1016         getSpBRelOffset b_slot                   `thenFC` \ spb_rel ->
1017         returnFC (Just b_slot,
1018                   CAssign (CVal spb_rel CostCentreRep) (CReg CurCostCentre))
1019
1020 restoreCurrentCostCentre :: Maybe VirtualSpBOffset -> FCode AbstractC
1021
1022 restoreCurrentCostCentre Nothing
1023  = returnFC AbsCNop
1024 restoreCurrentCostCentre (Just b_slot)
1025  = getSpBRelOffset b_slot                        `thenFC` \ spb_rel ->
1026    freeBStkSlot b_slot                           `thenC`
1027    returnFC (CCallProfCCMacro SLIT("RESTORE_CCC") [CVal spb_rel CostCentreRep])
1028     -- we use the RESTORE_CCC macro, rather than just
1029     -- assigning into CurCostCentre, in case RESTORE_CCC
1030     -- has some sanity-checking in it.
1031 \end{code}
1032
1033
1034 %************************************************************************
1035 %*                                                                      *
1036 \subsection[CgCase-return-vec]{Building a return vector}
1037 %*                                                                      *
1038 %************************************************************************
1039
1040 Build a return vector, and return a suitable label addressing
1041 mode for it.
1042
1043 \begin{code}
1044 mkReturnVector :: Unique
1045                -> Type
1046                -> [(ConTag, AbstractC)] -- Branch codes
1047                -> AbstractC             -- Default case
1048                -> FCode CAddrMode
1049
1050 mkReturnVector uniq ty tagged_alt_absCs deflt_absC
1051   = let
1052      (return_vec_amode, vtbl_body) = case (ctrlReturnConvAlg tycon) of {
1053
1054       UnvectoredReturn _ ->
1055         (CUnVecLbl ret_label vtbl_label,
1056          absC (CRetUnVector vtbl_label
1057                             (CLabelledCode ret_label
1058                                            (mkAlgAltsCSwitch (CReg TagReg)
1059                                                              tagged_alt_absCs
1060                                                              deflt_absC))));
1061       VectoredReturn table_size ->
1062         (CLbl vtbl_label DataPtrRep,
1063          absC (CRetVector vtbl_label
1064                         -- must restore cc before each alt, if required
1065                           (map mk_vector_entry [fIRST_TAG .. (table_size+fIRST_TAG-1)])
1066                           deflt_absC))
1067
1068 -- Leave nops and comments in for now; they are eliminated
1069 -- lazily as it's printed.
1070 --                        (case (nonemptyAbsC deflt_absC) of
1071 --                              Nothing  -> AbsCNop
1072 --                              Just def -> def)
1073
1074     } in
1075     vtbl_body                                               `thenC`
1076     returnFC return_vec_amode
1077     -- )
1078   where
1079
1080     (tycon,_,_) = case splitAlgTyConApp_maybe ty of -- *must* be a real "data" type constructor
1081               Just xx -> xx
1082               Nothing -> pprPanic "ERROR: can't generate code for polymorphic case"
1083                                   (vcat [text "probably a mis-use of `seq' or `par';",
1084                                          text "the User's Guide has more details.",
1085                                          text "Offending type:" <+> ppr ty
1086                                   ])
1087
1088     vtbl_label = mkVecTblLabel uniq
1089     ret_label = mkReturnPtLabel uniq
1090
1091     mk_vector_entry :: ConTag -> Maybe CAddrMode
1092     mk_vector_entry tag
1093       = case [ absC | (t, absC) <- tagged_alt_absCs, t == tag ] of
1094              []     -> Nothing
1095              [absC] -> Just (CCode absC)
1096              _      -> panic "mkReturnVector: too many"
1097 \end{code}
1098
1099 %************************************************************************
1100 %*                                                                      *
1101 \subsection[CgCase-utils]{Utilities for handling case expressions}
1102 %*                                                                      *
1103 %************************************************************************
1104
1105 @possibleHeapCheck@ tests a flag passed in to decide whether to
1106 do a heap check or not.
1107
1108 \begin{code}
1109 possibleHeapCheck :: GCFlag -> [MagicId] -> Bool -> Code -> Code
1110
1111 possibleHeapCheck GCMayHappen regs node_reqd code = heapCheck regs node_reqd code
1112 possibleHeapCheck NoGC        _    _         code = code
1113 \end{code}
1114
1115 Select a restricted set of registers based on a usage mask.
1116
1117 \begin{code}
1118 selectByMask []         []         = []
1119 selectByMask (True:ms)  (x:xs) = x : selectByMask ms xs
1120 selectByMask (False:ms) (x:xs) = selectByMask ms xs
1121 \end{code}