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;  | 
