summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MachineBlockPlacement.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-11-20 11:22:06 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-11-20 11:22:06 +0000
commit18dfac385b1a99f5164ebcceb8ccec9699930275 (patch)
tree1c8162ce4bff43c05f30d4b4f8f9e2faab0363e0 /llvm/lib/CodeGen/MachineBlockPlacement.cpp
parentbcb5f39526bf33fec12dff6a01ecdfbbfc376afb (diff)
downloadbcm5719-llvm-18dfac385b1a99f5164ebcceb8ccec9699930275.tar.gz
bcm5719-llvm-18dfac385b1a99f5164ebcceb8ccec9699930275.zip
The logic for breaking the CFG in the presence of hot successors didn't
properly account for the *global* probability of the edge being taken. This manifested as a very large number of unconditional branches to blocks being merged against the CFG even though they weren't particularly hot within the CFG. The fix is to check whether the edge being merged is both locally hot relative to other successors for the source block, and globally hot compared to other (unmerged) predecessors of the destination block. This introduces a new crasher on GCC single-source, but it's currently behind a flag, and Ben has offered to work on the reduction. =] llvm-svn: 145010
Diffstat (limited to 'llvm/lib/CodeGen/MachineBlockPlacement.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineBlockPlacement.cpp32
1 files changed, 29 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
index e83ae935284..4cbc94e0b7d 100644
--- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp
@@ -365,9 +365,35 @@ MachineBasicBlock *MachineBlockPlacement::selectBestSuccessor(
// 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
OpenPOWER on IntegriCloud