
#13647: Tidy up TcTypeable -------------------------------------+------------------------------------- Reporter: simonpj | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.4.1 Component: Compiler | Version: 8.0.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- 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. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13647 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler