Draft: Enforce single register invariant for CPS primops
This MR attempts to address #21868 in a different way than !11229, by adding a constraint to the types of primops which require that a certain representation fit in a single register.
For example, with this change, keepAlive#
has type
keepAlive# :: forall {s} {a_lev :: Levity} {b_rep :: RuntimeRep}
(a :: TYPE (BoxedRep a_lev)) (b :: TYPE b_rep)
. SmallRep# b_rep
=> a -> State# s -> (State# s -> b) -> b
Here
SmallRep# :: RuntimeRep -> CONSTRAINT (TupleRep '[])
is a type family that reduces when its argument is a RuntimeRep
that
fits into a single register (see GHC.Builtin.Types.Prim.matchSmallRepPrim
).
This ensures that any usage of the keepAlive#
primop includes evidence
that the b_rep
representation is sufficiently small. Note also
that one cannot quantify over this constraint, because b_rep
is
affected by a representation-polymorphism check.
Primops impacted by this change:
keepAlive#
catch#
-
maskAsyncExceptions#
,unmaskAsyncExceptions#
,maskUninterruptible#
Edited by sheaf