Index: include/llvm/CodeGen/MachineLoopInfo.h =================================================================== --- include/llvm/CodeGen/MachineLoopInfo.h +++ include/llvm/CodeGen/MachineLoopInfo.h @@ -81,6 +81,14 @@ LoopInfoBase& getBase() { return LI; } + /// Find a preaheader of the given loop. + MachineBasicBlock * findLoopPreheader(MachineLoop *L) const; + + /// \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. + MachineBasicBlock* getExitingBlock(MachineLoop *L); + /// The iterator interface to the top-level loops in the current function. typedef LoopInfoBase::iterator iterator; inline iterator begin() const { return LI.begin(); } Index: lib/CodeGen/MachineLoopInfo.cpp =================================================================== --- lib/CodeGen/MachineLoopInfo.cpp +++ lib/CodeGen/MachineLoopInfo.cpp @@ -77,6 +77,47 @@ return BotMBB; } +MachineBasicBlock * MachineLoopInfo::findLoopPreheader(MachineLoop *L) const { + if (MachineBasicBlock *PB = L->getLoopPreheader()) + return PB; + + 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; +} + +MachineBasicBlock* MachineLoopInfo::getExitingBlock(MachineLoop *L) { + if (MachineBasicBlock *Latch = L->getLoopLatch()) { + if (L->isLoopExiting(Latch)) + return Latch; + else + return L->getExitingBlock(); + } + return nullptr; +} + + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void MachineLoop::dump() const { print(dbgs()); Index: lib/Target/Hexagon/HexagonHardwareLoops.cpp =================================================================== --- lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -377,19 +377,6 @@ 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, @@ -398,7 +385,7 @@ MachineBasicBlock *Header = L->getHeader(); MachineBasicBlock *Preheader = findLoopPreheader(L); MachineBasicBlock *Latch = L->getLoopLatch(); - MachineBasicBlock *ExitingBlock = getExitingBlock(L); + MachineBasicBlock *ExitingBlock = MLI->getExitingBlock(L); if (!Header || !Preheader || !Latch || !ExitingBlock) return false; @@ -566,7 +553,7 @@ // 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 = MLI->getExitingBlock(L); if (!ExitingBlock) return nullptr; @@ -1149,7 +1136,7 @@ if (containsInvalidInstruction(L, IsInnerHWLoop)) return false; - MachineBasicBlock *LastMBB = getExitingBlock(L); + MachineBasicBlock *LastMBB = MLI->getExitingBlock(L); // Don't generate hw loop if the loop has more than one exit. if (!LastMBB) return false; @@ -1191,7 +1178,7 @@ // Determine the loop start. MachineBasicBlock *TopBlock = L->getTopBlock(); - MachineBasicBlock *ExitingBlock = getExitingBlock(L); + MachineBasicBlock *ExitingBlock = MLI->getExitingBlock(L); MachineBasicBlock *LoopStart = 0; if (ExitingBlock != L->getLoopLatch()) { MachineBasicBlock *TB = 0, *FB = 0; @@ -1580,7 +1567,7 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) { MachineBasicBlock *Header = L->getHeader(); MachineBasicBlock *Latch = L->getLoopLatch(); - MachineBasicBlock *ExitingBlock = getExitingBlock(L); + MachineBasicBlock *ExitingBlock = MLI->getExitingBlock(L); if (!(Header && Latch && ExitingBlock)) return false; @@ -1821,37 +1808,12 @@ /// 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; + return MLI->findLoopPreheader(L) } - /// createPreheaderForLoop - Create a preheader for a given loop. MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop( MachineLoop *L) { @@ -1862,7 +1824,7 @@ MachineBasicBlock *Header = L->getHeader(); MachineBasicBlock *Latch = L->getLoopLatch(); - MachineBasicBlock *ExitingBlock = getExitingBlock(L); + MachineBasicBlock *ExitingBlock = MLI->getExitingBlock(L); MachineFunction *MF = Header->getParent(); DebugLoc DL;