#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