Index: llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h +++ llvm/trunk/include/llvm/CodeGen/MachineLoopInfo.h @@ -54,6 +54,12 @@ /// 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 @@ LoopInfoBase& 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::iterator iterator; inline iterator begin() const { return LI.begin(); } Index: llvm/trunk/lib/CodeGen/MachineLoopInfo.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineLoopInfo.cpp +++ llvm/trunk/lib/CodeGen/MachineLoopInfo.cpp @@ -77,6 +77,51 @@ 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()); Index: llvm/trunk/lib/Target/Hexagon/HexagonHardwareLoops.cpp =================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ llvm/trunk/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -277,10 +277,6 @@ /// 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ // 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 @@ 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 @@ 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;