diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2015-06-24 23:43:41 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2015-06-26 08:33:06 +0100 |
commit | 9014a7ee6c1182df62dfd343e0a2269b0b4988d0 (patch) | |
tree | 6b3cf43a75c3b9cd14555e17588780b34be94126 /compiler/stranal | |
parent | cc0dba1e4da6857a740b866d3f8a12d8549dc452 (diff) | |
download | haskell-9014a7ee6c1182df62dfd343e0a2269b0b4988d0.tar.gz |
Fix addDataConStrictness
See Note [Add demands for strict constructors].
The new bit is the test for isAbsDmd in addDataConStrictness.
There was a cryptic note that said that this function
should add a seqDmd even for Absent arguments, but that
is definitely a bad thing (as the Note now says), causing
unused arguments to be passed to the worker.
Easy fix!
Diffstat (limited to 'compiler/stranal')
-rw-r--r-- | compiler/stranal/DmdAnal.hs | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/compiler/stranal/DmdAnal.hs b/compiler/stranal/DmdAnal.hs index a345e45327..a0e5fef8d8 100644 --- a/compiler/stranal/DmdAnal.hs +++ b/compiler/stranal/DmdAnal.hs @@ -431,10 +431,7 @@ in this case. In other words, for locally-bound lambdas we can infer one-shotness. --} - -{- Note [Add demands for strict constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this program (due to Roman): @@ -462,17 +459,23 @@ because X is strict, so its argument must be evaluated. And if we because the seq is discarded (very early) since X is strict! +We achieve the effect using addDataConStrictness. It is called at a +case expression, such as the pattern match on (X a) in the example +above. After computing how 'a' is used in the alternatives, we add an +extra 'seqDmd' to it. The case alternative isn't itself strict in the +sub-components, but simply evaluating the scrutinee to HNF does force +those sub-components. + +If the argument is not used at all in the alternative (i.e. it is +Absent), then *don't* add a 'seqDmd'. If we do, it makes it look used +and hence it'll be passed to the worker when it doesn't need to be. +Hence the isAbsDmd test in addDataConStrictness. + There is the usual danger of reboxing, which as usual we ignore. But if X is monomorphic, and has an UNPACK pragma, then this optimisation is even more important. We don't want the wrapper to rebox an unboxed argument, and pass an Int to $wfoo! -We add these extra strict demands to the demand on the *scrutinee* of -the case expression; hence the use of addDataConStrictness when -forming scrut_dmd. The case alternatives aren't strict in their -sub-components, but simply evaluating the scrutinee to HNF does force -those sub-components. - ************************************************************************ * * @@ -1101,9 +1104,9 @@ addDataConStrictness con ds zipWith add ds strs where strs = dataConRepStrictness con - add dmd str | isMarkedStrict str = dmd `bothDmd` seqDmd + add dmd str | isMarkedStrict str + , not (isAbsDmd dmd) = dmd `bothDmd` seqDmd | otherwise = dmd - -- Yes, even if 'dmd' is Absent! findBndrsDmds :: AnalEnv -> DmdType -> [Var] -> (DmdType, [Demand]) -- Return the demands on the Ids in the [Var] |