[PATCH] D22630: Loop rotation

Sebastian Pop via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 21 13:43:08 PDT 2016


Here is an example that cannot be handled by PRE no matter what it
does, as it cannot prove that the load B->at() is executed at least
once, so it cannot move B->at(n*i) past the potential exception thrown
by A->at():

#include <vector>

int fun(const std::vector<char>* A, const std::vector<char>* B, int n, int m)
{
  int res = 0;

  for (int i = 0; i < m; ++i)
    for (int j = 0; j < n; ++j)
      res += A->at(n * i + j) + B->at(n * i + j);

  return res;
}

the vector ->at() function contains bounds checks and may throw an
exception, so after the load in A->at() can be hoisted, though the
load in B->at() cannot because the A->at() may raise an exception.

After loop rotate peels off one full iteration of the loop:

   for (int i = 0; i < m; ++i) {
    x = A->at(n * i);
    if (exception)
      throw;
    y = B->at(n*i);
    if(exception)
      throw;
    res += x + y;
    for (int j = 0; j < n; ++j)
      res += A->at(n * i + j) + B->at(n * i + j);
   }

we now have the B->at(n*i) redundancy without the hard problem of
isGuaranteedToExecute,
and PRE or LICM should be able to remove the redundant expression out
of the innermost loop.


On Thu, Jul 21, 2016 at 2:41 PM, Daniel Berlin <dberlin at dberlin.org> wrote:
>
>
> On Thu, Jul 21, 2016 at 8:40 AM, Aditya Kumar via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
>>
>> hiraditya created this revision.
>> hiraditya added reviewers: hfinkel, sanjoy.
>> hiraditya added subscribers: mzolotukhin, sebpop, jlebar, llvm-commits.
>> Herald added a subscriber: sanjoy.
>>
>> This patch implements Loop Rotation Pass:
>>
>>  1. Canonicalize loop latch to have only one successor.
>>  2. Clone all the BBs which are exiting the loop.
>>  3. Adjust phi of cloned BBs
>>  4. Add phi to the new loop header
>>  5. Update DOM
>>
>> With this patch all the basic blocks which are exiting the loop can be
>> copied during rotation. This is helpful for passes like gvn/licm which can
>> now remove loop invariant code
>> because some computations (which might not dominate all the basic blocks
>> of loop) can now be PRE'd as they are available outside of the loop (due to
>> loop rotation).
>
>
> Can you give specific examples?
>
> If these are simply bad choices our PRE makes, we can just fix PRE instead
> of rotate loops to fix PRE :)


More information about the llvm-commits mailing list