[llvm] 10357e1 - [LoopUtils] Better accuracy for getLoopEstimatedTripCount.

Evgeniy Brevnov via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 20 02:00:54 PST 2020


Author: Evgeniy Brevnov
Date: 2020-01-20T16:58:07+07:00
New Revision: 10357e1c89b370a18500a8a8d69a68ab72db979e

URL: https://github.com/llvm/llvm-project/commit/10357e1c89b370a18500a8a8d69a68ab72db979e
DIFF: https://github.com/llvm/llvm-project/commit/10357e1c89b370a18500a8a8d69a68ab72db979e.diff

LOG: [LoopUtils] Better accuracy for getLoopEstimatedTripCount.

Summary: Current implementation of getLoopEstimatedTripCount returns 1 iteration less than it should. The reason is that in bottom tested loop first iteration is executed before first back branch is taken. For example for loop with !{!"branch_weights", i32 1 // taken, i32 1 // exit} metadata getLoopEstimatedTripCount gives 1 while actual number of iterations is 2.

Reviewers: Ayal, fhahn

Reviewed By: Ayal

Subscribers: mgorny, hiraditya, zzheng, llvm-commits

Tags: #llvm

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

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/LoopUtils.cpp
    llvm/test/Transforms/LoopUnroll/peel-loop-conditions-pgo-1.ll
    llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom-2.ll
    llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom.ll
    llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt.ll
    llvm/test/Transforms/LoopUnroll/peel-loop-pgo.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp
index 054ef17a9647..98e4ca5ed6ba 100644
--- a/llvm/lib/Transforms/Utils/LoopUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp
@@ -723,12 +723,15 @@ Optional<unsigned> llvm::getLoopEstimatedTripCount(Loop *L) {
   if (LatchBR->getSuccessor(0) != L->getHeader())
     std::swap(BackedgeTakenWeight, LatchExitWeight);
 
-  if (!BackedgeTakenWeight || !LatchExitWeight)
-    return 0;
+  if (!LatchExitWeight)
+    return None;
 
-  // Divide the count of the backedge by the count of the edge exiting the loop,
-  // rounding to nearest.
-  return llvm::divideNearest(BackedgeTakenWeight, LatchExitWeight);
+  // Estimated backedge taken count is a ratio of the backedge taken weight by
+  // the the edge exiting weight, rounded to nearest.
+  uint64_t BackedgeTakenCount =
+      llvm::divideNearest(BackedgeTakenWeight, LatchExitWeight);
+  // Estimated trip count is one plus estimated backedge taken count.
+  return BackedgeTakenCount + 1;
 }
 
 bool llvm::hasIterationCountInvariantInParent(Loop *InnerLoop,

diff  --git a/llvm/test/Transforms/LoopUnroll/peel-loop-conditions-pgo-1.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-conditions-pgo-1.ll
index 0c56229d0643..8624c8881d73 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-conditions-pgo-1.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-conditions-pgo-1.ll
@@ -11,7 +11,7 @@ declare void @f2()
 define void @test1(i32 %k) !prof !4 {
 ; CHECK: Loop Unroll: F[test1] Loop %for.body
 ; CHECK: PEELING loop %for.body with iteration count 2!
-; CHECK: PEELING loop %for.body with iteration count 4!
+; CHECK: PEELING loop %for.body with iteration count 5!
 ; CHECK: llvm.loop.unroll.disable
 for.body.lr.ph:
   br label %for.body

diff  --git a/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom-2.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom-2.ll
index 17fd5a741f2a..006f2bbb4c81 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom-2.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom-2.ll
@@ -5,7 +5,7 @@
 ; Regression test for setting the correct idom for exit blocks.
 
 ; CHECK: Loop Unroll: F[basic]
-; CHECK: PEELING loop %for.body with iteration count 1!
+; CHECK: PEELING loop %for.body with iteration count 2!
 
 define i32 @basic(i32* %p, i32 %k, i1 %c1, i1 %c2) #0 !prof !3 {
 entry:

diff  --git a/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom.ll
index ab3488c81107..7b0dcac3ed4d 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt-idom.ll
@@ -5,7 +5,7 @@
 ; Regression test for setting the correct idom for exit blocks.
 
 ; CHECK: Loop Unroll: F[basic]
-; CHECK: PEELING loop %for.body with iteration count 1!
+; CHECK: PEELING loop %for.body with iteration count 2!
 
 define i32 @basic(i32* %p, i32 %k, i1 %c1, i1 %c2) #0 !prof !3 {
 entry:

diff  --git a/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt.ll
index abad07948cc5..9c059ce23603 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-pgo-deopt.ll
@@ -8,7 +8,7 @@
 ; All side exits to deopt does not change weigths.
 
 ; CHECK: Loop Unroll: F[basic]
-; CHECK: PEELING loop %for.body with iteration count 3!
+; CHECK: PEELING loop %for.body with iteration count 4!
 ; CHECK-NO-PEEL-NOT: PEELING loop %for.body
 ; CHECK-LABEL: @basic
 ; CHECK: br i1 %c, label %{{.*}}, label %side_exit, !prof !15

diff  --git a/llvm/test/Transforms/LoopUnroll/peel-loop-pgo.ll b/llvm/test/Transforms/LoopUnroll/peel-loop-pgo.ll
index f34d3d46c82e..c3f6698a3fbd 100644
--- a/llvm/test/Transforms/LoopUnroll/peel-loop-pgo.ll
+++ b/llvm/test/Transforms/LoopUnroll/peel-loop-pgo.ll
@@ -9,7 +9,7 @@
 ; from the loop, and update the branch weights for the peeled loop properly.
 
 ; CHECK: Loop Unroll: F[basic]
-; CHECK: PEELING loop %for.body with iteration count 3!
+; CHECK: PEELING loop %for.body with iteration count 4!
 ; CHECK: Loop Unroll: F[optsize]
 ; CHECK-NOT: PEELING
 


        


More information about the llvm-commits mailing list