<div dir="ltr">Thanks, this is a great example :)<div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul 21, 2016 at 1:43 PM, Sebastian Pop <span dir="ltr"><<a href="mailto:sebpop@gmail.com" target="_blank">sebpop@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Here is an example that cannot be handled by PRE no matter what it<br>
does, as it cannot prove that the load B->at() is executed at least<br>
once, so it cannot move B->at(n*i) past the potential exception thrown<br>
by A->at():<br>
<br>
#include <vector><br>
<br>
int fun(const std::vector<char>* A, const std::vector<char>* B, int n, int m)<br>
{<br>
  int res = 0;<br>
<br>
  for (int i = 0; i < m; ++i)<br>
    for (int j = 0; j < n; ++j)<br>
      res += A->at(n * i + j) + B->at(n * i + j);<br>
<br>
  return res;<br>
}<br>
<br>
the vector ->at() function contains bounds checks and may throw an<br>
exception, so after the load in A->at() can be hoisted, though the<br>
load in B->at() cannot because the A->at() may raise an exception.<br>
<br>
After loop rotate peels off one full iteration of the loop:<br>
<br>
   for (int i = 0; i < m; ++i) {<br>
    x = A->at(n * i);<br>
    if (exception)<br>
      throw;<br>
    y = B->at(n*i);<br>
    if(exception)<br>
      throw;<br>
    res += x + y;<br>
    for (int j = 0; j < n; ++j)<br>
      res += A->at(n * i + j) + B->at(n * i + j);<br>
   }<br>
<br>
we now have the B->at(n*i) redundancy without the hard problem of<br>
isGuaranteedToExecute,<br>
and PRE or LICM should be able to remove the redundant expression out<br>
of the innermost loop.<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
On Thu, Jul 21, 2016 at 2:41 PM, Daniel Berlin <<a href="mailto:dberlin@dberlin.org">dberlin@dberlin.org</a>> wrote:<br>
><br>
><br>
> On Thu, Jul 21, 2016 at 8:40 AM, Aditya Kumar via llvm-commits<br>
> <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
>><br>
>> hiraditya created this revision.<br>
>> hiraditya added reviewers: hfinkel, sanjoy.<br>
>> hiraditya added subscribers: mzolotukhin, sebpop, jlebar, llvm-commits.<br>
>> Herald added a subscriber: sanjoy.<br>
>><br>
>> This patch implements Loop Rotation Pass:<br>
>><br>
>>  1. Canonicalize loop latch to have only one successor.<br>
>>  2. Clone all the BBs which are exiting the loop.<br>
>>  3. Adjust phi of cloned BBs<br>
>>  4. Add phi to the new loop header<br>
>>  5. Update DOM<br>
>><br>
>> With this patch all the basic blocks which are exiting the loop can be<br>
>> copied during rotation. This is helpful for passes like gvn/licm which can<br>
>> now remove loop invariant code<br>
>> because some computations (which might not dominate all the basic blocks<br>
>> of loop) can now be PRE'd as they are available outside of the loop (due to<br>
>> loop rotation).<br>
><br>
><br>
> Can you give specific examples?<br>
><br>
> If these are simply bad choices our PRE makes, we can just fix PRE instead<br>
> of rotate loops to fix PRE :)<br>
</div></div></blockquote></div><br></div>