[PATCH] D28593: Update loop branch_weight metadata after loop rotation.

Xin Tong via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 12 21:52:15 PST 2017


I came up with this example to show why we need to update the metadata
after loop-rotation and the way this patch provides works. You will
need https://reviews.llvm.org/D28593.


Loop that always executes at least 1 iteration.
===================================
The branch weight for always_call is {128, 128} and the loop executes
1 time each time always_call is called. Without updating the metadata
correctly after loop rotation, we will see the loop peeled 2X. This is
due to getEstimatedTripCount returns (128/128+1/2) + 1.This is
suboptimal as the loop only executes once every time.

In this case with proper metadata update after rotation, we will
assign backedge weight to 1 (minimum) and loop exit weight to 128.
This is because we assume the trip count of the loop are not
polarized, i.e. they are similar every-time the loop is hit and with
this information we know the not-take-once weight in the guard block
is 0 and we compute everything else based on that.

Loop that does not execute 1 iteration sometimes.
======================================
* The branch weight for call_on_odd is {64, 128} and the loop executes
not-even-once half of the time call_on_odd is called and once the
other half. Without updating metadata properly, we will end up peeling
2X which is suboptimal. This is due to getEstimatedTripCount returns
(64/128+1/2) + 1.

In this case with proper metadata update, we will assign backedge
weight to 1 (minimum), loop exit weight to 64 and not-taken-once
weight to 64. This is because we assume most of the iterations, the
backedge will not be taken. and with this information we compute the
rest of the branch weight.

NOTE: This assumes the loop tripcount is not polarized as we talked
before. In case this is not the case, the branch weight information is
not useful regardless of we do this adjustment to the metadata or not.
We simply do not know what the distribution would be and no good way
to make a reasonable choice.

Program && Command line I use to execute.
==================================

clang  -O2 -fprofile-generate=prof.raw loop-rotate.c -o instr_bin &&
./instr_bin  && llvm-profdata merge prof.raw -o prof && clang
loop-rotate.c  -c -O2 -fprofile-use=prof -emit-llvm -S -mllvm
-unroll-allow-peeling && vim loop-rotate.ll


/// loop-rotate.c
__attribute__((noinline)) void call_me(int *done_call) {
  *done_call = 1;
}


// Invoke call_me once when done_call is false.
// This is a case where the loop executes once everytime the function is called.
__attribute__((noinline)) void always_call(int *done_call) {
  while (!*done_call) {
    call_me(done_call);
  }
}


// Invoke call_me once when done_call is false and index is odd.
// This is a case where the loop does not execute even once half of the
// time because of the index.
__attribute__((noinline)) void call_on_odd(int *done_call, int index) {
  while (index % 2 && !*done_call) {
    call_me(done_call);
  }
}


int main() {
  int done_call;
  for (int i = 0; i < 128; ++i) {
    // Call always_call.
    done_call = 0;
    always_call(&done_call);

    // Call call_on_add.
    done_call = 0;
    call_on_odd(&done_call, i);
  }
  return 0;
}

On Thu, Jan 12, 2017 at 9:23 PM, Xin Tong via Phabricator
<reviews at reviews.llvm.org> wrote:
> trentxintong updated this revision to Diff 84223.
> trentxintong added a comment.
>
> I only want the head commit to be included in this patch.
>
>
> https://reviews.llvm.org/D28593
>
> Files:
>   lib/Transforms/Scalar/LoopRotation.cpp
>   test/Transforms/LoopRotate/loop-rotate-pgo.ll
>

On Thu, Jan 12, 2017 at 9:43 PM, Xin Tong via Phabricator
<reviews at reviews.llvm.org> wrote:
> trentxintong updated this revision to Diff 84224.
> trentxintong added a comment.
>
> I want to merge https://reviews.llvm.org/D28460, but I do not know how to do
> so on Phabricator. So I merged it manually =).
>
>
> https://reviews.llvm.org/D28593
>
> Files:
>   lib/Transforms/Scalar/LoopRotation.cpp
>   lib/Transforms/Utils/LoopUtils.cpp
>   test/Transforms/LoopRotate/loop-rotate-pgo.ll
>


More information about the llvm-commits mailing list