2 % (c) The AQUA Project, Glasgow University, 1994-1995
4 \section[SimplCase]{Simplification of `case' expression}
6 Support code for @Simplify@.
9 #include "HsVersions.h"
11 module SimplCase ( simplCase, bindLargeRhs ) where
14 import Pretty -- these are for debugging only
22 import AbsPrel ( getPrimOpResultInfo, PrimOpResultInfo(..), PrimOp,
23 voidPrimTy, voidPrimId, mkFunTy, primOpOkForSpeculation
24 IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
25 IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
27 import AbsUniType ( splitType, splitTyArgs, glueTyArgs,
28 getTyConFamilySize, isPrimType,
31 import BasicLit ( isNoRepLit, BasicLit, PrimKind )
32 import CmdLineOpts ( SimplifierSwitch(..) )
35 import Maybes ( catMaybes, maybeToBool, Maybe(..) )
38 import SimplVar ( completeVar )
46 Float let out of case.
50 -> InExpr -- Scrutinee
51 -> InAlts -- Alternatives
52 -> (SimplEnv -> InExpr -> SmplM OutExpr) -- Rhs handler
53 -> OutUniType -- Type of result expression
56 simplCase env (CoLet bind body) alts rhs_c result_ty
57 | not (switchIsSet env SimplNoLetFromCase)
58 = -- Float the let outside the case scrutinee (if not disabled by flag)
59 tick LetFloatFromCase `thenSmpl_`
60 simplBind env bind (\env -> simplCase env body alts rhs_c result_ty) result_ty
63 OK to do case-of-case if
65 * we allow arbitrary code duplication
69 * the inner case has one alternative
70 case (case e of (a,b) -> rhs) of
81 IF neither of these two things are the case, we avoid code-duplication
82 by abstracting the outer rhss wrt the pattern variables. For example
84 case (case e of { p1->rhs1; ...; pn -> rhsn }) of
90 p1 -> case rhs1 of (x,y) -> b x y
92 pn -> case rhsn of (x,y) -> b x y
95 OK, so outer case expression gets duplicated, but that's all. Furthermore,
96 (a) the binding for "b" will be let-no-escaped, so no heap allocation
97 will take place; the "call" to b will simply be a stack adjustment
99 (b) very commonly, at least some of the rhsi's will be constructors, which
100 makes life even simpler.
102 All of this works equally well if the outer case has multiple rhss.
106 simplCase env (CoCase inner_scrut inner_alts) outer_alts rhs_c result_ty
107 | switchIsSet env SimplCaseOfCase
108 = -- Ha! Do case-of-case
109 tick CaseOfCase `thenSmpl_`
111 if no_need_to_bind_large_alts
113 simplCase env inner_scrut inner_alts
114 (\env rhs -> simplCase env rhs outer_alts rhs_c result_ty) result_ty
116 bindLargeAlts env outer_alts rhs_c result_ty `thenSmpl` \ (extra_bindings, outer_alts') ->
118 rhs_c' = \env rhs -> simplExpr env rhs []
120 simplCase env inner_scrut inner_alts
121 (\env rhs -> simplCase env rhs outer_alts' rhs_c' result_ty)
123 `thenSmpl` \ case_expr ->
124 returnSmpl (mkCoLetsNoUnboxed extra_bindings case_expr)
127 no_need_to_bind_large_alts = switchIsSet env SimplOkToDupCode ||
128 isSingleton (nonErrorRHSs inner_alts)
131 Case of an application of error.
134 simplCase env scrut alts rhs_c result_ty
135 | maybeToBool maybe_error_app
136 = -- Look for an application of an error id
137 tick CaseOfError `thenSmpl_`
138 rhs_c env retyped_error_app
140 alts_ty = typeOfCoreAlts (unTagBindersAlts alts)
141 maybe_error_app = maybeErrorApp scrut (Just alts_ty)
142 Just retyped_error_app = maybe_error_app
145 Finally the default case
148 simplCase env other_scrut alts rhs_c result_ty
149 = -- Float the let outside the case scrutinee
150 simplExpr env other_scrut [] `thenSmpl` \ scrut' ->
151 completeCase env scrut' alts rhs_c
155 %************************************************************************
157 \subsection[Simplify-case]{Completing case-expression simplification}
159 %************************************************************************
164 -> OutExpr -- The already-simplified scrutinee
165 -> InAlts -- The un-simplified alternatives
166 -> (SimplEnv -> InExpr -> SmplM OutExpr) -- Rhs handler
167 -> SmplM OutExpr -- The whole case expression
170 Scrutinising a literal or constructor.
171 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
172 It's an obvious win to do:
174 case (C a b) of {...; C p q -> rhs; ...} ===> rhs[a/p,b/q]
176 and the similar thing for primitive case. If we have
180 and x is known to be of constructor form, then we'll already have
181 inlined the constructor to give (case (C a b) of ...), so we don't
182 need to check for the variable case separately.
184 Sanity check: we don't have a good
185 story to tell about case analysis on NoRep things. ToDo.
188 completeCase env (CoLit lit) alts rhs_c
189 | not (isNoRepLit lit)
190 = -- Ha! Select the appropriate alternative
191 tick KnownBranch `thenSmpl_`
192 completePrimCaseWithKnownLit env lit alts rhs_c
194 completeCase env expr@(CoCon con tys con_args) alts rhs_c
195 = -- Ha! Staring us in the face -- select the appropriate alternative
196 tick KnownBranch `thenSmpl_`
197 completeAlgCaseWithKnownCon env con tys con_args alts rhs_c
202 Start with a simple situation:
204 case x# of ===> e[x#/y#]
207 (when x#, y# are of primitive type, of course).
208 We can't (in general) do this for algebraic cases, because we might
209 turn bottom into non-bottom!
211 Actually, we generalise this idea to look for a case where we're
212 scrutinising a variable, and we know that only the default case can
217 other -> ...(case x of
221 Here the inner case can be eliminated. This really only shows up in
222 eliminating error-checking code.
224 Lastly, we generalise the transformation to handle this:
230 We only do this for very cheaply compared r's (constructors, literals
231 and variables). If pedantic bottoms is on, we only do it when the
232 scrutinee is a PrimOp which can't fail.
234 We do it *here*, looking at un-simplified alternatives, because we
235 have to check that r doesn't mention the variables bound by the
236 pattern in each alternative, so the binder-info is rather useful.
238 So the case-elimination algorithm is:
240 1. Eliminate alternatives which can't match
242 2. Check whether all the remaining alternatives
243 (a) do not mention in their rhs any of the variables bound in their pattern
244 and (b) have equal rhss
246 3. Check we can safely ditch the case:
247 * PedanticBottoms is off,
248 or * the scrutinee is an already-evaluated variable
249 or * the scrutinee is a primop which is ok for speculation
250 -- ie we want to preserve divide-by-zero errors, and
251 -- calls to error itself!
253 or * [Prim cases] the scrutinee is a primitive variable
255 or * [Alg cases] the scrutinee is a variable and
256 either * the rhs is the same variable
257 (eg case x of C a b -> x ===> x)
258 or * there is only one alternative, the default alternative,
259 and the binder is used strictly in its scope.
260 [NB this is helped by the "use default binder where
261 possible" transformation; see below.]
264 If so, then we can replace the case with one of the rhss.
267 completeCase env scrut alts rhs_c
268 | switchIsSet env SimplDoCaseElim &&
274 (not (switchIsSet env SimplPedanticBottoms) ||
276 scrut_is_eliminable_primitive ||
278 scrut_is_var_and_single_strict_default
281 = tick CaseElim `thenSmpl_`
284 -- Find the non-excluded rhss of the case; always at least one
285 (rhs1:rhss) = possible_rhss
286 all_rhss_same = all (cheap_eq rhs1) rhss
288 -- Find the reduced set of possible rhss, along with an indication of
289 -- whether none of their binders are used
290 (binders_unused, possible_rhss, new_env)
292 CoPrimAlts alts deflt -> (deflt_binder_unused, -- No binders other than deflt
296 (deflt_binder_unused, deflt_rhs, new_env) = elim_deflt_binder deflt
298 -- Eliminate unused rhss if poss
299 rhss = case scrut_form of
300 OtherLiteralForm not_these -> [rhs | (alt_lit,rhs) <- alts,
301 not (alt_lit `is_elem` not_these)
303 other -> [rhs | (_,rhs) <- alts]
305 CoAlgAlts alts deflt -> (deflt_binder_unused && all alt_binders_unused possible_alts,
306 deflt_rhs ++ [rhs | (_,_,rhs) <- possible_alts],
309 (deflt_binder_unused, deflt_rhs, new_env) = elim_deflt_binder deflt
311 -- Eliminate unused alts if poss
312 possible_alts = case scrut_form of
313 OtherConstructorForm not_these ->
314 -- Remove alts which can't match
315 [alt | alt@(alt_con,_,_) <- alts,
316 not (alt_con `is_elem` not_these)]
319 -- ConstructorForm c t v -> pprPanic "completeCase!" (ppAbove (ppCat [ppr PprDebug c, ppr PprDebug t, ppr PprDebug v]) (ppr PprDebug alts))
320 -- ConstructorForm can't happen, since we'd have
321 -- inlined it, and be in completeCaseWithKnownCon by now
325 alt_binders_unused (con, args, rhs) = all is_dead args
326 is_dead (_, DeadCode) = True
327 is_dead other_arg = False
329 -- If the scrutinee is a variable, look it up to see what we know about it
330 scrut_form = case scrut of
331 CoVar v -> lookupUnfolding env v
332 other -> NoUnfoldingDetails
334 -- If the scrut is already eval'd then there's no worry about
335 -- eliminating the case
336 scrut_is_evald = case scrut_form of
337 OtherLiteralForm _ -> True
338 ConstructorForm _ _ _ -> True
339 OtherConstructorForm _ -> True
343 scrut_is_eliminable_primitive
345 CoPrim op _ _ -> primOpOkForSpeculation op
346 CoVar _ -> case alts of
347 CoPrimAlts _ _ -> True -- Primitive, hence non-bottom
348 CoAlgAlts _ _ -> False -- Not primitive
351 -- case v of w -> e{strict in w} ===> e[v/w]
352 scrut_is_var_and_single_strict_default
354 CoVar _ -> case alts of
355 CoAlgAlts [] (CoBindDefault (v,_) _) -> willBeDemanded (getIdDemandInfo v)
359 elim_deflt_binder CoNoDefault -- No Binder
361 elim_deflt_binder (CoBindDefault (id, DeadCode) rhs) -- Binder unused
363 elim_deflt_binder (CoBindDefault used_binder rhs) -- Binder used
365 CoVar v -> -- Binder used, but can be eliminated in favour of scrut
366 (True, [rhs], extendIdEnvWithAtom env used_binder (CoVarAtom v))
367 non_var -> -- Binder used, and can't be elimd
370 -- Check whether the chosen unique rhs (ie rhs1) is the same as
371 -- the scrutinee. Remember that the rhs is as yet unsimplified.
372 rhs1_is_scrutinee = case (scrut, rhs1) of
373 (CoVar scrut_var, CoVar rhs_var)
374 -> case lookupId env rhs_var of
375 Just (ItsAnAtom (CoVarAtom rhs_var'))
376 -> rhs_var' == scrut_var
380 is_elem x ys = isIn "completeCase" x ys
383 Scrutinising anything else. If it's a variable, it can't be bound to a
384 constructor or literal, because that would have been inlined
387 completeCase env scrut alts rhs_c
388 = simplAlts env scrut alts rhs_c `thenSmpl` \ alts' ->
396 bindLargeAlts :: SimplEnv
398 -> (SimplEnv -> InExpr -> SmplM OutExpr) -- Old rhs handler
399 -> OutUniType -- Result type
400 -> SmplM ([OutBinding], -- Extra bindings
401 InAlts) -- Modified alts
403 bindLargeAlts env the_lot@(CoAlgAlts alts deflt) rhs_c rhs_ty
404 = mapAndUnzipSmpl do_alt alts `thenSmpl` \ (alt_bindings, alts') ->
405 bindLargeDefault env deflt rhs_ty rhs_c `thenSmpl` \ (deflt_bindings, deflt') ->
406 returnSmpl (deflt_bindings ++ alt_bindings, CoAlgAlts alts' deflt')
408 do_alt (con,args,rhs) = bindLargeRhs env args rhs_ty
409 (\env -> rhs_c env rhs) `thenSmpl` \ (bind,rhs') ->
410 returnSmpl (bind, (con,args,rhs'))
412 bindLargeAlts env the_lot@(CoPrimAlts alts deflt) rhs_c rhs_ty
413 = mapAndUnzipSmpl do_alt alts `thenSmpl` \ (alt_bindings, alts') ->
414 bindLargeDefault env deflt rhs_ty rhs_c `thenSmpl` \ (deflt_bindings, deflt') ->
415 returnSmpl (deflt_bindings ++ alt_bindings, CoPrimAlts alts' deflt')
417 do_alt (lit,rhs) = bindLargeRhs env [] rhs_ty
418 (\env -> rhs_c env rhs) `thenSmpl` \ (bind,rhs') ->
419 returnSmpl (bind, (lit,rhs'))
421 bindLargeDefault env CoNoDefault rhs_ty rhs_c
422 = returnSmpl ([], CoNoDefault)
423 bindLargeDefault env (CoBindDefault binder rhs) rhs_ty rhs_c
424 = bindLargeRhs env [binder] rhs_ty
425 (\env -> rhs_c env rhs) `thenSmpl` \ (bind,rhs') ->
426 returnSmpl ([bind], CoBindDefault binder rhs')
429 bindLargeRhs env [x1,..,xn] rhs rhs_ty rhs_c
430 | otherwise = (rhs_id = \x1..xn -> rhs_c rhs,
434 bindLargeRhs :: SimplEnv
435 -> [InBinder] -- The args wrt which the rhs should be abstracted
437 -> (SimplEnv -> SmplM OutExpr) -- Rhs handler
438 -> SmplM (OutBinding, -- New bindings (singleton or empty)
439 InExpr) -- Modified rhs
441 bindLargeRhs env args rhs_ty rhs_c
442 | null used_args && isPrimType rhs_ty
443 -- If we try to lift a primitive-typed something out
444 -- for let-binding-purposes, we will *caseify* it (!),
445 -- with potentially-disastrous strictness results. So
446 -- instead we turn it into a function: \v -> e
447 -- where v::VoidPrim. Since arguments of type
448 -- VoidPrim don't generate any code, this gives the
451 -- The general structure is just the same as for the common "otherwise~ case
452 = newId prim_rhs_fun_ty `thenSmpl` \ prim_rhs_fun_id ->
453 newId voidPrimTy `thenSmpl` \ void_arg_id ->
454 rhs_c env `thenSmpl` \ prim_new_body ->
456 returnSmpl (CoNonRec prim_rhs_fun_id (mkCoLam [void_arg_id] prim_new_body),
457 CoApp (CoVar prim_rhs_fun_id) (CoVarAtom voidPrimId))
460 = -- Make the new binding Id. NB: it's an OutId
461 newId rhs_fun_ty `thenSmpl` \ rhs_fun_id ->
464 cloneIds env used_args `thenSmpl` \ used_args' ->
466 new_env = extendIdEnvWithClones env used_args used_args'
468 rhs_c new_env `thenSmpl` \ rhs' ->
471 = (if switchIsSet new_env SimplDoEtaReduction
472 then mkCoLamTryingEta
473 else mkCoLam) used_args' rhs'
475 returnSmpl (CoNonRec rhs_fun_id final_rhs,
476 foldl CoApp (CoVar rhs_fun_id) used_arg_atoms)
477 -- This is slightly wierd. We're retuning an OutId as part of the
478 -- modified rhs, which is meant to be an InExpr. However, that's ok, because when
479 -- it's processed the OutId won't be found in the environment, so it
480 -- will be left unmodified.
482 rhs_fun_ty :: OutUniType
483 rhs_fun_ty = glueTyArgs [simplTy env (getIdUniType id) | (id,_) <- used_args] rhs_ty
485 used_args = [arg | arg@(_,usage) <- args, not (dead usage)]
486 used_arg_atoms = [CoVarAtom arg_id | (arg_id,_) <- used_args]
490 prim_rhs_fun_ty = mkFunTy voidPrimTy rhs_ty
493 Case alternatives when we don't know the scrutinee
494 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
496 A special case for case default. If we have
502 it is best to make sure that \tr{default_e} mentions \tr{x} in
503 preference to \tr{y}. The code generator can do a cheaper job if it
504 doesn't have to come up with a binding for \tr{y}.
507 simplAlts :: SimplEnv
508 -> OutExpr -- Simplified scrutinee;
509 -- only of interest if its a var,
510 -- in which case we record its form
512 -> (SimplEnv -> InExpr -> SmplM OutExpr) -- Rhs handler
515 simplAlts env scrut (CoAlgAlts alts deflt) rhs_c
516 = mapSmpl do_alt alts `thenSmpl` \ alts' ->
517 simplDefault env scrut deflt deflt_form rhs_c `thenSmpl` \ deflt' ->
518 returnSmpl (CoAlgAlts alts' deflt')
520 deflt_form = OtherConstructorForm [con | (con,_,_) <- alts]
521 do_alt (con, con_args, rhs)
522 = cloneIds env con_args `thenSmpl` \ con_args' ->
524 env1 = extendIdEnvWithClones env con_args con_args'
525 new_env = case scrut of
526 CoVar var -> _scc_ "euegC1" (extendUnfoldEnvGivenConstructor env1 var con con_args')
529 rhs_c new_env rhs `thenSmpl` \ rhs' ->
530 returnSmpl (con, con_args', rhs')
532 simplAlts env scrut (CoPrimAlts alts deflt) rhs_c
533 = mapSmpl do_alt alts `thenSmpl` \ alts' ->
534 simplDefault env scrut deflt deflt_form rhs_c `thenSmpl` \ deflt' ->
535 returnSmpl (CoPrimAlts alts' deflt')
537 deflt_form = OtherLiteralForm [lit | (lit,_) <- alts]
540 new_env = case scrut of
541 CoVar var -> _scc_ "euegFD1" (extendUnfoldEnvGivenFormDetails env var (LiteralForm lit))
544 rhs_c new_env rhs `thenSmpl` \ rhs' ->
545 returnSmpl (lit, rhs')
548 Use default binder where possible
549 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
550 There's one complication when simplifying the default clause of
551 a case expression. If we see
556 we'd like to convert it to
561 Reason 1: then there might be just one occurrence of x, and it can be
562 inlined as the case scrutinee. So we spot this case when dealing with
563 the default clause, and add a binding to the environment mapping x to
566 Reason 2: if the body is strict in x' then we can eliminate the
567 case altogether. By using x' in preference to x we give the max chance
568 of the strictness analyser finding that the body is strict in x'.
570 On the other hand, if x does *not* get inlined, then we'll actually
571 get somewhat better code from the former expression. So when
572 doing Core -> STG we convert back!
577 -> OutExpr -- Simplified scrutinee
578 -> InDefault -- Default alternative to be completed
579 -> UnfoldingDetails -- Gives form of scrutinee
580 -> (SimplEnv -> InExpr -> SmplM OutExpr) -- Old rhs handler
583 simplDefault env scrut CoNoDefault form rhs_c
584 = returnSmpl CoNoDefault
586 -- Special case for variable scrutinee; see notes above.
587 simplDefault env (CoVar scrut_var) (CoBindDefault binder rhs) form_from_this_case rhs_c
588 = cloneId env binder `thenSmpl` \ binder' ->
590 env1 = extendIdEnvWithAtom env binder (CoVarAtom binder')
592 -- Add form details for the default binder
593 scrut_form = lookupUnfolding env scrut_var
595 = case (form_from_this_case, scrut_form) of
596 (OtherConstructorForm cs, OtherConstructorForm ds) -> OtherConstructorForm (cs++ds)
597 (OtherLiteralForm cs, OtherLiteralForm ds) -> OtherLiteralForm (cs++ds)
598 -- ConstructorForm, LiteralForm impossible
599 -- (ASSERT? ASSERT? Hello? WDP 95/05)
600 other -> form_from_this_case
602 env2 = _scc_ "euegFD2" (extendUnfoldEnvGivenFormDetails env1 binder' final_form)
604 -- Change unfold details for scrut var. We now want to unfold it
606 new_scrut_var_form = GeneralForm True {- OK to dup -} WhnfForm
607 (CoVar binder') UnfoldAlways
608 new_env = extendUnfoldEnvGivenFormDetails env2 scrut_var new_scrut_var_form
611 rhs_c new_env rhs `thenSmpl` \ rhs' ->
612 returnSmpl (CoBindDefault binder' rhs')
614 simplDefault env scrut (CoBindDefault binder rhs) form rhs_c
615 = cloneId env binder `thenSmpl` \ binder' ->
617 env1 = extendIdEnvWithAtom env binder (CoVarAtom binder')
618 new_env = _scc_ "euegFD2" (extendUnfoldEnvGivenFormDetails env1 binder' form)
620 rhs_c new_env rhs `thenSmpl` \ rhs' ->
621 returnSmpl (CoBindDefault binder' rhs')
624 Case alternatives when we know what the scrutinee is
625 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
628 completePrimCaseWithKnownLit
632 -> (SimplEnv -> InExpr -> SmplM OutExpr) -- Rhs handler
635 completePrimCaseWithKnownLit env lit (CoPrimAlts alts deflt) rhs_c
638 search_alts :: [(BasicLit, InExpr)] -> SmplM OutExpr
640 search_alts ((alt_lit, rhs) : _)
642 = -- Matching alternative!
645 search_alts (_ : other_alts)
646 = -- This alternative doesn't match; keep looking
647 search_alts other_alts
651 CoNoDefault -> -- Blargh!
652 panic "completePrimCaseWithKnownLit: No matching alternative and no default"
654 CoBindDefault binder rhs -> -- OK, there's a default case
655 -- Just bind the Id to the atom and continue
657 new_env = extendIdEnvWithAtom env binder (CoLitAtom lit)
662 @completeAlgCaseWithKnownCon@: We know the constructor, so we can
663 select one case alternative (or default). If we choose the default:
664 we do different things depending on whether the constructor was
665 staring us in the face (e.g., \tr{case (p:ps) of {y -> ...}})
666 [let-bind it] or we just know the \tr{y} is now the same as some other
667 var [substitute \tr{y} out of existence].
670 completeAlgCaseWithKnownCon
672 -> DataCon -> [UniType] -> [InAtom]
673 -- Scrutinee is (con, type, value arguments)
675 -> (SimplEnv -> InExpr -> SmplM OutExpr) -- Rhs handler
678 completeAlgCaseWithKnownCon env con tys con_args (CoAlgAlts alts deflt) rhs_c
679 = ASSERT(isDataCon con)
682 search_alts :: [(Id, [InBinder], InExpr)] -> SmplM OutExpr
684 search_alts ((alt_con, alt_args, rhs) : _)
686 = -- Matching alternative!
688 new_env = extendIdEnvWithAtomList env (zip alt_args con_args)
692 search_alts (_ : other_alts)
693 = -- This alternative doesn't match; keep looking
694 search_alts other_alts
697 = -- No matching alternative
699 CoNoDefault -> -- Blargh!
700 panic "completeAlgCaseWithKnownCon: No matching alternative and no default"
702 CoBindDefault binder rhs -> -- OK, there's a default case
703 -- let-bind the binder to the constructor
704 cloneId env binder `thenSmpl` \ id' ->
706 env1 = extendIdEnvWithClone env binder id'
707 new_env = _scc_ "euegFD3" (extendUnfoldEnvGivenFormDetails env1 id'
708 (ConstructorForm con tys con_args))
710 rhs_c new_env rhs `thenSmpl` \ rhs' ->
711 returnSmpl (CoLet (CoNonRec id' (CoCon con tys con_args)) rhs')
714 Case absorption and identity-case elimination
715 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
718 mkCoCase :: OutExpr -> OutAlts -> SmplM OutExpr
721 @mkCoCase@ tries the following transformation (if possible):
723 case v of ==> case v of
724 p1 -> rhs1 p1 -> rhs1
726 pm -> rhsm pm -> rhsm
727 d -> case v of pn -> rhsn[v/d] {or (alg) let d=v in rhsn}
728 {or (prim) case v of d -> rhsn}
731 po -> rhso d -> rhsd[d/d'] {or let d'=d in rhsd}
734 which merges two cases in one case when -- the default alternative of
735 the outer case scrutises the same variable as the outer case This
736 transformation is called Case Merging. It avoids that the same
737 variable is scrutinised multiple times.
739 There's a closely-related transformation:
741 case e of ==> case e of
742 p1 -> rhs1 p1 -> rhs1
744 pm -> rhsm pm -> rhsm
745 d -> case d of pn -> let d = pn in rhsn
747 ... po -> let d = po in rhso
748 po -> rhso d -> rhsd[d/d'] {or let d'=d in rhsd}
751 Here, the let's are essential, because d isn't in scope any more.
752 Sigh. Of course, they may be unused, in which case they'll be
753 eliminated on the next round. Unfortunately, we can't figure out
754 whether or not they are used at this juncture.
756 NB: The binder in a CoBindDefault USED TO BE guaranteed unused if the
757 scrutinee is a variable, because it'll be mapped to the scrutinised
758 variable. Hence the [v/d] substitions can be omitted.
760 ALAS, now the default binder is used by preference, so we have to
761 generate trivial lets to express the substitutions, which will be
762 eliminated on the next pass.
764 The following code handles *both* these transformations (one
765 equation for AlgAlts, one for PrimAlts):
768 mkCoCase scrut (CoAlgAlts outer_alts
769 (CoBindDefault deflt_var
770 (CoCase (CoVar scrut_var')
771 (CoAlgAlts inner_alts inner_deflt))))
772 | (scrut_is_var && scrut_var == scrut_var') -- First transformation
773 || deflt_var == scrut_var' -- Second transformation
774 = -- Aha! The default-absorption rule applies
775 tick CaseMerge `thenSmpl_`
776 returnSmpl (CoCase scrut (CoAlgAlts (outer_alts ++ munged_reduced_inner_alts)
777 (munge_alg_deflt deflt_var inner_deflt)))
778 -- NB: see comment in this location for the CoPrimAlts case
781 scrut_is_var = case scrut of {CoVar v -> True; other -> False}
782 scrut_var = case scrut of CoVar v -> v
784 -- Eliminate any inner alts which are shadowed by the outer ones
785 reduced_inner_alts = [alt | alt@(con,_,_) <- inner_alts,
786 not (con `is_elem` outer_cons)]
787 outer_cons = [con | (con,_,_) <- outer_alts]
788 is_elem = isIn "mkAlgAlts"
790 -- Add the lets if necessary
791 munged_reduced_inner_alts = map munge_alt reduced_inner_alts
793 munge_alt (con, args, rhs) = (con, args, CoLet (CoNonRec deflt_var v) rhs)
795 v | scrut_is_var = CoVar scrut_var
796 | otherwise = CoCon con arg_tys (map CoVarAtom args)
798 arg_tys = case getUniDataTyCon_maybe (getIdUniType deflt_var) of
799 Just (_, arg_tys, _) -> arg_tys
801 mkCoCase scrut (CoPrimAlts
803 (CoBindDefault deflt_var (CoCase
805 (CoPrimAlts inner_alts inner_deflt))))
806 | (scrut_is_var && scrut_var == scrut_var') ||
807 deflt_var == scrut_var'
808 = -- Aha! The default-absorption rule applies
809 tick CaseMerge `thenSmpl_`
810 returnSmpl (CoCase scrut (CoPrimAlts (outer_alts ++ munged_reduced_inner_alts)
811 (munge_prim_deflt deflt_var inner_deflt)))
813 -- Nota Bene: we don't recurse to mkCoCase again, because the
814 -- default will now have a binding in it that prevents
815 -- mkCoCase doing anything useful. Much worse, in this
816 -- PrimAlts case the binding in the default branch is another
817 -- CoCase, so if we recurse to mkCoCase we will get into an
820 -- ToDo: think of a better way to do this. At the moment
821 -- there is at most one case merge per round. That's probably
822 -- plenty but it seems unclean somehow.
825 scrut_is_var = case scrut of {CoVar v -> True; other -> False}
826 scrut_var = case scrut of CoVar v -> v
828 -- Eliminate any inner alts which are shadowed by the outer ones
829 reduced_inner_alts = [alt | alt@(lit,_) <- inner_alts,
830 not (lit `is_elem` outer_lits)]
831 outer_lits = [lit | (lit,_) <- outer_alts]
832 is_elem = isIn "mkPrimAlts"
834 -- Add the lets (well cases actually) if necessary
835 -- The munged alternative looks like
836 -- lit -> case lit of d -> rhs
837 -- The next pass will certainly eliminate the inner case, but
838 -- it isn't easy to do so right away.
839 munged_reduced_inner_alts = map munge_alt reduced_inner_alts
842 | scrut_is_var = (lit, CoCase (CoVar scrut_var)
843 (CoPrimAlts [] (CoBindDefault deflt_var rhs)))
844 | otherwise = (lit, CoCase (CoLit lit)
845 (CoPrimAlts [] (CoBindDefault deflt_var rhs)))
848 Now the identity-case transformation:
859 = tick CaseIdentity `thenSmpl_`
862 identity_alts (CoAlgAlts alts deflt) = all identity_alg_alt alts && identity_deflt deflt
863 identity_alts (CoPrimAlts alts deflt) = all identity_prim_alt alts && identity_deflt deflt
865 identity_alg_alt (con, args, CoCon con' _ args')
866 = con == con' && and (zipWith eq_arg args args')
867 identity_alg_alt other
870 identity_prim_alt (lit, CoLit lit') = lit == lit'
871 identity_prim_alt other = False
873 -- For the default case we want to spot both
876 -- case y of { ... ; x -> y }
877 -- as "identity" defaults
878 identity_deflt CoNoDefault = True
879 identity_deflt (CoBindDefault binder (CoVar x)) = x == binder ||
883 identity_deflt _ = False
885 eq_arg binder (CoVarAtom x) = binder == x
892 mkCoCase other_scrut other_alts = returnSmpl (CoCase other_scrut other_alts)
895 Boring local functions used above. They simply introduce a trivial binding
896 for the binder, d', in an inner default; either
897 let d' = deflt_var in rhs
899 case deflt_var of d' -> rhs
900 depending on whether it's an algebraic or primitive case.
903 munge_prim_deflt _ CoNoDefault = CoNoDefault
905 munge_prim_deflt deflt_var (CoBindDefault d' rhs)
906 = CoBindDefault deflt_var (CoCase (CoVar deflt_var)
907 (CoPrimAlts [] (CoBindDefault d' rhs)))
909 munge_alg_deflt _ CoNoDefault = CoNoDefault
911 munge_alg_deflt deflt_var (CoBindDefault d' rhs)
912 = CoBindDefault deflt_var (CoLet (CoNonRec d' (CoVar deflt_var)) rhs)
914 -- This line caused a generic version of munge_deflt (ie one used for
915 -- both alg and prim) to space leak massively. No idea why.
916 -- = CoBindDefault deflt_var (mkCoLetUnboxedToCase (CoNonRec d' (CoVar deflt_var)) rhs)
920 -- A cheap equality test which bales out fast!
921 cheap_eq :: InExpr -> InExpr -> Bool
922 cheap_eq (CoVar v1) (CoVar v2) = v1==v2
923 cheap_eq (CoLit l1) (CoLit l2) = l1==l2
924 cheap_eq (CoCon con1 tys1 args1) (CoCon con2 tys2 args2) = (con1==con2) &&
925 (args1 `eq_args` args2)
926 -- Types bound to be equal
927 cheap_eq (CoPrim op1 tys1 args1) (CoPrim op2 tys2 args2) = (op1==op2) &&
928 (args1 `eq_args` args2)
929 -- Types bound to be equal
930 cheap_eq (CoApp f1 a1) (CoApp f2 a2) = (f1 `cheap_eq` f2) && (a1 `eq_atom` a2)
931 cheap_eq (CoTyApp f1 t1) (CoTyApp f2 t2) = (f1 `cheap_eq` f2) && (t1 == t2)
934 -- ToDo: make CoreAtom an instance of Eq
935 eq_args (arg1: args1) (arg2 : args2) = (arg1 `eq_atom` arg2) && (args1 `eq_args` args2)
937 eq_args other1 other2 = False
939 eq_atom (CoLitAtom l1) (CoLitAtom l2) = l1==l2
940 eq_atom (CoVarAtom v1) (CoVarAtom v2) = v1==v2
941 eq_atom other1 other2 = False