[GHC] #14201: Implement ideas from "Compiling Pattern Matching to Good Decision Trees"

GHC ghc-devs at haskell.org
Mon Jan 8 22:27:41 UTC 2018


#14201: Implement ideas from "Compiling Pattern Matching to Good Decision Trees"
-------------------------------------+-------------------------------------
        Reporter:  AndreasK          |                Owner:  AndreasK
            Type:  feature request   |               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 AndreasK):

 Thanks dfeuer. The imprecise exceptions paper

 ****
 == The bad ==

 * Compilation is slowed down too much currently. This should be fixable as
 I haven't optimized my code AT ALL yet.
 * For larger benchmarks advantages often disappear at -O2 (with
 microbencharms being faster). I'm not completly sure why.

 Possibly reasons I thought of:
 1. Performance reliant code is written with the current solution in mind
 2. The larger code size causes more cache misses
 3. There are some nasty edge cases

 1) This doesn't make this approach worse, but might be a reason why it
 makes little differences in performance sensitive libraries which I used
 for benchmarks.

 2/3) The larger code size is a given with this approach. I don't think
 it's a big issue outside of edge cases. However edge cases can blow up
 significantly.

 A good example the following which splits up the decision tree in a bad
 way.
 {{{
 f1 _ A E = 1
 f1 B _ _ = 2
 f1 C _ C = 3
 f1 A E A = 8
 f1 _ _ _ = 5
 }}}

 * We can't start at the third as we might not evaluate it, eg `f1 B B B`
 * We can't start at the first for the same reason, eg `f1 A A E`

 A perfect solution would switch between backtracking and tree based based
 on the pattern encountered.
 But maintaining both sounds like a nightmare and wouldn't be worth the
 trouble.

 There are also a few small things that I can still adjust which might
 enable a bit more CSE.
 But I'm not too optimistic that it will change much.

 == The good ==

 * Regular code at -O0/1 gets faster on average when the algorithm applies.
 * Strict code runs faster with tree matching even at -O2
 * The compiliation speed should be fixable
 * There are some small improvements still doable
   * Improve the heuristic which selects the column to match first
   * Change placement of the cleanup code which evaluates arguments not
 necessary for matching. (This is necessary to satisfy the
 exception/nontermination semantics)
 * I have enabled tree matching only for Vanilla Constructors as I had an
 issue with GADT's which didn't want to tackle at the time.

 == Where to go from here ==

 I plan to at least:
 * Try to enable tree matching on GADTs and see if any of the benchmarks I
 looked at change.
 * Play around with the clean up placement

 But I have to get my bachelor out of the way first in the next 1-2 Months.

 Then I will see how the above change the story at -O2.

 For O1/Strict code the speedup of a few % at time would already be worth
 it if I can reign the compile times in.

 But currently at O2 the speed is usually equal sometimes worse and
 slightly less often faster using tree matching.
 Assuming it stays that way changing it only makes sense if GHC ever gets
 profile guided optimization. As we then could chose the best column to
 match on based on actual data.

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


More information about the ghc-tickets mailing list