Skip to content

Draft: Enforce single register invariant for CPS primops

sheaf requested to merge sheaf/ghc:T21868-tyfam into master

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

Merge request reports