[GHC] #9661: Branchless ==# is compiled to branchy code

GHC ghc-devs at haskell.org
Fri Oct 3 10:33:48 UTC 2014


#9661: Branchless ==# is compiled to branchy code
-------------------------------------+-------------------------------------
              Reporter:  dfeuer      |            Owner:
                  Type:  bug         |           Status:  new
              Priority:  normal      |        Milestone:
             Component:  Compiler    |          Version:  7.9
            Resolution:              |         Keywords:
      Operating System:              |     Architecture:  Unknown/Multiple
  Unknown/Multiple                   |       Difficulty:  Unknown
       Type of failure:  Runtime     |       Blocked By:
  performance bug                    |  Related Tickets:
             Test Case:              |
              Blocking:              |
Differential Revisions:              |
-------------------------------------+-------------------------------------

Comment (by jstolarek):

 Replying to [comment:2 dfeuer]:
 > Furthermore, it appears to happen only when one of the arguments is
 known at compile time.
 That seems right. In `litEq` (literal equality) you'll see that we expect
 one of the arguments to be a literal. Also, `litEq` works for both
 equality and inequality tests.

 > There are a couple `tagToEnum#` invocations missing there
 The comment was written for the old primops and should have been updated
 when the new ones were introduced. This rule is intended for primops, not
 `(==)`.

 > but let's look at the whole process.
 > (...)
 I think the order of inlining should be different here: first calls to
 `==#`, then a call to `orI#` (at least that's what the Core you pasted
 suggests). This won't change the final result but it may be important for
 devising a solution.

 > So we can get this far without knowing anything about what (==) means.
 Now let's add part of that knowledge:
 >
 > {{{#!hs
 > case n# ==# 3# of
 >   1# -> e1
 >   0# -> case n# ==# 4# of
 >           1# -> e1
 >           0# -> e2
 > }}}
 When you rewrite the transformation to work on the `==#` primop this
 should be the result that you get, but I don't think that you can get such
 transformation by just inlining definition of `(==)`. The problem is that
 calls to `tagToEnum#` are not currently optimized away in Core (#8317).
 This stage should be followed by case merging to get the final result
 shown in the comment.

 After writing all this I really wonder what will happen when we disable
 `litEq`. It might not be as bad as I initially thought. After all, with
 these new primops we don't want branches.

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


More information about the ghc-tickets mailing list