summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MachineBlockPlacement.cpp
diff options
context:
space:
mode:
authorAmaury Sechet <deadalnix@gmail.com>2016-04-07 21:29:39 +0000
committerAmaury Sechet <deadalnix@gmail.com>2016-04-07 21:29:39 +0000
commitc53ad4f3b2b001e476010690e6cc42e8a3ea458e (patch)
tree004937107c422bad6d74e6e6b4c4773a4c846311 /llvm/lib/CodeGen/MachineBlockPlacement.cpp
parent846219ae105f30081973b4b65a3b49cf87f8be4b (diff)
downloadbcm5719-llvm-c53ad4f3b2b001e476010690e6cc42e8a3ea458e.tar.gz
bcm5719-llvm-c53ad4f3b2b001e476010690e6cc42e8a3ea458e.zip
Do not select EhPad BB in MachineBlockPlacement when there is regular BB to schedule
Summary: EHPad BB are not entered the classic way and therefor do not need to be placed after their predecessors. This patch make sure EHPad BB are not chosen amongst successors to form chains, and are selected as last resort when selecting the best candidate. EHPad are scheduled in reverse probability order in order to have them flow into each others naturally. Reviewers: chandlerc, majnemer, rafael, MatzeB, escha, silvas Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D17625 llvm-svn: 265726
Diffstat (limited to 'llvm/lib/CodeGen/MachineBlockPlacement.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineBlockPlacement.cpp78
1 files changed, 66 insertions, 12 deletions
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index 69c0a53fc92..af78d8a8924 100644
--- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -262,6 +262,7 @@ class MachineBlockPlacement : public MachineFunctionPass {
void markChainSuccessors(BlockChain &Chain, MachineBasicBlock *LoopHeaderBB,
SmallVectorImpl<MachineBasicBlock *> &BlockWorkList,
+ SmallVectorImpl<MachineBasicBlock *> &EHPadWorkList,
const BlockFilterSet *BlockFilter = nullptr);
MachineBasicBlock *selectBestSuccessor(MachineBasicBlock *BB,
BlockChain &Chain,
@@ -282,9 +283,11 @@ class MachineBlockPlacement : public MachineFunctionPass {
void fillWorkLists(MachineBasicBlock *MBB,
SmallPtrSetImpl<BlockChain *> &UpdatedPreds,
SmallVectorImpl<MachineBasicBlock *> &BlockWorkList,
+ SmallVectorImpl<MachineBasicBlock *> &EHPadWorkList,
const BlockFilterSet *BlockFilter);
void buildChain(MachineBasicBlock *BB, BlockChain &Chain,
SmallVectorImpl<MachineBasicBlock *> &BlockWorkList,
+ SmallVectorImpl<MachineBasicBlock *> &EHPadWorkList,
const BlockFilterSet *BlockFilter = nullptr);
MachineBasicBlock *findBestLoopTop(MachineLoop &L,
const BlockFilterSet &LoopBlockSet);
@@ -350,6 +353,7 @@ static std::string getBlockName(MachineBasicBlock *BB) {
void MachineBlockPlacement::markChainSuccessors(
BlockChain &Chain, MachineBasicBlock *LoopHeaderBB,
SmallVectorImpl<MachineBasicBlock *> &BlockWorkList,
+ SmallVectorImpl<MachineBasicBlock *> &EHPadWorkList,
const BlockFilterSet *BlockFilter) {
// Walk all the blocks in this chain, marking their successors as having
// a predecessor placed.
@@ -368,8 +372,15 @@ void MachineBlockPlacement::markChainSuccessors(
// This is a cross-chain edge that is within the loop, so decrement the
// loop predecessor count of the destination chain.
- if (SuccChain.UnscheduledPredecessors > 0 && --SuccChain.UnscheduledPredecessors == 0)
- BlockWorkList.push_back(*SuccChain.begin());
+ if (SuccChain.UnscheduledPredecessors == 0 ||
+ --SuccChain.UnscheduledPredecessors > 0)
+ continue;
+
+ auto *MBB = *SuccChain.begin();
+ if (MBB->isEHPad())
+ EHPadWorkList.push_back(MBB);
+ else
+ BlockWorkList.push_back(MBB);
}
}
}
@@ -412,7 +423,7 @@ MachineBlockPlacement::selectBestSuccessor(MachineBasicBlock *BB,
SmallVector<MachineBasicBlock *, 4> Successors;
for (MachineBasicBlock *Succ : BB->successors()) {
bool SkipSucc = false;
- if (BlockFilter && !BlockFilter->count(Succ)) {
+ if (Succ->isEHPad() || (BlockFilter && !BlockFilter->count(Succ))) {
SkipSucc = true;
} else {
BlockChain *SuccChain = BlockToChain[Succ];
@@ -532,9 +543,16 @@ MachineBasicBlock *MachineBlockPlacement::selectBestCandidateBlock(
}),
WorkList.end());
+ if (WorkList.empty())
+ return nullptr;
+
+ bool IsEHPad = WorkList[0]->isEHPad();
+
MachineBasicBlock *BestBlock = nullptr;
BlockFrequency BestFreq;
for (MachineBasicBlock *MBB : WorkList) {
+ assert(MBB->isEHPad() == IsEHPad);
+
BlockChain &SuccChain = *BlockToChain[MBB];
if (&SuccChain == &Chain)
continue;
@@ -544,11 +562,32 @@ MachineBasicBlock *MachineBlockPlacement::selectBestCandidateBlock(
BlockFrequency CandidateFreq = MBFI->getBlockFreq(MBB);
DEBUG(dbgs() << " " << getBlockName(MBB) << " -> ";
MBFI->printBlockFreq(dbgs(), CandidateFreq) << " (freq)\n");
- if (BestBlock && BestFreq >= CandidateFreq)
+
+ // For ehpad, we layout the least probable first as to avoid jumping back
+ // from least probable landingpads to more probable ones.
+ //
+ // FIXME: Using probability is probably (!) not the best way to achieve
+ // this. We should probably have a more principled approach to layout
+ // cleanup code.
+ //
+ // The goal is to get:
+ //
+ // +--------------------------+
+ // | V
+ // InnerLp -> InnerCleanup OuterLp -> OuterCleanup -> Resume
+ //
+ // Rather than:
+ //
+ // +-------------------------------------+
+ // V |
+ // OuterLp -> OuterCleanup -> Resume InnerLp -> InnerCleanup
+ if (BestBlock && (IsEHPad ^ (BestFreq >= CandidateFreq)))
continue;
+
BestBlock = MBB;
BestFreq = CandidateFreq;
}
+
return BestBlock;
}
@@ -582,6 +621,7 @@ void MachineBlockPlacement::fillWorkLists(
MachineBasicBlock *MBB,
SmallPtrSetImpl<BlockChain *> &UpdatedPreds,
SmallVectorImpl<MachineBasicBlock *> &BlockWorkList,
+ SmallVectorImpl<MachineBasicBlock *> &EHPadWorkList,
const BlockFilterSet *BlockFilter = nullptr) {
BlockChain &Chain = *BlockToChain[MBB];
if (!UpdatedPreds.insert(&Chain).second)
@@ -599,13 +639,20 @@ void MachineBlockPlacement::fillWorkLists(
}
}
- if (Chain.UnscheduledPredecessors == 0)
- BlockWorkList.push_back(*Chain.begin());
+ if (Chain.UnscheduledPredecessors != 0)
+ return;
+
+ MBB = *Chain.begin();
+ if (MBB->isEHPad())
+ EHPadWorkList.push_back(MBB);
+ else
+ BlockWorkList.push_back(MBB);
}
void MachineBlockPlacement::buildChain(
MachineBasicBlock *BB, BlockChain &Chain,
SmallVectorImpl<MachineBasicBlock *> &BlockWorkList,
+ SmallVectorImpl<MachineBasicBlock *> &EHPadWorkList,
const BlockFilterSet *BlockFilter) {
assert(BB);
assert(BlockToChain[BB] == &Chain);
@@ -613,7 +660,8 @@ void MachineBlockPlacement::buildChain(
MachineFunction::iterator PrevUnplacedBlockIt = F.begin();
MachineBasicBlock *LoopHeaderBB = BB;
- markChainSuccessors(Chain, LoopHeaderBB, BlockWorkList, BlockFilter);
+ markChainSuccessors(Chain, LoopHeaderBB, BlockWorkList, EHPadWorkList,
+ BlockFilter);
BB = *std::prev(Chain.end());
for (;;) {
assert(BB);
@@ -629,6 +677,8 @@ void MachineBlockPlacement::buildChain(
// this point. This won't be a fallthrough, but it will increase locality.
if (!BestSucc)
BestSucc = selectBestCandidateBlock(Chain, BlockWorkList);
+ if (!BestSucc)
+ BestSucc = selectBestCandidateBlock(Chain, EHPadWorkList);
if (!BestSucc) {
BestSucc =
@@ -647,7 +697,8 @@ void MachineBlockPlacement::buildChain(
SuccChain.UnscheduledPredecessors = 0;
DEBUG(dbgs() << "Merging from " << getBlockName(BB) << " to "
<< getBlockName(BestSucc) << "\n");
- markChainSuccessors(SuccChain, LoopHeaderBB, BlockWorkList, BlockFilter);
+ markChainSuccessors(SuccChain, LoopHeaderBB, BlockWorkList, EHPadWorkList,
+ BlockFilter);
Chain.merge(BestSucc, &SuccChain);
BB = *std::prev(Chain.end());
}
@@ -1067,6 +1118,7 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F,
buildLoopChains(F, *InnerLoop);
SmallVector<MachineBasicBlock *, 16> BlockWorkList;
+ SmallVector<MachineBasicBlock *, 16> EHPadWorkList;
BlockFilterSet LoopBlockSet = collectLoopBlockSet(F, L);
// Check if we have profile data for this function. If yes, we will rotate
@@ -1100,9 +1152,10 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F,
UpdatedPreds.insert(&LoopChain);
for (MachineBasicBlock *LoopBB : LoopBlockSet)
- fillWorkLists(LoopBB, UpdatedPreds, BlockWorkList, &LoopBlockSet);
+ fillWorkLists(LoopBB, UpdatedPreds, BlockWorkList, EHPadWorkList,
+ &LoopBlockSet);
- buildChain(LoopTop, LoopChain, BlockWorkList, &LoopBlockSet);
+ buildChain(LoopTop, LoopChain, BlockWorkList, EHPadWorkList, &LoopBlockSet);
if (RotateLoopWithProfile)
rotateLoopWithProfile(LoopChain, L, LoopBlockSet);
@@ -1199,13 +1252,14 @@ void MachineBlockPlacement::buildCFGChains(MachineFunction &F) {
buildLoopChains(F, *L);
SmallVector<MachineBasicBlock *, 16> BlockWorkList;
+ SmallVector<MachineBasicBlock *, 16> EHPadWorkList;
SmallPtrSet<BlockChain *, 4> UpdatedPreds;
for (MachineBasicBlock &MBB : F)
- fillWorkLists(&MBB, UpdatedPreds, BlockWorkList);
+ fillWorkLists(&MBB, UpdatedPreds, BlockWorkList, EHPadWorkList);
BlockChain &FunctionChain = *BlockToChain[&F.front()];
- buildChain(&F.front(), FunctionChain, BlockWorkList);
+ buildChain(&F.front(), FunctionChain, BlockWorkList, EHPadWorkList);
#ifndef NDEBUG
typedef SmallPtrSet<MachineBasicBlock *, 16> FunctionBlockSetType;
OpenPOWER on IntegriCloud