[llvm] r296898 - [LoopUnrolling] Peel loops with invariant backedge Phi input

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 3 10:19:16 PST 2017


Author: sanjoy
Date: Fri Mar  3 12:19:15 2017
New Revision: 296898

URL: http://llvm.org/viewvc/llvm-project?rev=296898&view=rev
Log:
[LoopUnrolling] Peel loops with invariant backedge Phi input

Summary:
If a loop contains a Phi node which has an invariant input from back
edge, it is profitable to peel such loops (rather than unroll them) to
use the advantage that this Phi is always invariant starting from 2nd
iteration. After the 1st iteration is peeled, other optimizations can
potentially simplify calculations with this invariant.

Patch by Max Kazantsev!

Reviewers: sanjoy, apilipenko, igor-laevsky, anna, mkuper, reames

Reviewed By: mkuper

Subscribers: mkuper, mzolotukhin, llvm-commits

Differential Revision: https://reviews.llvm.org/D30161

Added:
    llvm/trunk/test/Transforms/LoopUnroll/peel-loop-not-forced.ll
Modified:
    llvm/trunk/lib/Transforms/Utils/LoopUnrollPeel.cpp

Modified: llvm/trunk/lib/Transforms/Utils/LoopUnrollPeel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUnrollPeel.cpp?rev=296898&r1=296897&r2=296898&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LoopUnrollPeel.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LoopUnrollPeel.cpp Fri Mar  3 12:19:15 2017
@@ -71,6 +71,31 @@ void llvm::computePeelCount(Loop *L, uns
   if (!L->empty())
     return;
 
+  // Try to find a Phi node that has the same loop invariant as an input from
+  // its only back edge. If there is such Phi, peeling 1 iteration from the
+  // loop is profitable, because starting from 2nd iteration we will have an
+  // invariant instead of this Phi.
+  if (auto *BackEdge = L->getLoopLatch()) {
+    BasicBlock *Header = L->getHeader();
+    // Iterate over Phis to find one with invariant input on back edge.
+    bool FoundCandidate = false;
+    PHINode *Phi;
+    for (auto BI = Header->begin(); Phi = dyn_cast<PHINode>(&*BI); ++BI) {
+      Value *Input = Phi->getIncomingValueForBlock(BackEdge);
+      if (L->isLoopInvariant(Input)) {
+        FoundCandidate = true;
+        break;
+      }
+    }
+    if (FoundCandidate) {
+      DEBUG(dbgs() << "Peel one iteration to get rid of " << *Phi
+                   << " because starting from 2nd iteration it is always"
+                   << " an invariant\n");
+      UP.PeelCount = 1;
+      return;
+    }
+  }
+
   // Bail if we know the statically calculated trip count.
   // In this case we rather prefer partial unrolling.
   if (TripCount)

Added: llvm/trunk/test/Transforms/LoopUnroll/peel-loop-not-forced.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopUnroll/peel-loop-not-forced.ll?rev=296898&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LoopUnroll/peel-loop-not-forced.ll (added)
+++ llvm/trunk/test/Transforms/LoopUnroll/peel-loop-not-forced.ll Fri Mar  3 12:19:15 2017
@@ -0,0 +1,25 @@
+; RUN: opt < %s -S -loop-unroll | FileCheck %s
+
+define i32 @invariant_backedge_1(i32 %a, i32 %b) {
+; CHECK-LABEL: @invariant_backedge_1
+; CHECK-NOT:     %plus = phi
+; CHECK:       loop.peel:
+; CHECK:       loop:
+; CHECK:         %i = phi
+; CHECK:         %sum = phi
+entry:
+  br label %loop
+
+loop:
+  %i = phi i32 [ 0, %entry ], [ %inc, %loop ]
+  %sum = phi i32 [ 0, %entry ], [ %incsum, %loop ]
+  %plus = phi i32 [ %a, %entry ], [ %b, %loop ]
+
+  %incsum = add i32 %sum, %plus
+  %inc = add i32 %i, 1
+  %cmp = icmp slt i32 %i, 1000
+  br i1 %cmp, label %loop, label %exit
+
+exit:
+  ret i32 %sum
+}




More information about the llvm-commits mailing list