aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachineBlockPlacement.cpp
diff options
context:
space:
mode:
authorLogan Chien <loganchien@google.com>2011-11-25 08:46:08 +0800
committerLogan Chien <loganchien@google.com>2011-11-25 13:43:44 +0800
commit1429059dc0129c1cec938c29d6fce89e14293241 (patch)
treeec4c55e5138c7eb9ad0313d4af895ad0c56d0978 /lib/CodeGen/MachineBlockPlacement.cpp
parent1035c3e84815607b4f8994cab03ae62cc8519a63 (diff)
parent705f2431a086bbe662bca0035938e774378de3ec (diff)
downloadexternal_llvm-1429059dc0129c1cec938c29d6fce89e14293241.zip
external_llvm-1429059dc0129c1cec938c29d6fce89e14293241.tar.gz
external_llvm-1429059dc0129c1cec938c29d6fce89e14293241.tar.bz2
Merge with LLVM upstream r145126 (Nov 25th 2011)
Change-Id: I30d08ae004a4c3c74092ad2537ab30cce4280e1d
Diffstat (limited to 'lib/CodeGen/MachineBlockPlacement.cpp')
-rw-r--r--lib/CodeGen/MachineBlockPlacement.cpp154
1 files changed, 93 insertions, 61 deletions
diff --git a/lib/CodeGen/MachineBlockPlacement.cpp b/lib/CodeGen/MachineBlockPlacement.cpp
index 304f167..55d804b 100644
--- a/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/lib/CodeGen/MachineBlockPlacement.cpp
@@ -214,11 +214,12 @@ class MachineBlockPlacement : public MachineFunctionPass {
MachineBasicBlock *selectBestCandidateBlock(
BlockChain &Chain, SmallVectorImpl<MachineBasicBlock *> &WorkList,
const BlockFilterSet *BlockFilter);
- MachineBasicBlock *getFirstUnplacedBlock(const BlockChain &PlacedChain,
- ArrayRef<MachineBasicBlock *> Blocks,
- unsigned &PrevUnplacedBlockIdx);
+ MachineBasicBlock *getFirstUnplacedBlock(
+ MachineFunction &F,
+ const BlockChain &PlacedChain,
+ MachineFunction::iterator &PrevUnplacedBlockIt,
+ const BlockFilterSet *BlockFilter);
void buildChain(MachineBasicBlock *BB, BlockChain &Chain,
- ArrayRef<MachineBasicBlock *> Blocks,
SmallVectorImpl<MachineBasicBlock *> &BlockWorkList,
const BlockFilterSet *BlockFilter = 0);
void buildLoopChains(MachineFunction &F, MachineLoop &L);
@@ -314,7 +315,7 @@ 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.LoopPredecessors > 0 && --SuccChain.LoopPredecessors == 0)
- BlockWorkList.push_back(*SI);
+ BlockWorkList.push_back(*SuccChain.begin());
}
}
}
@@ -354,15 +355,45 @@ MachineBasicBlock *MachineBlockPlacement::selectBestSuccessor(
DEBUG(dbgs() << " " << getBlockName(*SI) << " -> Already merged!\n");
continue;
}
+ if (*SI != *SuccChain.begin()) {
+ DEBUG(dbgs() << " " << getBlockName(*SI) << " -> Mid chain!\n");
+ continue;
+ }
uint32_t SuccWeight = MBPI->getEdgeWeight(BB, *SI);
BranchProbability SuccProb(SuccWeight / WeightScale, SumWeight);
// Only consider successors which are either "hot", or wouldn't violate
// any CFG constraints.
- if (SuccChain.LoopPredecessors != 0 && SuccProb < HotProb) {
- DEBUG(dbgs() << " " << getBlockName(*SI) << " -> CFG conflict\n");
- continue;
+ if (SuccChain.LoopPredecessors != 0) {
+ if (SuccProb < HotProb) {
+ DEBUG(dbgs() << " " << getBlockName(*SI) << " -> CFG conflict\n");
+ continue;
+ }
+
+ // Make sure that a hot successor doesn't have a globally more important
+ // predecessor.
+ BlockFrequency CandidateEdgeFreq
+ = MBFI->getBlockFreq(BB) * SuccProb * HotProb.getCompl();
+ bool BadCFGConflict = false;
+ for (MachineBasicBlock::pred_iterator PI = (*SI)->pred_begin(),
+ PE = (*SI)->pred_end();
+ PI != PE; ++PI) {
+ if (*PI == *SI || (BlockFilter && !BlockFilter->count(*PI)) ||
+ BlockToChain[*PI] == &Chain)
+ continue;
+ BlockFrequency PredEdgeFreq
+ = MBFI->getBlockFreq(*PI) * MBPI->getEdgeProbability(*PI, *SI);
+ if (PredEdgeFreq >= CandidateEdgeFreq) {
+ BadCFGConflict = true;
+ break;
+ }
+ }
+ if (BadCFGConflict) {
+ DEBUG(dbgs() << " " << getBlockName(*SI)
+ << " -> non-cold CFG conflict\n");
+ continue;
+ }
}
DEBUG(dbgs() << " " << getBlockName(*SI) << " -> " << SuccProb
@@ -444,18 +475,23 @@ MachineBasicBlock *MachineBlockPlacement::selectBestCandidateBlock(
///
/// This routine is called when we are unable to use the CFG to walk through
/// all of the basic blocks and form a chain due to unnatural loops in the CFG.
-/// We walk through the sequence of blocks, starting from the
-/// LastUnplacedBlockIdx. We update this index to avoid re-scanning the entire
-/// sequence on repeated calls to this routine.
+/// We walk through the function's blocks in order, starting from the
+/// LastUnplacedBlockIt. We update this iterator on each call to avoid
+/// re-scanning the entire sequence on repeated calls to this routine.
MachineBasicBlock *MachineBlockPlacement::getFirstUnplacedBlock(
- const BlockChain &PlacedChain,
- ArrayRef<MachineBasicBlock *> Blocks,
- unsigned &PrevUnplacedBlockIdx) {
- for (unsigned i = PrevUnplacedBlockIdx, e = Blocks.size(); i != e; ++i) {
- MachineBasicBlock *BB = Blocks[i];
- if (BlockToChain[BB] != &PlacedChain) {
- PrevUnplacedBlockIdx = i;
- return BB;
+ MachineFunction &F, const BlockChain &PlacedChain,
+ MachineFunction::iterator &PrevUnplacedBlockIt,
+ const BlockFilterSet *BlockFilter) {
+ for (MachineFunction::iterator I = PrevUnplacedBlockIt, E = F.end(); I != E;
+ ++I) {
+ if (BlockFilter && !BlockFilter->count(I))
+ continue;
+ if (BlockToChain[I] != &PlacedChain) {
+ PrevUnplacedBlockIt = I;
+ // Now select the head of the chain to which the unplaced block belongs
+ // as the block to place. This will force the entire chain to be placed,
+ // and satisfies the requirements of merging chains.
+ return *BlockToChain[I]->begin();
}
}
return 0;
@@ -464,14 +500,12 @@ MachineBasicBlock *MachineBlockPlacement::getFirstUnplacedBlock(
void MachineBlockPlacement::buildChain(
MachineBasicBlock *BB,
BlockChain &Chain,
- ArrayRef<MachineBasicBlock *> Blocks,
SmallVectorImpl<MachineBasicBlock *> &BlockWorkList,
const BlockFilterSet *BlockFilter) {
assert(BB);
assert(BlockToChain[BB] == &Chain);
- assert(*Chain.begin() == BB);
- SmallVector<MachineOperand, 4> Cond; // For AnalyzeBranch.
- unsigned PrevUnplacedBlockIdx = 0;
+ MachineFunction &F = *BB->getParent();
+ MachineFunction::iterator PrevUnplacedBlockIt = F.begin();
MachineBasicBlock *LoopHeaderBB = BB;
markChainSuccessors(Chain, LoopHeaderBB, BlockWorkList, BlockFilter);
@@ -482,26 +516,9 @@ void MachineBlockPlacement::buildChain(
assert(*llvm::prior(Chain.end()) == BB);
MachineBasicBlock *BestSucc = 0;
- // Check for unreasonable branches, and forcibly merge the existing layout
- // successor for them. We can handle cases that AnalyzeBranch can't: jump
- // tables etc are fine. The case we want to handle specially is when there
- // is potential fallthrough, but the branch cannot be analyzed. This
- // includes blocks without terminators as well as other cases.
- Cond.clear();
- MachineBasicBlock *TBB = 0, *FBB = 0; // For AnalyzeBranch.
- if (TII->AnalyzeBranch(*BB, TBB, FBB, Cond) && BB->canFallThrough()) {
- MachineFunction::iterator I(BB), NextI(llvm::next(I));
- // Ensure that the layout successor is a viable block, as we know that
- // fallthrough is a possibility. Note that this may not be a valid block
- // in the loop, but we allow that to cope with degenerate situations.
- assert(NextI != BB->getParent()->end());
- BestSucc = NextI;
- }
-
- // Otherwise, look for the best viable successor if there is one to place
- // immediately after this block.
- if (!BestSucc)
- BestSucc = selectBestSuccessor(BB, Chain, BlockFilter);
+ // Look for the best viable successor if there is one to place immediately
+ // after this block.
+ BestSucc = selectBestSuccessor(BB, Chain, BlockFilter);
// If an immediate successor isn't available, look for the best viable
// block among those we've identified as not violating the loop's CFG at
@@ -510,7 +527,8 @@ void MachineBlockPlacement::buildChain(
BestSucc = selectBestCandidateBlock(Chain, BlockWorkList, BlockFilter);
if (!BestSucc) {
- BestSucc = getFirstUnplacedBlock(Chain, Blocks, PrevUnplacedBlockIdx);
+ BestSucc = getFirstUnplacedBlock(F, Chain, PrevUnplacedBlockIt,
+ BlockFilter);
if (!BestSucc)
break;
@@ -576,11 +594,10 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F,
}
if (Chain.LoopPredecessors == 0)
- BlockWorkList.push_back(*BI);
+ BlockWorkList.push_back(*Chain.begin());
}
- buildChain(*L.block_begin(), LoopChain, L.getBlocks(), BlockWorkList,
- &LoopBlockSet);
+ buildChain(*L.block_begin(), LoopChain, BlockWorkList, &LoopBlockSet);
DEBUG({
// Crash at the end so we get all of the debugging output first.
@@ -596,8 +613,7 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F,
if (!LoopBlockSet.erase(*BCI)) {
// We don't mark the loop as bad here because there are real situations
// where this can occur. For example, with an unanalyzable fallthrough
- // from a loop block to a non-loop block.
- // FIXME: Such constructs shouldn't exist. Track them down and fix them.
+ // from a loop block to a non-loop block or vice versa.
dbgs() << "Loop chain contains a block not contained by the loop!\n"
<< " Loop header: " << getBlockName(*L.block_begin()) << "\n"
<< " Chain header: " << getBlockName(*LoopChain.begin()) << "\n"
@@ -621,26 +637,43 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F,
void MachineBlockPlacement::buildCFGChains(MachineFunction &F) {
// Ensure that every BB in the function has an associated chain to simplify
// the assumptions of the remaining algorithm.
- for (MachineFunction::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
- BlockToChain[&*FI] =
- new (ChainAllocator.Allocate()) BlockChain(BlockToChain, &*FI);
+ SmallVector<MachineOperand, 4> Cond; // For AnalyzeBranch.
+ for (MachineFunction::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
+ MachineBasicBlock *BB = FI;
+ BlockChain *Chain
+ = new (ChainAllocator.Allocate()) BlockChain(BlockToChain, BB);
+ // Also, merge any blocks which we cannot reason about and must preserve
+ // the exact fallthrough behavior for.
+ for (;;) {
+ Cond.clear();
+ MachineBasicBlock *TBB = 0, *FBB = 0; // For AnalyzeBranch.
+ if (!TII->AnalyzeBranch(*BB, TBB, FBB, Cond) || !FI->canFallThrough())
+ break;
+
+ MachineFunction::iterator NextFI(llvm::next(FI));
+ MachineBasicBlock *NextBB = NextFI;
+ // Ensure that the layout successor is a viable block, as we know that
+ // fallthrough is a possibility.
+ assert(NextFI != FE && "Can't fallthrough past the last block.");
+ DEBUG(dbgs() << "Pre-merging due to unanalyzable fallthrough: "
+ << getBlockName(BB) << " -> " << getBlockName(NextBB)
+ << "\n");
+ Chain->merge(NextBB, 0);
+ FI = NextFI;
+ BB = NextBB;
+ }
+ }
// Build any loop-based chains.
for (MachineLoopInfo::iterator LI = MLI->begin(), LE = MLI->end(); LI != LE;
++LI)
buildLoopChains(F, **LI);
- // We need a vector of blocks so that buildChain can handle unnatural CFG
- // constructs by searching for unplaced blocks and just concatenating them.
- SmallVector<MachineBasicBlock *, 16> Blocks;
- Blocks.reserve(F.size());
-
SmallVector<MachineBasicBlock *, 16> BlockWorkList;
SmallPtrSet<BlockChain *, 4> UpdatedPreds;
for (MachineFunction::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
MachineBasicBlock *BB = &*FI;
- Blocks.push_back(BB);
BlockChain &Chain = *BlockToChain[BB];
if (!UpdatedPreds.insert(&Chain))
continue;
@@ -659,11 +692,11 @@ void MachineBlockPlacement::buildCFGChains(MachineFunction &F) {
}
if (Chain.LoopPredecessors == 0)
- BlockWorkList.push_back(BB);
+ BlockWorkList.push_back(*Chain.begin());
}
BlockChain &FunctionChain = *BlockToChain[&F.front()];
- buildChain(&F.front(), FunctionChain, Blocks, BlockWorkList);
+ buildChain(&F.front(), FunctionChain, BlockWorkList);
typedef SmallPtrSet<MachineBasicBlock *, 16> FunctionBlockSetType;
DEBUG({
@@ -695,7 +728,6 @@ void MachineBlockPlacement::buildCFGChains(MachineFunction &F) {
// Splice the blocks into place.
MachineFunction::iterator InsertPos = F.begin();
- SmallVector<MachineOperand, 4> Cond; // For AnalyzeBranch.
for (BlockChain::iterator BI = FunctionChain.begin(),
BE = FunctionChain.end();
BI != BE; ++BI) {