[PATCH] D14526: Don't recompute LCSSA after loop-unrolling when possible.

Michael Zolotukhin via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 10 11:23:33 PST 2015


Hi Duncan,

> On Nov 10, 2015, at 9:45 AM, Duncan P. N. Exon Smith <dexonsmith at apple.com> wrote:
> 
> 
>> On 2015-Nov-09, at 20:54, Michael Zolotukhin <mzolotukhin at apple.com> wrote:
>> 
>> mzolotukhin created this revision.
>> mzolotukhin added reviewers: chandlerc, hfinkel, dexonsmith, bogner, joker.eph.
>> mzolotukhin added a subscriber: llvm-commits.
>> 
>> Currently we always recompute LCSSA for outer loops after unrolling an
>> inner loop. That leads to compile time problem when we have big loop
>> nests, and we can solve it by avoiding unnecessary work. For instance,
>> if w eonly do partial unrolling, we don't break LCSSA, so we don't need
>> to rebuild it. Also, if all exits from the inner loop are inside the
>> enclosing loop, then complete unrolling won't break LCSSA either.
>> 
>> I replaced unconditional LCSSA recomputation with conditional recomputation +
>> unconditional assert and added several tests, which were failing when I
>> experimented with it.
>> 
>> Soon I plan to follow up with a similar patch for recalculation of dominators
>> tree.
>> 
>> http://reviews.llvm.org/D14526
>> 
>> Files:
>> lib/Transforms/Utils/LoopUnroll.cpp
>> test/Transforms/LoopUnroll/rebuild_lcssa.ll
>> 
>> <D14526.39782.patch>
> 
> This makes sense to me, although I don't know the loop algorithms too well
> so maybe someone else can confirm.  A few nitpicks below.
> 
>> Index: lib/Transforms/Utils/LoopUnroll.cpp
>> ===================================================================
>> --- lib/Transforms/Utils/LoopUnroll.cpp
>> +++ lib/Transforms/Utils/LoopUnroll.cpp
>> @@ -221,6 +221,16 @@
>> 
>>   // Are we eliminating the loop control altogether?
>>   bool CompletelyUnroll = Count == TripCount;
>> +  SmallVector<BasicBlock *, 4> ExitBlocks;
>> +  L->getExitBlocks(ExitBlocks);
>> +  Loop *ParentL = L->getParentLoop();
>> +  bool AllExitsAreInsideParentLoop = true;
>> +  for (auto BB : ExitBlocks) {
> 
> This would be clearer as `const BasicBlock *BB`, but should at least be
> `const auto *BB` to make clear to readers that there are no copies going
> on.
Makes sense.
> 
>> +    if (LI->getLoopFor(BB) != ParentL) {
>> +      AllExitsAreInsideParentLoop = false;
>> +      break;
>> +    }
>> +  }
>> 
>>   // We assume a run-time trip count if the compiler cannot
>>   // figure out the loop trip count and the unroll-runtime
>> @@ -554,7 +564,11 @@
>>         while (OuterL->getParentLoop() != LatchLoop)
>>           OuterL = OuterL->getParentLoop();
>> 
>> -      formLCSSARecursively(*OuterL, *DT, LI, SE);
>> +      if (CompletelyUnroll && !AllExitsAreInsideParentLoop)
>> +        formLCSSARecursively(*OuterL, *DT, LI, SE);
>> +
>> +      assert(OuterL->isLCSSAForm(*DT) &&
> 
> Is this check cheap?  If not, it seems wasteful to do it when we've just
> called `formLCSSARecursively()`.  Can you put this in an `else`, or do
> an early continue inside the `if`?
I thought it was fine to have even expensive checks under assert - isn’t it?
> 
>> +             "Must have loops in LCSSA form to after loop-unroll.");
> 
> s/to after/after/
Thanks!
> 
>>     }
>>   }
>> 
>> 
> 



More information about the llvm-commits mailing list