brintos

brintos / llvm-project-archived public Read only

0
0
Text · 31.6 KiB · 54c3cea Raw
874 lines · cpp
1//===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8// This pass replaces transfer instructions by combine instructions.9// We walk along a basic block and look for two combinable instructions and try10// to move them together. If we can move them next to each other we do so and11// replace them with a combine instruction.12//===----------------------------------------------------------------------===//13 14#include "HexagonInstrInfo.h"15#include "HexagonSubtarget.h"16#include "llvm/ADT/DenseMap.h"17#include "llvm/ADT/DenseSet.h"18#include "llvm/CodeGen/MachineBasicBlock.h"19#include "llvm/CodeGen/MachineFunction.h"20#include "llvm/CodeGen/MachineFunctionPass.h"21#include "llvm/CodeGen/MachineInstr.h"22#include "llvm/CodeGen/MachineInstrBuilder.h"23#include "llvm/CodeGen/Passes.h"24#include "llvm/CodeGen/TargetRegisterInfo.h"25#include "llvm/Pass.h"26#include "llvm/Support/CodeGen.h"27#include "llvm/Support/CommandLine.h"28#include "llvm/Support/Debug.h"29#include "llvm/Support/raw_ostream.h"30#include "llvm/Target/TargetMachine.h"31 32using namespace llvm;33 34#define DEBUG_TYPE "hexagon-copy-combine"35 36static cl::opt<bool>37    IsCombinesDisabled("disable-merge-into-combines", cl::Hidden,38 39                       cl::desc("Disable merging into combines"));40static cl::opt<bool>41    IsConst64Disabled("disable-const64", cl::Hidden,42 43                      cl::desc("Disable generation of const64"));44static45cl::opt<unsigned>46MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store",47                   cl::Hidden, cl::init(4),48                   cl::desc("Maximum distance between a tfr feeding a store we "49                            "consider the store still to be newifiable"));50 51namespace {52 53class HexagonCopyToCombine : public MachineFunctionPass  {54  const HexagonInstrInfo *TII;55  const TargetRegisterInfo *TRI;56  const HexagonSubtarget *ST;57  bool ShouldCombineAggressively;58 59  DenseSet<MachineInstr *> PotentiallyNewifiableTFR;60  SmallVector<MachineInstr *, 8> DbgMItoMove;61 62public:63  static char ID;64 65  HexagonCopyToCombine() : MachineFunctionPass(ID) {}66 67  void getAnalysisUsage(AnalysisUsage &AU) const override {68    MachineFunctionPass::getAnalysisUsage(AU);69  }70 71  StringRef getPassName() const override {72    return "Hexagon Copy-To-Combine Pass";73  }74 75  bool runOnMachineFunction(MachineFunction &Fn) override;76 77  MachineFunctionProperties getRequiredProperties() const override {78    return MachineFunctionProperties().setNoVRegs();79  }80 81private:82  MachineInstr *findPairable(MachineInstr &I1, bool &DoInsertAtI1,83                             bool AllowC64);84 85  void findPotentialNewifiableTFRs(MachineBasicBlock &);86 87  void combine(MachineInstr &I1, MachineInstr &I2,88               MachineBasicBlock::iterator &MI, bool DoInsertAtI1,89               bool OptForSize);90 91  bool isSafeToMoveTogether(MachineInstr &I1, MachineInstr &I2,92                            unsigned I1DestReg, unsigned I2DestReg,93                            bool &DoInsertAtI1);94 95  void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg,96                     MachineOperand &HiOperand, MachineOperand &LoOperand);97 98  void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg,99                     MachineOperand &HiOperand, MachineOperand &LoOperand);100 101  void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg,102                     MachineOperand &HiOperand, MachineOperand &LoOperand);103 104  void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg,105                     MachineOperand &HiOperand, MachineOperand &LoOperand);106 107  void emitConst64(MachineBasicBlock::iterator &Before, unsigned DestReg,108                   MachineOperand &HiOperand, MachineOperand &LoOperand);109};110 111} // End anonymous namespace.112 113char HexagonCopyToCombine::ID = 0;114 115INITIALIZE_PASS(HexagonCopyToCombine, "hexagon-copy-combine",116                "Hexagon Copy-To-Combine Pass", false, false)117 118static bool isCombinableInstType(MachineInstr &MI, const HexagonInstrInfo *TII,119                                 bool ShouldCombineAggressively) {120  switch (MI.getOpcode()) {121  case Hexagon::A2_tfr: {122    // A COPY instruction can be combined if its arguments are IntRegs (32bit).123    const MachineOperand &Op0 = MI.getOperand(0);124    const MachineOperand &Op1 = MI.getOperand(1);125    assert(Op0.isReg() && Op1.isReg());126 127    Register DestReg = Op0.getReg();128    Register SrcReg = Op1.getReg();129    return Hexagon::IntRegsRegClass.contains(DestReg) &&130           Hexagon::IntRegsRegClass.contains(SrcReg);131  }132 133  case Hexagon::A2_tfrsi: {134    // A transfer-immediate can be combined if its argument is a signed 8bit135    // value.136    const MachineOperand &Op0 = MI.getOperand(0);137    const MachineOperand &Op1 = MI.getOperand(1);138    assert(Op0.isReg());139 140    Register DestReg = Op0.getReg();141    // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a142    // workaround for an ABI bug that prevents GOT relocations on combine143    // instructions144    if (!Op1.isImm() && Op1.getTargetFlags() != HexagonII::MO_NO_FLAG)145      return false;146 147    // Only combine constant extended A2_tfrsi if we are in aggressive mode.148    bool NotExt = Op1.isImm() && isInt<8>(Op1.getImm());149    return Hexagon::IntRegsRegClass.contains(DestReg) &&150           (ShouldCombineAggressively || NotExt);151  }152 153  case Hexagon::V6_vassign:154    return true;155 156  default:157    break;158  }159 160  return false;161}162 163template <unsigned N> static bool isGreaterThanNBitTFRI(const MachineInstr &I) {164  if (I.getOpcode() == Hexagon::TFRI64_V4 ||165      I.getOpcode() == Hexagon::A2_tfrsi) {166    const MachineOperand &Op = I.getOperand(1);167    return !Op.isImm() || !isInt<N>(Op.getImm());168  }169  return false;170}171 172/// areCombinableOperations - Returns true if the two instruction can be merge173/// into a combine (ignoring register constraints).174static bool areCombinableOperations(const TargetRegisterInfo *TRI,175                                    MachineInstr &HighRegInst,176                                    MachineInstr &LowRegInst, bool AllowC64) {177  unsigned HiOpc = HighRegInst.getOpcode();178  unsigned LoOpc = LowRegInst.getOpcode();179 180  auto verifyOpc = [](unsigned Opc) -> void {181    switch (Opc) {182      case Hexagon::A2_tfr:183      case Hexagon::A2_tfrsi:184      case Hexagon::V6_vassign:185        break;186      default:187        llvm_unreachable("Unexpected opcode");188    }189  };190  verifyOpc(HiOpc);191  verifyOpc(LoOpc);192 193  if (HiOpc == Hexagon::V6_vassign || LoOpc == Hexagon::V6_vassign)194    return HiOpc == LoOpc;195 196  if (!AllowC64) {197    // There is no combine of two constant extended values.198    if (isGreaterThanNBitTFRI<8>(HighRegInst) &&199        isGreaterThanNBitTFRI<6>(LowRegInst))200      return false;201  }202 203  // There is a combine of two constant extended values into CONST64,204  // provided both constants are true immediates.205  if (isGreaterThanNBitTFRI<16>(HighRegInst) &&206      isGreaterThanNBitTFRI<16>(LowRegInst) && !IsConst64Disabled)207    return (HighRegInst.getOperand(1).isImm() &&208            LowRegInst.getOperand(1).isImm());209 210  // There is no combine of two constant extended values, unless handled above211  // Make both 8-bit size checks to allow both combine (#,##) and combine(##,#)212  if (isGreaterThanNBitTFRI<8>(HighRegInst) &&213      isGreaterThanNBitTFRI<8>(LowRegInst))214    return false;215 216  return true;217}218 219static bool isEvenReg(unsigned Reg) {220  assert(Register::isPhysicalRegister(Reg));221  if (Hexagon::IntRegsRegClass.contains(Reg))222    return (Reg - Hexagon::R0) % 2 == 0;223  if (Hexagon::HvxVRRegClass.contains(Reg))224    return (Reg - Hexagon::V0) % 2 == 0;225  llvm_unreachable("Invalid register");226}227 228static void removeKillInfo(MachineInstr &MI, unsigned RegNotKilled) {229  for (MachineOperand &Op : MI.operands())230    if (Op.isReg() && Op.getReg() == RegNotKilled && Op.isKill())231      Op.setIsKill(false);232}233 234/// Returns true if it is unsafe to move a copy instruction from \p UseReg to235/// \p DestReg over the instruction \p MI.236static bool isUnsafeToMoveAcross(MachineInstr &MI, unsigned UseReg,237                                 unsigned DestReg,238                                 const TargetRegisterInfo *TRI) {239  return (UseReg && (MI.modifiesRegister(UseReg, TRI))) ||240         MI.modifiesRegister(DestReg, TRI) || MI.readsRegister(DestReg, TRI) ||241         MI.hasUnmodeledSideEffects() || MI.isInlineAsm() ||242         MI.isMetaInstruction();243}244 245static Register UseReg(const MachineOperand& MO) {246  return MO.isReg() ? MO.getReg() : Register();247}248 249/// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such250/// that the two instructions can be paired in a combine.251bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr &I1,252                                                MachineInstr &I2,253                                                unsigned I1DestReg,254                                                unsigned I2DestReg,255                                                bool &DoInsertAtI1) {256  Register I2UseReg = UseReg(I2.getOperand(1));257 258  // It is not safe to move I1 and I2 into one combine if I2 has a true259  // dependence on I1.260  if (I2UseReg && I1.modifiesRegister(I2UseReg, TRI))261    return false;262 263  bool isSafe = true;264 265  // First try to move I2 towards I1.266  {267    // A reverse_iterator instantiated like below starts before I2, and I1268    // respectively.269    // Look at instructions I in between I2 and (excluding) I1.270    MachineBasicBlock::reverse_iterator I = ++I2.getIterator().getReverse();271    MachineBasicBlock::reverse_iterator End = I1.getIterator().getReverse();272    // At 03 we got better results (dhrystone!) by being more conservative.273    if (!ShouldCombineAggressively)274      End = ++I1.getIterator().getReverse();275    // If I2 kills its operand and we move I2 over an instruction that also276    // uses I2's use reg we need to modify that (first) instruction to now kill277    // this reg.278    unsigned KilledOperand = 0;279    if (I2.killsRegister(I2UseReg, /*TRI=*/nullptr))280      KilledOperand = I2UseReg;281    MachineInstr *KillingInstr = nullptr;282 283    for (; I != End; ++I) {284      // If the intervening instruction I:285      //   * modifies I2's use reg286      //   * modifies I2's def reg287      //   * reads I2's def reg288      //   * or has unmodelled side effects289      // we can't move I2 across it.290      if (I->isDebugInstr())291        continue;292 293      if (isUnsafeToMoveAcross(*I, I2UseReg, I2DestReg, TRI)) {294        isSafe = false;295        break;296      }297 298      // Update first use of the killed operand.299      if (!KillingInstr && KilledOperand &&300          I->readsRegister(KilledOperand, TRI))301        KillingInstr = &*I;302    }303    if (isSafe) {304      // Update the intermediate instruction to with the kill flag.305      if (KillingInstr) {306        bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true);307        (void)Added; // suppress compiler warning308        assert(Added && "Must successfully update kill flag");309        removeKillInfo(I2, KilledOperand);310      }311      DoInsertAtI1 = true;312      return true;313    }314  }315 316  // Try to move I1 towards I2.317  {318    // Look at instructions I in between I1 and (excluding) I2.319    MachineBasicBlock::iterator I(I1), End(I2);320    // At O3 we got better results (dhrystone) by being more conservative here.321    if (!ShouldCombineAggressively)322      End = std::next(MachineBasicBlock::iterator(I2));323    Register I1UseReg = UseReg(I1.getOperand(1));324    // Track killed operands. If we move across an instruction that kills our325    // operand, we need to update the kill information on the moved I1. It kills326    // the operand now.327    MachineInstr *KillingInstr = nullptr;328    unsigned KilledOperand = 0;329 330    while(++I != End) {331      MachineInstr &MI = *I;332      // If the intervening instruction MI:333      //   * modifies I1's use reg334      //   * modifies I1's def reg335      //   * reads I1's def reg336      //   * or has unmodelled side effects337      //   We introduce this special case because llvm has no api to remove a338      //   kill flag for a register (a removeRegisterKilled() analogous to339      //   addRegisterKilled) that handles aliased register correctly.340      //   * or has a killed aliased register use of I1's use reg341      //           %d4 = A2_tfrpi 16342      //           %r6 = A2_tfr %r9343      //           %r8 = KILL %r8, implicit killed %d4344      //      If we want to move R6 = across the KILL instruction we would have345      //      to remove the implicit killed %d4 operand. For now, we are346      //      conservative and disallow the move.347      // we can't move I1 across it.348      if (MI.isDebugInstr()) {349        if (MI.readsRegister(I1DestReg, TRI)) // Move this instruction after I2.350          DbgMItoMove.push_back(&MI);351        continue;352      }353 354      if (isUnsafeToMoveAcross(MI, I1UseReg, I1DestReg, TRI) ||355          // Check for an aliased register kill. Bail out if we see one.356          (!MI.killsRegister(I1UseReg, /*TRI=*/nullptr) &&357           MI.killsRegister(I1UseReg, TRI)))358        return false;359 360      // Check for an exact kill (registers match).361      if (I1UseReg && MI.killsRegister(I1UseReg, /*TRI=*/nullptr)) {362        assert(!KillingInstr && "Should only see one killing instruction");363        KilledOperand = I1UseReg;364        KillingInstr = &MI;365      }366    }367    if (KillingInstr) {368      removeKillInfo(*KillingInstr, KilledOperand);369      // Update I1 to set the kill flag. This flag will later be picked up by370      // the new COMBINE instruction.371      bool Added = I1.addRegisterKilled(KilledOperand, TRI);372      (void)Added; // suppress compiler warning373      assert(Added && "Must successfully update kill flag");374    }375    DoInsertAtI1 = false;376  }377 378  return true;379}380 381/// findPotentialNewifiableTFRs - Finds transfers that feed stores that could be382/// newified. (A use of a 64 bit register define can not be newified)383void384HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) {385  DenseMap<unsigned, MachineInstr *> LastDef;386  for (MachineInstr &MI : BB) {387    if (MI.isDebugInstr())388      continue;389 390    // Mark TFRs that feed a potential new value store as such.391    if (TII->mayBeNewStore(MI)) {392      // Look for uses of TFR instructions.393      for (const MachineOperand &Op : MI.operands()) {394        // Skip over anything except register uses.395        if (!Op.isReg() || !Op.isUse() || !Op.getReg())396          continue;397 398        // Look for the defining instruction.399        Register Reg = Op.getReg();400        MachineInstr *DefInst = LastDef[Reg];401        if (!DefInst)402          continue;403        if (!isCombinableInstType(*DefInst, TII, ShouldCombineAggressively))404          continue;405 406        // Only close newifiable stores should influence the decision.407        // Ignore the debug instructions in between.408        MachineBasicBlock::iterator It(DefInst);409        unsigned NumInstsToDef = 0;410        while (&*It != &MI) {411          if (!It->isDebugInstr())412            ++NumInstsToDef;413          ++It;414        }415 416        if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR)417          continue;418 419        PotentiallyNewifiableTFR.insert(DefInst);420      }421      // Skip to next instruction.422      continue;423    }424 425    // Put instructions that last defined integer or double registers into the426    // map.427    for (MachineOperand &Op : MI.operands()) {428      if (Op.isReg()) {429        if (!Op.isDef() || !Op.getReg())430          continue;431        Register Reg = Op.getReg();432        if (Hexagon::DoubleRegsRegClass.contains(Reg)) {433          for (MCPhysReg SubReg : TRI->subregs(Reg))434            LastDef[SubReg] = &MI;435        } else if (Hexagon::IntRegsRegClass.contains(Reg))436          LastDef[Reg] = &MI;437      } else if (Op.isRegMask()) {438        for (unsigned Reg : Hexagon::IntRegsRegClass)439          if (Op.clobbersPhysReg(Reg))440            LastDef[Reg] = &MI;441      }442    }443  }444}445 446bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {447  if (skipFunction(MF.getFunction()))448    return false;449 450  if (IsCombinesDisabled) return false;451 452  bool HasChanged = false;453 454  // Get target info.455  ST = &MF.getSubtarget<HexagonSubtarget>();456  TRI = ST->getRegisterInfo();457  TII = ST->getInstrInfo();458 459  const Function &F = MF.getFunction();460  bool OptForSize = F.hasOptSize();461 462  // Combine aggressively (for code size)463  ShouldCombineAggressively =464      MF.getTarget().getOptLevel() <= CodeGenOptLevel::Default;465 466  // Disable CONST64 for tiny core since it takes a LD resource.467  if (!OptForSize && ST->isTinyCore())468    IsConst64Disabled = true;469 470  // Traverse basic blocks.471  for (MachineBasicBlock &MBB : MF) {472    PotentiallyNewifiableTFR.clear();473    findPotentialNewifiableTFRs(MBB);474 475    // Traverse instructions in basic block.476    for (MachineBasicBlock::iterator MI = MBB.begin(), End = MBB.end();477         MI != End;) {478      MachineInstr &I1 = *MI++;479 480      if (I1.isDebugInstr())481        continue;482 483      // Don't combine a TFR whose user could be newified (instructions that484      // define double registers can not be newified - Programmer's Ref Manual485      // 5.4.2 New-value stores).486      if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&I1))487        continue;488 489      // Ignore instructions that are not combinable.490      if (!isCombinableInstType(I1, TII, ShouldCombineAggressively))491        continue;492 493      // Find a second instruction that can be merged into a combine494      // instruction. In addition, also find all the debug instructions that495      // need to be moved along with it.496      bool DoInsertAtI1 = false;497      DbgMItoMove.clear();498      MachineInstr *I2 = findPairable(I1, DoInsertAtI1, OptForSize);499      if (I2) {500        HasChanged = true;501        combine(I1, *I2, MI, DoInsertAtI1, OptForSize);502      }503    }504  }505 506  return HasChanged;507}508 509/// findPairable - Returns an instruction that can be merged with \p I1 into a510/// COMBINE instruction or 0 if no such instruction can be found. Returns true511/// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1512/// false if the combine must be inserted at the returned instruction.513MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr &I1,514                                                 bool &DoInsertAtI1,515                                                 bool AllowC64) {516  MachineBasicBlock::iterator I2 = std::next(MachineBasicBlock::iterator(I1));517  while (I2 != I1.getParent()->end() && I2->isDebugInstr())518    ++I2;519 520  Register I1DestReg = I1.getOperand(0).getReg();521 522  for (MachineBasicBlock::iterator End = I1.getParent()->end(); I2 != End;523       ++I2) {524    // Bail out early if we see a second definition of I1DestReg.525    if (I2->modifiesRegister(I1DestReg, TRI))526      break;527 528    // Ignore non-combinable instructions.529    if (!isCombinableInstType(*I2, TII, ShouldCombineAggressively))530      continue;531 532    // Don't combine a TFR whose user could be newified.533    if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&*I2))534      continue;535 536    Register I2DestReg = I2->getOperand(0).getReg();537 538    // Check that registers are adjacent and that the first destination register539    // is even.540    bool IsI1LowReg = (I2DestReg - I1DestReg) == 1;541    bool IsI2LowReg = (I1DestReg - I2DestReg) == 1;542    unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg;543    if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex))544      continue;545 546    // Check that the two instructions are combinable.547    // The order matters because in a A2_tfrsi we might can encode a int8 as548    // the hi reg operand but only a uint6 as the low reg operand.549    if ((IsI2LowReg && !areCombinableOperations(TRI, I1, *I2, AllowC64)) ||550        (IsI1LowReg && !areCombinableOperations(TRI, *I2, I1, AllowC64)))551      break;552 553    if (isSafeToMoveTogether(I1, *I2, I1DestReg, I2DestReg, DoInsertAtI1))554      return &*I2;555 556    // Not safe. Stop searching.557    break;558  }559  return nullptr;560}561 562void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2,563                                   MachineBasicBlock::iterator &MI,564                                   bool DoInsertAtI1, bool OptForSize) {565  // We are going to delete I2. If MI points to I2 advance it to the next566  // instruction.567  if (MI == I2.getIterator())568    ++MI;569 570  // Figure out whether I1 or I2 goes into the lowreg part.571  Register I1DestReg = I1.getOperand(0).getReg();572  Register I2DestReg = I2.getOperand(0).getReg();573  bool IsI1Loreg = (I2DestReg - I1DestReg) == 1;574  unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg;575  unsigned SubLo;576 577  const TargetRegisterClass *SuperRC = nullptr;578  if (Hexagon::IntRegsRegClass.contains(LoRegDef)) {579    SuperRC = &Hexagon::DoubleRegsRegClass;580    SubLo = Hexagon::isub_lo;581  } else if (Hexagon::HvxVRRegClass.contains(LoRegDef)) {582    assert(ST->useHVXOps());583    SuperRC = &Hexagon::HvxWRRegClass;584    SubLo = Hexagon::vsub_lo;585  } else586    llvm_unreachable("Unexpected register class");587 588  // Get the double word register.589  MCRegister DoubleRegDest = TRI->getMatchingSuperReg(LoRegDef, SubLo, SuperRC);590  assert(DoubleRegDest.isValid() && "Expect a valid register");591 592  // Setup source operands.593  MachineOperand &LoOperand = IsI1Loreg ? I1.getOperand(1) : I2.getOperand(1);594  MachineOperand &HiOperand = IsI1Loreg ? I2.getOperand(1) : I1.getOperand(1);595 596  // Figure out which source is a register and which a constant.597  bool IsHiReg = HiOperand.isReg();598  bool IsLoReg = LoOperand.isReg();599 600  // There is a combine of two constant extended values into CONST64.601  bool IsC64 = OptForSize && LoOperand.isImm() && HiOperand.isImm() &&602               isGreaterThanNBitTFRI<16>(I1) && isGreaterThanNBitTFRI<16>(I2);603 604  MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2);605  // Emit combine.606  if (IsHiReg && IsLoReg)607    emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand);608  else if (IsHiReg)609    emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand);610  else if (IsLoReg)611    emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand);612  else if (IsC64 && !IsConst64Disabled)613    emitConst64(InsertPt, DoubleRegDest, HiOperand, LoOperand);614  else615    emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand);616 617  // Move debug instructions along with I1 if it's being618  // moved towards I2.619  if (!DoInsertAtI1 && DbgMItoMove.size() != 0) {620    // Insert debug instructions at the new location before I2.621    MachineBasicBlock *BB = InsertPt->getParent();622    for (auto *NewMI : DbgMItoMove) {623      // If iterator MI is pointing to DEBUG_VAL, make sure624      // MI now points to next relevant instruction.625      if (NewMI == MI)626        ++MI;627      BB->splice(InsertPt, BB, NewMI);628    }629  }630 631  I1.eraseFromParent();632  I2.eraseFromParent();633}634 635void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator &InsertPt,636                                       unsigned DoubleDestReg,637                                       MachineOperand &HiOperand,638                                       MachineOperand &LoOperand) {639  LLVM_DEBUG(dbgs() << "Found a CONST64\n");640 641  DebugLoc DL = InsertPt->getDebugLoc();642  MachineBasicBlock *BB = InsertPt->getParent();643  assert(LoOperand.isImm() && HiOperand.isImm() &&644         "Both operands must be immediate");645 646  int64_t V = HiOperand.getImm();647  V = (V << 32) | (0x0ffffffffLL & LoOperand.getImm());648  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64), DoubleDestReg)649    .addImm(V);650}651 652void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,653                                         unsigned DoubleDestReg,654                                         MachineOperand &HiOperand,655                                         MachineOperand &LoOperand) {656  DebugLoc DL = InsertPt->getDebugLoc();657  MachineBasicBlock *BB = InsertPt->getParent();658 659  // Handle globals.660  if (HiOperand.isGlobal()) {661    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)662      .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),663                        HiOperand.getTargetFlags())664      .addImm(LoOperand.getImm());665    return;666  }667  if (LoOperand.isGlobal()) {668    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)669      .addImm(HiOperand.getImm())670      .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),671                        LoOperand.getTargetFlags());672    return;673  }674 675  // Handle block addresses.676  if (HiOperand.isBlockAddress()) {677    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)678      .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),679                       HiOperand.getTargetFlags())680      .addImm(LoOperand.getImm());681    return;682  }683  if (LoOperand.isBlockAddress()) {684    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)685      .addImm(HiOperand.getImm())686      .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),687                       LoOperand.getTargetFlags());688    return;689  }690 691  // Handle jump tables.692  if (HiOperand.isJTI()) {693    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)694      .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())695      .addImm(LoOperand.getImm());696    return;697  }698  if (LoOperand.isJTI()) {699    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)700      .addImm(HiOperand.getImm())701      .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());702    return;703  }704 705  // Handle constant pools.706  if (HiOperand.isCPI()) {707    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)708      .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),709                            HiOperand.getTargetFlags())710      .addImm(LoOperand.getImm());711    return;712  }713  if (LoOperand.isCPI()) {714    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)715      .addImm(HiOperand.getImm())716      .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),717                            LoOperand.getTargetFlags());718    return;719  }720 721  // First preference should be given to Hexagon::A2_combineii instruction722  // as it can include U6 (in Hexagon::A4_combineii) as well.723  // In this instruction, HiOperand is const extended, if required.724  if (isInt<8>(LoOperand.getImm())) {725    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)726      .addImm(HiOperand.getImm())727      .addImm(LoOperand.getImm());728      return;729  }730 731  // In this instruction, LoOperand is const extended, if required.732  if (isInt<8>(HiOperand.getImm())) {733    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)734      .addImm(HiOperand.getImm())735      .addImm(LoOperand.getImm());736    return;737  }738 739  // Insert new combine instruction.740  //  DoubleRegDest = combine #HiImm, #LoImm741  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)742    .addImm(HiOperand.getImm())743    .addImm(LoOperand.getImm());744}745 746void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt,747                                         unsigned DoubleDestReg,748                                         MachineOperand &HiOperand,749                                         MachineOperand &LoOperand) {750  Register LoReg = LoOperand.getReg();751  unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());752 753  DebugLoc DL = InsertPt->getDebugLoc();754  MachineBasicBlock *BB = InsertPt->getParent();755 756  // Handle globals.757  if (HiOperand.isGlobal()) {758    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)759      .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),760                        HiOperand.getTargetFlags())761      .addReg(LoReg, LoRegKillFlag);762    return;763  }764  // Handle block addresses.765  if (HiOperand.isBlockAddress()) {766    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)767      .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),768                       HiOperand.getTargetFlags())769      .addReg(LoReg, LoRegKillFlag);770    return;771  }772  // Handle jump tables.773  if (HiOperand.isJTI()) {774    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)775      .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())776      .addReg(LoReg, LoRegKillFlag);777    return;778  }779  // Handle constant pools.780  if (HiOperand.isCPI()) {781    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)782      .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),783                            HiOperand.getTargetFlags())784      .addReg(LoReg, LoRegKillFlag);785    return;786  }787  // Insert new combine instruction.788  //  DoubleRegDest = combine #HiImm, LoReg789  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)790    .addImm(HiOperand.getImm())791    .addReg(LoReg, LoRegKillFlag);792}793 794void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,795                                         unsigned DoubleDestReg,796                                         MachineOperand &HiOperand,797                                         MachineOperand &LoOperand) {798  unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());799  Register HiReg = HiOperand.getReg();800 801  DebugLoc DL = InsertPt->getDebugLoc();802  MachineBasicBlock *BB = InsertPt->getParent();803 804  // Handle global.805  if (LoOperand.isGlobal()) {806    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)807      .addReg(HiReg, HiRegKillFlag)808      .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),809                        LoOperand.getTargetFlags());810    return;811  }812  // Handle block addresses.813  if (LoOperand.isBlockAddress()) {814    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)815      .addReg(HiReg, HiRegKillFlag)816      .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),817                       LoOperand.getTargetFlags());818    return;819  }820  // Handle jump tables.821  if (LoOperand.isJTI()) {822    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)823      .addReg(HiOperand.getReg(), HiRegKillFlag)824      .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());825    return;826  }827  // Handle constant pools.828  if (LoOperand.isCPI()) {829    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)830      .addReg(HiOperand.getReg(), HiRegKillFlag)831      .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),832                            LoOperand.getTargetFlags());833    return;834  }835 836  // Insert new combine instruction.837  //  DoubleRegDest = combine HiReg, #LoImm838  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)839    .addReg(HiReg, HiRegKillFlag)840    .addImm(LoOperand.getImm());841}842 843void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt,844                                         unsigned DoubleDestReg,845                                         MachineOperand &HiOperand,846                                         MachineOperand &LoOperand) {847  unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill());848  unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());849  Register LoReg = LoOperand.getReg();850  Register HiReg = HiOperand.getReg();851 852  DebugLoc DL = InsertPt->getDebugLoc();853  MachineBasicBlock *BB = InsertPt->getParent();854 855  // Insert new combine instruction.856  //  DoubleRegDest = combine HiReg, LoReg857  unsigned NewOpc;858  if (Hexagon::DoubleRegsRegClass.contains(DoubleDestReg)) {859    NewOpc = Hexagon::A2_combinew;860  } else if (Hexagon::HvxWRRegClass.contains(DoubleDestReg)) {861    assert(ST->useHVXOps());862    NewOpc = Hexagon::V6_vcombine;863  } else864    llvm_unreachable("Unexpected register");865 866  BuildMI(*BB, InsertPt, DL, TII->get(NewOpc), DoubleDestReg)867    .addReg(HiReg, HiRegKillFlag)868    .addReg(LoReg, LoRegKillFlag);869}870 871FunctionPass *llvm::createHexagonCopyToCombine() {872  return new HexagonCopyToCombine();873}874