#2130: Mulitple comparisons on Word types produce redundant comparisons
-----------------------------------------+----------------------------------
    Reporter:  dons                      |       Owner:          
        Type:  run-time performance bug  |      Status:  new     
    Priority:  normal                    |   Component:  Compiler
     Version:  6.8.2                     |    Severity:  normal  
    Keywords:  performance, Word         |    Testcase:          
Architecture:  Unknown                   |          Os:  Multiple
-----------------------------------------+----------------------------------
 The Ord and Eq instances that are derived for Word types seems to be
 inefficient (and appeared while writing a ByteString decoder for UTF8,
 which does a lot of Word8 matching).

 The following code:

 {{{
 bad :: Word -> Bool
 bad c | c < 1     = True
       | c < 2     = True
       | otherwise = False
 }}}

 compiles to the rather horrible:

 {{{
     case GHC.Prim.eqWord# ww_sXC __word 1 of wild2_aSC {
       GHC.Base.False ->
         case GHC.Prim.ltWord# ww_sXC __word 1 of wild_B1 {
           GHC.Base.False ->
             case GHC.Prim.eqWord# ww_sXC __word 2 of wild21_XUq {
               GHC.Base.False -> GHC.Prim.ltWord# ww_sXC __word 2;
               GHC.Base.True -> GHC.Base.False
             };
           GHC.Base.True -> GHC.Base.True
         };
       GHC.Base.True ->
         case GHC.Prim.eqWord# ww_sXC __word 2 of wild21_XUo {
           GHC.Base.False -> GHC.Prim.ltWord# ww_sXC __word 2;
 }}}

 In particular, notice the (<) on Word becomes a `case eqWord# of case
 ltWord# of ...`

 While the equivalent at an Int type, using the hand written Ord/Eq
 instances in GHC.Base, produces:

 {{{
 M.good =
   \ (c_ag0 :: GHC.Base.Int) ->
     case c_ag0 of wild_aRF { GHC.Base.I# x_aRH ->
     case GHC.Prim.<# x_aRH 1 of wild1_B1 {
       GHC.Base.False -> GHC.Prim.<# x_aRH 2; GHC.Base.True ->
 GHC.Base.True
     }
     }
 }}}

 The poor code only seems to be generated if there's more than 1 comparison
 against the value.

 If I manually wrap Word, and write an instance Eq and Ord for it, based on
 the ones for Int (attached), we get identical code to the Int case:

 {{{
 M.good =
   \ (c_agn :: M.MyWord) ->
     case c_agn `cast` ((M.:CoMyWord) :: M.MyWord ~ GHC.Word.Word)

     of wild_B1 { GHC.Word.W# x_agV ->
         case GHC.Prim.ltWord# x_agV __word 1 of wild1_X33 {
           GHC.Base.False -> GHC.Prim.ltWord# x_agV __word 2;
           GHC.Base.True -> GHC.Base.True
     }
     }
 }}}

 The Ord and Eq instances for Word seem to be deeply magic:

 {{{
 data Word = W# Word# deriving (Eq, Ord)
 }}}

 Are the instances wired in?

 The solution to this might be to have similar instances of Eq and Ord for
 Word, as for Int, or to change the built-in deriving.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/2130>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to