#2130: Mulitple comparisons on Word types produce redundant comparisons
-----------------------------------------+----------------------------------
    Reporter:  dons                      |        Owner:       
        Type:  run-time performance bug  |       Status:  new  
    Priority:  normal                    |    Milestone:       
   Component:  Compiler                  |      Version:  6.8.2
    Severity:  normal                    |   Resolution:       
    Keywords:  performance, Word         |     Testcase:       
Architecture:  x86                       |           Os:  Linux
-----------------------------------------+----------------------------------
Changes (by morrow):

  * os:  Multiple => Linux
  * architecture:  Unknown => x86

Comment:

 Here is a duplication of the issue, and a writeup which will hopefully
 aid in comparing the code generated in various instances.

 -----------------------------------------------------------------------------

 GHC was invoked as follows for the below:
 {{{
 $ ghc -O2 -keep-s-files -fglasgow-exts -c XXX.hs
 }}}

 GHC version info:
 {{{
 $ ghc -V
 The Glorious Glasgow Haskell Compilation System, version 6.9.20080218
 }}}

 -----------------------------------------------------------------------------

 The code genereated for this example is basically equivalent to that
 generated by the Int -> Int example, as is desired.
 {{{
 import GHC.Word (Word(..)) -- for W#
 import GHC.Prim (ltWord#,int2Word#)

 choose :: Word -> Int
 choose (W# c)
     | c `ltWord#` (int2Word# 0x80#)  = 1
     | c `ltWord#` (int2Word# 0xc0#)  = 2
     | otherwise = 3
 }}}
 maps to (obtained with ghc --show-iface):
 {{{
 lvl :: GHC.Base.Int {- HasNoCafRefs Strictness: m Unfolding: (GHC.Base.I#
 1) -}
 lvl1 :: GHC.Base.Int {- HasNoCafRefs Strictness: m Unfolding: (GHC.Base.I#
 2) -}
 lvl2 :: GHC.Base.Int {- HasNoCafRefs Strictness: m Unfolding: (GHC.Base.I#
 3) -}
 2 choose :: GHC.Word.Word -> GHC.Base.Int
     {- Arity: 1 HasNoCafRefs Strictness: U(L)m
        Unfolding: (\ ds :: GHC.Word.Word ->
                    case @ GHC.Base.Int ds of wild { GHC.Word.W# c ->
                    case @ GHC.Base.Int GHC.Prim.ltWord# c __word 128 of
 wild1 {
                      GHC.Base.False
                      -> case @ GHC.Base.Int GHC.Prim.ltWord# c __word 192
 of wild2 {
                           GHC.Base.False -> M.lvl2 GHC.Base.True -> M.lvl1
 }
                      GHC.Base.True -> M.lvl } }) -}
 }}}

 -----------------------------------------------------------------------------

 The code generated for this example is that to which the other two
 aspire.
 {{{
 choose :: Int -> Int
 choose c
     | c < 0x80  = 1
     | c < 0xc0  = 2
     | otherwise = 3
 }}}
 maps to (obtained with ghc --show-iface):
 {{{
 lvl :: GHC.Base.Int {- HasNoCafRefs Strictness: m Unfolding: (GHC.Base.I#
 1) -}
 lvl1 :: GHC.Base.Int {- HasNoCafRefs Strictness: m Unfolding: (GHC.Base.I#
 2) -}
 lvl2 :: GHC.Base.Int {- HasNoCafRefs Strictness: m Unfolding: (GHC.Base.I#
 3) -}
 choose :: GHC.Base.Int -> GHC.Base.Int
   {- Arity: 1 HasNoCafRefs Strictness: U(L)m
      Unfolding: (\ c :: GHC.Base.Int ->
                  case @ GHC.Base.Int c of wild { GHC.Base.I# x ->
                  case @ GHC.Base.Int GHC.Prim.<# x 128 of wild1 {
                    GHC.Base.False
                    -> case @ GHC.Base.Int GHC.Prim.<# x 192 of wild2 {
                         GHC.Base.False -> Int.lvl2 GHC.Base.True ->
 Int.lvl1 }
                    GHC.Base.True -> Int.lvl } }) -}
 }}}

 -----------------------------------------------------------------------------

 This is the example of nonoptimal (wrt that of Int -> Int)
 code generated for the same function but with Word -> Int (and with
 no explicit unboxing).
 {{{
 import Data.Word (Word)

 choose :: Word -> Int
 choose c
     | c < 0x80  = 1
     | c < 0xc0  = 2
     | otherwise = 3
 }}}
 maps to (obtained with ghc --show-iface):
 {{{
 $wchoose :: GHC.Prim.Word# -> GHC.Prim.Int#
   {- Arity: 1 HasNoCafRefs Strictness: L
      Unfolding: (\ ww :: GHC.Prim.Word# ->
                  case @ GHC.Prim.Int# GHC.Prim.eqWord# ww __word 128 of
 wild2 {
                    GHC.Base.False
                    -> case @ GHC.Prim.Int# GHC.Prim.ltWord# ww __word 128
 of wild {
                         GHC.Base.False
                         -> case @ GHC.Prim.Int# GHC.Prim.eqWord# ww __word
 192 of wild21 {
                              GHC.Base.False
                              -> case @ GHC.Prim.Int# GHC.Prim.ltWord# ww
 __word 192 of wild1 {
                                   GHC.Base.False -> 3 GHC.Base.True -> 2 }
                              GHC.Base.True -> 3 }
                         GHC.Base.True -> 1 }
                    GHC.Base.True
                    -> case @ GHC.Prim.Int# GHC.Prim.eqWord# ww __word 192
 of wild21 {
                         GHC.Base.False
                         -> case @ GHC.Prim.Int# GHC.Prim.ltWord# ww __word
 192 of wild {
                              GHC.Base.False -> 3 GHC.Base.True -> 2 }
                         GHC.Base.True -> 3 } }) -}
 choose :: GHC.Word.Word -> GHC.Base.Int
   {- Arity: 1 HasNoCafRefs Strictness: U(L)m Worker: M.$wchoose 1 -}
 }}}

 -----------------------------------------------------------------------------

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/2130#comment:2>
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