Skip to content

Retain `OtherCon` unfoldings in simplLamBndr?

Currently it's implemented thus:

simplLamBndr :: SimplEnv -> InBndr -> SimplM (SimplEnv, OutBndr)
-- Used for lambda binders.  These sometimes have unfoldings added by
-- the worker/wrapper pass that must be preserved, because they can't
-- be reconstructed from context.  For example:
--      f x = case x of (a,b) -> fw a b x
--      fw a b x{=(a,b)} = ...
-- The "{=(a,b)}" is an unfolding we can't reconstruct otherwise.
simplLamBndr env bndr
  | isId bndr && hasCoreUnfolding old_unf   -- Special case
  = do { (env1, bndr1) <- simplBinder env bndr
       ; unf'          <- simplStableUnfolding env1 NotTopLevel Nothing bndr
                                      (idType bndr1) (idArityType bndr1) old_unf
       ; let bndr2 = bndr1 `setIdUnfolding` unf'
       ; return (modifyInScope env1 bndr2, bndr2) }

  | otherwise
  = simplBinder env bndr                -- Normal case
  where
    old_unf = idUnfolding bndr

But the example is not complete.

In fact we sometimes have a case like this:

If we have an expression like:

--      f x = case x of StrictPair a b -> fw a b x
--      fw a{=OtherCon[]} b{=OtherCon[]} x{=(StrictPair a b)} = ...

Then not only is x's unfolding impossible to reconstruct. But so is the information that a/b came out of strict fields.

Currently we only retain x's unfolding. But perhaps we should also do so for a/b.

I don't think we currently do anything interesting with this information but it would be more consistent.

Not that this is somewhat counter to #17530 (closed). If we implement #17530 (closed) we are also consistent. But we do so by removing all lambda binder unfoldings. Possibly at the cost of performance.

But since it's unclear if or when #17530 (closed) will be implemented I will put up an MR and we will see what happens.

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