summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MachineBlockPlacement.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-11-14 09:46:33 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-11-14 09:46:33 +0000
commit0af6a0bb699bfb2f3f3c2ff2f47f419f1bc4d8b4 (patch)
tree8b292a2419406175abbe0a17a55c45ed1346d434 /llvm/lib/CodeGen/MachineBlockPlacement.cpp
parent84cd44c750b0c4c0827206f97fe7591b00f0b1c3 (diff)
downloadbcm5719-llvm-0af6a0bb699bfb2f3f3c2ff2f47f419f1bc4d8b4.tar.gz
bcm5719-llvm-0af6a0bb699bfb2f3f3c2ff2f47f419f1bc4d8b4.zip
Begin chipping away at one of the biggest quadratic-ish behaviors in
this pass. We're leaving already merged blocks on the worklist, and scanning them again and again only to determine each time through that indeed they aren't viable. We can instead remove them once we're going to have to scan the worklist. This is the easy way to implement removing them. If this remains on the profile (as I somewhat suspect it will), we can get a lot more clever here, as the worklist's order is essentially irrelevant. We can use swapping and fold the two loops to reduce overhead even when there are many blocks on the worklist but only a few of them are removed. llvm-svn: 144531
Diffstat (limited to 'llvm/lib/CodeGen/MachineBlockPlacement.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineBlockPlacement.cpp28
1 files changed, 26 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index bd50ac3a4d5..6c8390fee61 100644
--- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -377,6 +377,23 @@ MachineBasicBlock *MachineBlockPlacement::selectBestSuccessor(
return BestSucc;
}
+namespace {
+/// \brief Predicate struct to detect blocks already placed.
+class IsBlockPlaced {
+ const BlockChain &PlacedChain;
+ const BlockToChainMapType &BlockToChain;
+
+public:
+ IsBlockPlaced(const BlockChain &PlacedChain,
+ const BlockToChainMapType &BlockToChain)
+ : PlacedChain(PlacedChain), BlockToChain(BlockToChain) {}
+
+ bool operator()(MachineBasicBlock *BB) const {
+ return BlockToChain.lookup(BB) == &PlacedChain;
+ }
+};
+}
+
/// \brief Select the best block from a worklist.
///
/// This looks through the provided worklist as a list of candidate basic
@@ -390,13 +407,20 @@ MachineBasicBlock *MachineBlockPlacement::selectBestSuccessor(
MachineBasicBlock *MachineBlockPlacement::selectBestCandidateBlock(
BlockChain &Chain, SmallVectorImpl<MachineBasicBlock *> &WorkList,
const BlockFilterSet *BlockFilter) {
+ // Once we need to walk the worklist looking for a candidate, cleanup the
+ // worklist of already placed entries.
+ // FIXME: If this shows up on profiles, it could be folded (at the cost of
+ // some code complexity) into the loop below.
+ WorkList.erase(std::remove_if(WorkList.begin(), WorkList.end(),
+ IsBlockPlaced(Chain, BlockToChain)),
+ WorkList.end());
+
MachineBasicBlock *BestBlock = 0;
BlockFrequency BestFreq;
for (SmallVectorImpl<MachineBasicBlock *>::iterator WBI = WorkList.begin(),
WBE = WorkList.end();
WBI != WBE; ++WBI) {
- if (BlockFilter && !BlockFilter->count(*WBI))
- continue;
+ assert(!BlockFilter || BlockFilter->count(*WBI));
BlockChain &SuccChain = *BlockToChain[*WBI];
if (&SuccChain == &Chain) {
DEBUG(dbgs() << " " << getBlockName(*WBI)
OpenPOWER on IntegriCloud