Record syntax and INLINE annotations

I have a curious situation. I've defined a data type using record syntax, and my module exports one of the accessor functions. I notice that GHC is not inlining any of the others, even though they are not exported. Furthermore, while poking around to see if I could bend it to my will, I found that I couldn't figure out where to place an INLINE annotation for an accessor function defined via record syntax such that the compiler would accept it. For now, I've dropped back to non-record syntax, my hand-crafted accessors are being inlined as I'd expect, and I win a few percent in performance. If anyone could shed a wee bit of light, I'd be most grateful.

can you give an example? GHC should inline selectors, whether exported or not, whenever it'd help. They are implicitly defined as INLINE. Since this obviously isn’t working right, I'd like to see the code. Perhaps you can boil it down a little, and submit a ticket? Simon | -----Original Message----- | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell- | users-bounces@haskell.org] On Behalf Of Bryan O'Sullivan | Sent: 13 June 2008 06:38 | To: glasgow-haskell-users@haskell.org | Subject: Record syntax and INLINE annotations | | I have a curious situation. I've defined a data type using record | syntax, and my module exports one of the accessor functions. I notice | that GHC is not inlining any of the others, even though they are not | exported. | | Furthermore, while poking around to see if I could bend it to my will, | I found that I couldn't figure out where to place an INLINE annotation | for an accessor function defined via record syntax such that the | compiler would accept it. | | For now, I've dropped back to non-record syntax, my hand-crafted | accessors are being inlined as I'd expect, and I win a few percent in | performance. If anyone could shed a wee bit of light, I'd be most | grateful. | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

is it trac bug #2070, http://hackage.haskell.org/trac/ghc/ticket/2070 (fixed in 6.9?) -Isaac Simon Peyton-Jones wrote:
can you give an example? GHC should inline selectors, whether exported or not, whenever it'd help. They are implicitly defined as INLINE. Since this obviously isn’t working right, I'd like to see the code. Perhaps you can boil it down a little, and submit a ticket?
Simon
| -----Original Message----- | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell- | users-bounces@haskell.org] On Behalf Of Bryan O'Sullivan | Sent: 13 June 2008 06:38 | To: glasgow-haskell-users@haskell.org | Subject: Record syntax and INLINE annotations | | I have a curious situation. I've defined a data type using record | syntax, and my module exports one of the accessor functions. I notice | that GHC is not inlining any of the others, even though they are not | exported. | | Furthermore, while poking around to see if I could bend it to my will, | I found that I couldn't figure out where to place an INLINE annotation | for an accessor function defined via record syntax such that the | compiler would accept it. | | For now, I've dropped back to non-record syntax, my hand-crafted | accessors are being inlined as I'd expect, and I win a few percent in | performance. If anyone could shed a wee bit of light, I'd be most | grateful. | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
------------------------------------------------------------------------
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Might be, but Bryan said that his selectors weren't getting inlined at all, which is a bit different perhaps S | -----Original Message----- | From: Isaac Dupree [mailto:isaacdupree@charter.net] | Sent: 13 June 2008 12:53 | To: Bryan O'Sullivan | Cc: Simon Peyton-Jones; glasgow-haskell-users@haskell.org | Subject: Re: Record syntax and INLINE annotations | | is it trac bug #2070, http://hackage.haskell.org/trac/ghc/ticket/2070 | (fixed in 6.9?) | | -Isaac | | | | Simon Peyton-Jones wrote: | > can you give an example? GHC should inline selectors, whether exported or | not, whenever it'd help. They are implicitly defined as INLINE. Since this | obviously isn’t working right, I'd like to see the code. Perhaps you can | boil it down a little, and submit a ticket? | > | > Simon | > | > | -----Original Message----- | > | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell- | > | users-bounces@haskell.org] On Behalf Of Bryan O'Sullivan | > | Sent: 13 June 2008 06:38 | > | To: glasgow-haskell-users@haskell.org | > | Subject: Record syntax and INLINE annotations | > | | > | I have a curious situation. I've defined a data type using record | > | syntax, and my module exports one of the accessor functions. I notice | > | that GHC is not inlining any of the others, even though they are not | > | exported. | > | | > | Furthermore, while poking around to see if I could bend it to my will, | > | I found that I couldn't figure out where to place an INLINE annotation | > | for an accessor function defined via record syntax such that the | > | compiler would accept it. | > | | > | For now, I've dropped back to non-record syntax, my hand-crafted | > | accessors are being inlined as I'd expect, and I win a few percent in | > | performance. If anyone could shed a wee bit of light, I'd be most | > | grateful. | > | _______________________________________________ | > | Glasgow-haskell-users mailing list | > | Glasgow-haskell-users@haskell.org | > | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users | > | > | > | > ------------------------------------------------------------------------ | > | > _______________________________________________ | > Glasgow-haskell-users mailing list | > Glasgow-haskell-users@haskell.org | > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |

Simon Peyton-Jones wrote:
can you give an example?
Certainly. This comes from the bloomfilter package on Hackage. type Hash = Word32 data MBloom s a = MB { hashMB :: {-# UNPACK #-} !(a -> [Hash]) , shiftMB :: {-# UNPACK #-} !Int , maskMB :: {-# UNPACK #-} !Int , bitArrayMB :: {-# UNPACK #-} !(STUArray s Int Hash) } insertMB :: MBloom s a -> a -> ST s () {-# SPECIALIZE insertMB :: MBloom s SB.ByteString -> SB.ByteString -> ST s () #-} insertMB mb elt = do let mu = bitArrayMB mb forM_ (hashesM mb elt) $ \(word :* bit) -> do old <- unsafeRead mu word unsafeWrite mu word (old .|. (1 `shiftL` bit)) If I look at the Core generated for any version of insertMB, specialised or not, I see the following. Note the non-inlined uses of maskMB and bitArrayMB. (I export bitArrayMB from the module, but not maskMB.) Data.BloomFilter.insertMB = \ (@ s_a2ta) (@ a_a2tb) (mb_X2n2 :: Data.BloomFilter.MBloom s_a2ta a_a2tb) (elt_X2n4 :: a_a2tb) -> __letrec { a2_s3g9 :: [Word32] -> State# s_a2ta -> (# State# s_a2ta, () #) [Arity 2 a2_s3g9 = \ (ds_a2S9 :: [Word32]) (eta_s37Y :: State# s_a2ta) -> case ds_a2S9 of wild_a2Sa { [] -> (# eta_s37Y, () #); : y_a2Se ys_a2Sf -> case y_a2Se of wild1_a2Io { W32# x#_a2Iq -> case Data.BloomFilter.maskMB @ s_a2ta @ a_a2tb mb_X2n2 of wild11_a2T0 { I# y#_a2T2 -> case Data.BloomFilter.bitArrayMB @ s_a2ta @ a_a2tb mb_X2n2 of wild2_a2P0 { Data.Array.Base.STUArray ds2_a2P2 ds3_a2P3 ds4_a2P4 marr#_a2P5 -> [......] If I switch to non-record syntax, the inliner does the right thing.
participants (3)
-
Bryan O'Sullivan
-
Isaac Dupree
-
Simon Peyton-Jones