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