diff options
author | Sebastian Graf <sebastian.graf@kit.edu> | 2021-06-15 21:27:22 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-06-29 15:35:29 -0400 |
commit | b760c1f743ddb496886f095baa920740b38c9ce0 (patch) | |
tree | 844ce6a598583512e2f549868403a1482e0a88dd /compiler/GHC/Tc/Utils | |
parent | a7f9670e899bcbc87276446a1aac2304cade2b2f (diff) | |
download | haskell-b760c1f743ddb496886f095baa920740b38c9ce0.tar.gz |
Demand: Better representation (#19050)
In #19050, we identified several ways in which we could make more illegal
states irrepresentable. This patch introduces a few representation changes
around `Demand` and `Card` with a better and earlier-failing API exported
through pattern synonyms. Specifically,
1. The old enum definition of `Card` led to severely bloated code of operations
on it. I switched to a bit vector representation; much nicer overall IMO.
See Note [Bit vector representation for Card].
Most of the gripes with the old representation were related to where which kind
of `Card` was allowed and the fact that it doesn't make sense for an absent or
bottoming demand to carry a `SubDemand` that describes an evaluation context
that is never realised.
2. So I refactored the `Demand` representation so that it has two new data
constructors for `AbsDmd` and `BotDmd`. The old `(:*)` data constructor
becomes a pattern synonym which expands absent demands as needed, so that
it still forms a complete match and a versatile builder. The new `Demand`
data constructor now carries a `CardNonAbs` and only occurs in a very limited
number of internal call sites.
3. Wherever a full-blown `Card` might end up in a `CardNonAbs` field (like that
of `D` or `Call`), I assert the consistency. When the smart builder of `(:*)`
is called with an absent `Card`, I assert that the `SubDemand` is the same
that we would expand to in the matcher.
4. `Poly` now takes a `CardNonOnce` and encodes the previously noticed invariant
that we never produce `Poly C_11` or `Poly C_01`. I made sure that we never
construct a `Poly` with `C_11` or `C_01`.
Fixes #19050.
We lose a tiny bit of anal perf overall, probably because the new `Demand`
definition can't be unboxed. The biggest loser is WWRec, where allocations go
from 16MB to 26MB in DmdAnal, making up for a total increase of (merely) 1.6%.
It's all within acceptance thresholds.
There are even two ghc/alloc metric decreases. T11545 decreases by *67%*!
Metric Decrease:
T11545
T18304
Diffstat (limited to 'compiler/GHC/Tc/Utils')
0 files changed, 0 insertions, 0 deletions