[GHC] #14222: Simple text fusion example results in rather duplicative code

GHC ghc-devs at haskell.org
Thu Sep 14 13:18:25 UTC 2017


#14222: Simple text fusion example results in rather duplicative code
-------------------------------------+-------------------------------------
        Reporter:  bgamari           |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.2.1
      Resolution:                    |             Keywords:
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 simonpj):

 I agree that CBE should nail it, so let's do #14226.  But still it'd be
 even better to do it in Core.

 As you'll see in `Note [Combine identical alternatives]` in `CoreUtils` we
 do some combining of identical alternatives, but only in the very
 convenient case where one of them is the DEFAULT, which is not the case
 here.  I suppose we'd like
 {{{
 case ww4_X2zB of
   __DEFAULT -> GHC.Types.False;
   '+'# -> jump $wloop_all_s2z2 (GHC.Prim.+# ww3_s2z0 2#);
   '-'# -> jump $wloop_all_s2z2 (GHC.Prim.+# ww3_s2z0 2#);
   '.'# -> jump $wloop_all_s2z2 (GHC.Prim.+# ww3_s2z0 2#);
   'E'# -> jump $wloop_all_s2z2 (GHC.Prim.+# ww3_s2z0 2#);
   'e'# -> jump $wloop_all_s2z2 (GHC.Prim.+# ww3_s2z0 2#)

 ===>

 join j = jump $wloop_all_s2z2 (GHC.Prim.+# ww3_s2z0 2#)
 in case ww4_X2zB of
   __DEFAULT -> GHC.Types.False;
   '+'# -> jump j
   '-'# -> jump j
   '.'# -> jump j
   'E'# -> jump j
   'e'# -> jump j
 }}}
 You could imagine trying that.

 It's a variant of something I've wanted to try for some time to get better
 CSE.  Suppose we have
 {{{
 f (x+y) (g (x+y))
 }}}
 Currently we don't CSE the two `(x+y)` expressions.  Suppose we did this:

 1.  Convert to ANF, by let-binding every sub-expression
 {{{
 f (let a1 = x+y in a1)
   (let a2 = let a3 = x+y in g a3 in a2)
 }}}

 2.  Float out aggressively
 {{{
 let a1 = x+y in
 let a3 = x+y in
 let a2 = g a3 in
 f a1 a2
 }}}

 3. Do CSE exactly as now
 {{{
 let a1 = x+y in
 let a3 = a1 in
 let a2 = g a3 in
 f a1 a2
 }}}

 4. Now inline as usual
 {{{
 let a1 = x+1 in
 f a1 (g a1)
 }}}
   which is what we want.

 I like this 4-step plan because only step 1 is new: the other passes exist
 already.  It's a bit brutal but it would do the job.

 And (provided we did this for join-points too) it would nail the example
 nicely.

 Anyone want to have a go?

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


More information about the ghc-tickets mailing list