コード例 #1
0
ファイル: HexagonPeephole.cpp プロジェクト: sigma-random/llvm
void HexagonPeephole::ChangeOpInto(MachineOperand &Dst, MachineOperand &Src) {
  assert (&Dst != &Src && "Cannot duplicate into itself");
  switch (Dst.getType()) {
    case MachineOperand::MO_Register:
      if (Src.isReg()) {
        Dst.setReg(Src.getReg());
      } else if (Src.isImm()) {
        Dst.ChangeToImmediate(Src.getImm());
      } else {
        llvm_unreachable("Unexpected src operand type");
      }
      break;

    case MachineOperand::MO_Immediate:
      if (Src.isImm()) {
        Dst.setImm(Src.getImm());
      } else if (Src.isReg()) {
        Dst.ChangeToRegister(Src.getReg(), Src.isDef(), Src.isImplicit(),
                             Src.isKill(), Src.isDead(), Src.isUndef(),
                             Src.isDebug());
      } else {
        llvm_unreachable("Unexpected src operand type");
      }
      break;

    default:
      llvm_unreachable("Unexpected dst operand type");
      break;
  }
}
コード例 #2
0
static std::string getShuffleComment(const MachineOperand &DstOp,
                                     const MachineOperand &SrcOp,
                                     ArrayRef<int> Mask) {
  std::string Comment;

  // Compute the name for a register. This is really goofy because we have
  // multiple instruction printers that could (in theory) use different
  // names. Fortunately most people use the ATT style (outside of Windows)
  // and they actually agree on register naming here. Ultimately, this is
  // a comment, and so its OK if it isn't perfect.
  auto GetRegisterName = [](unsigned RegNum) -> StringRef {
    return X86ATTInstPrinter::getRegisterName(RegNum);
  };

  StringRef DstName = DstOp.isReg() ? GetRegisterName(DstOp.getReg()) : "mem";
  StringRef SrcName = SrcOp.isReg() ? GetRegisterName(SrcOp.getReg()) : "mem";

  raw_string_ostream CS(Comment);
  CS << DstName << " = ";
  bool NeedComma = false;
  bool InSrc = false;
  for (int M : Mask) {
    // Wrap up any prior entry...
    if (M == SM_SentinelZero && InSrc) {
      InSrc = false;
      CS << "]";
    }
    if (NeedComma)
      CS << ",";
    else
      NeedComma = true;

    // Print this shuffle...
    if (M == SM_SentinelZero) {
      CS << "zero";
    } else {
      if (!InSrc) {
        InSrc = true;
        CS << SrcName << "[";
      }
      if (M == SM_SentinelUndef)
        CS << "u";
      else
        CS << M;
    }
  }
  if (InSrc)
    CS << "]";
  CS.flush();

  return Comment;
}
コード例 #3
0
ファイル: HexagonGenMux.cpp プロジェクト: llvm-beanz/llvm
unsigned HexagonGenMux::getMuxOpcode(const MachineOperand &Src1,
                                     const MachineOperand &Src2) const {
    bool IsReg1 = Src1.isReg(), IsReg2 = Src2.isReg();
    if (IsReg1)
        return IsReg2 ? Hexagon::C2_mux : Hexagon::C2_muxir;
    if (IsReg2)
        return Hexagon::C2_muxri;

    // Neither is a register. The first source is extendable, but the second
    // is not (s8).
    if (Src2.isImm() && isInt<8>(Src2.getImm()))
        return Hexagon::C2_muxii;

    return 0;
}
コード例 #4
0
/// Get the opcode for a conditional transfer of the value in SO (source
/// operand). The condition (true/false) is given in Cond.
unsigned HexagonExpandCondsets::getCondTfrOpcode(const MachineOperand &SO,
      bool Cond) {
  using namespace Hexagon;
  if (SO.isReg()) {
    unsigned PhysR;
    RegisterRef RS = SO;
    if (TargetRegisterInfo::isVirtualRegister(RS.Reg)) {
      const TargetRegisterClass *VC = MRI->getRegClass(RS.Reg);
      assert(VC->begin() != VC->end() && "Empty register class");
      PhysR = *VC->begin();
    } else {
      assert(TargetRegisterInfo::isPhysicalRegister(RS.Reg));
      PhysR = RS.Reg;
    }
    unsigned PhysS = (RS.Sub == 0) ? PhysR : TRI->getSubReg(PhysR, RS.Sub);
    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(PhysS);
    switch (RC->getSize()) {
      case 4:
        return Cond ? A2_tfrt : A2_tfrf;
      case 8:
        return Cond ? A2_tfrpt : A2_tfrpf;
    }
    llvm_unreachable("Invalid register operand");
  }
  if (SO.isImm() || SO.isFPImm())
    return Cond ? C2_cmoveit : C2_cmoveif;
  llvm_unreachable("Unexpected source operand");
}
コード例 #5
0
ファイル: MipsCodeEmitter.cpp プロジェクト: CartBlanche/llvm
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                            const MachineOperand &MO) const {
  if (MO.isReg())
    return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
  else if (MO.isImm())
    return static_cast<unsigned>(MO.getImm());
  else if (MO.isGlobal()) {
    if (MI.getOpcode() == Mips::ULW || MI.getOpcode() == Mips::USW ||
          MI.getOpcode() == Mips::ULH || MI.getOpcode() == Mips::ULHu)
      emitGlobalAddressUnaligned(MO.getGlobal(), getRelocation(MI, MO), 4);
    else if (MI.getOpcode() == Mips::USH)
      emitGlobalAddressUnaligned(MO.getGlobal(), getRelocation(MI, MO), 8);
    else
      emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
  } else if (MO.isSymbol())
    emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
  else if (MO.isCPI())
    emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
  else if (MO.isJTI())
    emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO));
  else if (MO.isMBB())
    emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
  else
    llvm_unreachable("Unable to encode MachineOperand!");
  return 0;
}
コード例 #6
0
MachineOperand
AMDGPUInstructionSelector::getSubOperand64(MachineOperand &MO,
                                           unsigned SubIdx) const {

  MachineInstr *MI = MO.getParent();
  MachineBasicBlock *BB = MO.getParent()->getParent();
  MachineFunction *MF = BB->getParent();
  MachineRegisterInfo &MRI = MF->getRegInfo();
  unsigned DstReg = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);

  if (MO.isReg()) {
    unsigned ComposedSubIdx = TRI.composeSubRegIndices(MO.getSubReg(), SubIdx);
    unsigned Reg = MO.getReg();
    BuildMI(*BB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), DstReg)
            .addReg(Reg, 0, ComposedSubIdx);

    return MachineOperand::CreateReg(DstReg, MO.isDef(), MO.isImplicit(),
                                     MO.isKill(), MO.isDead(), MO.isUndef(),
                                     MO.isEarlyClobber(), 0, MO.isDebug(),
                                     MO.isInternalRead());
  }

  assert(MO.isImm());

  APInt Imm(64, MO.getImm());

  switch (SubIdx) {
  default:
    llvm_unreachable("do not know to split immediate with this sub index.");
  case AMDGPU::sub0:
    return MachineOperand::CreateImm(Imm.getLoBits(32).getSExtValue());
  case AMDGPU::sub1:
    return MachineOperand::CreateImm(Imm.getHiBits(32).getSExtValue());
  }
}
コード例 #7
0
ファイル: ARMCodeEmitter.cpp プロジェクト: albertz/llvm
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                           const MachineOperand &MO) {
  if (MO.isReg())
    return ARMRegisterInfo::getRegisterNumbering(MO.getReg());
  else if (MO.isImm())
    return static_cast<unsigned>(MO.getImm());
  else if (MO.isGlobal())
    emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true, false);
  else if (MO.isSymbol())
    emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_branch);
  else if (MO.isCPI()) {
    const TargetInstrDesc &TID = MI.getDesc();
    // For VFP load, the immediate offset is multiplied by 4.
    unsigned Reloc =  ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPLdStFrm)
      ? ARM::reloc_arm_vfp_cp_entry : ARM::reloc_arm_cp_entry;
    emitConstPoolAddress(MO.getIndex(), Reloc);
  } else if (MO.isJTI())
    emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative);
  else if (MO.isMBB())
    emitMachineBasicBlock(MO.getMBB(), ARM::reloc_arm_branch);
  else {
#ifndef NDEBUG
    errs() << MO;
#endif
    llvm_unreachable(0);
  }
  return 0;
}
コード例 #8
0
void MachineRegisterInfo::verifyUseList(unsigned Reg) const {
#ifndef NDEBUG
  bool Valid = true;
  for (reg_iterator I = reg_begin(Reg), E = reg_end(); I != E; ++I) {
    MachineOperand *MO = &I.getOperand();
    MachineInstr *MI = MO->getParent();
    if (!MI) {
      errs() << PrintReg(Reg, TRI) << " use list MachineOperand " << MO
             << " has no parent instruction.\n";
      Valid = false;
    }
    MachineOperand *MO0 = &MI->getOperand(0);
    unsigned NumOps = MI->getNumOperands();
    if (!(MO >= MO0 && MO < MO0+NumOps)) {
      errs() << PrintReg(Reg, TRI) << " use list MachineOperand " << MO
             << " doesn't belong to parent MI: " << *MI;
      Valid = false;
    }
    if (!MO->isReg()) {
      errs() << PrintReg(Reg, TRI) << " MachineOperand " << MO << ": " << *MO
             << " is not a register\n";
      Valid = false;
    }
    if (MO->getReg() != Reg) {
      errs() << PrintReg(Reg, TRI) << " use-list MachineOperand " << MO << ": "
             << *MO << " is the wrong register\n";
      Valid = false;
    }
  }
  assert(Valid && "Invalid use list");
#endif
}
コード例 #9
0
void AArch64A57FPLoadBalancing::
maybeKillChain(MachineOperand &MO, unsigned Idx,
               std::map<unsigned, Chain*> &ActiveChains) {
  // Given an operand and the set of active chains (keyed by register),
  // determine if a chain should be ended and remove from ActiveChains.
  MachineInstr *MI = MO.getParent();

  if (MO.isReg()) {

    // If this is a KILL of a current chain, record it.
    if (MO.isKill() && ActiveChains.find(MO.getReg()) != ActiveChains.end()) {
      DEBUG(dbgs() << "Kill seen for chain " << TRI->getName(MO.getReg())
            << "\n");
      ActiveChains[MO.getReg()]->setKill(MI, Idx, /*Immutable=*/MO.isTied());
    }
    ActiveChains.erase(MO.getReg());

  } else if (MO.isRegMask()) {

    for (auto I = ActiveChains.begin(), E = ActiveChains.end();
         I != E;) {
      if (MO.clobbersPhysReg(I->first)) {
        DEBUG(dbgs() << "Kill (regmask) seen for chain "
              << TRI->getName(I->first) << "\n");
        I->second->setKill(MI, Idx, /*Immutable=*/true);
        ActiveChains.erase(I++);
      } else
        ++I;
    }

  }
}
コード例 #10
0
/// Implements the 'w' and 'x' inline asm operand modifiers, which print a GPR
/// with the obvious type and an immediate 0 as either wzr or xzr.
static bool printModifiedGPRAsmOperand(const MachineOperand &MO,
                                       const TargetRegisterInfo *TRI,
                                       const TargetRegisterClass &RegClass,
                                       raw_ostream &O) {
  char Prefix = &RegClass == &AArch64::GPR32RegClass ? 'w' : 'x';

  if (MO.isImm() && MO.getImm() == 0) {
    O << Prefix << "zr";
    return false;
  } else if (MO.isReg()) {
    if (MO.getReg() == AArch64::XSP || MO.getReg() == AArch64::WSP) {
      O << (Prefix == 'x' ? "sp" : "wsp");
      return false;
    }

    for (MCRegAliasIterator AR(MO.getReg(), TRI, true); AR.isValid(); ++AR) {
      if (RegClass.contains(*AR)) {
        O << AArch64InstPrinter::getRegisterName(*AR);
        return false;
      }
    }
  }

  return true;
}
コード例 #11
0
bool SIInsertWaits::isOpRelevant(MachineOperand &Op) {

  // Constants are always irrelevant
  if (!Op.isReg())
    return false;

  // Defines are always relevant
  if (Op.isDef())
    return true;

  // For exports all registers are relevant
  MachineInstr &MI = *Op.getParent();
  if (MI.getOpcode() == AMDGPU::EXP)
    return true;

  // For stores the stored value is also relevant
  if (!MI.getDesc().mayStore())
    return false;

  for (MachineInstr::mop_iterator I = MI.operands_begin(),
       E = MI.operands_end(); I != E; ++I) {

    if (I->isReg() && I->isUse())
      return Op.isIdenticalTo(*I);
  }

  return false;
}
コード例 #12
0
bool InstructionSelector::isOperandImmEqual(
    const MachineOperand &MO, int64_t Value,
    const MachineRegisterInfo &MRI) const {
  if (MO.isReg() && MO.getReg())
    if (auto VRegVal = getConstantVRegVal(MO.getReg(), MRI))
      return *VRegVal == Value;
  return false;
}
コード例 #13
0
ファイル: HexagonSplitDouble.cpp プロジェクト: CAFxX/llvm-1
static inline uint32_t getRegState(const MachineOperand &R) {
  assert(R.isReg());
  return getDefRegState(R.isDef()) |
         getImplRegState(R.isImplicit()) |
         getKillRegState(R.isKill()) |
         getDeadRegState(R.isDead()) |
         getUndefRegState(R.isUndef()) |
         getInternalReadRegState(R.isInternalRead()) |
         (R.isDebug() ? RegState::Debug : 0);
}
コード例 #14
0
ファイル: A15SDOptimizer.cpp プロジェクト: ADonut/LLVM-GPGPU
// Returns true if this is a use of a SPR register.
bool A15SDOptimizer::usesRegClass(MachineOperand &MO,
                                  const TargetRegisterClass *TRC) {
  if (!MO.isReg())
    return false;
  unsigned Reg = MO.getReg();

  if (TargetRegisterInfo::isVirtualRegister(Reg))
    return MRI->getRegClass(Reg)->hasSuperClassEq(TRC);
  else
    return TRC->contains(Reg);
}
コード例 #15
0
ファイル: AArch64AsmPrinter.cpp プロジェクト: anupam128/llvm
// Prints the register in MO using class RC using the offset in the
// new register class. This should not be used for cross class
// printing.
bool AArch64AsmPrinter::printAsmRegInClass(const MachineOperand &MO,
                                           const TargetRegisterClass *RC,
                                           bool isVector, raw_ostream &O) {
  assert(MO.isReg() && "Should only get here with a register!");
  const TargetRegisterInfo *RI = STI->getRegisterInfo();
  unsigned Reg = MO.getReg();
  unsigned RegToPrint = RC->getRegister(RI->getEncodingValue(Reg));
  assert(RI->regsOverlap(RegToPrint, Reg));
  O << AArch64InstPrinter::getRegisterName(
           RegToPrint, isVector ? AArch64::vreg : AArch64::NoRegAltName);
  return false;
}
コード例 #16
0
ファイル: GCNRegPressure.cpp プロジェクト: dongjinxian/llvm
static LaneBitmask getDefRegMask(const MachineOperand &MO,
                                 const MachineRegisterInfo &MRI) {
  assert(MO.isDef() && MO.isReg() &&
    TargetRegisterInfo::isVirtualRegister(MO.getReg()));

  // We don't rely on read-undef flag because in case of tentative schedule
  // tracking it isn't set correctly yet. This works correctly however since
  // use mask has been tracked before using LIS.
  return MO.getSubReg() == 0 ?
    MRI.getMaxLaneMaskForVReg(MO.getReg()) :
    MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
}
コード例 #17
0
ファイル: RegisterPressure.cpp プロジェクト: xatier/llvm
 /// Push this operand's register onto the correct vector.
 void collect(const MachineOperand &MO) {
   if (!MO.isReg() || !MO.getReg())
     return;
   if (MO.readsReg())
     pushRegUnits(MO.getReg(), Uses);
   if (MO.isDef()) {
     if (MO.isDead())
       pushRegUnits(MO.getReg(), DeadDefs);
     else
       pushRegUnits(MO.getReg(), Defs);
   }
 }
