summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Graf <sebastian.graf@kit.edu>2020-03-16 18:18:55 +0100
committerSebastian Graf <sebastian.graf@kit.edu>2020-03-17 11:05:58 +0100
commit9760f64c62afc1cdc2dc499b04259e8626832064 (patch)
treebd4737c3346233c21b4204c19d12f9624fb2e692
parent80f003453c59dd248a7474592203319009413b14 (diff)
downloadhaskell-9760f64c62afc1cdc2dc499b04259e8626832064.tar.gz
Actually use conDiv
-rw-r--r--compiler/basicTypes/Demand.hs28
-rw-r--r--compiler/basicTypes/MkId.hs8
-rw-r--r--compiler/prelude/primops.txt.pp26
-rw-r--r--compiler/specialise/SpecConstr.hs8
-rw-r--r--compiler/stranal/DmdAnal.hs2
5 files changed, 36 insertions, 36 deletions
diff --git a/compiler/basicTypes/Demand.hs b/compiler/basicTypes/Demand.hs
index 7f780be532..7380ab6ba6 100644
--- a/compiler/basicTypes/Demand.hs
+++ b/compiler/basicTypes/Demand.hs
@@ -1092,9 +1092,7 @@ data DmdType = DmdType
{-
Note [Nature of result demand]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A Divergence contains information about termination (currently distinguishing
-definite divergence and no information; it is possible to include definite
-convergence here), and CPR information about the result.
+A Divergence contains information about termination.
The semantics of this depends on whether we are looking at a DmdType, i.e. the
demand put on by an expression _under a specific incoming demand_ on its
@@ -1105,9 +1103,7 @@ For a
generated with, while for
* a StrictSig it holds after applying enough arguments.
-The CPR information, though, is valid after the number of arguments mentioned
-in the type is given. Therefore, when forgetting the demand on arguments, as in
-dmdAnalRhs, this needs to be considered (via removeDmdTyArgs).
+See also Note [Understanding DmdType and StrictSig].
Consider
b2 x y = x `seq` y `seq` error (show x)
@@ -1224,7 +1220,7 @@ emptyDmdEnv = emptyVarEnv
-- Note that it is ''not'' the top of the lattice (which would be "may use everything"),
-- so it is (no longer) called topDmd
nopDmdType, botDmdType :: DmdType
-nopDmdType = DmdType emptyDmdEnv [] topDiv
+nopDmdType = DmdType emptyDmdEnv [] conDiv
botDmdType = DmdType emptyDmdEnv [] botDiv
isTopDmdType :: DmdType -> Bool
@@ -1240,8 +1236,7 @@ dmdTypeDepth (DmdType _ ds _) = length ds
-- | This makes sure we can use the demand type with n arguments.
-- It extends the argument list with the correct resTypeArgDmd.
--- It also adjusts the Divergence: Divergence survives additional arguments,
--- CPR information does not (and definite converge also would not).
+-- It also adjusts the Divergence: Divergence survives additional arguments.
ensureArgs :: Arity -> DmdType -> DmdType
ensureArgs n d | n == depth = d
| otherwise = DmdType fv ds' r'
@@ -1250,8 +1245,11 @@ ensureArgs n d | n == depth = d
ds' = take n (ds ++ repeat (resTypeArgDmd r))
r' = case r of -- See [Nature of result demand]
- Dunno -> topDiv
- _ -> r
+ ConOrDiv
+ | n > length ds
+ -> Dunno -- supplying more arguments might throw
+ -- a precise exception in a lambda body
+ _ -> r
seqDmdType :: DmdType -> ()
@@ -1307,8 +1305,10 @@ postProcessDmdType du@(JD { sd = ss }) (DmdType fv _ res_ty)
= (postProcessDmdEnv du fv, postProcessDivergence ss res_ty)
postProcessDivergence :: Str () -> Divergence -> Divergence
-postProcessDivergence Lazy _ = topDiv
-postProcessDivergence _ res = res
+-- In a Lazy scenario, we might not force the Divergence, in which case we
+-- converge. That corresponds to @lubDivergence ConOrDiv@.
+postProcessDivergence Lazy d = lubDivergence conDiv d
+postProcessDivergence _ d = d
postProcessDmdEnv :: DmdShell -> DmdEnv -> DmdEnv
postProcessDmdEnv ds@(JD { sd = ss, ud = us }) env
@@ -1737,7 +1737,7 @@ dmdTransformDictSelSig (StrictSig (DmdType _ [dict_dmd] _)) cd
| (cd',defer_use) <- peelCallDmd cd
, Just jds <- splitProdDmd_maybe dict_dmd
= postProcessUnsat defer_use $
- DmdType emptyDmdEnv [mkOnceUsedDmd $ mkProdDmd $ map (enhance cd') jds] topDiv
+ DmdType emptyDmdEnv [mkOnceUsedDmd $ mkProdDmd $ map (enhance cd') jds] conDiv
| otherwise
= nopDmdType -- See Note [Demand transformer for a dictionary selector]
where
diff --git a/compiler/basicTypes/MkId.hs b/compiler/basicTypes/MkId.hs
index 3b73882fb1..a5e2014c50 100644
--- a/compiler/basicTypes/MkId.hs
+++ b/compiler/basicTypes/MkId.hs
@@ -442,7 +442,7 @@ mkDictSelId name clas
-- It's worth giving one, so that absence info etc is generated
-- even if the selector isn't inlined
- strict_sig = mkClosedStrictSig [arg_dmd] topDiv
+ strict_sig = mkClosedStrictSig [arg_dmd] conDiv
arg_dmd | new_tycon = evalDmd
| otherwise = mkManyUsedDmd $
mkProdDmd [ if name == sel_name then evalDmd else absDmd
@@ -518,7 +518,7 @@ mkDataConWorkId wkr_name data_con
-- setNeverLevPoly
wkr_arity = dataConRepArity data_con
- wkr_sig = mkClosedStrictSig (replicate wkr_arity topDmd) topDiv
+ wkr_sig = mkClosedStrictSig (replicate wkr_arity topDmd) conDiv
-- Note [Data-con worker strictness]
-- Notice that we do *not* say the worker Id is strict
-- even if the data constructor is declared strict
@@ -663,7 +663,7 @@ mkDataConRep dflags fam_envs wrap_name mb_bangs data_con
-- so it not make sure that the CAF info is sane
`setLevityInfoWithType` wrap_ty
- wrap_sig = mkClosedStrictSig wrap_arg_dmds topDiv
+ wrap_sig = mkClosedStrictSig wrap_arg_dmds conDiv
wrap_arg_dmds =
replicate (length theta) topDmd ++ map mk_dmd arg_ibangs
@@ -1272,7 +1272,7 @@ mkFCallId dflags uniq fcall ty
(bndrs, _) = tcSplitPiTys ty
arity = count isAnonTyCoBinder bndrs
- strict_sig = mkClosedStrictSig (replicate arity topDmd) topDiv
+ strict_sig = mkClosedStrictSig (replicate arity topDmd) conDiv
-- the call does not claim to be strict in its arguments, since they
-- may be lifted (foreign import prim) and the called code doesn't
-- necessarily force them. See #11076.
diff --git a/compiler/prelude/primops.txt.pp b/compiler/prelude/primops.txt.pp
index 685a867b0d..ba2291ff47 100644
--- a/compiler/prelude/primops.txt.pp
+++ b/compiler/prelude/primops.txt.pp
@@ -72,7 +72,7 @@ defaults
can_fail = False -- See Note [PrimOp can_fail and has_side_effects] in PrimOp
commutable = False
code_size = { primOpCodeSizeDefault }
- strictness = { \ arity -> mkClosedStrictSig (replicate arity topDmd) topDiv }
+ strictness = { \ arity -> mkClosedStrictSig (replicate arity topDmd) conDiv }
fixity = Nothing
llvm_only = False
vector = []
@@ -2584,7 +2584,7 @@ primop CatchOp "catch#" GenPrimOp
with
strictness = { \ _arity -> mkClosedStrictSig [ lazyApply1Dmd
, lazyApply2Dmd
- , topDmd] topDiv }
+ , topDmd] conDiv }
-- See Note [Strictness for mask/unmask/catch]
out_of_line = True
has_side_effects = True
@@ -2677,7 +2677,7 @@ primop MaskAsyncExceptionsOp "maskAsyncExceptions#" GenPrimOp
(State# RealWorld -> (# State# RealWorld, a #))
-> (State# RealWorld -> (# State# RealWorld, a #))
with
- strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv }
+ strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] conDiv }
-- See Note [Strictness for mask/unmask/catch]
out_of_line = True
has_side_effects = True
@@ -2686,7 +2686,7 @@ primop MaskUninterruptibleOp "maskUninterruptible#" GenPrimOp
(State# RealWorld -> (# State# RealWorld, a #))
-> (State# RealWorld -> (# State# RealWorld, a #))
with
- strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv }
+ strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] conDiv }
out_of_line = True
has_side_effects = True
@@ -2694,7 +2694,7 @@ primop UnmaskAsyncExceptionsOp "unmaskAsyncExceptions#" GenPrimOp
(State# RealWorld -> (# State# RealWorld, a #))
-> (State# RealWorld -> (# State# RealWorld, a #))
with
- strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv }
+ strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] conDiv }
-- See Note [Strictness for mask/unmask/catch]
out_of_line = True
has_side_effects = True
@@ -2715,7 +2715,7 @@ primop AtomicallyOp "atomically#" GenPrimOp
(State# RealWorld -> (# State# RealWorld, a #) )
-> State# RealWorld -> (# State# RealWorld, a #)
with
- strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv }
+ strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] conDiv }
-- See Note [Strictness for mask/unmask/catch]
out_of_line = True
has_side_effects = True
@@ -2744,7 +2744,7 @@ primop CatchRetryOp "catchRetry#" GenPrimOp
with
strictness = { \ _arity -> mkClosedStrictSig [ lazyApply1Dmd
, lazyApply1Dmd
- , topDmd ] topDiv }
+ , topDmd ] conDiv }
-- See Note [Strictness for mask/unmask/catch]
out_of_line = True
has_side_effects = True
@@ -2756,7 +2756,7 @@ primop CatchSTMOp "catchSTM#" GenPrimOp
with
strictness = { \ _arity -> mkClosedStrictSig [ lazyApply1Dmd
, lazyApply2Dmd
- , topDmd ] topDiv }
+ , topDmd ] conDiv }
-- See Note [Strictness for mask/unmask/catch]
out_of_line = True
has_side_effects = True
@@ -3281,7 +3281,7 @@ section "Tag to enum stuff"
primop DataToTagOp "dataToTag#" GenPrimOp
a -> Int# -- Zero-indexed; the first constructor has tag zero
with
- strictness = { \ _arity -> mkClosedStrictSig [evalDmd] topDiv }
+ strictness = { \ _arity -> mkClosedStrictSig [evalDmd] conDiv }
-- See Note [dataToTag# magic] in PrelRules
primop TagToEnumOp "tagToEnum#" GenPrimOp
@@ -3797,7 +3797,7 @@ primop PrefetchAddrOp3 "prefetchAddr3#" GenPrimOp
primop PrefetchValueOp3 "prefetchValue3#" GenPrimOp
a -> State# s -> State# s
- with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv }
+ with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] conDiv }
has_side_effects = True
----
@@ -3815,7 +3815,7 @@ primop PrefetchAddrOp2 "prefetchAddr2#" GenPrimOp
primop PrefetchValueOp2 "prefetchValue2#" GenPrimOp
a -> State# s -> State# s
- with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv }
+ with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] conDiv }
has_side_effects = True
----
@@ -3833,7 +3833,7 @@ primop PrefetchAddrOp1 "prefetchAddr1#" GenPrimOp
primop PrefetchValueOp1 "prefetchValue1#" GenPrimOp
a -> State# s -> State# s
- with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv }
+ with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] conDiv }
has_side_effects = True
----
@@ -3851,7 +3851,7 @@ primop PrefetchAddrOp0 "prefetchAddr0#" GenPrimOp
primop PrefetchValueOp0 "prefetchValue0#" GenPrimOp
a -> State# s -> State# s
- with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv }
+ with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] conDiv }
has_side_effects = True
------------------------------------------------------------------------
diff --git a/compiler/specialise/SpecConstr.hs b/compiler/specialise/SpecConstr.hs
index 7ab207afc5..0174bfa40c 100644
--- a/compiler/specialise/SpecConstr.hs
+++ b/compiler/specialise/SpecConstr.hs
@@ -1761,10 +1761,10 @@ calcSpecStrictness :: Id -- The original function
-> StrictSig -- Strictness of specialised thing
-- See Note [Transfer strictness]
calcSpecStrictness fn qvars pats
- = mkClosedStrictSig spec_dmds topDiv
+ = mkClosedStrictSig spec_dmds div
where
spec_dmds = [ lookupVarEnv dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ]
- StrictSig (DmdType _ dmds _) = idStrictness fn
+ StrictSig (DmdType _ dmds div) = idStrictness fn
dmd_env = go emptyVarEnv dmds pats
@@ -1824,10 +1824,10 @@ Note [Transfer strictness]
We must transfer strictness information from the original function to
the specialised one. Suppose, for example
- f has strictness SS
+ f has strictness SSx
and a RULE f (a:as) b = f_spec a as b
-Now we want f_spec to have strictness LLS, otherwise we'll use call-by-need
+Now we want f_spec to have strictness LLSx, otherwise we'll use call-by-need
when calling f_spec instead of call-by-value. And that can result in
unbounded worsening in space (cf the classic foldl vs foldl')
diff --git a/compiler/stranal/DmdAnal.hs b/compiler/stranal/DmdAnal.hs
index c7cb4e0358..529224ddff 100644
--- a/compiler/stranal/DmdAnal.hs
+++ b/compiler/stranal/DmdAnal.hs
@@ -829,7 +829,7 @@ a product type.
-}
unitDmdType :: DmdEnv -> DmdType
-unitDmdType dmd_env = DmdType dmd_env [] topDiv
+unitDmdType dmd_env = DmdType dmd_env [] conDiv
coercionDmdEnv :: Coercion -> DmdEnv
coercionDmdEnv co = mapVarEnv (const topDmd) (getUniqSet $ coVarsOfCo co)