Skip to content

Optimize unboxed sums which are isomorphic to a unlifted maybe into a single word representation.

@alexbiehl came up with this idea and told me about it at zurihac:

Currently if we want to represent a type like this:

type UnliftedMaybe :: Type -> UnliftedType
data UnliftedMaybe a = Nothing | Just a 

As a unboxed sum. The straight forward representation is: (# a | Void# #)

Which at runtime gives us this two word representation:

(# a | #)    = [0, ptrTo<a>]
(# | void #) = [1, () ]

The argument is that we could represent this by a single word.

(# a | #)    = [ptrTo<a>]
(# | void #) = [ unboxedCon1 ]

This relies on the fact that unboxedCon1 would be a built in RTS closure, which is not accessible to users. So we can always distinguish between the tag0 case and tag1 case by comparing the closure ptr to unboxedCon1.

Establishing the tag of the unboxed sum would then compile down to a comparison again unboxedCon1.

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