[llvm] r278661 - MachineLoop: add methods findLoopControlBlock and findLoopPreheader
Sjoerd Meijer via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 15 01:22:42 PDT 2016
Author: sjoerdmeijer
Date: Mon Aug 15 03:22:42 2016
New Revision: 278661
URL: http://llvm.org/viewvc/llvm-project?rev=278661&view=rev
Log:
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
Modified:
llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h
llvm/trunk/lib/CodeGen/MachineLoopInfo.cpp
llvm/trunk/lib/Target/Hexagon/HexagonHardwareLoops.cpp
Modified: llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h?rev=278661&r1=278660&r2=278661&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h Mon Aug 15 03:22:42 2016
@@ -54,6 +54,12 @@ public:
/// that contains the header.
MachineBasicBlock *getBottomBlock();
+ /// \brief Find the block that contains the loop control variable and the
+ /// loop test. This will return the latch block if it's one of the exiting
+ /// blocks. Otherwise, return the exiting block. Return 'null' when
+ /// multiple exiting blocks are present.
+ MachineBasicBlock *findLoopControlBlock();
+
void dump() const;
private:
@@ -81,6 +87,14 @@ public:
LoopInfoBase<MachineBasicBlock, MachineLoop>& getBase() { return LI; }
+ /// \brief Find the block that either is the loop preheader, or could
+ /// speculatively be used as the preheader. This is e.g. useful to place
+ /// loop setup code. Code that cannot be speculated should not be placed
+ /// here. SpeculativePreheader is controlling whether it also tries to
+ /// find the speculative preheader if the regular preheader is not present.
+ MachineBasicBlock *findLoopPreheader(MachineLoop *L,
+ bool SpeculativePreheader = false) const;
+
/// The iterator interface to the top-level loops in the current function.
typedef LoopInfoBase<MachineBasicBlock, MachineLoop>::iterator iterator;
inline iterator begin() const { return LI.begin(); }
Modified: llvm/trunk/lib/CodeGen/MachineLoopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLoopInfo.cpp?rev=278661&r1=278660&r2=278661&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineLoopInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineLoopInfo.cpp Mon Aug 15 03:22:42 2016
@@ -77,6 +77,51 @@ MachineBasicBlock *MachineLoop::getBotto
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());
Modified: llvm/trunk/lib/Target/Hexagon/HexagonHardwareLoops.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonHardwareLoops.cpp?rev=278661&r1=278660&r2=278661&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonHardwareLoops.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonHardwareLoops.cpp Mon Aug 15 03:22:42 2016
@@ -277,10 +277,6 @@ namespace {
/// cannot be adjusted to reflect the post-bump value.
bool fixupInductionVariable(MachineLoop *L);
- /// \brief Find the block that either is the loop preheader, or could
- /// speculatively be used as the preheader.
- MachineBasicBlock *findLoopPreheader(MachineLoop *L) const;
-
/// \brief Given a loop, if it does not have a preheader, create one.
/// Return the block that is the preheader.
MachineBasicBlock *createPreheaderForLoop(MachineLoop *L);
@@ -377,28 +373,15 @@ bool HexagonHardwareLoops::runOnMachineF
return Changed;
}
-/// \brief Return the latch block if it's one of the exiting blocks. Otherwise,
-/// return the exiting block. Return 'null' when multiple exiting blocks are
-/// present.
-static MachineBasicBlock* getExitingBlock(MachineLoop *L) {
- if (MachineBasicBlock *Latch = L->getLoopLatch()) {
- if (L->isLoopExiting(Latch))
- return Latch;
- else
- return L->getExitingBlock();
- }
- return nullptr;
-}
-
bool HexagonHardwareLoops::findInductionRegister(MachineLoop *L,
unsigned &Reg,
int64_t &IVBump,
MachineInstr *&IVOp
) const {
MachineBasicBlock *Header = L->getHeader();
- MachineBasicBlock *Preheader = findLoopPreheader(L);
+ MachineBasicBlock *Preheader = MLI->findLoopPreheader(L, SpecPreheader);
MachineBasicBlock *Latch = L->getLoopLatch();
- MachineBasicBlock *ExitingBlock = getExitingBlock(L);
+ MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
if (!Header || !Preheader || !Latch || !ExitingBlock)
return false;
@@ -566,7 +549,7 @@ CountValue *HexagonHardwareLoops::getLoo
// Look for the cmp instruction to determine if we can get a useful trip
// count. The trip count can be either a register or an immediate. The
// location of the value depends upon the type (reg or imm).
- MachineBasicBlock *ExitingBlock = getExitingBlock(L);
+ MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
if (!ExitingBlock)
return nullptr;
@@ -577,7 +560,7 @@ CountValue *HexagonHardwareLoops::getLoo
if (!FoundIV)
return nullptr;
- MachineBasicBlock *Preheader = findLoopPreheader(L);
+ MachineBasicBlock *Preheader = MLI->findLoopPreheader(L, SpecPreheader);
MachineOperand *InitialValue = nullptr;
MachineInstr *IV_Phi = MRI->getVRegDef(IVReg);
@@ -798,7 +781,7 @@ CountValue *HexagonHardwareLoops::comput
if (!isPowerOf2_64(std::abs(IVBump)))
return nullptr;
- MachineBasicBlock *PH = findLoopPreheader(Loop);
+ MachineBasicBlock *PH = MLI->findLoopPreheader(Loop, SpecPreheader);
assert (PH && "Should have a preheader by now");
MachineBasicBlock::iterator InsertPos = PH->getFirstTerminator();
DebugLoc DL;
@@ -1149,7 +1132,7 @@ bool HexagonHardwareLoops::convertToHard
if (containsInvalidInstruction(L, IsInnerHWLoop))
return false;
- MachineBasicBlock *LastMBB = getExitingBlock(L);
+ MachineBasicBlock *LastMBB = L->findLoopControlBlock();
// Don't generate hw loop if the loop has more than one exit.
if (!LastMBB)
return false;
@@ -1164,7 +1147,7 @@ bool HexagonHardwareLoops::convertToHard
// Ensure the loop has a preheader: the loop instruction will be
// placed there.
- MachineBasicBlock *Preheader = findLoopPreheader(L);
+ MachineBasicBlock *Preheader = MLI->findLoopPreheader(L, SpecPreheader);
if (!Preheader) {
Preheader = createPreheaderForLoop(L);
if (!Preheader)
@@ -1191,7 +1174,7 @@ bool HexagonHardwareLoops::convertToHard
// Determine the loop start.
MachineBasicBlock *TopBlock = L->getTopBlock();
- MachineBasicBlock *ExitingBlock = getExitingBlock(L);
+ MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
MachineBasicBlock *LoopStart = 0;
if (ExitingBlock != L->getLoopLatch()) {
MachineBasicBlock *TB = 0, *FB = 0;
@@ -1580,7 +1563,7 @@ static bool isImmValidForOpcode(unsigned
bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) {
MachineBasicBlock *Header = L->getHeader();
MachineBasicBlock *Latch = L->getLoopLatch();
- MachineBasicBlock *ExitingBlock = getExitingBlock(L);
+ MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
if (!(Header && Latch && ExitingBlock))
return false;
@@ -1818,51 +1801,17 @@ bool HexagonHardwareLoops::fixupInductio
return false;
}
-/// Find a preaheader of the given loop.
-MachineBasicBlock *HexagonHardwareLoops::findLoopPreheader(MachineLoop *L)
- const {
- if (MachineBasicBlock *PB = L->getLoopPreheader())
- return PB;
- if (!SpecPreheader)
- 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 = MLI->getLoopFor(S);
- if (T && T->getHeader() == S)
- return nullptr;
- }
- return Preheader;
-}
-
-
/// createPreheaderForLoop - Create a preheader for a given loop.
MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop(
MachineLoop *L) {
- if (MachineBasicBlock *TmpPH = findLoopPreheader(L))
+ if (MachineBasicBlock *TmpPH = MLI->findLoopPreheader(L, SpecPreheader))
return TmpPH;
if (!HWCreatePreheader)
return nullptr;
MachineBasicBlock *Header = L->getHeader();
MachineBasicBlock *Latch = L->getLoopLatch();
- MachineBasicBlock *ExitingBlock = getExitingBlock(L);
+ MachineBasicBlock *ExitingBlock = L->findLoopControlBlock();
MachineFunction *MF = Header->getParent();
DebugLoc DL;
More information about the llvm-commits
mailing list