aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachineBlockPlacement.cpp
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-04-16 09:31:23 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-04-16 09:31:23 +0000
commit16295fc20b68f9a9318cada4e4d96e964b1cdd7e (patch)
tree56ca18ae1e43f574477b2fbd936310e1b91f15b3 /lib/CodeGen/MachineBlockPlacement.cpp
parent246de858e37a989a9cdf9b80d7434453b2c52e70 (diff)
downloadexternal_llvm-16295fc20b68f9a9318cada4e4d96e964b1cdd7e.zip
external_llvm-16295fc20b68f9a9318cada4e4d96e964b1cdd7e.tar.gz
external_llvm-16295fc20b68f9a9318cada4e4d96e964b1cdd7e.tar.bz2
Tweak the loop rotation logic to check whether the loop is naturally
laid out in a form with a fallthrough into the header and a fallthrough out of the bottom. In that case, leave the loop alone because any rotation will introduce unnecessary branches. If either side looks like it will require an explicit branch, then the rotation won't add any, do it to ensure the branch occurs outside of the loop (if possible) and maximize the benefit of the fallthrough in the bottom. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154806 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineBlockPlacement.cpp')
-rw-r--r--lib/CodeGen/MachineBlockPlacement.cpp62
1 files changed, 51 insertions, 11 deletions
diff --git a/lib/CodeGen/MachineBlockPlacement.cpp b/lib/CodeGen/MachineBlockPlacement.cpp
index 6226237..511a558 100644
--- a/lib/CodeGen/MachineBlockPlacement.cpp
+++ b/lib/CodeGen/MachineBlockPlacement.cpp
@@ -215,6 +215,8 @@ class MachineBlockPlacement : public MachineFunctionPass {
MachineLoop &L,
const BlockFilterSet &LoopBlockSet);
void buildLoopChains(MachineFunction &F, MachineLoop &L);
+ void rotateLoop(BlockChain &LoopChain, MachineBasicBlock *ExitingBB,
+ const BlockFilterSet &LoopBlockSet);
void buildCFGChains(MachineFunction &F);
public:
@@ -659,6 +661,54 @@ MachineBlockPlacement::findBestLoopExit(MachineFunction &F,
return ExitingBB;
}
+/// \brief Attempt to rotate an exiting block to the bottom of the loop.
+///
+/// Once we have built a chain, try to rotate it to line up the hot exit block
+/// with fallthrough out of the loop if doing so doesn't introduce unnecessary
+/// branches. For example, if the loop has fallthrough into its header and out
+/// of its bottom already, don't rotate it.
+void MachineBlockPlacement::rotateLoop(BlockChain &LoopChain,
+ MachineBasicBlock *ExitingBB,
+ const BlockFilterSet &LoopBlockSet) {
+ if (!ExitingBB)
+ return;
+
+ MachineBasicBlock *Top = *LoopChain.begin();
+ bool ViableTopFallthrough = false;
+ for (MachineBasicBlock::pred_iterator PI = Top->pred_begin(),
+ PE = Top->pred_end();
+ PI != PE; ++PI) {
+ BlockChain *PredChain = BlockToChain[*PI];
+ if (!LoopBlockSet.count(*PI) &&
+ (!PredChain || *PI == *llvm::prior(PredChain->end()))) {
+ ViableTopFallthrough = true;
+ break;
+ }
+ }
+
+ // If the header has viable fallthrough, check whether the current loop
+ // bottom is a viable exiting block. If so, bail out as rotating will
+ // introduce an unnecessary branch.
+ if (ViableTopFallthrough) {
+ MachineBasicBlock *Bottom = *llvm::prior(LoopChain.end());
+ for (MachineBasicBlock::succ_iterator SI = Bottom->succ_begin(),
+ SE = Bottom->succ_end();
+ SI != SE; ++SI) {
+ BlockChain *SuccChain = BlockToChain[*SI];
+ if (!LoopBlockSet.count(*SI) &&
+ (!SuccChain || *SI == *SuccChain->begin()))
+ return;
+ }
+ }
+
+ BlockChain::iterator ExitIt = std::find(LoopChain.begin(), LoopChain.end(),
+ ExitingBB);
+ if (ExitIt == LoopChain.end())
+ return;
+
+ std::rotate(LoopChain.begin(), llvm::next(ExitIt), LoopChain.end());
+}
+
/// \brief Forms basic block chains from the natural loop structures.
///
/// These chains are designed to preserve the existing *structure* of the code
@@ -709,17 +759,7 @@ void MachineBlockPlacement::buildLoopChains(MachineFunction &F,
}
buildChain(L.getHeader(), LoopChain, BlockWorkList, &LoopBlockSet);
-
- // Once we have built a chain, try to rotate it to line up the hot exit block
- // with fallthrough out of the loop (if we have a valid exit block for that).
- if (ExitingBB) {
- BlockChain::iterator ExitIt = std::find(LoopChain.begin(), LoopChain.end(),
- ExitingBB);
-
- if (ExitIt != LoopChain.end()) {
- std::rotate(LoopChain.begin(), llvm::next(ExitIt), LoopChain.end());
- }
- }
+ rotateLoop(LoopChain, ExitingBB, LoopBlockSet);
DEBUG({
// Crash at the end so we get all of the debugging output first.