X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FsimplCore%2FOccurAnal.lhs;h=4082fcc757a7a35d7eec4acf4fba6223d626bdae;hb=129e40f1ba90cdccee79009a33482dcfd537fd88;hp=00fdebe234b3049f89743d13cb2e6028f3681a94;hpb=b7d8dffaf1fefdf2f6b52fcf039a06843a28d586;p=ghc-hetmet.git diff --git a/compiler/simplCore/OccurAnal.lhs b/compiler/simplCore/OccurAnal.lhs index 00fdebe..4082fcc 100644 --- a/compiler/simplCore/OccurAnal.lhs +++ b/compiler/simplCore/OccurAnal.lhs @@ -455,6 +455,11 @@ occAnal env (Note note body) = case occAnal env body of { (usage, body') -> (usage, Note note body') } + +occAnal env (Cast expr co) + = case occAnal env expr of { (usage, expr') -> + (usage, Cast expr' co) + } \end{code} \begin{code} @@ -502,8 +507,8 @@ occAnal env expr@(Lam _ _) is_one_shot b = isId b && isOneShotBndr b occAnal env (Case scrut bndr ty alts) - = case occ_anal_scrut scrut alts of { (scrut_usage, scrut') -> - case mapAndUnzip (occAnalAlt env bndr) alts of { (alts_usage_s, alts') -> + = case occ_anal_scrut scrut alts of { (scrut_usage, scrut') -> + case mapAndUnzip (occAnalAlt alt_env bndr) alts of { (alts_usage_s, alts') -> let alts_usage = foldr1 combineAltsUsageDetails alts_usage_s alts_usage' = addCaseBndrUsage alts_usage @@ -523,6 +528,10 @@ occAnal env (Case scrut bndr ty alts) Nothing -> usage Just occ -> extendVarEnv usage bndr (markMany occ) + alt_env = setVanillaCtxt env + -- Consider x = case v of { True -> (p,q); ... } + -- Then it's fine to inline p and q + occ_anal_scrut (Var v) (alt1 : other_alts) | not (null other_alts) || not (isDefaultAlt alt1) = (mkOneOcc env v True, Var v) @@ -545,7 +554,6 @@ Applications are dealt with specially because we want the "build hack" to work. \begin{code} --- Hack for build, fold, runST occAnalApp env (Var fun, args) is_rhs = case args_stuff of { (args_uds, args') -> let @@ -566,6 +574,8 @@ occAnalApp env (Var fun, args) is_rhs where fun_uniq = idUnique fun fun_uds = mkOneOcc env fun (valArgCount args > 0) + + -- Hack for build, fold, runST args_stuff | fun_uniq == buildIdKey = appSpecial env 2 [True,True] args | fun_uniq == augmentIdKey = appSpecial env 2 [True,True] args | fun_uniq == foldrIdKey = appSpecial env 3 [False,True] args @@ -627,15 +637,22 @@ is rather like If e turns out to be (e1,e2) we indeed get something like let a = e1; b = e2; x = (a,b) in rhs +Note [Aug 06]: I don't think this is necessary any more, and it helpe + to know when binders are unused. See esp the call to + isDeadBinder in Simplify.mkDupableAlt + \begin{code} occAnalAlt env case_bndr (con, bndrs, rhs) = case occAnal env rhs of { (rhs_usage, rhs') -> let (final_usage, tagged_bndrs) = tagBinders rhs_usage bndrs + final_bndrs = tagged_bndrs -- See Note [Aug06] above +{- final_bndrs | case_bndr `elemVarEnv` final_usage = bndrs | otherwise = tagged_bndrs -- Leave the binders untagged if the case -- binder occurs at all; see note above +-} in (final_usage, (con, final_bndrs, rhs')) } \end{code} @@ -685,6 +702,10 @@ rhsCtxt = OccEnv OccRhs [] isRhsEnv (OccEnv OccRhs _) = True isRhsEnv (OccEnv OccVanilla _) = False +setVanillaCtxt :: OccEnv -> OccEnv +setVanillaCtxt (OccEnv OccRhs ctxt_ty) = OccEnv OccVanilla ctxt_ty +setVanillaCtxt other_env = other_env + setCtxt :: OccEnv -> CtxtTy -> OccEnv setCtxt (OccEnv encl _) ctxt = OccEnv encl ctxt