diff options
Diffstat (limited to 'llvm/lib/CodeGen/MachineBlockPlacement.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineBlockPlacement.cpp | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/MachineBlockPlacement.cpp b/llvm/lib/CodeGen/MachineBlockPlacement.cpp index a246717cad6..265aeabc15e 100644 --- a/llvm/lib/CodeGen/MachineBlockPlacement.cpp +++ b/llvm/lib/CodeGen/MachineBlockPlacement.cpp @@ -453,6 +453,8 @@ class MachineBlockPlacement : public MachineFunctionPass { BlockFilterSet *BlockFilter = nullptr); bool canMoveBottomBlockToTop(const MachineBasicBlock *BottomBlock, const MachineBasicBlock *OldTop); + bool hasViableTopFallthrough(const MachineBasicBlock *Top, + const BlockFilterSet &LoopBlockSet); MachineBasicBlock *findBestLoopTop( const MachineLoop &L, const BlockFilterSet &LoopBlockSet); MachineBasicBlock *findBestLoopExit( @@ -1984,6 +1986,39 @@ MachineBlockPlacement::findBestLoopExit(const MachineLoop &L, return ExitingBB; } +/// Check if there is a fallthrough to loop header Top. +/// +/// 1. Look for a Pred that can be layout before Top. +/// 2. Check if Top is the most possible successor of Pred. +bool +MachineBlockPlacement::hasViableTopFallthrough( + const MachineBasicBlock *Top, + const BlockFilterSet &LoopBlockSet) { + for (MachineBasicBlock *Pred : Top->predecessors()) { + BlockChain *PredChain = BlockToChain[Pred]; + if (!LoopBlockSet.count(Pred) && + (!PredChain || Pred == *std::prev(PredChain->end()))) { + // Found a Pred block can be placed before Top. + // Check if Top is the best successor of Pred. + auto TopProb = MBPI->getEdgeProbability(Pred, Top); + bool TopOK = true; + for (MachineBasicBlock *Succ : Pred->successors()) { + auto SuccProb = MBPI->getEdgeProbability(Pred, Succ); + BlockChain *SuccChain = BlockToChain[Succ]; + // Check if Succ can be placed after Pred. + // Succ should not be in any chain, or it is the head of some chain. + if ((!SuccChain || Succ == *SuccChain->begin()) && SuccProb > TopProb) { + TopOK = false; + break; + } + } + if (TopOK) + return true; + } + } + return false; +} + /// 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 @@ -2003,15 +2038,7 @@ void MachineBlockPlacement::rotateLoop(BlockChain &LoopChain, if (Bottom == ExitingBB) return; - bool ViableTopFallthrough = false; - for (MachineBasicBlock *Pred : Top->predecessors()) { - BlockChain *PredChain = BlockToChain[Pred]; - if (!LoopBlockSet.count(Pred) && - (!PredChain || Pred == *std::prev(PredChain->end()))) { - ViableTopFallthrough = true; - break; - } - } + bool ViableTopFallthrough = hasViableTopFallthrough(Top, LoopBlockSet); // If the header has viable fallthrough, check whether the current loop // bottom is a viable exiting block. If so, bail out as rotating will |