[GHC] #14562: IntRep vs WordRep

GHC ghc-devs at haskell.org
Thu Dec 7 13:36:17 UTC 2017


#14562: IntRep vs WordRep
-------------------------------------+-------------------------------------
        Reporter:  andrewthad        |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.2.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------
Description changed by andrewthad:

Old description:

> Why do `Int#` and `Word#` have different runtime representations? By this
> I mean that:
>
> {{{#!hs
> Int# :: TYPE 'IntRep
> Word# :: TYPE 'WordRep
> }}}
>
> To my understanding, they are always the same size and always live in the
> same set of registers. The docs for unsafeCoerce# state that it can be
> used for:
>
> > Casting an unboxed type to another unboxed type of the same size (but
> not coercions between floating-point and integral types)
>
> The implies that a cast between `Int#` and `Word#` is acceptable. But if
> you're able to unsafeCoerce# between two types, shouldn't they be defined
> as having the same representation?
>
> What I'm suggesting is that it may be better to collapse `IntRep` and
> `WordRep` into a single representation (probably named `WordRep`). We
> would then get slightly more reusable code in some cases:
>
> {{{#!hs
>
> data WordList (x :: TYPE 'WordRep)
>   = WordListCons x (WordList x)
>   | WordListNil
>
> ints :: WordList Int#
> ints = WordListCons 5# (WordListCons 8# WordListNil)
>

> words :: WordList Word#
> words = WordListCons 4## (WordListCons 12## WordListNil)
>
> mapWordList :: forall (x :: TYPE 'WordRep). (x -> x) -> WordList x ->
> WordList x
> mapWordList _ WordListNil = WordListNil
> mapWordList f (WordListCons x xs) = WordListCons (f x) xs
>
> biggerInts :: WordList Int#
> biggerInts = mapWordList (\x -> x +# 3) ints
>
> biggerWords :: WordList Int#
> biggerWords = mapWordList (\x -> plusWord# x 3) ints
> }}}

New description:

 Why do `Int#` and `Word#` have different runtime representations? By this
 I mean that:

 {{{#!hs
 Int# :: TYPE 'IntRep
 Word# :: TYPE 'WordRep
 }}}

 To my understanding, they are always the same size and always live in the
 same set of registers. The docs for unsafeCoerce# state that it can be
 used for:

 > Casting an unboxed type to another unboxed type of the same size (but
 not coercions between floating-point and integral types)

 The implies that a cast between `Int#` and `Word#` is acceptable. But if
 you're able to unsafeCoerce# between two types, shouldn't they be defined
 as having the same representation?

 What I'm suggesting is that it may be better to collapse `IntRep` and
 `WordRep` into a single representation (probably named `WordRep`). We
 would then get slightly more reusable code in some cases:

 {{{#!hs

 data WordList (x :: TYPE 'WordRep)
   = WordListCons x (WordList x)
   | WordListNil

 ints :: WordList Int#
 ints = WordListCons 5# (WordListCons 8# WordListNil)


 words :: WordList Word#
 words = WordListCons 4## (WordListCons 12## WordListNil)

 mapWordList :: forall (x :: TYPE 'WordRep). (x -> x) -> WordList x ->
 WordList x
 mapWordList _ WordListNil = WordListNil
 mapWordList f (WordListCons x xs) = WordListCons (f x) xs

 biggerInts :: WordList Int#
 biggerInts = mapWordList (\x -> x +# 3) ints

 biggerWords :: WordList Int#
 biggerWords = mapWordList (\x -> plusWord# x 3) ints
 }}}

 For additional context, I'd add that, excluding `SumRep` and `TupleRep`
 (because you can produce different nestings with equivalent
 representations), coercions between types of different representations are
 always unsound.

--

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14562#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list