diff options
author | Joachim Breitner <mail@joachim-breitner.de> | 2022-04-07 22:02:46 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-04-09 13:02:19 -0400 |
commit | dcf30da8ff3ddcea9db3369870039f1b2c5d7b2c (patch) | |
tree | 588c1dea5790df294158f096d1d21af81a5baff3 /compiler/GHC/Builtin/PrimOps.hs | |
parent | 27362265e50b59aee9a0ae17560ce091f5501985 (diff) | |
download | haskell-dcf30da8ff3ddcea9db3369870039f1b2c5d7b2c.tar.gz |
Drop the app invariantghc-9.5-start
previously, GHC had the "let/app-invariant" which said that the RHS of a
let or the argument of an application must be of lifted type or ok for
speculation. We want this on let to freely float them around, and we
wanted that on app to freely convert between the two (e.g. in
beta-reduction or inlining).
However, the app invariant meant that simple code didn't stay simple and
this got in the way of rules matching. By removing the app invariant,
this thus fixes #20554.
The new invariant is now called "let-can-float invariant", which is
hopefully easier to guess its meaning correctly.
Dropping the app invariant means that everywhere where we effectively do
beta-reduction (in the two simplifiers, but also in `exprIsConApp_maybe`
and other innocent looking places) we now have to check if the argument
must be evaluated (unlifted and side-effecting), and analyses have to be
adjusted to the new semantics of `App`.
Also, `LetFloats` in the simplifier can now also carry such non-floating
bindings.
The fix for DmdAnal, refine by Sebastian, makes functions with unlifted
arguments strict in these arguments, which changes some signatures.
This causes some extra calls to `exprType` and `exprOkForSpeculation`,
so some perf benchmarks regress a bit (while others improve).
Metric Decrease:
T9020
Metric Increase:
LargeRecord
T12545
T15164
T16577
T18223
T5642
T9961
Co-authored-by: Sebastian Graf <sebastian.graf@kit.edu>
Diffstat (limited to 'compiler/GHC/Builtin/PrimOps.hs')
-rw-r--r-- | compiler/GHC/Builtin/PrimOps.hs | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/compiler/GHC/Builtin/PrimOps.hs b/compiler/GHC/Builtin/PrimOps.hs index d1df0fbaf2..574cfa4659 100644 --- a/compiler/GHC/Builtin/PrimOps.hs +++ b/compiler/GHC/Builtin/PrimOps.hs @@ -325,8 +325,8 @@ Note [Checking versus non-checking primops] never throw an exception, so we cannot rewrite to a call to error. It is important that a non-checking primop never be transformed in a way that - would cause it to bottom. Doing so would violate Core's let/app invariant - (see Note [Core let/app invariant] in GHC.Core) which is critical to + would cause it to bottom. Doing so would violate Core's let-can-float invariant + (see Note [Core let-can-float invariant] in GHC.Core) which is critical to the simplifier's ability to float without fear of changing program meaning. @@ -479,7 +479,7 @@ Two main predicates on primops test these flags: * The "no-float-out" thing is achieved by ensuring that we never let-bind a can_fail or has_side_effects primop. The RHS of a let-binding (which can float in and out freely) satisfies - exprOkForSpeculation; this is the let/app invariant. And + exprOkForSpeculation; this is the let-can-float invariant. And exprOkForSpeculation is false of can_fail and has_side_effects. * So can_fail and has_side_effects primops will appear only as the |