summaryrefslogtreecommitdiff
path: root/lib/CodeGen/MachineLoopInfo.cpp
diff options
context:
space:
mode:
authorSjoerd Meijer <sjoerd.meijer@arm.com>2016-08-15 08:22:42 +0000
committerSjoerd Meijer <sjoerd.meijer@arm.com>2016-08-15 08:22:42 +0000
commit47a3de7f4db76bd34b6a9b1202841d4b85294ca5 (patch)
treef71f60b4da2289f41c7b9fdabc78bd26837979ae /lib/CodeGen/MachineLoopInfo.cpp
parent7bc6001b578c682790e28bd8031d9f3641f10603 (diff)
MachineLoop: add methods findLoopControlBlock and findLoopPreheader
This adds two new utility functions findLoopControlBlock and findLoopPreheader to MachineLoop and MachineLoopInfo. These functions are refactored and taken from the Hexagon target as they are target independent; thus this is intendend to be a non-functional change. Differential Revision: https://reviews.llvm.org/D22959 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278661 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineLoopInfo.cpp')
-rw-r--r--lib/CodeGen/MachineLoopInfo.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/lib/CodeGen/MachineLoopInfo.cpp b/lib/CodeGen/MachineLoopInfo.cpp
index 376f78fda1c..fdeaf7b7116 100644
--- a/lib/CodeGen/MachineLoopInfo.cpp
+++ b/lib/CodeGen/MachineLoopInfo.cpp
@@ -77,6 +77,51 @@ MachineBasicBlock *MachineLoop::getBottomBlock() {
return BotMBB;
}
+MachineBasicBlock *MachineLoop::findLoopControlBlock() {
+ if (MachineBasicBlock *Latch = getLoopLatch()) {
+ if (isLoopExiting(Latch))
+ return Latch;
+ else
+ return getExitingBlock();
+ }
+ return nullptr;
+}
+
+MachineBasicBlock *
+MachineLoopInfo::findLoopPreheader(MachineLoop *L,
+ bool SpeculativePreheader) const {
+ if (MachineBasicBlock *PB = L->getLoopPreheader())
+ return PB;
+
+ if (!SpeculativePreheader)
+ return nullptr;
+
+ MachineBasicBlock *HB = L->getHeader(), *LB = L->getLoopLatch();
+ if (HB->pred_size() != 2 || HB->hasAddressTaken())
+ return nullptr;
+ // Find the predecessor of the header that is not the latch block.
+ MachineBasicBlock *Preheader = nullptr;
+ for (MachineBasicBlock *P : HB->predecessors()) {
+ if (P == LB)
+ continue;
+ // Sanity.
+ if (Preheader)
+ return nullptr;
+ Preheader = P;
+ }
+
+ // Check if the preheader candidate is a successor of any other loop
+ // headers. We want to avoid having two loop setups in the same block.
+ for (MachineBasicBlock *S : Preheader->successors()) {
+ if (S == HB)
+ continue;
+ MachineLoop *T = getLoopFor(S);
+ if (T && T->getHeader() == S)
+ return nullptr;
+ }
+ return Preheader;
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void MachineLoop::dump() const {
print(dbgs());