diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp | 143 |
1 files changed, 78 insertions, 65 deletions
diff --git a/contrib/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/contrib/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp index cc154c4..e477dcc 100644 --- a/contrib/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/contrib/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -25,22 +25,37 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/SmallSet.h" -#include "Hexagon.h" +#include "HexagonInstrInfo.h" #include "HexagonSubtarget.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/PassSupport.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetInstrInfo.h" -#include <algorithm> +#include "llvm/Target/TargetRegisterInfo.h" +#include <cassert> +#include <cstdint> +#include <cstdlib> +#include <iterator> +#include <map> +#include <set> +#include <utility> #include <vector> using namespace llvm; @@ -60,15 +75,26 @@ static cl::opt<bool> HWCreatePreheader("hexagon-hwloop-preheader", cl::Hidden, cl::init(true), cl::desc("Add a preheader to a hardware loop if one doesn't exist")); +// Turn it off by default. If a preheader block is not created here, the +// software pipeliner may be unable to find a block suitable to serve as +// a preheader. In that case SWP will not run. +static cl::opt<bool> SpecPreheader("hwloop-spec-preheader", cl::init(false), + cl::Hidden, cl::ZeroOrMore, cl::desc("Allow speculation of preheader " + "instructions")); + STATISTIC(NumHWLoops, "Number of loops converted to hardware loops"); namespace llvm { + FunctionPass *createHexagonHardwareLoops(); void initializeHexagonHardwareLoopsPass(PassRegistry&); -} + +} // end namespace llvm namespace { + class CountValue; + struct HexagonHardwareLoops : public MachineFunctionPass { MachineLoopInfo *MLI; MachineRegisterInfo *MRI; @@ -87,7 +113,7 @@ namespace { bool runOnMachineFunction(MachineFunction &MF) override; - const char *getPassName() const override { return "Hexagon Hardware Loops"; } + StringRef getPassName() const override { return "Hexagon Hardware Loops"; } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<MachineDominatorTree>(); @@ -138,7 +164,6 @@ namespace { static bool isUnsigned(Kind Cmp) { return (Cmp & U); } - }; /// \brief Find the register that contains the loop controlling @@ -289,6 +314,7 @@ namespace { CV_Register, CV_Immediate }; + private: CountValueType Kind; union Values { @@ -309,6 +335,7 @@ namespace { Contents.ImmVal = v; } } + bool isReg() const { return Kind == CV_Register; } bool isImm() const { return Kind == CV_Immediate; } @@ -330,8 +357,8 @@ namespace { if (isImm()) { OS << Contents.ImmVal; } } }; -} // end anonymous namespace +} // end anonymous namespace INITIALIZE_PASS_BEGIN(HexagonHardwareLoops, "hwloops", "Hexagon Hardware Loops", false, false) @@ -366,28 +393,15 @@ bool HexagonHardwareLoops::runOnMachineFunction(MachineFunction &MF) { 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 = L->getLoopPreheader(); + 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; @@ -417,10 +431,8 @@ bool HexagonHardwareLoops::findInductionRegister(MachineLoop *L, unsigned PhiOpReg = Phi->getOperand(i).getReg(); MachineInstr *DI = MRI->getVRegDef(PhiOpReg); - unsigned UpdOpc = DI->getOpcode(); - bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp); - if (isAdd) { + if (DI->getDesc().isAdd()) { // If the register operand to the add is the PHI we're looking at, this // meets the induction pattern. unsigned IndReg = DI->getOperand(1).getReg(); @@ -555,7 +567,7 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L, // 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; @@ -566,7 +578,7 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L, if (!FoundIV) return nullptr; - MachineBasicBlock *Preheader = L->getLoopPreheader(); + MachineBasicBlock *Preheader = MLI->findLoopPreheader(L, SpecPreheader); MachineOperand *InitialValue = nullptr; MachineInstr *IV_Phi = MRI->getVRegDef(IVReg); @@ -593,7 +605,7 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L, // the fall through can go to the header. assert (TB && "Exit block without a branch?"); if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) { - MachineBasicBlock *LTB = 0, *LFB = 0; + MachineBasicBlock *LTB = nullptr, *LFB = nullptr; SmallVector<MachineOperand,2> LCond; bool NotAnalyzed = TII->analyzeBranch(*Latch, LTB, LFB, LCond, false); if (NotAnalyzed) @@ -787,7 +799,7 @@ CountValue *HexagonHardwareLoops::computeCount(MachineLoop *Loop, if (!isPowerOf2_64(std::abs(IVBump))) return nullptr; - MachineBasicBlock *PH = Loop->getLoopPreheader(); + MachineBasicBlock *PH = MLI->findLoopPreheader(Loop, SpecPreheader); assert (PH && "Should have a preheader by now"); MachineBasicBlock::iterator InsertPos = PH->getFirstTerminator(); DebugLoc DL; @@ -951,8 +963,8 @@ bool HexagonHardwareLoops::isInvalidLoopOperation(const MachineInstr *MI, // Call is not allowed because the callee may use a hardware loop except for // the case when the call never returns. - if (MI->getDesc().isCall() && MI->getOpcode() != Hexagon::CALLv3nr) - return true; + if (MI->getDesc().isCall()) + return !TII->doesNotReturn(*MI); // Check if the instruction defines a hardware loop register. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { @@ -1138,7 +1150,7 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L, 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; @@ -1153,7 +1165,7 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L, // Ensure the loop has a preheader: the loop instruction will be // placed there. - MachineBasicBlock *Preheader = L->getLoopPreheader(); + MachineBasicBlock *Preheader = MLI->findLoopPreheader(L, SpecPreheader); if (!Preheader) { Preheader = createPreheaderForLoop(L); if (!Preheader) @@ -1180,10 +1192,10 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L, // Determine the loop start. MachineBasicBlock *TopBlock = L->getTopBlock(); - MachineBasicBlock *ExitingBlock = getExitingBlock(L); - MachineBasicBlock *LoopStart = 0; + MachineBasicBlock *ExitingBlock = L->findLoopControlBlock(); + MachineBasicBlock *LoopStart = nullptr; if (ExitingBlock != L->getLoopLatch()) { - MachineBasicBlock *TB = 0, *FB = 0; + MachineBasicBlock *TB = nullptr, *FB = nullptr; SmallVector<MachineOperand, 2> Cond; if (TII->analyzeBranch(*ExitingBlock, TB, FB, Cond, false)) @@ -1254,7 +1266,7 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L, if (LastI != LastMBB->end()) LastI = LastMBB->erase(LastI); SmallVector<MachineOperand, 0> Cond; - TII->InsertBranch(*LastMBB, BranchTarget, nullptr, Cond, LastIDL); + TII->insertBranch(*LastMBB, BranchTarget, nullptr, Cond, LastIDL); } } else { // Conditional branch to loop start; just delete it. @@ -1423,12 +1435,13 @@ bool HexagonHardwareLoops::loopCountMayWrapOrUnderFlow( if (!TII->analyzeCompare(*MI, CmpReg1, CmpReg2, CmpMask, CmpValue)) continue; - MachineBasicBlock *TBB = 0, *FBB = 0; + MachineBasicBlock *TBB = nullptr, *FBB = nullptr; SmallVector<MachineOperand, 2> Cond; if (TII->analyzeBranch(*MI->getParent(), TBB, FBB, Cond, false)) continue; - Comparison::Kind Cmp = getComparisonKind(MI->getOpcode(), 0, 0, 0); + Comparison::Kind Cmp = + getComparisonKind(MI->getOpcode(), nullptr, nullptr, 0); if (Cmp == 0) continue; if (TII->predOpcodeHasNot(Cond) ^ (TBB != MBB)) @@ -1479,8 +1492,8 @@ bool HexagonHardwareLoops::checkForImmediate(const MachineOperand &MO, case TargetOpcode::COPY: case Hexagon::A2_tfrsi: case Hexagon::A2_tfrpi: - case Hexagon::CONST32_Int_Real: - case Hexagon::CONST64_Int_Real: { + case Hexagon::CONST32: + case Hexagon::CONST64: { // Call recursively to avoid an extra check whether operand(1) is // indeed an immediate (it could be a global address, for example), // plus we can handle COPY at the same time. @@ -1509,9 +1522,9 @@ bool HexagonHardwareLoops::checkForImmediate(const MachineOperand &MO, return false; unsigned Sub2 = DI->getOperand(2).getImm(); unsigned Sub4 = DI->getOperand(4).getImm(); - if (Sub2 == Hexagon::subreg_loreg && Sub4 == Hexagon::subreg_hireg) + if (Sub2 == Hexagon::isub_lo && Sub4 == Hexagon::isub_hi) TV = V1 | (V3 << 32); - else if (Sub2 == Hexagon::subreg_hireg && Sub4 == Hexagon::subreg_loreg) + else if (Sub2 == Hexagon::isub_hi && Sub4 == Hexagon::isub_lo) TV = V3 | (V1 << 32); else llvm_unreachable("Unexpected form of REG_SEQUENCE"); @@ -1522,13 +1535,13 @@ bool HexagonHardwareLoops::checkForImmediate(const MachineOperand &MO, return false; } - // By now, we should have successfuly obtained the immediate value defining + // By now, we should have successfully obtained the immediate value defining // the register referenced in MO. Handle a potential use of a subregister. switch (MO.getSubReg()) { - case Hexagon::subreg_loreg: + case Hexagon::isub_lo: Val = TV & 0xFFFFFFFFULL; break; - case Hexagon::subreg_hireg: + case Hexagon::isub_hi: Val = (TV >> 32) & 0xFFFFFFFFULL; break; default: @@ -1569,7 +1582,7 @@ static bool isImmValidForOpcode(unsigned CmpOpc, int64_t Imm) { 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; @@ -1598,10 +1611,8 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) { unsigned PhiReg = Phi->getOperand(i).getReg(); MachineInstr *DI = MRI->getVRegDef(PhiReg); - unsigned UpdOpc = DI->getOpcode(); - bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp); - if (isAdd) { + if (DI->getDesc().isAdd()) { // If the register operand to the add/sub is the PHI we are looking // at, this meets the induction pattern. unsigned IndReg = DI->getOperand(1).getReg(); @@ -1626,7 +1637,7 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) { return false; if (ExitingBlock != Latch && (TB == Latch || FB == Latch)) { - MachineBasicBlock *LTB = 0, *LFB = 0; + MachineBasicBlock *LTB = nullptr, *LFB = nullptr; SmallVector<MachineOperand,2> LCond; bool NotAnalyzed = TII->analyzeBranch(*Latch, LTB, LFB, LCond, false); if (NotAnalyzed) @@ -1764,7 +1775,8 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) { // It is not valid to do this transformation on an unsigned comparison // because it may underflow. - Comparison::Kind Cmp = getComparisonKind(PredDef->getOpcode(), 0, 0, 0); + Comparison::Kind Cmp = + getComparisonKind(PredDef->getOpcode(), nullptr, nullptr, 0); if (!Cmp || Comparison::isUnsigned(Cmp)) return false; @@ -1807,18 +1819,17 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) { return false; } -/// \brief Create a preheader for a given loop. +/// createPreheaderForLoop - Create a preheader for a given loop. MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop( MachineLoop *L) { - if (MachineBasicBlock *TmpPH = L->getLoopPreheader()) + 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; @@ -1898,7 +1909,6 @@ MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop( PN->addOperand(MachineOperand::CreateReg(NewPR, false)); PN->addOperand(MachineOperand::CreateMBB(NewPH)); } - } else { assert(Header->pred_size() == 2); @@ -1934,7 +1944,7 @@ MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop( (void)NotAnalyzed; // suppress compiler warning assert (!NotAnalyzed && "Should be analyzable!"); if (TB != Header && (Tmp2.empty() || FB != Header)) - TII->InsertBranch(*PB, NewPH, nullptr, EmptyCond, DL); + TII->insertBranch(*PB, NewPH, nullptr, EmptyCond, DL); PB->ReplaceUsesOfBlockWith(Header, NewPH); } } @@ -1946,10 +1956,10 @@ MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop( (void)LatchNotAnalyzed; // suppress compiler warning assert (!LatchNotAnalyzed && "Should be analyzable!"); if (!TB && !FB) - TII->InsertBranch(*Latch, Header, nullptr, EmptyCond, DL); + TII->insertBranch(*Latch, Header, nullptr, EmptyCond, DL); // Finally, the branch from the preheader to the header. - TII->InsertBranch(*NewPH, Header, nullptr, EmptyCond, DL); + TII->insertBranch(*NewPH, Header, nullptr, EmptyCond, DL); NewPH->addSuccessor(Header); MachineLoop *ParentLoop = L->getParentLoop(); @@ -1958,9 +1968,12 @@ MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop( // Update the dominator information with the new preheader. if (MDT) { - MachineDomTreeNode *HDom = MDT->getNode(Header); - MDT->addNewBlock(NewPH, HDom->getIDom()->getBlock()); - MDT->changeImmediateDominator(Header, NewPH); + if (MachineDomTreeNode *HN = MDT->getNode(Header)) { + if (MachineDomTreeNode *DHN = HN->getIDom()) { + MDT->addNewBlock(NewPH, DHN->getBlock()); + MDT->changeImmediateDominator(Header, NewPH); + } + } } return NewPH; |