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
.