X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FsimplCore%2FSimplUtils.lhs;h=2342491c6846a72a77fc6953f3934d28103948fb;hb=a35f75aa20bf0a329be0b782986c3e12155b4d49;hp=4a61341b5b95a8a150279a6df3a454f057f65d9c;hpb=a43af120cd6317d6b8269ff7811c60ed23ac10c2;p=ghc-hetmet.git diff --git a/compiler/simplCore/SimplUtils.lhs b/compiler/simplCore/SimplUtils.lhs index 4a61341..2342491 100644 --- a/compiler/simplCore/SimplUtils.lhs +++ b/compiler/simplCore/SimplUtils.lhs @@ -51,9 +51,8 @@ import Type ( Type, splitFunTys, dropForAlls, isStrictType, import Coercion ( isEqPredTy ) import Coercion ( Coercion, mkUnsafeCoercion, coercionKind ) -import TyCon ( tyConDataCons_maybe, isNewTyCon ) -import DataCon ( DataCon, dataConRepArity, dataConExTyVars, - dataConInstArgTys, dataConTyCon ) +import TyCon ( tyConDataCons_maybe, isClosedNewTyCon ) +import DataCon ( DataCon, dataConRepArity, dataConInstArgTys, dataConTyCon ) import VarSet import BasicTypes ( TopLevelFlag(..), isNotTopLevel, OccInfo(..), isLoopBreaker, isOneOcc, Activation, isAlwaysActive, isActive ) @@ -722,7 +721,8 @@ postInlineUnconditionally -> Bool postInlineUnconditionally env top_lvl bndr occ_info rhs unfolding | not active = False - | isLoopBreaker occ_info = False + | isLoopBreaker occ_info = False -- If it's a loop-breaker of any kind, dont' inline + -- because it might be referred to "earlier" | isExportedId bndr = False | exprIsTrivial rhs = True | otherwise @@ -1139,27 +1139,6 @@ tryRhsTyLam env tyvars body -- Only does something if there's a let %* * %************************************************************************ -\begin{code} -mkDataConAlt :: DataCon -> [OutType] -> InExpr -> SimplM InAlt --- Make a data-constructor alternative to replace the DEFAULT case --- NB: there's something a bit bogus here, because we put OutTypes into an InAlt -mkDataConAlt con inst_tys rhs - = do { tv_uniqs <- getUniquesSmpl - ; arg_uniqs <- getUniquesSmpl - ; let tv_bndrs = zipWith mk_tv_bndr (dataConExTyVars con) tv_uniqs - arg_tys = dataConInstArgTys con (inst_tys ++ mkTyVarTys tv_bndrs) - arg_bndrs = zipWith mk_arg arg_tys arg_uniqs - ; return (DataAlt con, tv_bndrs ++ arg_bndrs, rhs) } - where - mk_arg arg_ty uniq -- Equality predicates get a TyVar - -- while dictionaries and others get an Id - | isEqPredTy arg_ty = mk_tv arg_ty uniq - | otherwise = mk_id arg_ty uniq - - mk_tv_bndr tv uniq = mk_tv (tyVarKind tv) uniq - mk_tv kind uniq = mkTyVar (mkSysTvName uniq FSLIT("t")) kind - mk_id ty uniq = mkSysLocal FSLIT("a") uniq ty -\end{code} mkCase puts a case expression back together, trying various transformations first. @@ -1483,36 +1462,31 @@ mkCase1 scrut case_bndr ty [(con,bndrs,rhs)] mkCase1 scrut case_bndr ty alts -- Identity case | all identity_alt alts = tick (CaseIdentity case_bndr) `thenSmpl_` - returnSmpl (re_note scrut) + returnSmpl (re_cast scrut) where - identity_alt (con, args, rhs) = de_note rhs `cheapEqExpr` identity_rhs con args + identity_alt (con, args, rhs) = de_cast rhs `cheapEqExpr` mk_id_rhs con args - identity_rhs (DataAlt con) args - | isNewTyCon (dataConTyCon con) - = wrapNewTypeBody (dataConTyCon con) arg_tys (varToCoreExpr $ head args) - | otherwise - = pprTrace "mkCase1" (ppr con) $ mkConApp con (arg_ty_exprs ++ varsToCoreExprs args) - identity_rhs (LitAlt lit) _ = Lit lit - identity_rhs DEFAULT _ = Var case_bndr + mk_id_rhs (DataAlt con) args = mkConApp con (arg_tys ++ varsToCoreExprs args) + mk_id_rhs (LitAlt lit) _ = Lit lit + mk_id_rhs DEFAULT _ = Var case_bndr - arg_tys = (tyConAppArgs (idType case_bndr)) - arg_ty_exprs = map Type arg_tys + arg_tys = map Type (tyConAppArgs (idType case_bndr)) -- We've seen this: - -- case coerce T e of x { _ -> coerce T' x } - -- And we definitely want to eliminate this case! - -- So we throw away notes from the RHS, and reconstruct - -- (at least an approximation) at the other end - de_note (Note _ e) = de_note e - de_note e = e - - -- re_note wraps a coerce if it might be necessary - re_note scrut = case head alts of - (_,_,rhs1@(Note _ _)) -> - let co = mkUnsafeCoercion (idType case_bndr) (exprType rhs1) in - -- this unsafeCoercion is bad, make this better - mkCoerce co scrut - other -> scrut + -- case e of x { _ -> x `cast` c } + -- And we definitely want to eliminate this case, to give + -- e `cast` c + -- So we throw away the cast from the RHS, and reconstruct + -- it at the other end. All the RHS casts must be the same + -- if (all identity_alt alts) holds. + -- + -- Don't worry about nested casts, because the simplifier combines them + de_cast (Cast e _) = e + de_cast e = e + + re_cast scrut = case head alts of + (_,_,Cast _ co) -> Cast scrut co + other -> scrut