[GHC] #10012: Cheap-to-compute values aren't pushed into case branches inducing unnecessary register pressure

GHC ghc-devs at haskell.org
Thu Jan 22 09:51:08 UTC 2015


#10012: Cheap-to-compute values aren't pushed into case branches inducing
unnecessary register pressure
-------------------------------------+-------------------------------------
        Reporter:  bgamari           |                   Owner:
            Type:  bug               |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  Compiler          |                 Version:  7.8.4
      Resolution:                    |                Keywords:
Operating System:  Unknown/Multiple  |            Architecture:
 Type of failure:  Runtime           |  Unknown/Multiple
  performance bug                    |               Test Case:
      Blocked By:                    |                Blocking:
 Related Tickets:                    |  Differential Revisions:
-------------------------------------+-------------------------------------

Comment (by simonpj):

 Here's some more dialogue between Ben and me:

 > I think you are talking about code like this:
 {{{
 let t1=e1; t2=e2; ...; tn=en in
 if ... then
   do { write r1a t1; ...; write rna tn }
 else
   do { write r1b t1; ...; write rnb tn }
 }}}
 > What you would prefer is to *duplicate* the ti=ei bindings, and sink
 them really close to their consumers.  (NB: That can sometimes *increase*
 register pressure if ei have lots of free variables.)
 >
 > Correct?

 Correct.

 > Question: the ti=ei bindings are used in both branches of the
 conditional.  Did they begin duplicated, and became shared by CSE?  Or did
 they start shared?  If the latter, it becomes delicate indeed: duplicating
 work to (hopefully) improve (but possible worsen) register pressure seems
 dodgy.

 Unfortunately they started shared. This code is sadly a bit difficult to
 optimize. The case analysis in question examines whether there is enough
 room in a buffer to accomoate the requested data to be written; the
 bindings being shared are the values to be written to the buffer. If there
 is room in the buffer then we perform the write immediately; otherwise we
 return a closure so that the user can continue writing into a new buffer.

 This situation affects performance in a rather unfortunate way: in
 principle we should be able to perform better the more data we statically
 know needs to be written. Unfortunately, as it stands now, the more data
 we write, the more performance suffers due to register pressure

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


More information about the ghc-tickets mailing list