Prep: Refactor for more flexible FloatingBinds
Discussion started in !10088 (comment 499584). Today, we have
data FloatingBind
= FloatLet CoreBind -- Rhs of bindings are CpeRhss
-- They are always of lifted type;
-- unlifted ones are done with FloatCase
| FloatCase
CpeBody -- Always ok-for-speculation
Id -- Case binder
AltCon [Var] -- Single alternative
Bool -- Ok-for-speculation; False of a strict,
-- but lifted binding
-- | See Note [Floating Ticks in CorePrep]
| FloatTick CoreTickish
Issues:
- We never use
FloatCase
with something different than aDEFAULT
AltCon
, so it really is just a strictLet
. - We cache for a
FloatCase
whether it's ok-for-spec-eval. If it is, we may float it freely out of lazy contexts while retaining the strict binding semantics. But if the binding is not ok-for-spec-eval (e.g., a regular case binding), we may not float it out of lazy contexts, unless we change it into a lazy float (the benefit of which is far from clear and not the subject of this issue). - An ok-for-spec-eval
FloatCase
is not much different to a regular lazyFloatLet
, yet they are represented completely differently.
In a call, Simon and I came up with the following idea:
data FloatingBind
= Float
CoreBind
RhsInfo
-- | See Note [Floating Ticks in CorePrep]
| FloatTick CoreTickish
data RhsInfo
= NormalForm -- Literal or saturated constructor application with trivial arguments
| OkForSpec -- Lifted but ok-for-spec
| NotOkForSpec -- Lifted and perhaps not ok-for-spec
| StrictlyUsed -- Used strictly or is of unlifted type, might be ok-for-spec or not. Don't float out of lazy binds
Much simpler and more expressive.