diff options
author | Sebastian Graf <sebastian.graf@kit.edu> | 2020-03-16 18:18:55 +0100 |
---|---|---|
committer | Sebastian Graf <sebastian.graf@kit.edu> | 2020-03-17 11:05:58 +0100 |
commit | 9760f64c62afc1cdc2dc499b04259e8626832064 (patch) | |
tree | bd4737c3346233c21b4204c19d12f9624fb2e692 | |
parent | 80f003453c59dd248a7474592203319009413b14 (diff) | |
download | haskell-9760f64c62afc1cdc2dc499b04259e8626832064.tar.gz |
Actually use conDiv
-rw-r--r-- | compiler/basicTypes/Demand.hs | 28 | ||||
-rw-r--r-- | compiler/basicTypes/MkId.hs | 8 | ||||
-rw-r--r-- | compiler/prelude/primops.txt.pp | 26 | ||||
-rw-r--r-- | compiler/specialise/SpecConstr.hs | 8 | ||||
-rw-r--r-- | compiler/stranal/DmdAnal.hs | 2 |
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) |