Skip to content

New core transformation: promote case[One] into case[Many]

Motivation

Since !852 (closed) was merged, the case expression in the Core definition of constructor wrappers are linear cases.

data T = MkT !Int

Will have a wrapper along the lines of

$WT n = case n of n' # 1
  _ -> MkT n'

Now, as explained in the wiki, having a case[One] prevents binder-swap from happening. And, as it happens, we have seen examples of Core getting less optimised because of it. I don't remember the precise example, unfortunately, but it concerned a cascade of such workers inlined into one-another, and some case-of-case not happening (probably unsurprisingly as this is very much the sort of things that binder-swap is here to detect).

It doesn't really show in any tests, but it does make some non-linear code a bit less optimised. And that's rather unfortunate.

Proposal

My suggestion is to add, as part of occurrence analysis, a new transformation. This transformation would detect cases where the scrutinee is really unrestricted, and change the case[One] into a case[Many].

The point is that: if case[Many] is still well typed, then we have strictly more freedom for optimisation.

The question remains of how we can detect that case[One] can be promoted to case[Many]. My proposal is to do so if and only if the scrutinee is a variable and this variable is bound with multiplicity Many.

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