[GHC] #14865: GHC Defeats Manual Worker Wrapper with Unboxed Sum

GHC ghc-devs at haskell.org
Wed Feb 28 14:52:30 UTC 2018


#14865: GHC Defeats Manual Worker Wrapper with Unboxed Sum
-------------------------------------+-------------------------------------
        Reporter:  andrewthad        |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.5
      Resolution:                    |             Keywords:  UnboxedSums
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by andrewthad):

 Your suggested change produces the desired behavior:

 {{{
 findByte :: Int -> Int -> Word8 -> ByteArray -> Maybe Int
 findByte !off !len0 !w0 !arr0 = boxMaybeInt (go off (len0 + off) w0 arr0)
 where
   go :: Int -> Int -> Word8 -> ByteArray -> Maybe# Int#
   go !ix !end !w !arr = if ix < end
     then if PM.indexByteArray arr ix == w
       then (# | unboxInt ix #)
       else go (ix + 1) end w arr
     else (# (# #) | #)
 }}}

 Results in the following Core:

 {{{
 Rec {
 -- RHS size: {terms: 34, types: 21, coercions: 0, joins: 0/0}
 $wgo
 $wgo
   = \ ww_s3zd ww1_s3zh ww2_s3zl ww3_s3zp ->
       case tagToEnum# (<# ww_s3zd ww1_s3zh) of {
         False -> (#_|#) (##);
         True ->
           case indexWord8Array# ww3_s3zp ww_s3zd of wild1_a3vI { __DEFAULT
 ->
           case tagToEnum# (eqWord# wild1_a3vI ww2_s3zl) of {
             False -> $wgo (+# ww_s3zd 1#) ww1_s3zh ww2_s3zl ww3_s3zp;
             True -> (#|_#) ww_s3zd
           }
           }
       }
 end Rec }

 -- RHS size: {terms: 18, types: 11, coercions: 0, joins: 0/0}
 $wfindByte
 $wfindByte
   = \ ww_s3zy ww1_s3zC ww2_s3zG ww3_s3zK ->
       case $wgo ww_s3zy (+# ww1_s3zC ww_s3zy) ww2_s3zG ww3_s3zK of {
         (#_|#) ds_d3ui -> Nothing;
         (#|_#) a_a1Dk -> Just (I# a_a1Dk)
       }

 -- RHS size: {terms: 21, types: 12, coercions: 0, joins: 0/0}
 findByte
 findByte
   = \ w_s3zs w1_s3zt w2_s3zu w3_s3zv ->
       case w_s3zs of { I# ww1_s3zy ->
       case w1_s3zt of { I# ww3_s3zC ->
       case w2_s3zu of { W8# ww5_s3zG ->
       case w3_s3zv of { ByteArray ww7_s3zK ->
       $wfindByte ww1_s3zy ww3_s3zC ww5_s3zG ww7_s3zK
       }
       }
       }
       }
 }}}

 I don't much mind having to do this by hand. It's just nice to know that
 there's a reliable way to coax GHC into doing it.

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


More information about the ghc-tickets mailing list