diff options
Diffstat (limited to 'lib/Target/Hexagon/HexagonHardwareLoops.cpp')
| -rw-r--r-- | lib/Target/Hexagon/HexagonHardwareLoops.cpp | 105 |
1 files changed, 66 insertions, 39 deletions
diff --git a/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/lib/Target/Hexagon/HexagonHardwareLoops.cpp index 86a8089401c2..715fd52f3acd 100644 --- a/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -1,4 +1,4 @@ -//===-- HexagonHardwareLoops.cpp - Identify and generate hardware loops ---===// +//===- HexagonHardwareLoops.cpp - Identify and generate hardware loops ----===// // // The LLVM Compiler Infrastructure // @@ -27,6 +27,8 @@ #include "HexagonInstrInfo.h" #include "HexagonSubtarget.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -40,6 +42,7 @@ #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugLoc.h" #include "llvm/Pass.h" @@ -48,13 +51,13 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetRegisterInfo.h" #include <cassert> #include <cstdint> #include <cstdlib> #include <iterator> #include <map> #include <set> +#include <string> #include <utility> #include <vector> @@ -108,9 +111,7 @@ namespace { public: static char ID; - HexagonHardwareLoops() : MachineFunctionPass(ID) { - initializeHexagonHardwareLoopsPass(*PassRegistry::getPassRegistry()); - } + HexagonHardwareLoops() : MachineFunctionPass(ID) {} bool runOnMachineFunction(MachineFunction &MF) override; @@ -123,7 +124,7 @@ namespace { } private: - typedef std::map<unsigned, MachineInstr *> LoopFeederMap; + using LoopFeederMap = std::map<unsigned, MachineInstr *>; /// Kinds of comparisons in the compare instructions. struct Comparison { @@ -275,7 +276,7 @@ namespace { /// value, either directly, or via a register. void setImmediate(MachineOperand &MO, int64_t Val); - /// \brief Fix the data flow of the induction varible. + /// \brief Fix the data flow of the induction variable. /// The desired flow is: phi ---> bump -+-> comparison-in-latch. /// | /// +-> back to phi @@ -344,17 +345,19 @@ namespace { assert(isReg() && "Wrong CountValue accessor"); return Contents.R.Reg; } + unsigned getSubReg() const { assert(isReg() && "Wrong CountValue accessor"); return Contents.R.Sub; } + unsigned getImm() const { assert(isImm() && "Wrong CountValue accessor"); return Contents.ImmVal; } void print(raw_ostream &OS, const TargetRegisterInfo *TRI = nullptr) const { - if (isReg()) { OS << PrintReg(Contents.R.Reg, TRI, Contents.R.Sub); } + if (isReg()) { OS << printReg(Contents.R.Reg, TRI, Contents.R.Sub); } if (isImm()) { OS << Contents.ImmVal; } } }; @@ -374,7 +377,7 @@ FunctionPass *llvm::createHexagonHardwareLoops() { bool HexagonHardwareLoops::runOnMachineFunction(MachineFunction &MF) { DEBUG(dbgs() << "********* Hexagon Hardware Loops *********\n"); - if (skipFunction(*MF.getFunction())) + if (skipFunction(MF.getFunction())) return false; bool Changed = false; @@ -410,17 +413,18 @@ bool HexagonHardwareLoops::findInductionRegister(MachineLoop *L, // This pair represents an induction register together with an immediate // value that will be added to it in each loop iteration. - typedef std::pair<unsigned,int64_t> RegisterBump; + using RegisterBump = std::pair<unsigned, int64_t>; // Mapping: R.next -> (R, bump), where R, R.next and bump are derived // from an induction operation // R.next = R + bump // where bump is an immediate value. - typedef std::map<unsigned,RegisterBump> InductionMap; + using InductionMap = std::map<unsigned, RegisterBump>; InductionMap IndMap; - typedef MachineBasicBlock::instr_iterator instr_iterator; + using instr_iterator = MachineBasicBlock::instr_iterator; + for (instr_iterator I = Header->instr_begin(), E = Header->instr_end(); I != E && I->isPHI(); ++I) { MachineInstr *Phi = &*I; @@ -507,8 +511,8 @@ HexagonHardwareLoops::getComparisonKind(unsigned CondOpc, int64_t IVBump) const { Comparison::Kind Cmp = (Comparison::Kind)0; switch (CondOpc) { - case Hexagon::C2_cmpeqi: case Hexagon::C2_cmpeq: + case Hexagon::C2_cmpeqi: case Hexagon::C2_cmpeqp: Cmp = Comparison::EQ; break; @@ -516,21 +520,35 @@ HexagonHardwareLoops::getComparisonKind(unsigned CondOpc, case Hexagon::C4_cmpneqi: Cmp = Comparison::NE; break; + case Hexagon::C2_cmplt: + Cmp = Comparison::LTs; + break; + case Hexagon::C2_cmpltu: + Cmp = Comparison::LTu; + break; case Hexagon::C4_cmplte: + case Hexagon::C4_cmpltei: Cmp = Comparison::LEs; break; case Hexagon::C4_cmplteu: + case Hexagon::C4_cmplteui: Cmp = Comparison::LEu; break; - case Hexagon::C2_cmpgtui: + case Hexagon::C2_cmpgt: + case Hexagon::C2_cmpgti: + case Hexagon::C2_cmpgtp: + Cmp = Comparison::GTs; + break; case Hexagon::C2_cmpgtu: + case Hexagon::C2_cmpgtui: case Hexagon::C2_cmpgtup: Cmp = Comparison::GTu; break; - case Hexagon::C2_cmpgti: - case Hexagon::C2_cmpgt: - case Hexagon::C2_cmpgtp: - Cmp = Comparison::GTs; + case Hexagon::C2_cmpgei: + Cmp = Comparison::GEs; + break; + case Hexagon::C2_cmpgeui: + Cmp = Comparison::GEs; break; default: return (Comparison::Kind)0; @@ -679,15 +697,21 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L, if (InitialValue->isReg()) { unsigned R = InitialValue->getReg(); MachineBasicBlock *DefBB = MRI->getVRegDef(R)->getParent(); - if (!MDT->properlyDominates(DefBB, Header)) - return nullptr; + if (!MDT->properlyDominates(DefBB, Header)) { + int64_t V; + if (!checkForImmediate(*InitialValue, V)) + return nullptr; + } OldInsts.push_back(MRI->getVRegDef(R)); } if (EndValue->isReg()) { unsigned R = EndValue->getReg(); MachineBasicBlock *DefBB = MRI->getVRegDef(R)->getParent(); - if (!MDT->properlyDominates(DefBB, Header)) - return nullptr; + if (!MDT->properlyDominates(DefBB, Header)) { + int64_t V; + if (!checkForImmediate(*EndValue, V)) + return nullptr; + } OldInsts.push_back(MRI->getVRegDef(R)); } @@ -970,6 +994,7 @@ bool HexagonHardwareLoops::isInvalidLoopOperation(const MachineInstr *MI, // Check if the instruction defines a hardware loop register. using namespace Hexagon; + static const unsigned Regs01[] = { LC0, SA0, LC1, SA1 }; static const unsigned Regs1[] = { LC1, SA1 }; auto CheckRegs = IsInnerHWLoop ? makeArrayRef(Regs01, array_lengthof(Regs01)) @@ -986,7 +1011,7 @@ bool HexagonHardwareLoops::isInvalidLoopOperation(const MachineInstr *MI, bool HexagonHardwareLoops::containsInvalidInstruction(MachineLoop *L, bool IsInnerHWLoop) const { const std::vector<MachineBasicBlock *> &Blocks = L->getBlocks(); - DEBUG(dbgs() << "\nhw_loop head, BB#" << Blocks[0]->getNumber();); + DEBUG(dbgs() << "\nhw_loop head, " << printMBBReference(*Blocks[0])); for (unsigned i = 0, e = Blocks.size(); i != e; ++i) { MachineBasicBlock *MBB = Blocks[i]; for (MachineBasicBlock::iterator @@ -1017,7 +1042,7 @@ bool HexagonHardwareLoops::isDead(const MachineInstr *MI, if (MRI->use_nodbg_empty(Reg)) continue; - typedef MachineRegisterInfo::use_nodbg_iterator use_nodbg_iterator; + using use_nodbg_iterator = MachineRegisterInfo::use_nodbg_iterator; // This instruction has users, but if the only user is the phi node for the // parent block, and the only use of that phi node is this instruction, then @@ -1231,7 +1256,7 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L, // if the immediate fits in the instructions. Otherwise, we need to // create a new virtual register. int64_t CountImm = TripCount->getImm(); - if (!TII->isValidOffset(LOOP_i, CountImm)) { + if (!TII->isValidOffset(LOOP_i, CountImm, TRI)) { unsigned CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass); BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::A2_tfrsi), CountReg) .addImm(CountImm); @@ -1300,7 +1325,8 @@ bool HexagonHardwareLoops::orderBumpCompare(MachineInstr *BumpI, if (CmpI->getParent() != BB) return false; - typedef MachineBasicBlock::instr_iterator instr_iterator; + using instr_iterator = MachineBasicBlock::instr_iterator; + // Check if things are in order to begin with. for (instr_iterator I(BumpI), E = BB->instr_end(); I != E; ++I) if (&*I == CmpI) @@ -1341,7 +1367,7 @@ bool HexagonHardwareLoops::isLoopFeeder(MachineLoop *L, MachineBasicBlock *A, LoopFeederMap &LoopFeederPhi) const { if (LoopFeederPhi.find(MO->getReg()) == LoopFeederPhi.end()) { const std::vector<MachineBasicBlock *> &Blocks = L->getBlocks(); - DEBUG(dbgs() << "\nhw_loop head, BB#" << Blocks[0]->getNumber();); + DEBUG(dbgs() << "\nhw_loop head, " << printMBBReference(*Blocks[0])); // Ignore all BBs that form Loop. for (unsigned i = 0, e = Blocks.size(); i != e; ++i) { MachineBasicBlock *MBB = Blocks[i]; @@ -1493,14 +1519,13 @@ bool HexagonHardwareLoops::checkForImmediate(const MachineOperand &MO, case Hexagon::A2_tfrsi: case Hexagon::A2_tfrpi: case Hexagon::CONST32: - case Hexagon::CONST64: { + 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. if (!checkForImmediate(DI->getOperand(1), TV)) return false; break; - } case Hexagon::A2_combineii: case Hexagon::A4_combineir: case Hexagon::A4_combineii: @@ -1589,17 +1614,18 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) { // These data structures follow the same concept as the corresponding // ones in findInductionRegister (where some comments are). - typedef std::pair<unsigned,int64_t> RegisterBump; - typedef std::pair<unsigned,RegisterBump> RegisterInduction; - typedef std::set<RegisterInduction> RegisterInductionSet; + using RegisterBump = std::pair<unsigned, int64_t>; + using RegisterInduction = std::pair<unsigned, RegisterBump>; + using RegisterInductionSet = std::set<RegisterInduction>; // Register candidates for induction variables, with their associated bumps. RegisterInductionSet IndRegs; // Look for induction patterns: - // vreg1 = PHI ..., [ latch, vreg2 ] - // vreg2 = ADD vreg1, imm - typedef MachineBasicBlock::instr_iterator instr_iterator; + // %1 = PHI ..., [ latch, %2 ] + // %2 = ADD %1, imm + using instr_iterator = MachineBasicBlock::instr_iterator; + for (instr_iterator I = Header->instr_begin(), E = Header->instr_end(); I != E && I->isPHI(); ++I) { MachineInstr *Phi = &*I; @@ -1694,7 +1720,7 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) { MachineOperand &MO = PredDef->getOperand(i); if (MO.isReg()) { // Skip all implicit references. In one case there was: - // %vreg140<def> = FCMPUGT32_rr %vreg138, %vreg139, %USR<imp-use> + // %140 = FCMPUGT32_rr %138, %139, implicit %usr if (MO.isImplicit()) continue; if (MO.isUse()) { @@ -1834,18 +1860,19 @@ MachineBasicBlock *HexagonHardwareLoops::createPreheaderForLoop( DebugLoc DL; #ifndef NDEBUG - if ((PHFn != "") && (PHFn != MF->getName())) + if ((!PHFn.empty()) && (PHFn != MF->getName())) return nullptr; #endif if (!Latch || !ExitingBlock || Header->hasAddressTaken()) return nullptr; - typedef MachineBasicBlock::instr_iterator instr_iterator; + using instr_iterator = MachineBasicBlock::instr_iterator; // Verify that all existing predecessors have analyzable branches // (or no branches at all). - typedef std::vector<MachineBasicBlock*> MBBVector; + using MBBVector = std::vector<MachineBasicBlock *>; + MBBVector Preds(Header->pred_begin(), Header->pred_end()); SmallVector<MachineOperand,2> Tmp1; MachineBasicBlock *TB = nullptr, *FB = nullptr; |
