[GHC] #8662: GHC does not inline cheap inner loop when used in two places
GHC
ghc-devs at haskell.org
Fri Jan 10 14:31:00 UTC 2014
#8662: GHC does not inline cheap inner loop when used in two places
------------------------------+--------------------------------------------
Reporter: nh2 | Owner:
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 7.6.3
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: Runtime performance bug
Unknown/Multiple | Test Case:
Difficulty: Unknown | Blocking:
Blocked By: |
Related Tickets: |
------------------------------+--------------------------------------------
When I made a Criterion benchmark of Neil Michell's "Tight Inner Loop"
blog post (http://neilmitchell.blogspot.co.uk/2014/01/optimising-haskell-
for-tight-inner-loop.html), I noticed that GHC 7.6.3 will not inline the
performance-critical function when it's called from two different places
(inside the same module).
{{{
break0_2pleaseinline :: (Char -> Bool) -> ByteString0 -> (ByteString,
ByteString0)
break0_2pleaseinline f (BS0 bs) = (BS.unsafeTake i bs, BS0 $ BS.unsafeDrop
i bs)
where
i = Internal.inlinePerformIO $ BS.unsafeUseAsCString bs $ \ptr ->
do
let start = castPtr ptr :: Ptr Word8
let end = go start
return $! Ptr end `minusPtr` start
go s@(Ptr a) | c == '\0' || f c = a
| otherwise = go $ inc s
where c = chr s
versionInl1 :: ByteString0 -> (ByteString, ByteString0)
versionInl1 str = break0_2pleaseinline test str
where
test x = x <= '$' && (x == ' ' || x == '\r' || x == '\n' || x == '$')
versionInl2 :: ByteString0 -> (ByteString, ByteString0)
versionInl2 str = break0_2pleaseinline test str
where
test x = x <= '$' && (x == ' ' || x == '\r' || x == '\n' || x == '$')
}}}
Full code here: https://github.com/nh2/inner-loop-
benchmarks/blob/6715d1e9946d6b5e6d9bb53203982ed3d2ed32ff/Bench.hs#L166.
{{{break0_2pleaseinline}}} does not get inlined, which makes
{{{versionInl1}}} and {{{versionInl2}}} over 4 times slower than when
inlined. The inlining doens't happen, not even with {{{-O2}}} and
{{{-O3}}}, only an {{{INLINE}}} pragma will move GHC to do it.
If I was a compiler, I would so inline that function!
I am surprised that GHC doesn't decide to do so.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8662>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list