[GHC] #8814: 7.8 optimizes attoparsec improperly

GHC ghc-devs at haskell.org
Thu Mar 6 19:03:34 UTC 2014


#8814: 7.8 optimizes attoparsec improperly
--------------------------------------------+------------------------------
        Reporter:  joelteon                 |            Owner:
            Type:  bug                      |           Status:  new
        Priority:  normal                   |        Milestone:
       Component:  Compiler                 |          Version:  7.8.1-rc1
      Resolution:                           |         Keywords:
Operating System:  MacOS X                  |     Architecture:  x86_64
 Type of failure:  Runtime performance bug  |  (amd64)
       Test Case:                           |       Difficulty:  Unknown
        Blocking:                           |       Blocked By:
                                            |  Related Tickets:  #8763
--------------------------------------------+------------------------------

Comment (by bos):

 Replying to [comment:11 simonpj]:
 > We're a bit stalled here.  There is something mysterious going on, which
 a single INLINE pragma (Bryan's patch) fixes.  But why?  My guess is that
 it's something to do with the interaction between inlining and
 attoparsec's RULES.

 I assume you're referring to text's RULES, as attoparsec doesn't contain
 any (it does contain a lot of inlining, though).

 The goal behind the RULES in text is to expose opportunities to perform
 stream fusion and, if the rewrite phases do not reveal any, to drop from
 the fusion style of programming back to thwacking directly on an array
 (which is typically a lot faster).

 For example, here are the two main RULES that you spotted in the output
 above:

 {{{
 {-# RULES
 "TEXT append -> fused" [~1] forall t1 t2.
     append t1 t2 = unstream (S.append (stream t1) (stream t2))
 "TEXT append -> unfused" [1] forall t1 t2.
     unstream (S.append (stream t1) (stream t2)) = append t1 t2
  #-}
 }}}

 If we see an unadorned use of `append` in an early phase, we rewrite it so
 that a fusion rule can have a chance to transform it. Once we get closer
 to the end of our phases, if we find that a fusion-style append hasn't yet
 been gobbled up, we transform it back to the direct style.

 There's a tangential wrinkle here: for the longest time, the definition of
 `append` had an `INLINE` annotation,
 [https://github.com/bos/text/commit/109941228d16cc873a08da9924cb881c51be853b
 which I just removed]. I don't believe this is implicated in the slowdown.

 Please let me know what else it would be helpful to explain. As you know,
 forests of rewrite rules are rather fragile affairs, so it's entirely
 possible that there's been a longstanding bug in those rules (and perhaps
 ''not in the compiler'') that is merely now being exposed in 7.8.

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


More information about the ghc-tickets mailing list