aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/MachineBlockPlacement.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-11-13 11:42:26 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-11-13 11:42:26 +0000
commitf3fc0050abc1698504cbaede7766c4180c076928 (patch)
treea1d36d6886d33c54f2f5c60221798ac8d6a19cda /lib/CodeGen/MachineBlockPlacement.cpp
parent729bec89bd8c4368a741359fb882967ce01a6909 (diff)
Hoist another gross nested loop into a helper method.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144498 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineBlockPlacement.cpp')
-rw-r--r--lib/CodeGen/MachineBlockPlacement.cpp67
1 files changed, 44 insertions, 23 deletions
diff --git a/lib/CodeGen/MachineBlockPlacement.cpp b/lib/CodeGen/MachineBlockPlacement.cpp
index ec0877fc05..f934776731 100644
--- a/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/lib/CodeGen/MachineBlockPlacement.cpp
@@ -211,6 +211,9 @@ class MachineBlockPlacement : public MachineFunctionPass {
MachineBasicBlock *selectBestSuccessor(MachineBasicBlock *BB,
BlockChain &Chain,
const BlockFilterSet *BlockFilter);
+ MachineBasicBlock *selectBestCandidateBlock(
+ BlockChain &Chain, SmallVectorImpl<MachineBasicBlock *> &WorkList,
+ const BlockFilterSet *BlockFilter);
void buildChain(MachineBasicBlock *BB, BlockChain &Chain,
SmallVectorImpl<MachineBasicBlock *> &Blocks,
const BlockFilterSet *BlockFilter = 0);
@@ -361,6 +364,45 @@ MachineBasicBlock *MachineBlockPlacement::selectBestSuccessor(
return BestSucc;
}
+/// \brief Select the best block from a worklist.
+///
+/// This looks through the provided worklist as a list of candidate basic
+/// blocks and select the most profitable one to place. The definition of
+/// profitable only really makes sense in the context of a loop. This returns
+/// the most frequently visited block in the worklist, which in the case of
+/// a loop, is the one most desirable to be physically close to the rest of the
+/// loop body in order to improve icache behavior.
+///
+/// \returns The best block found, or null if none are viable.
+MachineBasicBlock *MachineBlockPlacement::selectBestCandidateBlock(
+ BlockChain &Chain, SmallVectorImpl<MachineBasicBlock *> &WorkList,
+ const BlockFilterSet *BlockFilter) {
+ MachineBasicBlock *BestBlock = 0;
+ BlockFrequency BestFreq;
+ for (SmallVectorImpl<MachineBasicBlock *>::iterator WBI = WorkList.begin(),
+ WBE = WorkList.end();
+ WBI != WBE; ++WBI) {
+ if (BlockFilter && !BlockFilter->count(*WBI))
+ continue;
+ BlockChain &SuccChain = *BlockToChain[*WBI];
+ if (&SuccChain == &Chain) {
+ DEBUG(dbgs() << " " << getBlockName(*WBI)
+ << " -> Already merged!\n");
+ continue;
+ }
+ assert(SuccChain.LoopPredecessors == 0 && "Found CFG-violating block");
+
+ BlockFrequency CandidateFreq = MBFI->getBlockFreq(*WBI);
+ DEBUG(dbgs() << " " << getBlockName(*WBI) << " -> " << CandidateFreq
+ << " (freq)\n");
+ if (BestBlock && BestFreq >= CandidateFreq)
+ continue;
+ BestBlock = *WBI;
+ BestFreq = CandidateFreq;
+ }
+ return BestBlock;
+}
+
void MachineBlockPlacement::buildChain(
MachineBasicBlock *BB,
BlockChain &Chain,
@@ -384,30 +426,9 @@ void MachineBlockPlacement::buildChain(
// 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
// this point. This won't be a fallthrough, but it will increase locality.
- if (!BestSucc) {
- BlockFrequency BestFreq;
- for (SmallVectorImpl<MachineBasicBlock *>::iterator WBI = BlockWorkList.begin(),
- WBE = BlockWorkList.end();
- WBI != WBE; ++WBI) {
- if (BlockFilter && !BlockFilter->count(*WBI))
- continue;
- BlockChain &SuccChain = *BlockToChain[*WBI];
- if (&SuccChain == &Chain) {
- DEBUG(dbgs() << " " << getBlockName(*WBI)
- << " -> Already merged!\n");
- continue;
- }
- assert(SuccChain.LoopPredecessors == 0 && "Found CFG-violating block");
+ if (!BestSucc)
+ BestSucc = selectBestCandidateBlock(Chain, BlockWorkList, BlockFilter);
- BlockFrequency CandidateFreq = MBFI->getBlockFreq(*WBI);
- DEBUG(dbgs() << " " << getBlockName(*WBI) << " -> " << CandidateFreq
- << " (freq)\n");
- if (BestSucc && BestFreq >= CandidateFreq)
- continue;
- BestSucc = *WBI;
- BestFreq = CandidateFreq;
- }
- }
if (!BestSucc) {
DEBUG(dbgs() << "Finished forming chain for header block "
<< getBlockNum(*Chain.begin()) << "\n");