summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Core')
-rw-r--r--compiler/GHC/Core/Opt/Arity.hs3
-rw-r--r--compiler/GHC/Core/Opt/DmdAnal.hs15
-rw-r--r--compiler/GHC/Core/Opt/Simplify/Utils.hs9
-rw-r--r--compiler/GHC/Core/Utils.hs13
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.