Skip to content

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:

  1. We never use FloatCase with something different than a DEFAULT AltCon, so it really is just a strict Let.
  2. 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).
  3. An ok-for-spec-eval FloatCase is not much different to a regular lazy FloatLet, 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.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information