summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsimonpj <unknown>2004-12-22 12:07:41 +0000
committersimonpj <unknown>2004-12-22 12:07:41 +0000
commitd7c402a3cedbe49345a34f2e58a3f3050638dcb4 (patch)
treedd321b3f222abb558567c077a3799ccf3bc590aa
parent1f3a9ff8e19636fcb5bf477922012bc67fd52b02 (diff)
downloadhaskell-d7c402a3cedbe49345a34f2e58a3f3050638dcb4.tar.gz
[project @ 2004-12-22 12:06:13 by simonpj]
---------------------------------------- New Core invariant: keep case alternatives in sorted order ---------------------------------------- We now keep the alternatives of a Case in the Core language in sorted order. Sorted, that is, by constructor tag for DataAlt by literal for LitAlt The main reason is that it makes matching and equality testing more robust. But in fact some lines of code vanished from SimplUtils.mkAlts. WARNING: no change to interface file formats, but you'll need to recompile your libraries so that they generate interface files that respect the invariant.
-rw-r--r--ghc/compiler/basicTypes/MkId.lhs13
-rw-r--r--ghc/compiler/coreSyn/CoreLint.lhs10
-rw-r--r--ghc/compiler/coreSyn/CorePrep.lhs3
-rw-r--r--ghc/compiler/coreSyn/CoreSyn.lhs31
-rw-r--r--ghc/compiler/coreSyn/CoreTidy.lhs2
-rw-r--r--ghc/compiler/coreSyn/CoreUnfold.lhs1
-rw-r--r--ghc/compiler/coreSyn/CoreUtils.lhs24
-rw-r--r--ghc/compiler/coreSyn/PprCore.lhs2
-rw-r--r--ghc/compiler/coreSyn/PprExternalCore.lhs1
-rw-r--r--ghc/compiler/cprAnalysis/CprAnalyse.lhs8
-rw-r--r--ghc/compiler/deSugar/DsArrows.lhs1
-rw-r--r--ghc/compiler/deSugar/DsCCall.lhs8
-rw-r--r--ghc/compiler/deSugar/DsListComp.lhs5
-rw-r--r--ghc/compiler/deSugar/DsUtils.lhs21
-rw-r--r--ghc/compiler/deSugar/MatchLit.lhs2
-rw-r--r--ghc/compiler/iface/TcIface.lhs1
-rw-r--r--ghc/compiler/main/TidyPgm.lhs13
-rw-r--r--ghc/compiler/ndpFlatten/Flattening.hs1
-rw-r--r--ghc/compiler/ndpFlatten/NDPCoreUtils.hs1
-rw-r--r--ghc/compiler/ndpFlatten/PArrAnal.hs1
-rw-r--r--ghc/compiler/prelude/PrelRules.lhs1
-rw-r--r--ghc/compiler/simplCore/FloatIn.lhs1
-rw-r--r--ghc/compiler/simplCore/FloatOut.lhs1
-rw-r--r--ghc/compiler/simplCore/LiberateCase.lhs1
-rw-r--r--ghc/compiler/simplCore/OccurAnal.lhs4
-rw-r--r--ghc/compiler/simplCore/SetLevels.lhs1
-rw-r--r--ghc/compiler/simplCore/SimplUtils.lhs101
-rw-r--r--ghc/compiler/simplCore/Simplify.lhs9
-rw-r--r--ghc/compiler/specialise/Rules.lhs6
-rw-r--r--ghc/compiler/specialise/SpecConstr.lhs2
-rw-r--r--ghc/compiler/specialise/Specialise.lhs3
-rw-r--r--ghc/compiler/stgSyn/CoreToStg.lhs1
-rw-r--r--ghc/compiler/stranal/DmdAnal.lhs4
-rw-r--r--ghc/compiler/stranal/WorkWrap.lhs2
-rw-r--r--ghc/compiler/stranal/WwLib.lhs6
-rw-r--r--ghc/compiler/types/TyCon.lhs2
-rw-r--r--ghc/compiler/utils/Util.lhs7
37 files changed, 142 insertions, 159 deletions
diff --git a/ghc/compiler/basicTypes/MkId.lhs b/ghc/compiler/basicTypes/MkId.lhs
index 7dabf46148..e7084ca7f2 100644
--- a/ghc/compiler/basicTypes/MkId.lhs
+++ b/ghc/compiler/basicTypes/MkId.lhs
@@ -64,8 +64,7 @@ import PrimOp ( PrimOp, primOpSig, primOpOcc, primOpTag )
import ForeignCall ( ForeignCall )
import DataCon ( DataCon, DataConIds(..), dataConTyVars,
dataConFieldLabels, dataConRepArity,
- dataConRepArgTys, dataConRepType,
- dataConStupidTheta, dataConOrigArgTys,
+ dataConRepArgTys, dataConRepType, dataConStupidTheta,
dataConSig, dataConStrictMarks, dataConExStricts,
splitProductType, isVanillaDataCon
)
@@ -305,15 +304,15 @@ mkDataConIds wrap_name wkr_name data_con
MarkedStrict
| isUnLiftedType (idType arg) -> body i (arg:rep_args)
| otherwise ->
--- gaw 2004
Case (Var arg) arg result_ty [(DEFAULT,[], body i (arg:rep_args))]
MarkedUnboxed
-> case splitProductType "do_unbox" (idType arg) of
(tycon, tycon_args, con, tys) ->
--- gaw 2004
- Case (Var arg) arg result_ty [(DataAlt con, con_args,
- body i' (reverse con_args ++ rep_args))]
+ Case (Var arg) arg result_ty
+ [(DataAlt con,
+ con_args,
+ body i' (reverse con_args ++ rep_args))]
where
(con_args, i') = mkLocals i tys
@@ -454,7 +453,7 @@ mkRecordSelId tycon field_label field_ty
arg_base = dict_id_base + 1
alts = map mk_maybe_alt data_cons
- the_alts = catMaybes alts
+ the_alts = catMaybes alts -- Already sorted by data-con
no_default = all isJust alts -- No default needed
default_alt | no_default = []
diff --git a/ghc/compiler/coreSyn/CoreLint.lhs b/ghc/compiler/coreSyn/CoreLint.lhs
index df2f323f0e..a3ea531320 100644
--- a/ghc/compiler/coreSyn/CoreLint.lhs
+++ b/ghc/compiler/coreSyn/CoreLint.lhs
@@ -382,7 +382,8 @@ checkKinds tyvar arg_ty
\begin{code}
checkCaseAlts :: CoreExpr -> Type -> [CoreAlt] -> LintM ()
-- a) Check that the alts are non-empty
--- b) Check that the DEFAULT comes first, if it exists
+-- b1) Check that the DEFAULT comes first, if it exists
+-- b2) Check that the others are in increasing order
-- c) Check that there's a default for infinite types
-- NB: Algebraic cases are not necessarily exhaustive, because
-- the simplifer correctly eliminates case that can't
@@ -393,11 +394,16 @@ checkCaseAlts e ty []
checkCaseAlts e ty alts =
do { checkL (all non_deflt con_alts) (mkNonDefltMsg e)
+ ; checkL (increasing_tag con_alts) (mkNonIncreasingAltsMsg e)
; checkL (isJust maybe_deflt || not is_infinite_ty)
(nonExhaustiveAltsMsg e) }
where
(con_alts, maybe_deflt) = findDefault alts
+ -- Check that successive alternatives have increasing tags
+ increasing_tag (alt1 : rest@( alt2 : _)) = alt1 `ltAlt` alt2 && increasing_tag rest
+ increasing_tag other = True
+
non_deflt (DEFAULT, _, _) = False
non_deflt alt = True
@@ -683,6 +689,8 @@ mkScrutMsg var scrut_ty
mkNonDefltMsg e
= hang (text "Case expression with DEFAULT not at the beginnning") 4 (ppr e)
+mkNonIncreasingAltsMsg e
+ = hang (text "Case expression with badly-ordered alternatives") 4 (ppr e)
nonExhaustiveAltsMsg :: CoreExpr -> Message
nonExhaustiveAltsMsg e
diff --git a/ghc/compiler/coreSyn/CorePrep.lhs b/ghc/compiler/coreSyn/CorePrep.lhs
index 925a51f6ac..169b86efed 100644
--- a/ghc/compiler/coreSyn/CorePrep.lhs
+++ b/ghc/compiler/coreSyn/CorePrep.lhs
@@ -407,13 +407,11 @@ corePrepExprFloat env expr@(Lam _ _)
where
(bndrs,body) = collectBinders expr
--- gaw 2004
corePrepExprFloat env (Case scrut bndr ty alts)
= corePrepExprFloat env scrut `thenUs` \ (floats1, scrut1) ->
deLamFloat scrut1 `thenUs` \ (floats2, scrut2) ->
cloneBndr env bndr `thenUs` \ (env', bndr') ->
mapUs (sat_alt env') alts `thenUs` \ alts' ->
--- gaw 2004
returnUs (floats1 `appendFloats` floats2 , Case scrut2 bndr' ty alts')
where
sat_alt env (con, bs, rhs)
@@ -587,7 +585,6 @@ mkBinds (Floats _ binds) body
| otherwise = deLam body `thenUs` \ body' ->
returnUs (foldrOL mk_bind body' binds)
where
--- gaw 2004
mk_bind (FloatCase bndr rhs _) body = Case rhs bndr (exprType body) [(DEFAULT, [], body)]
mk_bind (FloatLet bind) body = Let bind body
diff --git a/ghc/compiler/coreSyn/CoreSyn.lhs b/ghc/compiler/coreSyn/CoreSyn.lhs
index 28c913d369..3e9127689c 100644
--- a/ghc/compiler/coreSyn/CoreSyn.lhs
+++ b/ghc/compiler/coreSyn/CoreSyn.lhs
@@ -15,7 +15,7 @@ module CoreSyn (
mkConApp,
varToCoreExpr,
- isTyVar, isId,
+ isTyVar, isId, cmpAltCon, cmpAlt, ltAlt,
bindersOf, bindersOfBinds, rhssOfBind, rhssOfAlts,
collectBinders, collectTyBinders, collectValBinders, collectTyAndValBinders,
collectArgs,
@@ -54,7 +54,7 @@ import CostCentre ( CostCentre, noCostCentre )
import Var ( Var, Id, TyVar, isTyVar, isId )
import Type ( Type, mkTyVarTy, seqType )
import Literal ( Literal, mkMachInt )
-import DataCon ( DataCon, dataConWorkId )
+import DataCon ( DataCon, dataConWorkId, dataConTag )
import BasicTypes ( Activation )
import VarSet
import FastString
@@ -78,13 +78,17 @@ data Expr b -- "b" for the type of binders,
| App (Expr b) (Arg b)
| Lam b (Expr b)
| Let (Bind b) (Expr b)
- -- gaw 2004, added Type field
| Case (Expr b) b Type [Alt b] -- Binder gets bound to value of scrutinee
-- Invariant: The list of alternatives is ALWAYS EXHAUSTIVE,
-- meaning that it covers all cases that can occur
-- See the example below
--
-- Invariant: The DEFAULT case must be *first*, if it occurs at all
+ -- Invariant: The remaining cases are in order of increasing
+ -- tag (for DataAlts)
+ -- lit (for LitAlts)
+ -- This makes finding the relevant constructor easy,
+ -- and makes comparison easier too
| Note Note (Expr b)
| Type Type -- This should only show up at the top
-- level of an Arg
@@ -110,6 +114,7 @@ data AltCon = DataAlt DataCon
| DEFAULT
deriving (Eq, Ord)
+
data Bind b = NonRec b (Expr b)
| Rec [(b, (Expr b))]
@@ -345,6 +350,26 @@ instance Outputable AltCon where
instance Show AltCon where
showsPrec p con = showsPrecSDoc p (ppr con)
+
+cmpAlt :: Alt b -> Alt b -> Ordering
+cmpAlt (con1, _, _) (con2, _, _) = con1 `cmpAltCon` con2
+
+ltAlt :: Alt b -> Alt b -> Bool
+ltAlt a1 a2 = case a1 `cmpAlt` a2 of { LT -> True; other -> False }
+
+cmpAltCon :: AltCon -> AltCon -> Ordering
+-- Compares AltCons within a single list of alternatives
+cmpAltCon DEFAULT DEFAULT = EQ
+cmpAltCon DEFAULT con = LT
+
+cmpAltCon (DataAlt d1) (DataAlt d2) = dataConTag d1 `compare` dataConTag d2
+cmpAltCon (DataAlt _) DEFAULT = GT
+cmpAltCon (LitAlt l1) (LitAlt l2) = l1 `compare` l2
+cmpAltCon (LitAlt _) DEFAULT = GT
+
+cmpAltCon con1 con2 = WARN( True, text "Comparing incomparable AltCons" <+>
+ ppr con1 <+> ppr con2 )
+ LT
\end{code}
diff --git a/ghc/compiler/coreSyn/CoreTidy.lhs b/ghc/compiler/coreSyn/CoreTidy.lhs
index 76d1bd3dff..131d8a7714 100644
--- a/ghc/compiler/coreSyn/CoreTidy.lhs
+++ b/ghc/compiler/coreSyn/CoreTidy.lhs
@@ -71,10 +71,8 @@ tidyExpr env (Let b e)
= tidyBind env b =: \ (env', b') ->
Let b' (tidyExpr env' e)
--- gaw 2004
tidyExpr env (Case e b ty alts)
= tidyBndr env b =: \ (env', b) ->
--- gaw 2004
Case (tidyExpr env e) b (tidyType env ty) (map (tidyAlt env') alts)
tidyExpr env (Lam b e)
diff --git a/ghc/compiler/coreSyn/CoreUnfold.lhs b/ghc/compiler/coreSyn/CoreUnfold.lhs
index d3c1679e09..cc664f1b59 100644
--- a/ghc/compiler/coreSyn/CoreUnfold.lhs
+++ b/ghc/compiler/coreSyn/CoreUnfold.lhs
@@ -218,7 +218,6 @@ sizeExpr bOMB_OUT_SIZE top_args expr
where
rhs_size = foldr (addSize . size_up . snd) sizeZero pairs
--- gaw 2004
size_up (Case (Var v) _ _ alts)
| v `elem` top_args -- We are scrutinising an argument variable
=
diff --git a/ghc/compiler/coreSyn/CoreUtils.lhs b/ghc/compiler/coreSyn/CoreUtils.lhs
index 77f2156408..b07d917777 100644
--- a/ghc/compiler/coreSyn/CoreUtils.lhs
+++ b/ghc/compiler/coreSyn/CoreUtils.lhs
@@ -90,7 +90,6 @@ exprType :: CoreExpr -> Type
exprType (Var var) = idType var
exprType (Lit lit) = literalType lit
exprType (Let _ body) = exprType body
--- gaw 2004
exprType (Case _ _ ty alts) = ty
exprType (Note (Coerce ty _) e) = ty -- **! should take usage from e
exprType (Note other_note e) = exprType e
@@ -247,7 +246,6 @@ bindNonRec :: Id -> CoreExpr -> CoreExpr -> CoreExpr
-- deals with them perfectly well.
bindNonRec bndr rhs body
--- gaw 2004
| needsCaseBinding (idType bndr) rhs = Case rhs bndr (exprType body) [(DEFAULT,[],body)]
| otherwise = Let (NonRec bndr rhs) body
@@ -268,11 +266,10 @@ mkAltExpr (LitAlt lit) [] []
mkIfThenElse :: CoreExpr -> CoreExpr -> CoreExpr -> CoreExpr
mkIfThenElse guard then_expr else_expr
--- gaw 2004
-- Not going to be refining, so okay to take the type of the "then" clause
= Case guard (mkWildId boolTy) (exprType then_expr)
- [ (DataAlt trueDataCon, [], then_expr),
- (DataAlt falseDataCon, [], else_expr) ]
+ [ (DataAlt falseDataCon, [], else_expr), -- Increasing order of tag!
+ (DataAlt trueDataCon, [], then_expr) ]
\end{code}
@@ -295,14 +292,15 @@ findAlt con alts
= case alts of
(deflt@(DEFAULT,_,_):alts) -> go alts deflt
other -> go alts panic_deflt
-
where
panic_deflt = pprPanic "Missing alternative" (ppr con $$ vcat (map ppr alts))
- go [] deflt = deflt
- go (alt@(con1,_,_) : alts) deflt | con == con1 = alt
- | otherwise = ASSERT( not (con1 == DEFAULT) )
- go alts deflt
+ go [] deflt = deflt
+ go (alt@(con1,_,_) : alts) deflt
+ = case con `cmpAltCon` con1 of
+ LT -> deflt -- Missed it already; the alts are in increasing order
+ EQ -> alt
+ GT -> ASSERT( not (con1 == DEFAULT) ) go alts deflt
\end{code}
@@ -414,7 +412,6 @@ exprIsCheap (Var _) = True
exprIsCheap (Note InlineMe e) = True
exprIsCheap (Note _ e) = exprIsCheap e
exprIsCheap (Lam x e) = isRuntimeVar x || exprIsCheap e
--- gaw 2004
exprIsCheap (Case e _ _ alts) = exprIsCheap e &&
and [exprIsCheap rhs | (_,_,rhs) <- alts]
-- Experimentally, treat (case x of ...) as cheap
@@ -546,12 +543,12 @@ exprIsBottom e = go 0 e
-- n is the number of args
go n (Note _ e) = go n e
go n (Let _ e) = go n e
--- gaw 2004
go n (Case e _ _ _) = go 0 e -- Just check the scrut
go n (App e _) = go (n+1) e
go n (Var v) = idAppIsBottom v n
go n (Lit _) = False
go n (Lam _ _) = False
+ go n (Type _) = False
idAppIsBottom :: Id -> Int -> Bool
idAppIsBottom id n_val_args = appIsBottom (idNewStrictness id) n_val_args
@@ -818,7 +815,6 @@ arityType (App f a) = case arityType f of
-- ===>
-- f x y = case x of { (a,b) -> e }
-- The difference is observable using 'seq'
--- gaw 2004
arityType (Case scrut _ _ alts) = case foldr1 andArityType [arityType rhs | (_,_,rhs) <- alts] of
xs@(AFun one_shot _) | one_shot -> xs
xs | exprIsCheap scrut -> xs
@@ -1087,7 +1083,6 @@ exprSize (Lit lit) = lit `seq` 1
exprSize (App f a) = exprSize f + exprSize a
exprSize (Lam b e) = varSize b + exprSize e
exprSize (Let b e) = bindSize b + exprSize e
--- gaw 2004
exprSize (Case e b t as) = seqType t `seq` exprSize e + varSize b + 1 + foldr ((+) . altSize) 0 as
exprSize (Note n e) = noteSize n + exprSize e
exprSize (Type t) = seqType t `seq` 1
@@ -1131,7 +1126,6 @@ hashExpr e | hash < 0 = 77 -- Just in case we hit -maxInt
hash_expr (Note _ e) = hash_expr e
hash_expr (Let (NonRec b r) e) = hashId b
hash_expr (Let (Rec ((b,r):_)) e) = hashId b
--- gaw 2004
hash_expr (Case _ b _ _) = hashId b
hash_expr (App f e) = hash_expr f * fast_hash_expr e
hash_expr (Var v) = hashId v
diff --git a/ghc/compiler/coreSyn/PprCore.lhs b/ghc/compiler/coreSyn/PprCore.lhs
index 10ad00c6b5..1c20f5118e 100644
--- a/ghc/compiler/coreSyn/PprCore.lhs
+++ b/ghc/compiler/coreSyn/PprCore.lhs
@@ -153,7 +153,6 @@ ppr_expr add_par expr@(App fun arg)
other -> add_par (hang (pprParendExpr fun) 2 pp_args)
}
--- gaw 2004
ppr_expr add_par (Case expr var ty [(con,args,rhs)])
= add_par $
sep [sep [ptext SLIT("case") <+> parens (ppr ty) <+> pprCoreExpr expr,
@@ -168,7 +167,6 @@ ppr_expr add_par (Case expr var ty [(con,args,rhs)])
where
ppr_bndr = pprBndr CaseBind
--- gaw 2004
ppr_expr add_par (Case expr var ty alts)
= add_par $
sep [sep [ptext SLIT("case") <+> parens (ppr ty) <+> pprCoreExpr expr,
diff --git a/ghc/compiler/coreSyn/PprExternalCore.lhs b/ghc/compiler/coreSyn/PprExternalCore.lhs
index dbcc86d153..ba592a9e4f 100644
--- a/ghc/compiler/coreSyn/PprExternalCore.lhs
+++ b/ghc/compiler/coreSyn/PprExternalCore.lhs
@@ -125,7 +125,6 @@ pappexp e as = fsep (paexp e : map pa as)
pexp (Lam b e) = char '\\' <+> plamexp [b] e
pexp (Let vd e) = (text "%let" <+> pvdefg vd) $$ (text "%in" <+> pexp e)
--- gaw 2004
pexp (Case e vb ty alts) = sep [text "%case" <+> parens (paty ty) <+> paexp e,
text "%of" <+> pvbind vb]
$$ (indent (braces (vcat (punctuate (char ';') (map palt alts)))))
diff --git a/ghc/compiler/cprAnalysis/CprAnalyse.lhs b/ghc/compiler/cprAnalysis/CprAnalyse.lhs
index cbc28442ea..a41e62fb6c 100644
--- a/ghc/compiler/cprAnalysis/CprAnalyse.lhs
+++ b/ghc/compiler/cprAnalysis/CprAnalyse.lhs
@@ -252,11 +252,11 @@ cprAnalExpr rho (Type t)
cprAnalCaseAlts :: CPREnv -> [CoreAlt] -> ([CoreAlt], AbsVal)
cprAnalCaseAlts rho alts
- = foldl anal_alt ([], Bot) alts
+ = foldr anal_alt ([], Bot) alts
where
- anal_alt :: ([CoreAlt], AbsVal) -> CoreAlt -> ([CoreAlt], AbsVal)
- anal_alt (done, aval) (con, binds, exp)
- = (done ++ [(con,binds,exp_cpr)], aval `lub` exp_aval)
+ anal_alt :: CoreAlt -> ([CoreAlt], AbsVal) -> ([CoreAlt], AbsVal)
+ anal_alt (con, binds, exp) (done, aval)
+ = ((con,binds,exp_cpr) : done, exp_aval `lub` aval)
where (exp_cpr, exp_aval) = cprAnalExpr rho' exp
rho' = rho `extendVarEnvList` (zip binds (repeat Top))
diff --git a/ghc/compiler/deSugar/DsArrows.lhs b/ghc/compiler/deSugar/DsArrows.lhs
index 30531eaf30..4db17ea00f 100644
--- a/ghc/compiler/deSugar/DsArrows.lhs
+++ b/ghc/compiler/deSugar/DsArrows.lhs
@@ -139,7 +139,6 @@ coreCaseTuple uniqs scrut_var vars body
coreCasePair :: Id -> Id -> Id -> CoreExpr -> CoreExpr
coreCasePair scrut_var var1 var2 body
--- gaw 2004
= Case (Var scrut_var) scrut_var (exprType body)
[(DataAlt (tupleCon Boxed 2), [var1, var2], body)]
\end{code}
diff --git a/ghc/compiler/deSugar/DsCCall.lhs b/ghc/compiler/deSugar/DsCCall.lhs
index a2af48e577..576c721608 100644
--- a/ghc/compiler/deSugar/DsCCall.lhs
+++ b/ghc/compiler/deSugar/DsCCall.lhs
@@ -169,12 +169,11 @@ unboxArg arg
tc `hasKey` boolTyConKey
= newSysLocalDs intPrimTy `thenDs` \ prim_arg ->
returnDs (Var prim_arg,
--- gaw 2004
\ body -> Case (Case arg (mkWildId arg_ty) intPrimTy
[(DataAlt falseDataCon,[],mkIntLit 0),
(DataAlt trueDataCon, [],mkIntLit 1)])
+ -- In increasing tag order!
prim_arg
--- gaw 2004
(exprType body)
[(DEFAULT,[],body)])
@@ -186,7 +185,6 @@ unboxArg arg
newSysLocalDs arg_ty `thenDs` \ case_bndr ->
newSysLocalDs data_con_arg_ty1 `thenDs` \ prim_arg ->
returnDs (Var prim_arg,
--- gaw 2004
\ body -> Case arg case_bndr (exprType body) [(DataAlt data_con,[prim_arg],body)]
)
@@ -203,7 +201,6 @@ unboxArg arg
= newSysLocalDs arg_ty `thenDs` \ case_bndr ->
newSysLocalsDs data_con_arg_tys `thenDs` \ vars@[l_var, r_var, arr_cts_var] ->
returnDs (Var arr_cts_var,
--- gaw 2004
\ body -> Case arg case_bndr (exprType body) [(DataAlt data_con,vars,body)]
)
@@ -309,7 +306,6 @@ boxResult arg_ids augment mbTopCon result_ty
Lam state_id $
Case (App the_call (Var state_id))
(mkWildId ccall_res_ty)
--- gaw 2004
(coreAltType the_alt)
[the_alt]
]
@@ -327,7 +323,6 @@ boxResult arg_ids augment mbTopCon result_ty
let
wrap = \ the_call -> Case (App the_call (Var realWorldPrimId))
(mkWildId ccall_res_ty)
--- gaw 2004
(coreAltType the_alt)
[the_alt]
in
@@ -397,7 +392,6 @@ resultWrapper result_ty
| Just (tc,_) <- maybe_tc_app, tc `hasKey` boolTyConKey
= returnDs
(Just intPrimTy, \e -> Case e (mkWildId intPrimTy)
--- gaw 2004
boolTy
[(DEFAULT ,[],Var trueDataConId ),
(LitAlt (mkMachInt 0),[],Var falseDataConId)])
diff --git a/ghc/compiler/deSugar/DsListComp.lhs b/ghc/compiler/deSugar/DsListComp.lhs
index 8491613e1d..9f19dd152f 100644
--- a/ghc/compiler/deSugar/DsListComp.lhs
+++ b/ghc/compiler/deSugar/DsListComp.lhs
@@ -212,10 +212,10 @@ deBindComp pat core_list1 quals core_list2
rest_expr core_fail `thenDs` \ core_match ->
let
rhs = Lam u1 $
--- gaw 2004
Case (Var u1) u1 res_ty
[(DataAlt nilDataCon, [], core_list2),
(DataAlt consDataCon, [u2, u3], core_match)]
+ -- Increasing order of tag
in
returnDs (Let (Rec [(h, rhs)]) letrec_body)
\end{code}
@@ -250,11 +250,10 @@ mkZipBind elt_tys
zip_fn_ty = mkFunTys list_tys list_ret_ty
mk_case (as, a', as') rest
--- gaw 2004
= Case (Var as) as list_ret_ty
[(DataAlt nilDataCon, [], mkNilExpr ret_elt_ty),
(DataAlt consDataCon, [a', as'], rest)]
-
+ -- Increasing order of tag
-- Helper functions that makes an HsTuple only for non-1-sized tuples
mk_hs_tuple_expr :: [Id] -> LHsExpr Id
mk_hs_tuple_expr [] = nlHsVar unitDataConId
diff --git a/ghc/compiler/deSugar/DsUtils.lhs b/ghc/compiler/deSugar/DsUtils.lhs
index 931bcc9029..10fd4abb55 100644
--- a/ghc/compiler/deSugar/DsUtils.lhs
+++ b/ghc/compiler/deSugar/DsUtils.lhs
@@ -52,9 +52,9 @@ import Var ( Var )
import Name ( Name )
import Literal ( Literal(..), mkStringLit, inIntRange, tARGET_MAX_INT )
import TyCon ( isNewTyCon, tyConDataCons )
-import DataCon ( DataCon, dataConSourceArity, dataConTyCon )
+import DataCon ( DataCon, dataConSourceArity, dataConTyCon, dataConTag )
import Type ( mkFunTy, isUnLiftedType, Type, splitTyConApp, mkTyVarTy )
-import TcType ( tcTyConAppTyCon, tcEqType )
+import TcType ( tcEqType )
import TysPrim ( intPrimTy )
import TysWiredIn ( nilDataCon, consDataCon,
tupleCon, mkTupleTy,
@@ -70,8 +70,8 @@ import PrelNames ( unpackCStringName, unpackCStringUtf8Name,
lengthPName, indexPName )
import Outputable
import UnicodeUtil ( intsToUtf8 )
-import SrcLoc ( Located(..), unLoc, noLoc )
-import Util ( isSingleton, notNull, zipEqual )
+import SrcLoc ( Located(..), unLoc )
+import Util ( isSingleton, notNull, zipEqual, sortWith )
import ListSetOps ( assocDefault )
import FastString
\end{code}
@@ -302,9 +302,10 @@ mkCoPrimCaseMatchResult var ty match_alts
= MatchResult CanFail mk_case
where
mk_case fail
- = mappM (mk_alt fail) match_alts `thenDs` \ alts ->
+ = mappM (mk_alt fail) sorted_alts `thenDs` \ alts ->
returnDs (Case (Var var) var ty ((DEFAULT, [], fail) : alts))
+ sorted_alts = sortWith fst match_alts -- Right order for a Case
mk_alt fail (lit, MatchResult _ body_fn) = body_fn fail `thenDs` \ body ->
returnDs (LitAlt lit, [], body)
@@ -343,7 +344,9 @@ mkCoAlgCaseMatchResult var ty match_alts
= CanFail
wild_var = mkWildId (idType var)
- mk_case fail = mappM (mk_alt fail) match_alts `thenDs` \ alts ->
+ sorted_alts = sortWith get_tag match_alts
+ get_tag (con, _, _) = dataConTag con
+ mk_case fail = mappM (mk_alt fail) sorted_alts `thenDs` \ alts ->
returnDs (Case (Var var) wild_var ty (mk_default fail ++ alts))
mk_alt fail (con, args, MatchResult _ body_fn)
@@ -401,8 +404,8 @@ mkCoAlgCaseMatchResult var ty match_alts
--
unboxAlt =
newSysLocalDs intPrimTy `thenDs` \l ->
- dsLookupGlobalId indexPName `thenDs` \indexP ->
- mappM (mkAlt indexP) match_alts `thenDs` \alts ->
+ dsLookupGlobalId indexPName `thenDs` \indexP ->
+ mappM (mkAlt indexP) sorted_alts `thenDs` \alts ->
returnDs (DataAlt intDataCon, [l], (Case (Var l) wild ty (dft : alts)))
where
wild = mkWildId intPrimTy
@@ -772,7 +775,6 @@ mkSmallTupleCase
mkSmallTupleCase [var] body _scrut_var scrut
= bindNonRec var scrut body
mkSmallTupleCase vars body scrut_var scrut
--- gaw 2004
-- One branch no refinement?
= Case scrut scrut_var (exprType body) [(DataAlt (tupleCon Boxed (length vars)), vars, body)]
\end{code}
@@ -824,7 +826,6 @@ mkCoreSel [var] should_be_the_same_var scrut_var scrut
mkCoreSel vars the_var scrut_var scrut
= ASSERT( notNull vars )
--- gaw 2004
Case scrut scrut_var (idType the_var)
[(DataAlt (tupleCon Boxed (length vars)), vars, Var the_var)]
\end{code}
diff --git a/ghc/compiler/deSugar/MatchLit.lhs b/ghc/compiler/deSugar/MatchLit.lhs
index ea307ac45c..75a0a62d6d 100644
--- a/ghc/compiler/deSugar/MatchLit.lhs
+++ b/ghc/compiler/deSugar/MatchLit.lhs
@@ -25,7 +25,7 @@ import PrelNames ( ratioTyConKey )
import TysWiredIn ( stringTy, consDataCon, intDataCon, floatDataCon, doubleDataCon )
import Unique ( hasKey )
import Literal ( mkMachInt, Literal(..) )
-import SrcLoc ( noLoc, unLoc )
+import SrcLoc ( noLoc )
import ListSetOps ( equivClasses, runs )
import Ratio ( numerator, denominator )
import SrcLoc ( Located(..) )
diff --git a/ghc/compiler/iface/TcIface.lhs b/ghc/compiler/iface/TcIface.lhs
index 7f4e83e395..63be22cd54 100644
--- a/ghc/compiler/iface/TcIface.lhs
+++ b/ghc/compiler/iface/TcIface.lhs
@@ -642,7 +642,6 @@ tcIfaceExpr (IfaceApp fun arg)
tcIfaceExpr arg `thenM` \ arg' ->
returnM (App fun' arg')
--- gaw 2004
tcIfaceExpr (IfaceCase scrut case_bndr ty alts)
= tcIfaceExpr scrut `thenM` \ scrut' ->
newIfaceName case_bndr `thenM` \ case_bndr_name ->
diff --git a/ghc/compiler/main/TidyPgm.lhs b/ghc/compiler/main/TidyPgm.lhs
index bcafd651bc..a4fb275926 100644
--- a/ghc/compiler/main/TidyPgm.lhs
+++ b/ghc/compiler/main/TidyPgm.lhs
@@ -644,14 +644,13 @@ cafRefs p (Var id)
Just id' -> fastBool (mayHaveCafRefs (idCafInfo id'))
Nothing -> fastBool False
-cafRefs p (Lit l) = fastBool False
-cafRefs p (App f a) = fastOr (cafRefs p f) (cafRefs p) a
-cafRefs p (Lam x e) = cafRefs p e
-cafRefs p (Let b e) = fastOr (cafRefss p (rhssOfBind b)) (cafRefs p) e
--- gaw 2004
+cafRefs p (Lit l) = fastBool False
+cafRefs p (App f a) = fastOr (cafRefs p f) (cafRefs p) a
+cafRefs p (Lam x e) = cafRefs p e
+cafRefs p (Let b e) = fastOr (cafRefss p (rhssOfBind b)) (cafRefs p) e
cafRefs p (Case e bndr _ alts) = fastOr (cafRefs p e) (cafRefss p) (rhssOfAlts alts)
-cafRefs p (Note n e) = cafRefs p e
-cafRefs p (Type t) = fastBool False
+cafRefs p (Note n e) = cafRefs p e
+cafRefs p (Type t) = fastBool False
cafRefss p [] = fastBool False
cafRefss p (e:es) = fastOr (cafRefs p e) (cafRefss p) es
diff --git a/ghc/compiler/ndpFlatten/Flattening.hs b/ghc/compiler/ndpFlatten/Flattening.hs
index 393762fe40..cd4bdd447f 100644
--- a/ghc/compiler/ndpFlatten/Flattening.hs
+++ b/ghc/compiler/ndpFlatten/Flattening.hs
@@ -285,7 +285,6 @@ vectorise (Let bind body) =
(vbody, vbodyTy) <- vectorise body
return ((Let vbind vbody), vbodyTy)
--- gaw 2004
vectorise (Case expr b ty alts) =
do
(vexpr, vexprTy) <- vectorise expr
diff --git a/ghc/compiler/ndpFlatten/NDPCoreUtils.hs b/ghc/compiler/ndpFlatten/NDPCoreUtils.hs
index 193f6028aa..85b0110be0 100644
--- a/ghc/compiler/ndpFlatten/NDPCoreUtils.hs
+++ b/ghc/compiler/ndpFlatten/NDPCoreUtils.hs
@@ -163,7 +163,6 @@ substIdEnv env (Let (Rec bnds) expr) =
newExpr = substIdEnv newEnv expr
substBnd (b,e) = (b, substIdEnv newEnv e)
in Let (Rec (map substBnd bnds)) newExpr
--- gaw 2004
substIdEnv env (Case expr b ty alts) =
Case (substIdEnv newEnv expr) b ty (map substAlt alts)
where
diff --git a/ghc/compiler/ndpFlatten/PArrAnal.hs b/ghc/compiler/ndpFlatten/PArrAnal.hs
index b4d084364b..2db56221b2 100644
--- a/ghc/compiler/ndpFlatten/PArrAnal.hs
+++ b/ghc/compiler/ndpFlatten/PArrAnal.hs
@@ -75,7 +75,6 @@ arrUsage (Let (Rec bnds) expr) =
t2 = arrUsage expr
in if isArrayUsage t1 then Array else t2
--- gaw 2004
arrUsage (Case expr b _ alts) =
let
t1 = arrUsage expr
diff --git a/ghc/compiler/prelude/PrelRules.lhs b/ghc/compiler/prelude/PrelRules.lhs
index 4fdec53451..3ab8d6eedc 100644
--- a/ghc/compiler/prelude/PrelRules.lhs
+++ b/ghc/compiler/prelude/PrelRules.lhs
@@ -289,7 +289,6 @@ litEq is_eq [expr, Lit lit] = do_lit_eq is_eq lit expr
litEq is_eq other = Nothing
do_lit_eq is_eq lit expr
--- gaw 2004
= Just (Case expr (mkWildId (literalType lit)) boolTy
[(DEFAULT, [], val_if_neq),
(LitAlt lit, [], val_if_eq)])
diff --git a/ghc/compiler/simplCore/FloatIn.lhs b/ghc/compiler/simplCore/FloatIn.lhs
index 061cd4b85d..0ca2257189 100644
--- a/ghc/compiler/simplCore/FloatIn.lhs
+++ b/ghc/compiler/simplCore/FloatIn.lhs
@@ -323,7 +323,6 @@ bindings are: (a)~inside the scrutinee, (b)~inside one of the
alternatives/default [default FVs always {\em first}!].
\begin{code}
--- gaw 2004
fiExpr to_drop (_, AnnCase scrut case_bndr ty alts)
= mkCoLets' drop_here1 $
mkCoLets' drop_here2 $
diff --git a/ghc/compiler/simplCore/FloatOut.lhs b/ghc/compiler/simplCore/FloatOut.lhs
index b14f04230c..e3b877e975 100644
--- a/ghc/compiler/simplCore/FloatOut.lhs
+++ b/ghc/compiler/simplCore/FloatOut.lhs
@@ -330,7 +330,6 @@ floatExpr lvl (Let bind body)
where
bind_lvl = getBindLevel bind
--- gaw 2004
floatExpr lvl (Case scrut (TB case_bndr case_lvl) ty alts)
= case floatExpr lvl scrut of { (fse, fde, scrut') ->
case floatList float_alt alts of { (fsa, fda, alts') ->
diff --git a/ghc/compiler/simplCore/LiberateCase.lhs b/ghc/compiler/simplCore/LiberateCase.lhs
index 8df30e1416..a1a41315ef 100644
--- a/ghc/compiler/simplCore/LiberateCase.lhs
+++ b/ghc/compiler/simplCore/LiberateCase.lhs
@@ -220,7 +220,6 @@ libCase env (Let bind body)
where
(env_body, bind') = libCaseBind env bind
--- gaw 2004
libCase env (Case scrut bndr ty alts)
= Case (libCase env scrut) bndr ty (map (libCaseAlt env_alts) alts)
where
diff --git a/ghc/compiler/simplCore/OccurAnal.lhs b/ghc/compiler/simplCore/OccurAnal.lhs
index 5ea95a25c5..bc45befbc2 100644
--- a/ghc/compiler/simplCore/OccurAnal.lhs
+++ b/ghc/compiler/simplCore/OccurAnal.lhs
@@ -648,10 +648,9 @@ occAnal env expr@(Lam _ _)
env2 = env1 `addNewCands` binders -- Add in-scope binders
env_body = vanillaCtxt env2 -- Body is (no longer) an RhsContext
--- gaw 2004
occAnal env (Case scrut bndr ty alts)
= case mapAndUnzip (occAnalAlt alt_env bndr) alts of { (alts_usage_s, alts') ->
- case occAnal (vanillaCtxt env) scrut of { (scrut_usage, scrut') ->
+ case occAnal (vanillaCtxt env) scrut of { (scrut_usage, scrut') ->
-- No need for rhsCtxt
let
alts_usage = foldr1 combineAltsUsageDetails alts_usage_s
@@ -659,7 +658,6 @@ occAnal env (Case scrut bndr ty alts)
(alts_usage1, tagged_bndr) = tagBinder alts_usage' bndr
total_usage = scrut_usage `combineUsageDetails` alts_usage1
in
--- gaw 2004
total_usage `seq` (total_usage, Case scrut' tagged_bndr ty alts') }}
where
alt_env = env `addNewCand` bndr
diff --git a/ghc/compiler/simplCore/SetLevels.lhs b/ghc/compiler/simplCore/SetLevels.lhs
index 08f3d8406b..d0f043b3c9 100644
--- a/ghc/compiler/simplCore/SetLevels.lhs
+++ b/ghc/compiler/simplCore/SetLevels.lhs
@@ -332,7 +332,6 @@ lvlExpr ctxt_lvl env (_, AnnLet bind body)
lvlExpr ctxt_lvl new_env body `thenLvl` \ body' ->
returnLvl (Let bind' body')
--- gaw 2004
lvlExpr ctxt_lvl env (_, AnnCase expr case_bndr ty alts)
= lvlMFE True ctxt_lvl env expr `thenLvl` \ expr' ->
let
diff --git a/ghc/compiler/simplCore/SimplUtils.lhs b/ghc/compiler/simplCore/SimplUtils.lhs
index 60892770d6..960ab4504b 100644
--- a/ghc/compiler/simplCore/SimplUtils.lhs
+++ b/ghc/compiler/simplCore/SimplUtils.lhs
@@ -834,8 +834,8 @@ of the inner case y, which give us nowhere to go!
\begin{code}
prepareAlts :: OutExpr -- Scrutinee
-> InId -- Case binder
- -> [InAlt]
- -> SimplM ([InAlt], -- Better alternatives
+ -> [InAlt] -- Increasing order
+ -> SimplM ([InAlt], -- Better alternatives, still incresaing order
[AltCon]) -- These cases are handled
prepareAlts scrut case_bndr alts
@@ -861,7 +861,9 @@ prepareAlts scrut case_bndr alts
-- is only one constructor left
prepareDefault case_bndr handled_cons maybe_deflt `thenSmpl` \ deflt_alt ->
- returnSmpl (deflt_alt ++ better_alts, handled_cons)
+ returnSmpl (mergeAlts better_alts deflt_alt, handled_cons)
+ -- We need the mergeAlts in case the new default_alt
+ -- has turned into a constructor alternative.
prepareDefault case_bndr handled_cons (Just rhs)
| Just (tycon, inst_tys) <- splitTyConApp_maybe (idType case_bndr),
@@ -929,10 +931,13 @@ mk_tv_bndrs missing_con inst_tys
mkCase puts a case expression back together, trying various transformations first.
\begin{code}
-mkCase :: OutExpr -> OutId -> OutType -> [OutAlt] -> SimplM OutExpr
+mkCase :: OutExpr -> OutId -> OutType
+ -> [OutAlt] -- Increasing order
+ -> SimplM OutExpr
mkCase scrut case_bndr ty alts
- = mkAlts scrut case_bndr alts `thenSmpl` \ better_alts ->
+ = getDOptsSmpl `thenSmpl` \dflags ->
+ mkAlts dflags scrut case_bndr alts `thenSmpl` \ better_alts ->
mkCase1 scrut case_bndr ty better_alts
\end{code}
@@ -998,7 +1003,7 @@ and similarly in cascade for all the join points!
--------------------------------------------------
-- 1. Merge identical branches
--------------------------------------------------
-mkAlts scrut case_bndr alts@((con1,bndrs1,rhs1) : con_alts)
+mkAlts dflags scrut case_bndr alts@((con1,bndrs1,rhs1) : con_alts)
| all isDeadBinder bndrs1, -- Remember the default
length filtered_alts < length con_alts -- alternative comes first
= tick (AltMerge case_bndr) `thenSmpl_`
@@ -1013,56 +1018,53 @@ mkAlts scrut case_bndr alts@((con1,bndrs1,rhs1) : con_alts)
-- 2. Merge nested cases
--------------------------------------------------
-mkAlts scrut outer_bndr outer_alts
- = getDOptsSmpl `thenSmpl` \dflags ->
- mkAlts' dflags scrut outer_bndr outer_alts
- where
- mkAlts' dflags scrut outer_bndr outer_alts
- | dopt Opt_CaseMerge dflags,
- (outer_alts_without_deflt, maybe_outer_deflt) <- findDefault outer_alts,
--- gaw 2004
- Just (Case (Var scrut_var) inner_bndr _ inner_alts) <- maybe_outer_deflt,
- scruting_same_var scrut_var
-
- = let -- Eliminate any inner alts which are shadowed by the outer ones
- outer_cons = [con | (con,_,_) <- outer_alts_without_deflt]
-
- munged_inner_alts = [ (con, args, munge_rhs rhs)
- | (con, args, rhs) <- inner_alts,
- not (con `elem` outer_cons) -- Eliminate shadowed inner alts
- ]
- munge_rhs rhs = bindCaseBndr inner_bndr (Var outer_bndr) rhs
-
- (inner_con_alts, maybe_inner_default) = findDefault munged_inner_alts
-
- new_alts = add_default maybe_inner_default
- (outer_alts_without_deflt ++ inner_con_alts)
+mkAlts dflags scrut outer_bndr outer_alts
+ | dopt Opt_CaseMerge dflags,
+ (outer_alts_without_deflt, maybe_outer_deflt) <- findDefault outer_alts,
+ Just (Case (Var scrut_var) inner_bndr _ inner_alts) <- maybe_outer_deflt,
+ scruting_same_var scrut_var
+ = let
+ munged_inner_alts = [(con, args, munge_rhs rhs) | (con, args, rhs) <- inner_alts]
+ munge_rhs rhs = bindCaseBndr inner_bndr (Var outer_bndr) rhs
+
+ new_alts = mergeAlts outer_alts_without_deflt munged_inner_alts
+ -- The merge keeps the inner DEFAULT at the front, if there is one
+ -- and eliminates any inner_alts that are shadowed by the outer_alts
in
tick (CaseMerge outer_bndr) `thenSmpl_`
returnSmpl new_alts
- -- Warning: don't call mkAlts recursively!
- -- Firstly, there's no point, because inner alts have already had
- -- mkCase applied to them, so they won't have a case in their default
- -- Secondly, if you do, you get an infinite loop, because the bindCaseBndr
- -- in munge_rhs may put a case into the DEFAULT branch!
- where
- -- We are scrutinising the same variable if it's
- -- the outer case-binder, or if the outer case scrutinises a variable
- -- (and it's the same). Testing both allows us not to replace the
- -- outer scrut-var with the outer case-binder (Simplify.simplCaseBinder).
- scruting_same_var = case scrut of
+ -- Warning: don't call mkAlts recursively!
+ -- Firstly, there's no point, because inner alts have already had
+ -- mkCase applied to them, so they won't have a case in their default
+ -- Secondly, if you do, you get an infinite loop, because the bindCaseBndr
+ -- in munge_rhs may put a case into the DEFAULT branch!
+ where
+ -- We are scrutinising the same variable if it's
+ -- the outer case-binder, or if the outer case scrutinises a variable
+ -- (and it's the same). Testing both allows us not to replace the
+ -- outer scrut-var with the outer case-binder (Simplify.simplCaseBinder).
+ scruting_same_var = case scrut of
Var outer_scrut -> \ v -> v == outer_bndr || v == outer_scrut
other -> \ v -> v == outer_bndr
- add_default (Just rhs) alts = (DEFAULT,[],rhs) : alts
- add_default Nothing alts = alts
-
-
---------------------------------------------------
+------------------------------------------------
-- Catch-all
---------------------------------------------------
-
- mkAlts' dflags scrut case_bndr other_alts = returnSmpl other_alts
+------------------------------------------------
+
+mkAlts dflags scrut case_bndr other_alts = returnSmpl other_alts
+
+
+---------------------------------
+mergeAlts :: [OutAlt] -> [OutAlt] -> [OutAlt]
+-- Merge preserving order; alternatives in the first arg
+-- shadow ones in the second
+mergeAlts [] as2 = as2
+mergeAlts as1 [] = as1
+mergeAlts (a1:as1) (a2:as2)
+ = case a1 `cmpAlt` a2 of
+ LT -> a1 : mergeAlts as1 (a2:as2)
+ EQ -> a1 : mergeAlts as1 as2 -- Discard a2
+ GT -> a2 : mergeAlts (a1:as1) as2
\end{code}
@@ -1285,7 +1287,6 @@ mkCase1 scrut case_bndr ty alts -- Identity case
--------------------------------------------------
-- Catch-all
--------------------------------------------------
--- gaw 2004
mkCase1 scrut bndr ty alts = returnSmpl (Case scrut bndr ty alts)
\end{code}
diff --git a/ghc/compiler/simplCore/Simplify.lhs b/ghc/compiler/simplCore/Simplify.lhs
index 15bd6123db..0f0616e9d3 100644
--- a/ghc/compiler/simplCore/Simplify.lhs
+++ b/ghc/compiler/simplCore/Simplify.lhs
@@ -49,8 +49,7 @@ import Rules ( lookupRule )
import BasicTypes ( isMarkedStrict )
import CostCentre ( currentCCS )
import Type ( TvSubstEnv, isUnLiftedType, seqType, tyConAppArgs, funArgTy,
- splitFunTy_maybe, splitFunTy, coreEqType, substTy,
- mkTyVarTys, mkTyConApp
+ splitFunTy_maybe, splitFunTy, coreEqType, substTy, mkTyVarTys
)
import VarEnv ( elemVarEnv )
import Subst ( SubstResult(..), emptySubst, substExpr,
@@ -64,7 +63,7 @@ import OrdList
import Maybe ( Maybe )
import Maybes ( orElse )
import Outputable
-import Util ( notNull, equalLength )
+import Util ( notNull )
\end{code}
@@ -350,7 +349,6 @@ simplNonRecX env bndr new_rhs thing_inside
-- because quotInt# can fail.
= simplBinder env bndr `thenSmpl` \ (env, bndr') ->
thing_inside env `thenSmpl` \ (floats, body) ->
--- gaw 2004
let body' = wrapFloats floats body in
returnSmpl (emptyFloats env, Case new_rhs bndr' (exprType body') [(DEFAULT, [], body')])
@@ -733,7 +731,6 @@ simplExprF env (Type ty) cont
simplType env ty `thenSmpl` \ ty' ->
rebuild env (Type ty') cont
--- gaw 2004
simplExprF env (Case scrut bndr case_ty alts) cont
| not (switchIsOn (getSwitchChecker env) NoCaseOfCase)
= -- Simplify the scrutinee with a Select continuation
@@ -1290,7 +1287,7 @@ Blob of helper functions for the "case-of-something-else" situation.
rebuildCase :: SimplEnv
-> OutExpr -- Scrutinee
-> InId -- Case binder
- -> [InAlt] -- Alternatives
+ -> [InAlt] -- Alternatives (inceasing order)
-> SimplCont
-> SimplM FloatsWithExpr
diff --git a/ghc/compiler/specialise/Rules.lhs b/ghc/compiler/specialise/Rules.lhs
index e09dc22c0b..095a0a5358 100644
--- a/ghc/compiler/specialise/Rules.lhs
+++ b/ghc/compiler/specialise/Rules.lhs
@@ -32,7 +32,6 @@ import BasicTypes ( Activation, CompilerPhase, isActive )
import Outputable
import FastString
import Maybe ( isJust, fromMaybe )
-import Util ( sortLe )
import Bag
import List ( isPrefixOf )
\end{code}
@@ -263,7 +262,7 @@ match menv subst (Case e1 x1 ty1 alts1) (Case e2 x2 ty2 alts2)
= do { subst1 <- match_ty menv subst ty1 ty2
; subst2 <- match menv subst1 e1 e2
; let menv' = menv { me_env = rnBndr2 (me_env menv) x2 x2 }
- ; match_alts menv' subst2 (sortLe le_alt alts1) (sortLe le_alt alts2)
+ ; match_alts menv' subst2 alts1 alts2 -- Alts are both sorted
}
match menv subst (Type ty1) (Type ty2)
@@ -311,8 +310,6 @@ match_alts menv subst ((c1,vs1,r1):alts1) ((c2,vs2,r2):alts2)
match_alts menv subst alts1 alts2
= Nothing
-
-le_alt (con1, _, _) (con2, _, _) = con1 <= con2
\end{code}
Matching Core types: use the matcher in TcType.
@@ -450,7 +447,6 @@ ruleCheck env (App f a) = ruleCheckApp env (App f a) []
ruleCheck env (Note n e) = ruleCheck env e
ruleCheck env (Let bd e) = ruleCheckBind env bd `unionBags` ruleCheck env e
ruleCheck env (Lam b e) = ruleCheck env e
--- gaw 2004
ruleCheck env (Case e _ _ as) = ruleCheck env e `unionBags`
unionManyBags [ruleCheck env r | (_,_,r) <- as]
diff --git a/ghc/compiler/specialise/SpecConstr.lhs b/ghc/compiler/specialise/SpecConstr.lhs
index e07470be1e..eb516869b0 100644
--- a/ghc/compiler/specialise/SpecConstr.lhs
+++ b/ghc/compiler/specialise/SpecConstr.lhs
@@ -335,11 +335,9 @@ scExpr env (Note n e) = scExpr env e `thenUs` \ (usg,e') ->
scExpr env (Lam b e) = scExpr (extendBndr env b) e `thenUs` \ (usg,e') ->
returnUs (usg, Lam b e')
--- gaw 2004
scExpr env (Case scrut b ty alts)
= sc_scrut scrut `thenUs` \ (scrut_usg, scrut') ->
mapAndUnzipUs sc_alt alts `thenUs` \ (alts_usgs, alts') ->
--- gaw 2004
returnUs (combineUsages alts_usgs `combineUsage` scrut_usg,
Case scrut' b ty alts')
where
diff --git a/ghc/compiler/specialise/Specialise.lhs b/ghc/compiler/specialise/Specialise.lhs
index 1813d7ef97..2863348904 100644
--- a/ghc/compiler/specialise/Specialise.lhs
+++ b/ghc/compiler/specialise/Specialise.lhs
@@ -659,9 +659,8 @@ specExpr subst e@(Lam _ _)
-- More efficient to collect a group of binders together all at once
-- and we don't want to split a lambda group with dumped bindings
--- gaw 2004
specExpr subst (Case scrut case_bndr ty alts)
- = specExpr subst scrut `thenSM` \ (scrut', uds_scrut) ->
+ = specExpr subst scrut `thenSM` \ (scrut', uds_scrut) ->
mapAndCombineSM spec_alt alts `thenSM` \ (alts', uds_alts) ->
returnSM (Case scrut' case_bndr' (substTy subst ty) alts', uds_scrut `plusUDs` uds_alts)
where
diff --git a/ghc/compiler/stgSyn/CoreToStg.lhs b/ghc/compiler/stgSyn/CoreToStg.lhs
index 9397af6c74..e351ea4a27 100644
--- a/ghc/compiler/stgSyn/CoreToStg.lhs
+++ b/ghc/compiler/stgSyn/CoreToStg.lhs
@@ -333,7 +333,6 @@ coreToStgExpr (Note other_note expr)
-- Cases require a little more real work.
--- gaw 2004
coreToStgExpr (Case scrut bndr _ alts)
= extendVarEnvLne [(bndr, LambdaBound)] (
mapAndUnzip3Lne vars_alt alts `thenLne` \ (alts2, fvs_s, escs_s) ->
diff --git a/ghc/compiler/stranal/DmdAnal.lhs b/ghc/compiler/stranal/DmdAnal.lhs
index 903cff200d..8928b20b7a 100644
--- a/ghc/compiler/stranal/DmdAnal.lhs
+++ b/ghc/compiler/stranal/DmdAnal.lhs
@@ -204,7 +204,6 @@ dmdAnal sigs dmd (Lam var body)
in
(deferType lam_ty, Lam var' body')
--- gaw 2004
dmdAnal sigs dmd (Case scrut case_bndr ty [alt@(DataAlt dc,bndrs,rhs)])
| let tycon = dataConTyCon dc,
isProductTyCon tycon,
@@ -251,10 +250,8 @@ dmdAnal sigs dmd (Case scrut case_bndr ty [alt@(DataAlt dc,bndrs,rhs)])
(scrut_ty, scrut') = dmdAnal sigs scrut_dmd scrut
in
--- gaw 2004
(alt_ty1 `bothType` scrut_ty, Case scrut' case_bndr' ty [alt'])
--- gaw 2004
dmdAnal sigs dmd (Case scrut case_bndr ty alts)
= let
(alt_tys, alts') = mapAndUnzip (dmdAnalAlt sigs dmd) alts
@@ -262,7 +259,6 @@ dmdAnal sigs dmd (Case scrut case_bndr ty alts)
(alt_ty, case_bndr') = annotateBndr (foldr1 lubType alt_tys) case_bndr
in
-- pprTrace "dmdAnal:Case" (ppr alts $$ ppr alt_tys)
--- gaw 2004
(alt_ty `bothType` scrut_ty, Case scrut' case_bndr' ty alts')
dmdAnal sigs dmd (Let (NonRec id rhs) body)
diff --git a/ghc/compiler/stranal/WorkWrap.lhs b/ghc/compiler/stranal/WorkWrap.lhs
index 276d8da52f..f407691db9 100644
--- a/ghc/compiler/stranal/WorkWrap.lhs
+++ b/ghc/compiler/stranal/WorkWrap.lhs
@@ -158,11 +158,9 @@ wwExpr (Let bind expr)
wwExpr expr `thenUs` \ new_expr ->
returnUs (mkLets intermediate_bind new_expr)
--- gaw 2004
wwExpr (Case expr binder ty alts)
= wwExpr expr `thenUs` \ new_expr ->
mapUs ww_alt alts `thenUs` \ new_alts ->
--- gaw 2004
returnUs (Case new_expr binder ty new_alts)
where
ww_alt (con, binders, rhs)
diff --git a/ghc/compiler/stranal/WwLib.lhs b/ghc/compiler/stranal/WwLib.lhs
index b84f9c60b3..3d595394b5 100644
--- a/ghc/compiler/stranal/WwLib.lhs
+++ b/ghc/compiler/stranal/WwLib.lhs
@@ -429,7 +429,6 @@ mkWWcpr body_ty RetCPR
arg = mk_ww_local arg_uniq con_arg_ty1
con_app = mkConApp data_con (map Type tycon_arg_tys ++ [Var arg])
in
--- gaw 2004
returnUs (\ wkr_call -> Case wkr_call arg (exprType con_app) [(DEFAULT, [], con_app)],
\ body -> workerCase body work_wild con_arg_ty1 [(DataAlt data_con, [arg], Var arg)],
con_arg_ty1)
@@ -446,7 +445,6 @@ mkWWcpr body_ty RetCPR
ubx_tup_app = mkConApp ubx_tup_con (map Type con_arg_tys ++ arg_vars)
con_app = mkConApp data_con (map Type tycon_arg_tys ++ arg_vars)
in
--- gaw 2004
returnUs (\ wkr_call -> Case wkr_call wrap_wild (exprType con_app) [(DataAlt ubx_tup_con, args, con_app)],
\ body -> workerCase body work_wild ubx_tup_ty [(DataAlt data_con, args, ubx_tup_app)],
ubx_tup_ty)
@@ -469,9 +467,7 @@ mkWWcpr body_ty other -- No CPR info
-- This transform doesn't move work or allocation
-- from one cost centre to another
--- gaw 2004
workerCase (Note (SCC cc) e) arg ty alts = Note (SCC cc) (Case e arg ty alts)
--- gaw 2004
workerCase e arg ty alts = Case e arg ty alts
\end{code}
@@ -498,11 +494,9 @@ mk_unpk_case arg unpk_args boxing_con boxing_tycon body
-- A data type
= Case (Var arg)
(sanitiseCaseBndr arg)
--- gaw 2004
(exprType body)
[(DataAlt boxing_con, unpk_args, body)]
--- gaw 2004
mk_seq_case arg body = Case (Var arg) (sanitiseCaseBndr arg) (exprType body) [(DEFAULT, [], body)]
sanitiseCaseBndr :: Id -> Id
diff --git a/ghc/compiler/types/TyCon.lhs b/ghc/compiler/types/TyCon.lhs
index 9fad373410..7fdf2e3a29 100644
--- a/ghc/compiler/types/TyCon.lhs
+++ b/ghc/compiler/types/TyCon.lhs
@@ -177,6 +177,8 @@ data AlgTyConRhs
-- e.g. data T a where { ... }
[DataCon] -- The constructors; can be empty if the user declares
-- the type to have no constructors
+ -- INVARIANT: Kept in order of increasing tag
+ -- (see the tag assignment in DataCon.mkDataCon)
Bool -- Cached: True <=> an enumeration type
| NewTyCon -- Newtypes always have exactly one constructor
diff --git a/ghc/compiler/utils/Util.lhs b/ghc/compiler/utils/Util.lhs
index 6d2be048be..a23b2d748c 100644
--- a/ghc/compiler/utils/Util.lhs
+++ b/ghc/compiler/utils/Util.lhs
@@ -21,7 +21,7 @@ module Util (
nTimes,
-- sorting
- sortLe,
+ sortLe, sortWith,
-- transitive closures
transitiveClosure,
@@ -426,6 +426,11 @@ mergeSortLe le = generalMergeSort le
sortLe :: (a->a->Bool) -> [a] -> [a]
sortLe le = generalNaturalMergeSort le
+
+sortWith :: Ord b => (a->b) -> [a] -> [a]
+sortWith get_key xs = sortLe le xs
+ where
+ x `le` y = get_key x < get_key y
\end{code}
%************************************************************************