[PATCH] Switch lowering: use profile info to build weight-balanced binary search trees

Hans Wennborg hans at chromium.org
Sat Jun 20 10:23:21 PDT 2015


REPOSITORY
  rL LLVM

================
Comment at: test/CodeGen/Generic/MachineBranchProb.ll:58
@@ +57,3 @@
+; Check that we set branch weights on the pivot cmp instruction correctly.
+; Cases {0,10,20,30} go on the left with weight 13; cases {40,50} go on the
+; right with weight 20.
----------------
hans wrote:
> djasper wrote:
> > This is actually an interesting case. As I understand it, LLVM will now do?
> > 
> >   this_case = (x < 40
> >                    ? x < 20 ? x == 0 ? A : x == 10 ? B : DEFAULT
> >                             : x == 20 ? C : x == 30 ? D : DEFAULT
> >                    : x == 40 ? E : x == 50 ? F : DEFAULT);
> > 
> > (I hope it is somewhat readable what I mean, case A represents 0, case B 10,... - I just didn't want to re-use the numbers as that would be even more confusing).
> > 
> > Now, I hope I counted correctly, this gives me the following numbers.
> > 
> >   No of comparisons:
> >   A:    3 (Weight: 10, Weighted: 30)
> >   B:    4 (Weight:  1, Weighted:  4)
> >   C:    3 (Weight:  1, Weighted:  3)
> >   D:    4 (Weight:  1, Weighted:  4)
> >   E:    2 (Weight: 10, Weighted: 20)
> >   F:    3 (Weight: 10, Weighted: 30)
> >   ---
> >   SUM: 19 (            Weighted: 91)
> > 
> > However, if we split this equally, we get to do a linear scan on both sides:
> > 
> >   this_case = (x < 30 ? x == 0 ? A : x == 10 ? B : x == 20 ? C : DEFAULT
> >                       : x == 40 ? E : x == 50 ? F : x == 30 ? D : DEFAULT);
> > 
> >   No of comparisons:
> >   A:    2 (Weight: 10, Weighted: 20)
> >   B:    3 (Weight:  1, Weighted:  3)
> >   C:    4 (Weight:  1, Weighted:  4)
> >   D:    4 (Weight:  1, Weighted:  4)
> >   E:    2 (Weight: 10, Weighted: 20)
> >   F:    3 (Weight: 10, Weighted: 30)
> >   ---
> >   SUM: 18 (            Weighted: 81)
> > 
> > Which seems beneficial in total. I think the rule might be something like: Do never create a split with less than three elements on one side unless the smallest weight on that side is larger than all the weights on the other side. But that might not be sufficient.
> It's going to be
> ```
> this_case = (x < 40
>                  ? x < 30 ? x == 0 ? A : default
>                           : x == 10 ? C : x == 20 ? C : x == 30 ? D : DEFAULT
>                  : x == 40 ? E : x == 50 ? F : DEFAULT);
> ```
> But the numbers add upp the same way.
> 
> This is interesting. It's something about our leaves being different than in a typical binary tree in that we can do up to three comparisons in them.
> 
> Like you, I'm also thinking we should probably be careful creating a split with less than three on one side + some conditions. But this will require some thinking.
> 
> As discussed on the IRC channel, for switches where some cases are completely dominating, hoisting them out is probably a good idea. What I've been doing when playing with benchmarks is turning:
> ```
> switch (x) {
>   cases ...
> }
> ```
> into
> ```
> switch (x) {
>   hot_case 1:
>   hot_case 2:
>   ...
> }
> switch (x) {
>   cold_cases here
> }
> ```
> And that's been really beneficial for switches where a few cases dominate.
> 
> I like the current approach for handling switches in general though, and I think the hoisting would be a separate thing that takes place before.
Coming back to this example where weight-balancing the tree actually makes the example worse, since it would have been better to have 3 elements in the leaf node instead of just one. I committed r240224 to address this. It's not perfect, but I think it helps a lot.

http://reviews.llvm.org/D9318

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/






More information about the llvm-commits mailing list