Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Helping GHC unbox an Int in equality on a constant

Here is a test program:

main = do
    n <- fmap read $ getLine :: IO Int
    if (999999 == n) then putStrLn "equal" else return ()

And here is the relevant bit of core when compiled with ghc --make -O2 -ddump-to-file -ddump-simpl -dsuppress-module-prefixes -dsuppress-uniques -ddump-core-stats -ddump-inlinings:

case readEither6 @ Int (run @ Int main3 ipv1) of _ [Occ=Dead] {
  [] -> case error @ Int readEither4 of wild1 { };
  : x ds1 ->
    case ds1 of _ [Occ=Dead] {
      [] ->
        case x of _ [Occ=Dead] { I# ipv2 ->
        case ipv2 of _ [Occ=Dead] {
          __DEFAULT -> (# ipv, () #);
          999999 -> hPutStr2 stdout main2 True ipv
        }
        };
      : ipv2 ipv3 -> case error @ Int readEither2 of wild2 { }
    }

I'm wondering if the case match on the literal 999999 is really the most efficient thing here, and if not how can I encourage GHC to turn this into a call to ==# or something?

(My actual application is more involved)

like image 821
jberryman Avatar asked Dec 17 '14 18:12

jberryman


2 Answers

On my Ubuntu box, the relevant core code compiled to this

406168: 48 81 7b 07 3f 42 0f    cmpq   $0xf423f,0x7(%rbx)
40616f: 00 
406170: 75 28                   jne    40619a <c4fz_info+0x32>
406172: bf 52 e3 6d 00          mov    $0x6de352,%edi
406177: be 90 65 6d 00          mov    $0x6d6590,%esi
40617c: 41 be 18 6a 6d 00       mov    $0x6d6a18,%r14d
406182: 48 83 c5 08             add    $0x8,%rbp
406186: e9 65 3c 00 00          jmpq   409df0 <base_GHCziIOziHandleziText_hPutStr2_info>

The first to third line are basically equivalant to the c code

if (variable == 999999) { ....

Which is about as optimal as you can get.

like image 78
jamshidh Avatar answered Nov 10 '22 23:11

jamshidh


It won't matter. In code generation, that case will turn into a simple comparison and conditional jump. That's what always happens for such small case expressions. There are definitely times when this translation of ==# is unfortunate, making code that has a lot of poorly predicted branches, but that does not apply to the example you give.

To clarify, I'm talking about the inner case.

like image 26
dfeuer Avatar answered Nov 10 '22 22:11

dfeuer