コード例 #18
0
bool NVPTXInstrInfo::isMoveInstr(const MachineInstr &MI, unsigned &SrcReg,
                                 unsigned &DestReg) const {
  // Look for the appropriate part of TSFlags
  bool isMove = false;

  unsigned TSFlags =
      (MI.getDesc().TSFlags & NVPTX::SimpleMoveMask) >> NVPTX::SimpleMoveShift;
  isMove = (TSFlags == 1);

  if (isMove) {
    MachineOperand dest = MI.getOperand(0);
    MachineOperand src = MI.getOperand(1);
    assert(dest.isReg() && "dest of a movrr is not a reg");
    assert(src.isReg() && "src of a movrr is not a reg");

    SrcReg = src.getReg();
    DestReg = dest.getReg();
    return true;
  }

  return false;
}
コード例 #19
0
bool SIInsertWaits::isOpRelevant(MachineOperand &Op) {

    // Constants are always irrelevant
    if (!Op.isReg())
        return false;

    // Defines are always relevant
    if (Op.isDef())
        return true;

    // For exports all registers are relevant
    MachineInstr &MI = *Op.getParent();
    if (MI.getOpcode() == AMDGPU::EXP)
        return true;

    // For stores the stored value is also relevant
    if (!MI.getDesc().mayStore())
        return false;

    // Check if this operand is the value being stored.
    // Special case for DS instructions, since the address
    // operand comes before the value operand and it may have
    // multiple data operands.

    if (TII->isDS(MI.getOpcode())) {
        MachineOperand *Data = TII->getNamedOperand(MI, AMDGPU::OpName::data);
        if (Data && Op.isIdenticalTo(*Data))
            return true;

        MachineOperand *Data0 = TII->getNamedOperand(MI, AMDGPU::OpName::data0);
        if (Data0 && Op.isIdenticalTo(*Data0))
            return true;

        MachineOperand *Data1 = TII->getNamedOperand(MI, AMDGPU::OpName::data1);
        if (Data1 && Op.isIdenticalTo(*Data1))
            return true;

        return false;
    }

    // NOTE: This assumes that the value operand is before the
    // address operand, and that there is only one value operand.
    for (MachineInstr::mop_iterator I = MI.operands_begin(),
            E = MI.operands_end(); I != E; ++I) {

        if (I->isReg() && I->isUse())
            return Op.isIdenticalTo(*I);
    }

    return false;
}
コード例 #20
0
// Helper function for getting a MachineOperand's register number and adding it
// to RegDefs or RegUses.
static void insertDefUse(const MachineOperand &MO,
                         SmallSet<unsigned, 32> &RegDefs,
                         SmallSet<unsigned, 32> &RegUses,
                         unsigned ExcludedReg = 0) {
  unsigned Reg;

  if (!MO.isReg() || !(Reg = MO.getReg()) || (Reg == ExcludedReg))
    return;

  if (MO.isDef())
    RegDefs.insert(Reg);
  else if (MO.isUse())
    RegUses.insert(Reg);
}
コード例 #21
0
/// Try to print a floating-point register as if it belonged to a specified
/// register-class. For example the inline asm operand modifier "b" requires its
/// argument to be printed as "bN".
static bool printModifiedFPRAsmOperand(const MachineOperand &MO,
                                       const TargetRegisterInfo *TRI,
                                       const TargetRegisterClass &RegClass,
                                       raw_ostream &O) {
  if (!MO.isReg())
    return true;

  for (MCRegAliasIterator AR(MO.getReg(), TRI, true); AR.isValid(); ++AR) {
    if (RegClass.contains(*AR)) {
      O << AArch64InstPrinter::getRegisterName(*AR);
      return false;
    }
  }
  return true;
}
コード例 #22
0
bool InstructionSelector::isBaseWithConstantOffset(
    const MachineOperand &Root, const MachineRegisterInfo &MRI) const {
  if (!Root.isReg())
    return false;

  MachineInstr *RootI = MRI.getVRegDef(Root.getReg());
  if (RootI->getOpcode() != TargetOpcode::G_GEP)
    return false;

  MachineOperand &RHS = RootI->getOperand(2);
  MachineInstr *RHSI = MRI.getVRegDef(RHS.getReg());
  if (RHSI->getOpcode() != TargetOpcode::G_CONSTANT)
    return false;

  return true;
}
コード例 #23
0
ファイル: BitLevelInfo.cpp プロジェクト: b14ckkn19ht/Shang
void BitLevelInfo::propagateBitWidth(MachineOperand &MO) {
  assert(MO.isReg() && "Wrong operand type!");

  unsigned RegNo = MO.getReg();
  unsigned char BitWidth = VInstrInfo::getBitWidth(MO);
  assert(BitWidth && "Bit width not available!");

  for (MachineRegisterInfo::use_iterator I = MRI->use_begin(RegNo),
       E = MRI->use_end(); I != E; ++I) {
    MachineOperand &MO = I.getOperand();

    // Propagate bit width information through the def-use chain.
    if (updateBitWidth(MO, BitWidth) && (I->isCopy() || I->isPHI()))
      computeBitWidth(&*I);
  }
}
コード例 #24
0
unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                           const MachineOperand &MO) const {

  if (MO.isReg()) {
    // MTCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
    // The GPR operand should come through here though.
    assert((MI.getOpcode() != PPC::MTCRF && MI.getOpcode() != PPC::MTCRF8 &&
             MI.getOpcode() != PPC::MFOCRF) ||
           MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
    return TM.getRegisterInfo()->getEncodingValue(MO.getReg());
  }
  
  assert(MO.isImm() &&
         "Relocation required in an instruction that we cannot encode!");
  return MO.getImm();
}
コード例 #25
0
ファイル: AArch64AsmPrinter.cpp プロジェクト: ujhpc/llvm
/// Try to print a floating-point register as if it belonged to a specified
/// register-class. For example the inline asm operand modifier "b" requires its
/// argument to be printed as "bN".
static bool printModifiedFPRAsmOperand(const MachineOperand &MO,
                                       const TargetRegisterInfo *TRI,
                                       char RegType, raw_ostream &O) {
    if (!MO.isReg())
        return true;

    for (MCRegAliasIterator AR(MO.getReg(), TRI, true); AR.isValid(); ++AR) {
        if (AArch64::FPR8RegClass.contains(*AR)) {
            O << RegType << TRI->getEncodingValue(MO.getReg());
            return false;
        }
    }

    // The register doesn't correspond to anything floating-point like.
    return true;
}
コード例 #26
0
unsigned CoffeeCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                           const MachineOperand &MO) const {

  if (MO.isReg()) {
    // MTCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
    // The GPR operand should come through here though.
    /*assert((MI.getOpcode() != Coffee::MTCRF && MI.getOpcode() != Coffee::MTCRF8 &&
             MI.getOpcode() != Coffee::MFOCRF) ||
           MO.getReg() < Coffee::CR0 || MO.getReg() > Coffee::CR7);*/
    return getCoffeeRegisterNumbering(MO.getReg());
  }
  
  assert(MO.isImm() &&
         "Relocation required in an instruction that we cannot encode!");
  return MO.getImm();
}
コード例 #27
0
RegInterval SIInsertWaits::getRegInterval(MachineOperand &Op) {

  if (!Op.isReg())
    return std::make_pair(0, 0);

  unsigned Reg = Op.getReg();
  unsigned Size = TRI.getMinimalPhysRegClass(Reg)->getSize();

  assert(Size >= 4);

  RegInterval Result;
  Result.first = TRI.getEncodingValue(Reg);
  Result.second = Result.first + Size / 4;

  return Result;
}
コード例 #28
0
ファイル: GCNRegPressure.cpp プロジェクト: dongjinxian/llvm
static LaneBitmask getUsedRegMask(const MachineOperand &MO,
                                  const MachineRegisterInfo &MRI,
                                  const LiveIntervals &LIS) {
  assert(MO.isUse() && MO.isReg() &&
         TargetRegisterInfo::isVirtualRegister(MO.getReg()));

  if (auto SubReg = MO.getSubReg())
    return MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(SubReg);

  auto MaxMask = MRI.getMaxLaneMaskForVReg(MO.getReg());
  if (MaxMask == LaneBitmask::getLane(0)) // cannot have subregs
    return MaxMask;

  // For a tentative schedule LIS isn't updated yet but livemask should remain
  // the same on any schedule. Subreg defs can be reordered but they all must
  // dominate uses anyway.
  auto SI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex();
  return getLiveLaneMask(MO.getReg(), SI, LIS, MRI);
}
コード例 #29
0
ファイル: MipsCodeEmitter.cpp プロジェクト: agheorghiu/root
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                            const MachineOperand &MO) const {
  if (MO.isReg())
    return TM.getRegisterInfo()->getEncodingValue(MO.getReg());
  else if (MO.isImm())
    return static_cast<unsigned>(MO.getImm());
  else if (MO.isGlobal())
    emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
  else if (MO.isSymbol())
    emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
  else if (MO.isCPI())
    emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
  else if (MO.isJTI())
    emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO));
  else if (MO.isMBB())
    emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
  else
    llvm_unreachable("Unable to encode MachineOperand!");
  return 0;
}
コード例 #30
0
ファイル: HexagonOptAddrMode.cpp プロジェクト: CSI-LLVM/llvm
bool HexagonOptAddrMode::hasRepForm(MachineInstr *MI, unsigned TfrDefR) {
  const MCInstrDesc &MID = MI->getDesc();

  if ((!MID.mayStore() && !MID.mayLoad()) || HII->isPredicated(*MI))
    return false;

  if (MID.mayStore()) {
    MachineOperand StOp = MI->getOperand(MI->getNumOperands() - 1);
    if (StOp.isReg() && StOp.getReg() == TfrDefR)
      return false;
  }

  if (HII->getAddrMode(MI) == HexagonII::BaseRegOffset)
    // Tranform to Absolute plus register offset.
    return (HII->getBaseWithLongOffset(MI) >= 0);
  else if (HII->getAddrMode(MI) == HexagonII::BaseImmOffset)
    // Tranform to absolute addressing mode.
    return (HII->getAbsoluteForm(MI) >= 0);

  return false;
}