summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Hahn <florian.hahn@arm.com>2018-04-25 09:35:54 +0000
committerFlorian Hahn <florian.hahn@arm.com>2018-04-25 09:35:54 +0000
commit1da30c659dc1631862536af35fe63acf289c4650 (patch)
tree8adfef89a1a2c56f98322e57df4e6db937ea0f94
parenteb896b148b1640b8481191c285894dbbe097f9f2 (diff)
downloadbcm5719-llvm-1da30c659dc1631862536af35fe63acf289c4650.tar.gz
bcm5719-llvm-1da30c659dc1631862536af35fe63acf289c4650.zip
[LoopInterchange] Use getExitBlock()/getExitingBlock instead of manual impl.
This also means we have to check if the latch is the exiting block now, as `transform` expects the latches to be the exiting blocks too. https://bugs.llvm.org/show_bug.cgi?id=36586 Reviewers: efriedma, davide, karthikthecool Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D45279 llvm-svn: 330806
-rw-r--r--llvm/lib/Transforms/Scalar/LoopInterchange.cpp60
-rw-r--r--llvm/test/Transforms/LoopInterchange/currentLimitation.ll51
2 files changed, 74 insertions, 37 deletions
diff --git a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
index 5dcb630c814..45d76fdb7c9 100644
--- a/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopInterchange.cpp
@@ -543,22 +543,16 @@ struct LoopInterchange : public FunctionPass {
printDepMatrix(DependencyMatrix);
#endif
- BasicBlock *OuterMostLoopLatch = OuterMostLoop->getLoopLatch();
- BranchInst *OuterMostLoopLatchBI =
- dyn_cast<BranchInst>(OuterMostLoopLatch->getTerminator());
- if (!OuterMostLoopLatchBI || OuterMostLoopLatchBI->getNumSuccessors() != 2)
- return false;
-
// Since we currently do not handle LCSSA PHI's any failure in loop
// condition will now branch to LoopNestExit.
// TODO: This should be removed once we handle LCSSA PHI nodes.
// Get the Outermost loop exit.
- BasicBlock *LoopNestExit;
- if (OuterMostLoopLatchBI->getSuccessor(0) == OuterMostLoop->getHeader())
- LoopNestExit = OuterMostLoopLatchBI->getSuccessor(1);
- else
- LoopNestExit = OuterMostLoopLatchBI->getSuccessor(0);
+ BasicBlock *LoopNestExit = OuterMostLoop->getExitBlock();
+ if (!LoopNestExit) {
+ DEBUG(dbgs() << "OuterMostLoop needs an unique exit block");
+ return false;
+ }
if (isa<PHINode>(LoopNestExit->begin())) {
DEBUG(dbgs() << "PHI Nodes in loop nest exit is not handled for now "
@@ -756,28 +750,29 @@ static bool containsSafePHI(BasicBlock *Block, bool isOuterLoopExitBlock) {
return true;
}
-static BasicBlock *getLoopLatchExitBlock(BasicBlock *LatchBlock,
- BasicBlock *LoopHeader) {
- if (BranchInst *BI = dyn_cast<BranchInst>(LatchBlock->getTerminator())) {
- assert(BI->getNumSuccessors() == 2 &&
- "Branch leaving loop latch must have 2 successors");
- for (BasicBlock *Succ : BI->successors()) {
- if (Succ == LoopHeader)
- continue;
- return Succ;
- }
- }
- return nullptr;
-}
-
// This function indicates the current limitations in the transform as a result
// of which we do not proceed.
bool LoopInterchangeLegality::currentLimitations() {
BasicBlock *InnerLoopPreHeader = InnerLoop->getLoopPreheader();
- BasicBlock *InnerLoopHeader = InnerLoop->getHeader();
BasicBlock *InnerLoopLatch = InnerLoop->getLoopLatch();
- BasicBlock *OuterLoopLatch = OuterLoop->getLoopLatch();
- BasicBlock *OuterLoopHeader = OuterLoop->getHeader();
+
+ // transform currently expects the loop latches to also be the exiting
+ // blocks.
+ if (InnerLoop->getExitingBlock() != InnerLoopLatch ||
+ OuterLoop->getExitingBlock() != OuterLoop->getLoopLatch() ||
+ !isa<BranchInst>(InnerLoopLatch->getTerminator()) ||
+ !isa<BranchInst>(OuterLoop->getLoopLatch()->getTerminator())) {
+ DEBUG(dbgs() << "Loops where the latch is not the exiting block are not"
+ << " supported currently.\n");
+ ORE->emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "ExitingNotLatch",
+ OuterLoop->getStartLoc(),
+ OuterLoop->getHeader())
+ << "Loops where the latch is not the exiting block cannot be"
+ " interchange currently.";
+ });
+ return true;
+ }
PHINode *InnerInductionVar;
SmallVector<PHINode *, 8> Inductions;
@@ -867,9 +862,8 @@ bool LoopInterchangeLegality::currentLimitations() {
}
// TODO: We only handle LCSSA PHI's corresponding to reduction for now.
- BasicBlock *LoopExitBlock =
- getLoopLatchExitBlock(OuterLoopLatch, OuterLoopHeader);
- if (!LoopExitBlock || !containsSafePHI(LoopExitBlock, true)) {
+ BasicBlock *OuterExit = OuterLoop->getExitBlock();
+ if (!containsSafePHI(OuterExit, true)) {
DEBUG(dbgs() << "Can only handle LCSSA PHIs in outer loops currently.\n");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NoLCSSAPHIOuter",
@@ -881,8 +875,8 @@ bool LoopInterchangeLegality::currentLimitations() {
return true;
}
- LoopExitBlock = getLoopLatchExitBlock(InnerLoopLatch, InnerLoopHeader);
- if (!LoopExitBlock || !containsSafePHI(LoopExitBlock, false)) {
+ BasicBlock *InnerExit = InnerLoop->getExitBlock();
+ if (!containsSafePHI(InnerExit, false)) {
DEBUG(dbgs() << "Can only handle LCSSA PHIs in inner loops currently.\n");
ORE->emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NoLCSSAPHIOuterInner",
diff --git a/llvm/test/Transforms/LoopInterchange/currentLimitation.ll b/llvm/test/Transforms/LoopInterchange/currentLimitation.ll
index f644e043a78..1a9d42dbb9a 100644
--- a/llvm/test/Transforms/LoopInterchange/currentLimitation.ll
+++ b/llvm/test/Transforms/LoopInterchange/currentLimitation.ll
@@ -1,12 +1,13 @@
-; REQUIRES: asserts
-; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -verify-loop-info \
-; RUN: -S -debug 2>&1 | FileCheck %s
+; RUN: opt < %s -basicaa -loop-interchange -pass-remarks-missed='loop-interchange' \
+; RUN: -pass-remarks-output=%t -verify-loop-info -verify-dom-info -S | FileCheck -check-prefix=IR %s
+; RUN: FileCheck --input-file=%t %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@A = common global [100 x [100 x i32]] zeroinitializer
@B = common global [100 x [100 x [100 x i32]]] zeroinitializer
+@C = common global [100 x [100 x i64]] zeroinitializer
;;--------------------------------------Test case 01------------------------------------
;; [FIXME] This loop though valid is currently not interchanged due to the limitation that we cannot split the inner loop latch due to multiple use of inner induction
@@ -15,7 +16,12 @@ target triple = "x86_64-unknown-linux-gnu"
;; for(int j=1;j<N-1;j++)
;; A[j+1][i+1] = A[j+1][i+1] + k;
-; CHECK: Not interchanging loops. Cannot prove legality.
+; FIXME: Currently fails because of DA changes.
+; IR-LABEL: @interchange_01
+; IR-NOT: split
+
+; CHECK: Name: Dependence
+; CHECK-NEXT: Function: interchange_01
define void @interchange_01(i32 %k, i32 %N) {
entry:
@@ -52,3 +58,40 @@ define void @interchange_01(i32 %k, i32 %N) {
for.end17:
ret void
}
+
+; When currently cannot interchange this loop, because transform currently
+; expects the latches to be the exiting blocks too.
+
+; IR-LABEL: @interchange_02
+; IR-NOT: split
+;
+; CHECK: Name: ExitingNotLatch
+; CHECK-NEXT: Function: interchange_02
+define void @interchange_02(i64 %k, i64 %N) {
+entry:
+ br label %for1.header
+
+for1.header:
+ %j23 = phi i64 [ 0, %entry ], [ %j.next24, %for1.inc10 ]
+ br label %for2
+
+for2:
+ %j = phi i64 [ %j.next, %latch ], [ 0, %for1.header ]
+ %arrayidx5 = getelementptr inbounds [100 x [100 x i64]], [100 x [100 x i64]]* @C, i64 0, i64 %j, i64 %j23
+ %lv = load i64, i64* %arrayidx5
+ %add = add nsw i64 %lv, %k
+ store i64 %add, i64* %arrayidx5
+ %exitcond = icmp eq i64 %j, 99
+ br i1 %exitcond, label %for1.inc10, label %latch
+latch:
+ %j.next = add nuw nsw i64 %j, 1
+ br label %for2
+
+for1.inc10:
+ %j.next24 = add nuw nsw i64 %j23, 1
+ %exitcond26 = icmp eq i64 %j23, 99
+ br i1 %exitcond26, label %for.end12, label %for1.header
+
+for.end12:
+ ret void
+}
OpenPOWER on IntegriCloud