mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
[LoopInterchange] Incrementally update the dominator tree.
We can use incremental dominator tree updates to avoid re-calculating the dominator tree after interchanging 2 loops. Reviewers: dmgreen, kuhar Reviewed By: kuhar Differential Revision: https://reviews.llvm.org/D43176 llvm-svn: 325122
This commit is contained in:
parent
da0ab3b6ed
commit
0c62c8e2fa
@ -453,6 +453,8 @@ struct LoopInterchange : public FunctionPass {
|
|||||||
AU.addRequiredID(LoopSimplifyID);
|
AU.addRequiredID(LoopSimplifyID);
|
||||||
AU.addRequiredID(LCSSAID);
|
AU.addRequiredID(LCSSAID);
|
||||||
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
|
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
|
||||||
|
|
||||||
|
AU.addPreserved<DominatorTreeWrapperPass>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool runOnFunction(Function &F) override {
|
bool runOnFunction(Function &F) override {
|
||||||
@ -462,8 +464,7 @@ struct LoopInterchange : public FunctionPass {
|
|||||||
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||||
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
||||||
DI = &getAnalysis<DependenceAnalysisWrapperPass>().getDI();
|
DI = &getAnalysis<DependenceAnalysisWrapperPass>().getDI();
|
||||||
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
|
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||||
DT = DTWP ? &DTWP->getDomTree() : nullptr;
|
|
||||||
ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
|
ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
|
||||||
PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
|
PreserveLCSSA = mustPreserveAnalysisID(LCSSAID);
|
||||||
|
|
||||||
@ -573,7 +574,6 @@ struct LoopInterchange : public FunctionPass {
|
|||||||
|
|
||||||
// Update the DependencyMatrix
|
// Update the DependencyMatrix
|
||||||
interChangeDependencies(DependencyMatrix, i, i - 1);
|
interChangeDependencies(DependencyMatrix, i, i - 1);
|
||||||
DT->recalculate(F);
|
|
||||||
#ifdef DUMP_DEP_MATRICIES
|
#ifdef DUMP_DEP_MATRICIES
|
||||||
DEBUG(dbgs() << "Dependence after interchange\n");
|
DEBUG(dbgs() << "Dependence after interchange\n");
|
||||||
printDepMatrix(DependencyMatrix);
|
printDepMatrix(DependencyMatrix);
|
||||||
@ -1265,8 +1265,31 @@ void LoopInterchangeTransform::updateIncomingBlock(BasicBlock *CurrBlock,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Update BI to jump to NewBB instead of OldBB. Records updates to
|
||||||
|
/// the dominator tree in DTUpdates, if DT should be preserved.
|
||||||
|
static void updateSuccessor(BranchInst *BI, BasicBlock *OldBB,
|
||||||
|
BasicBlock *NewBB,
|
||||||
|
std::vector<DominatorTree::UpdateType> &DTUpdates) {
|
||||||
|
assert(llvm::count_if(BI->successors(),
|
||||||
|
[OldBB](BasicBlock *BB) { return BB == OldBB; }) < 2 &&
|
||||||
|
"BI must jump to OldBB at most once.");
|
||||||
|
for (unsigned i = 0, e = BI->getNumSuccessors(); i < e; ++i) {
|
||||||
|
if (BI->getSuccessor(i) == OldBB) {
|
||||||
|
BI->setSuccessor(i, NewBB);
|
||||||
|
|
||||||
|
DTUpdates.push_back(
|
||||||
|
{DominatorTree::UpdateKind::Insert, BI->getParent(), NewBB});
|
||||||
|
DTUpdates.push_back(
|
||||||
|
{DominatorTree::UpdateKind::Delete, BI->getParent(), OldBB});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool LoopInterchangeTransform::adjustLoopBranches() {
|
bool LoopInterchangeTransform::adjustLoopBranches() {
|
||||||
DEBUG(dbgs() << "adjustLoopBranches called\n");
|
DEBUG(dbgs() << "adjustLoopBranches called\n");
|
||||||
|
std::vector<DominatorTree::UpdateType> DTUpdates;
|
||||||
|
|
||||||
// Adjust the loop preheader
|
// Adjust the loop preheader
|
||||||
BasicBlock *InnerLoopHeader = InnerLoop->getHeader();
|
BasicBlock *InnerLoopHeader = InnerLoop->getHeader();
|
||||||
BasicBlock *OuterLoopHeader = OuterLoop->getHeader();
|
BasicBlock *OuterLoopHeader = OuterLoop->getHeader();
|
||||||
@ -1306,27 +1329,18 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Adjust Loop Preheader and headers
|
// Adjust Loop Preheader and headers
|
||||||
|
updateSuccessor(OuterLoopPredecessorBI, OuterLoopPreHeader,
|
||||||
unsigned NumSucc = OuterLoopPredecessorBI->getNumSuccessors();
|
InnerLoopPreHeader, DTUpdates);
|
||||||
for (unsigned i = 0; i < NumSucc; ++i) {
|
updateSuccessor(OuterLoopHeaderBI, OuterLoopLatch, LoopExit, DTUpdates);
|
||||||
if (OuterLoopPredecessorBI->getSuccessor(i) == OuterLoopPreHeader)
|
updateSuccessor(OuterLoopHeaderBI, InnerLoopPreHeader,
|
||||||
OuterLoopPredecessorBI->setSuccessor(i, InnerLoopPreHeader);
|
InnerLoopHeaderSuccessor, DTUpdates);
|
||||||
}
|
|
||||||
|
|
||||||
NumSucc = OuterLoopHeaderBI->getNumSuccessors();
|
|
||||||
for (unsigned i = 0; i < NumSucc; ++i) {
|
|
||||||
if (OuterLoopHeaderBI->getSuccessor(i) == OuterLoopLatch)
|
|
||||||
OuterLoopHeaderBI->setSuccessor(i, LoopExit);
|
|
||||||
else if (OuterLoopHeaderBI->getSuccessor(i) == InnerLoopPreHeader)
|
|
||||||
OuterLoopHeaderBI->setSuccessor(i, InnerLoopHeaderSuccessor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust reduction PHI's now that the incoming block has changed.
|
// Adjust reduction PHI's now that the incoming block has changed.
|
||||||
updateIncomingBlock(InnerLoopHeaderSuccessor, InnerLoopHeader,
|
updateIncomingBlock(InnerLoopHeaderSuccessor, InnerLoopHeader,
|
||||||
OuterLoopHeader);
|
OuterLoopHeader);
|
||||||
|
|
||||||
BranchInst::Create(OuterLoopPreHeader, InnerLoopHeaderBI);
|
updateSuccessor(InnerLoopHeaderBI, InnerLoopHeaderSuccessor,
|
||||||
InnerLoopHeaderBI->eraseFromParent();
|
OuterLoopPreHeader, DTUpdates);
|
||||||
|
|
||||||
// -------------Adjust loop latches-----------
|
// -------------Adjust loop latches-----------
|
||||||
if (InnerLoopLatchBI->getSuccessor(0) == InnerLoopHeader)
|
if (InnerLoopLatchBI->getSuccessor(0) == InnerLoopHeader)
|
||||||
@ -1334,11 +1348,8 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
|
|||||||
else
|
else
|
||||||
InnerLoopLatchSuccessor = InnerLoopLatchBI->getSuccessor(0);
|
InnerLoopLatchSuccessor = InnerLoopLatchBI->getSuccessor(0);
|
||||||
|
|
||||||
NumSucc = InnerLoopLatchPredecessorBI->getNumSuccessors();
|
updateSuccessor(InnerLoopLatchPredecessorBI, InnerLoopLatch,
|
||||||
for (unsigned i = 0; i < NumSucc; ++i) {
|
InnerLoopLatchSuccessor, DTUpdates);
|
||||||
if (InnerLoopLatchPredecessorBI->getSuccessor(i) == InnerLoopLatch)
|
|
||||||
InnerLoopLatchPredecessorBI->setSuccessor(i, InnerLoopLatchSuccessor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjust PHI nodes in InnerLoopLatchSuccessor. Update all uses of PHI with
|
// Adjust PHI nodes in InnerLoopLatchSuccessor. Update all uses of PHI with
|
||||||
// the value and remove this PHI node from inner loop.
|
// the value and remove this PHI node from inner loop.
|
||||||
@ -1358,19 +1369,14 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
|
|||||||
else
|
else
|
||||||
OuterLoopLatchSuccessor = OuterLoopLatchBI->getSuccessor(0);
|
OuterLoopLatchSuccessor = OuterLoopLatchBI->getSuccessor(0);
|
||||||
|
|
||||||
if (InnerLoopLatchBI->getSuccessor(1) == InnerLoopLatchSuccessor)
|
updateSuccessor(InnerLoopLatchBI, InnerLoopLatchSuccessor,
|
||||||
InnerLoopLatchBI->setSuccessor(1, OuterLoopLatchSuccessor);
|
OuterLoopLatchSuccessor, DTUpdates);
|
||||||
else
|
updateSuccessor(OuterLoopLatchBI, OuterLoopLatchSuccessor, InnerLoopLatch,
|
||||||
InnerLoopLatchBI->setSuccessor(0, OuterLoopLatchSuccessor);
|
DTUpdates);
|
||||||
|
|
||||||
updateIncomingBlock(OuterLoopLatchSuccessor, OuterLoopLatch, InnerLoopLatch);
|
updateIncomingBlock(OuterLoopLatchSuccessor, OuterLoopLatch, InnerLoopLatch);
|
||||||
|
|
||||||
if (OuterLoopLatchBI->getSuccessor(0) == OuterLoopLatchSuccessor) {
|
DT->applyUpdates(DTUpdates);
|
||||||
OuterLoopLatchBI->setSuccessor(0, InnerLoopLatch);
|
|
||||||
} else {
|
|
||||||
OuterLoopLatchBI->setSuccessor(1, InnerLoopLatch);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
;; These are test that fail to interchange due to current limitation. This will go off once we extend the loop interchange pass.
|
;; These are test that fail to interchange due to current limitation. This will go off once we extend the loop interchange pass.
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
|
|
||||||
@A10 = local_unnamed_addr global [3 x [3 x i32]] zeroinitializer, align 16
|
@A10 = local_unnamed_addr global [3 x [3 x i32]] zeroinitializer, align 16
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
;; We test the complete .ll for adjustment in outer loop header/latch and inner loop header/latch.
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
;; Checks the order of the inner phi nodes does not cause havoc.
|
;; Checks the order of the inner phi nodes does not cause havoc.
|
||||||
;; The inner loop has a reduction into c. The IV is not the first phi.
|
;; The inner loop has a reduction into c. The IV is not the first phi.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
;; We test profitability model in these test cases.
|
;; We test profitability model in these test cases.
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt < %s -basicaa -loop-interchange -S | FileCheck %s
|
; RUN: opt < %s -basicaa -loop-interchange -verify-dom-info -S | FileCheck %s
|
||||||
|
|
||||||
@A = common global [500 x [500 x i32]] zeroinitializer
|
@A = common global [500 x [500 x i32]] zeroinitializer
|
||||||
@X = common global i32 0
|
@X = common global i32 0
|
||||||
|
Loading…
Reference in New Issue
Block a user