diff options
Diffstat (limited to 'compiler/GHC/Core')
-rw-r--r-- | compiler/GHC/Core/Opt/Arity.hs | 3 | ||||
-rw-r--r-- | compiler/GHC/Core/Opt/DmdAnal.hs | 15 | ||||
-rw-r--r-- | compiler/GHC/Core/Opt/Simplify/Utils.hs | 9 | ||||
-rw-r--r-- | compiler/GHC/Core/Utils.hs | 13 |
4 files changed, 28 insertions, 12 deletions
diff --git a/compiler/GHC/Core/Opt/Arity.hs b/compiler/GHC/Core/Opt/Arity.hs index 6c0729ec5b..7125397637 100644 --- a/compiler/GHC/Core/Opt/Arity.hs +++ b/compiler/GHC/Core/Opt/Arity.hs @@ -359,6 +359,9 @@ this transformation. So we try to limit it as much as possible: Of course both (1) and (2) are readily defeated by disguising the bottoms. +Another place where -fpedantic-bottoms comes up is during eta-reduction. +See Note [Eta reduction soundness], the bit about -fpedantic-bottoms. + 4. Note [Newtype arity] ~~~~~~~~~~~~~~~~~~~~~~~~ Non-recursive newtypes are transparent, and should not get in the way. diff --git a/compiler/GHC/Core/Opt/DmdAnal.hs b/compiler/GHC/Core/Opt/DmdAnal.hs index ca51fd5f4c..b01e6f502a 100644 --- a/compiler/GHC/Core/Opt/DmdAnal.hs +++ b/compiler/GHC/Core/Opt/DmdAnal.hs @@ -413,7 +413,7 @@ dmdAnal' env dmd (App fun arg) -- , text "arg dmd =" <+> ppr arg_dmd -- , text "arg dmd_ty =" <+> ppr arg_ty -- , text "res dmd_ty =" <+> ppr res_ty --- , text "overall res dmd_ty =" <+> ppr (res_ty `bothDmdType` arg_ty) ]) +-- , text "overall res dmd_ty =" <+> ppr (res_ty `plusDmdType` arg_ty) ]) WithDmdType (res_ty `plusDmdType` arg_ty) (App fun' arg') dmdAnal' env dmd (Lam var body) @@ -447,7 +447,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty [Alt alt bndrs rhs]) -- What matters is its nested sub-demand! -- NB: If case_bndr_dmd is absDmd, boxity will say Unboxed, which is -- what we want, because then `seq` will put a `seqDmd` on its scrut. - (_ :* case_bndr_sd) = case_bndr_dmd + (_ :* case_bndr_sd) = strictifyDmd case_bndr_dmd -- Compute demand on the scrutinee -- FORCE the result, otherwise thunks will end up retaining the -- whole DmdEnv @@ -520,7 +520,7 @@ dmdAnal' env dmd (Case scrut case_bndr ty alts) in -- pprTrace "dmdAnal:Case2" (vcat [ text "scrut" <+> ppr scrut -- , text "scrut_ty" <+> ppr scrut_ty --- , text "alt_tys" <+> ppr alt_tys +-- , text "alt_ty1" <+> ppr alt_ty1 -- , text "alt_ty2" <+> ppr alt_ty2 -- , text "res_ty" <+> ppr res_ty ]) $ WithDmdType res_ty (Case scrut' case_bndr' ty alts') @@ -576,7 +576,8 @@ dmdAnalSumAlt env dmd case_bndr (Alt con bndrs rhs) (!_scrut_sd, dmds') = addCaseBndrDmd case_bndr_sd dmds -- Do not put a thunk into the Alt !new_ids = setBndrsDemandInfo bndrs dmds' - = WithDmdType alt_ty (Alt con new_ids rhs') + = -- pprTrace "dmdAnalSumAlt" (ppr con $$ ppr case_bndr $$ ppr dmd $$ ppr alt_ty) $ + WithDmdType alt_ty (Alt con new_ids rhs') -- Precondition: The SubDemand is not a Call -- See Note [Demand on the scrutinee of a product case] @@ -588,6 +589,7 @@ addCaseBndrDmd :: SubDemand -- On the case binder -- and final demands for the components of the constructor addCaseBndrDmd case_sd fld_dmds | Just (_, ds) <- viewProd (length fld_dmds) scrut_sd + -- , pprTrace "addCaseBndrDmd" (ppr case_sd $$ ppr fld_dmds $$ ppr scrut_sd) True = (scrut_sd, ds) | otherwise = pprPanic "was a call demand" (ppr case_sd $$ ppr fld_dmds) -- See the Precondition @@ -879,7 +881,8 @@ dmdTransform :: AnalEnv -- ^ The analysis environment dmdTransform env var sd -- Data constructors | isDataConWorkId var - = dmdTransformDataConSig (idArity var) sd + = -- pprTraceWith "dmdTransform:DataCon" (\ty -> ppr var $$ ppr sd $$ ppr ty) $ + dmdTransformDataConSig (idArity var) sd -- Dictionary component selectors -- Used to be controlled by a flag. -- See #18429 for some perf measurements. @@ -1744,7 +1747,7 @@ dmdFix top_lvl env let_dmd orig_pairs -- annotation does not change any more. loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) loop n pairs = -- pprTrace "dmdFix" (ppr n <+> vcat [ ppr id <+> ppr (idDmdSig id) - -- | (id,_)<- pairs]) $ + -- | (id,_) <- pairs]) $ loop' n pairs loop' n pairs diff --git a/compiler/GHC/Core/Opt/Simplify/Utils.hs b/compiler/GHC/Core/Opt/Simplify/Utils.hs index 1c0e228e79..ce69e35aea 100644 --- a/compiler/GHC/Core/Opt/Simplify/Utils.hs +++ b/compiler/GHC/Core/Opt/Simplify/Utils.hs @@ -1655,7 +1655,10 @@ mkLam env bndrs body cont -- See Note [Eta reduction based on evaluation context] -- NB: cont is never ApplyToVal, otherwise contEvalContext panics - eval_sd = contEvalContext cont + eval_sd dflags | gopt Opt_PedanticBottoms dflags = topSubDmd + -- See Note [Eta reduction soundness], criterion (S) + -- the bit about -fpedantic-bottoms + | otherwise = contEvalContext cont mkLam' :: DynFlags -> [OutBndr] -> OutExpr -> SimplM OutExpr mkLam' dflags bndrs body@(Lam {}) @@ -1679,8 +1682,8 @@ mkLam env bndrs body cont mkLam' dflags bndrs body | gopt Opt_DoEtaReduction dflags - -- , pprTrace "try eta" (ppr bndrs $$ ppr body $$ ppr cont $$ ppr eval_sd) True - , Just etad_lam <- {-# SCC "tryee" #-} tryEtaReduce bndrs body eval_sd + -- , pprTrace "try eta" (ppr bndrs $$ ppr body $$ ppr cont $$ ppr (eval_sd dflags)) True + , Just etad_lam <- {-# SCC "tryee" #-} tryEtaReduce bndrs body (eval_sd dflags) = do { tick (EtaReduction (head bndrs)) ; return etad_lam } diff --git a/compiler/GHC/Core/Utils.hs b/compiler/GHC/Core/Utils.hs index eea81d1502..b4c736bcdc 100644 --- a/compiler/GHC/Core/Utils.hs +++ b/compiler/GHC/Core/Utils.hs @@ -2409,13 +2409,20 @@ case where `e` is trivial): like `g (\x y z. e x y z)` to `g e`, because that diverges when `e = \x y. bot`. - Could we relax to "At least *one call in the same trace* is with n args"? + Could we relax to "*At least one call in the same trace* is with n args"? + (NB: Strictness analysis can only answer this relaxed question, not the + original formulation.) Consider what happens for ``g2 c = c True `seq` c False 42`` - Here, `g2` will call `c` with 2 two arguments (if there is a call at all). - But it is unsafe to eta-reduce the arg in `g2 (\x y. e x y)` to `g2 e` + Here, `g2` will call `c` with 2 arguments (if there is a call at all). + But it is unsound to eta-reduce the arg in `g2 (\x y. e x y)` to `g2 e` when `e = \x. if x then bot else id`, because the latter will diverge when the former would not. + On the other hand, with `-fno-pendantic-bottoms` , we will have eta-expanded + the definition of `e` and then eta-reduction is sound + (see Note [Dealing with bottom]). + Consequence: We have to check that `-fpedantic-bottoms` is off; otherwise + eta-reduction based on demands is in fact unsound. See Note [Eta reduction based on evaluation context] for the implementation details. This criterion is tested extensively in T21261. |