Note [Getting from RuntimeRep to PrimRep]

GHC/Types/RepType.hs:468 compiler

General info on RuntimeRep and PrimRep is in Note [RuntimeRep and PrimRep].

How do we get from an Id to the list or PrimReps used to store it? We get
the Id's type ty (using idType), then ty's kind ki (using typeKind), then
pattern-match on ki to extract rep (in kindPrimRep), then extract the PrimRep
from the RuntimeRep (in runtimeRepPrimRep).

We now must convert the RuntimeRep to a list of PrimReps. Let's look at two
examples:

  1. x :: Int#
  2. y :: (# Int, Word# #)

With these types, we can extract these kinds:

  1. Int# :: TYPE IntRep
  2. (# Int, Word# #) :: TYPE (TupleRep [LiftedRep, WordRep])

In the end, we will get these PrimReps:

  1. [IntRep]
  2. [LiftedRep, WordRep]

It would thus seem that we should have a function somewhere of
type `RuntimeRep -> [PrimRep]`. This doesn't work though: when we
look at the argument of TYPE, we get something of type Type (of course).
RuntimeRep exists in the user's program, but not in GHC as such.
Instead, we must decompose the Type of kind RuntimeRep into tycons and
extract the PrimReps from the TyCons. This is what runtimeRepPrimRep does:
it takes a Type and returns a [PrimRep]

runtimeRepPrimRep works by using tyConRuntimeRepInfo. That function
should be passed the TyCon produced by promoting one of the constructors
of RuntimeRep into type-level data. The RuntimeRep promoted datacons are
associated with a RuntimeRepInfo (stored directly in the PromotedDataCon
constructor of TyCon, field promDcRepInfo).
This pairing happens in GHC.Builtin.Types. A RuntimeRepInfo
usually(*) contains a function from [Type] to [PrimRep]: the [Type] are
the arguments to the promoted datacon. These arguments are necessary
for the TupleRep and SumRep constructors, so that this process can recur,
producing a flattened list of PrimReps. Calling this extracted function
happens in runtimeRepPrimRep; the functions themselves are defined in
tupleRepDataCon and sumRepDataCon, both in GHC.Builtin.Types.

The (*) above is to support vector representations. RuntimeRep refers
to VecCount and VecElem, whose promoted datacons have nuggets of information
related to vectors; these form the other alternatives for RuntimeRepInfo.

Returning to our examples, the Types we get (after stripping off TYPE) are

  1. TyConApp (PromotedDataCon "IntRep") []
  2. TyConApp (PromotedDataCon "TupleRep")
              [TyConApp (PromotedDataCon ":")
                        [ TyConApp (AlgTyCon "RuntimeRep") []
                        , TyConApp (PromotedDataCon "LiftedRep") []
                        , TyConApp (PromotedDataCon ":")
                                   [ TyConApp (AlgTyCon "RuntimeRep") []
                                   , TyConApp (PromotedDataCon "WordRep") []
                                   , TyConApp (PromotedDataCon "'[]")
                                              [TyConApp (AlgTyCon "RuntimeRep") []]]]]

runtimeRepPrimRep calls tyConRuntimeRepInfo on (PromotedDataCon "IntRep"), resp.
(PromotedDataCon "TupleRep"), extracting a function that will produce the PrimReps.
In example 1, this function is passed an empty list (the empty list of args to IntRep)
and returns the PrimRep IntRep. (See the definition of runtimeRepSimpleDataCons in
GHC.Builtin.Types and its helper function mk_runtime_rep_dc.) Example 2 passes the promoted
list as the one argument to the extracted function. The extracted function is defined
as prim_rep_fun within tupleRepDataCon in GHC.Builtin.Types. It takes one argument, decomposes
the promoted list (with extractPromotedList), and then recurses back to runtimeRepPrimRep
to process the LiftedRep and WordRep, concatenating the results.

References 1

Referenced by 15