diff options
| author | Florian Hahn <florian.hahn@arm.com> | 2018-04-25 09:35:54 +0000 |
|---|---|---|
| committer | Florian Hahn <florian.hahn@arm.com> | 2018-04-25 09:35:54 +0000 |
| commit | 1da30c659dc1631862536af35fe63acf289c4650 (patch) | |
| tree | 8adfef89a1a2c56f98322e57df4e6db937ea0f94 | |
| parent | eb896b148b1640b8481191c285894dbbe097f9f2 (diff) | |
| download | bcm5719-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.cpp | 60 | ||||
| -rw-r--r-- | llvm/test/Transforms/LoopInterchange/currentLimitation.ll | 51 |
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 +} |

