Skip to content

Tidy up TcTypeable

There is code in TcTypeable that generates a KindRep for each TyCon (see Note [Representing TyCon kinds: KindRep]). There's nothing actually wrong with it.

But it's pretty hard to understand. And it generates a staggering amount of data structure, when compiling GHC.Types.

Result size of Tidy Core
  = {terms: 74,615, types: 41,335, coercions: 2, joins: 0/0}

Why? Well, it injects a TyCon binding for each unboxed tuple size. For example, here is the code for pairs (#,#)

$tc(#,#)
  = TyCon 16533601304077481746##
          7902994497850328874##
          tr$ModuleGHCPrim
          $tc(#,#)2
          2#
          $tc(#,#)1

-- TYPE #0 -> TYPE #1 -> TYPE (TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))))
$tc(#,#)1 :: KindRep
$tc(#,#)1       = KindRepFun $krep2115_r6ji $krep18009_rarE

$krep18009_rarE = KindRepFun $krep2117_r6jk $krep18008_rarD

-- TYPE (TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))))
$krep18008_rarD = KindRepTyConApp $tcTYPE $krep18007_rarC
$krep18007_rarC = : @ KindRep $krep18006_rarB ([] @ KindRep)

-- TupleRep (': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep)))
$krep18006_rarB = KindRepTyConApp $tc'TupleRep $krep18005_rarA
$krep18005_rarA = : @ KindRep $krep2283_r6m0 ([] @ KindRep)

-- ': RuntimeRep #0 (': RuntimeRep #1 ('[] RuntimeRep))
$krep2283_r6m0  = KindRepTyConApp $tc': $krep2282_r6lZ
$krep2282_r6lZ  = : @ KindRep $tc'AddrRep1 $krep2281_r6lY
$krep2281_r6lY  = : @ KindRep $krep61_r5Ma           $krep2280_r6lX
$krep2280_r6lX  = : @ KindRep $krep2279_r6lW         ([] @ KindRep)

-- ': RuntimeRep #1 ('[] RuntimeRep)
$krep2279_r6lW = KindRepTyConApp $tc': $krep2278_r6lV
$krep2278_r6lV = : @ KindRep $tc'AddrRep1 $krep2277_r6lU
$krep2277_r6lU = : @ KindRep $krep60_r5M9           $krep2276_r6lT
$krep2276_r6lT = : @ KindRep $krep2274_r6lR          ([] @ KindRep)

-- '[] RuntimeRep
$krep2274_r6lR = KindRepTyConApp $tc'[] $krep2273_r6lQ
$krep2273_r6lQ = : @ KindRep $tc'AddrRep1 ([] @ KindRep)

-- RuntimeRep
$tc'AddrRep1 = KindRepTyConApp $tcRuntimeRep ([] @ KindRep)

-------------- TYPE #0
$krep2115_r6ji = KindRepTyConApp $tcTYPE $krep2114_r6jh
$krep2114_r6jh = : @ KindRep $krep61_r5Ma ([] @ KindRep)
$krep61_r5Ma   = KindRepVar 0#

-------------- TYPE #1
$krep2117_r6jk = KindRepTyConApp $tcTYPE $krep2116_r6jj
$krep2116_r6jj = : @ KindRep $krep60_r5M9 ([] @ KindRep)
$krep60_r5M9   = KindRepVar 1#

That's a lot, and it's only for pairs. We generate all this up to 62-tuples!

Suggestions (read Note [Representing TyCon kinds: KindRep] first)

  • KindRep is a description of a polykind; an interpreter, called instantiateKindRep turns it into a kind. So we can add whatever constructors we like to KindRep.
  • One good one would be UnboxedTupleRep n, which instantiateKindRep can instantiate to the kind of an unboxed tuple. It just moves the work somewhere else, of course, but it will make the generated code dramatically smaller.
  • We have a few canned kind-reps, via TcTypeable.builtInKindReps. It'd be simpler and easier instead to make each of them into a data constructor of KindRep.
  • Once that is done, I suspect that the entire machinery of tyring to share KindReps (which makes my head hurt) would be unnecessary

None of this is essential, but I think that matters can be improved.

Trac metadata
Trac field Value
Version 8.0.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information