diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 | 
| commit | b915e9e0fc85ba6f398b3fab0db6a81a8913af94 (patch) | |
| tree | 98b8f811c7aff2547cab8642daf372d6c59502fb /lib/CodeGen/MachineInstr.cpp | |
| parent | 6421cca32f69ac849537a3cff78c352195e99f1b (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/MachineInstr.cpp')
| -rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 190 | 
1 files changed, 109 insertions, 81 deletions
| diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 3cdf8d2941d3f..d2ce001103df4 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -26,6 +26,7 @@  #include "llvm/IR/DebugInfo.h"  #include "llvm/IR/Function.h"  #include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Intrinsics.h"  #include "llvm/IR/LLVMContext.h"  #include "llvm/IR/Metadata.h"  #include "llvm/IR/Module.h" @@ -40,6 +41,7 @@  #include "llvm/Support/MathExtras.h"  #include "llvm/Support/raw_ostream.h"  #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetIntrinsicInfo.h"  #include "llvm/Target/TargetMachine.h"  #include "llvm/Target/TargetRegisterInfo.h"  #include "llvm/Target/TargetSubtargetInfo.h" @@ -91,6 +93,8 @@ void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) {      // Note that getSubReg() may return 0 if the sub-register doesn't exist.      // That won't happen in legal code.      setSubReg(0); +    if (isDef()) +      setIsUndef(false);    }    setReg(Reg);  } @@ -171,6 +175,16 @@ void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) {    Contents.Sym = Sym;  } +void MachineOperand::ChangeToFrameIndex(int Idx) { +  assert((!isReg() || !isTied()) && +         "Cannot change a tied operand into a FrameIndex"); + +  removeRegFromUses(); + +  OpKind = MO_FrameIndex; +  setIndex(Idx); +} +  /// ChangeToRegister - Replace this operand with a new register operand of  /// the specified value.  If an operand is known to be an register already,  /// the setReg method should be used. @@ -256,6 +270,10 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {      return getCFIIndex() == Other.getCFIIndex();    case MachineOperand::MO_Metadata:      return getMetadata() == Other.getMetadata(); +  case MachineOperand::MO_IntrinsicID: +    return getIntrinsicID() == Other.getIntrinsicID(); +  case MachineOperand::MO_Predicate: +    return getPredicate() == Other.getPredicate();    }    llvm_unreachable("Invalid machine operand type");  } @@ -300,18 +318,23 @@ hash_code llvm::hash_value(const MachineOperand &MO) {      return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol());    case MachineOperand::MO_CFIIndex:      return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); +  case MachineOperand::MO_IntrinsicID: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); +  case MachineOperand::MO_Predicate: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate());    }    llvm_unreachable("Invalid machine operand type");  } -void MachineOperand::print(raw_ostream &OS, -                           const TargetRegisterInfo *TRI) const { +void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, +                           const TargetIntrinsicInfo *IntrinsicInfo) const {    ModuleSlotTracker DummyMST(nullptr); -  print(OS, DummyMST, TRI); +  print(OS, DummyMST, TRI, IntrinsicInfo);  }  void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, -                           const TargetRegisterInfo *TRI) const { +                           const TargetRegisterInfo *TRI, +                           const TargetIntrinsicInfo *IntrinsicInfo) const {    switch (getType()) {    case MachineOperand::MO_Register:      OS << PrintReg(getReg(), TRI, getSubReg()); @@ -378,7 +401,7 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,      } else if (getFPImm()->getType()->isHalfTy()) {        APFloat APF = getFPImm()->getValueAPF();        bool Unused; -      APF.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &Unused); +      APF.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &Unused);        OS << "half " << APF.convertToFloat();      } else {        OS << getFPImm()->getValueAPF().convertToDouble(); @@ -454,12 +477,32 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,    case MachineOperand::MO_CFIIndex:      OS << "<call frame instruction>";      break; +  case MachineOperand::MO_IntrinsicID: { +    Intrinsic::ID ID = getIntrinsicID(); +    if (ID < Intrinsic::num_intrinsics) +      OS << "<intrinsic:@" << Intrinsic::getName(ID, None) << '>'; +    else if (IntrinsicInfo) +      OS << "<intrinsic:@" << IntrinsicInfo->getName(ID) << '>'; +    else +      OS << "<intrinsic:" << ID << '>'; +    break; +  } +  case MachineOperand::MO_Predicate: { +    auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); +    OS << '<' << (CmpInst::isIntPredicate(Pred) ? "intpred" : "floatpred") +       << CmpInst::getPredicateName(Pred) << '>'; +  }    } -    if (unsigned TF = getTargetFlags())      OS << "[TF=" << TF << ']';  } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +LLVM_DUMP_METHOD void MachineOperand::dump() const { +  dbgs() << *this << '\n'; +} +#endif +  //===----------------------------------------------------------------------===//  // MachineMemOperand Implementation  //===----------------------------------------------------------------------===// @@ -500,7 +543,10 @@ MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF,  MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,                                       uint64_t s, unsigned int a,                                       const AAMDNodes &AAInfo, -                                     const MDNode *Ranges) +                                     const MDNode *Ranges, +                                     SynchronizationScope SynchScope, +                                     AtomicOrdering Ordering, +                                     AtomicOrdering FailureOrdering)      : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1),        AAInfo(AAInfo), Ranges(Ranges) {    assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue*>() || @@ -508,6 +554,13 @@ MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,           "invalid pointer value");    assert(getBaseAlignment() == a && "Alignment is not a power of 2!");    assert((isLoad() || isStore()) && "Not a load/store!"); + +  AtomicInfo.SynchScope = static_cast<unsigned>(SynchScope); +  assert(getSynchScope() == SynchScope && "Value truncated"); +  AtomicInfo.Ordering = static_cast<unsigned>(Ordering); +  assert(getOrdering() == Ordering && "Value truncated"); +  AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering); +  assert(getFailureOrdering() == FailureOrdering && "Value truncated");  }  /// Profile - Gather unique data for the object. @@ -623,10 +676,10 @@ void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const {      OS << ")";    } -  // Print nontemporal info.    if (isNonTemporal())      OS << "(nontemporal)"; - +  if (isDereferenceable()) +    OS << "(dereferenceable)";    if (isInvariant())      OS << "(invariant)";  } @@ -653,12 +706,7 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,                             DebugLoc dl, bool NoImp)      : MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), Flags(0),        AsmPrinterFlags(0), NumMemRefs(0), MemRefs(nullptr), -      debugLoc(std::move(dl)) -#ifdef LLVM_BUILD_GLOBAL_ISEL -      , -      Ty(nullptr) -#endif -{ +      debugLoc(std::move(dl)) {    assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");    // Reserve space for the expected number of operands. @@ -677,12 +725,7 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,  MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)      : MCID(&MI.getDesc()), Parent(nullptr), Operands(nullptr), NumOperands(0),        Flags(0), AsmPrinterFlags(0), NumMemRefs(MI.NumMemRefs), -      MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc()) -#ifdef LLVM_BUILD_GLOBAL_ISEL -      , -      Ty(nullptr) -#endif -{ +      MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc()) {    assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");    CapOperands = OperandCapacity::get(MI.getNumOperands()); @@ -705,25 +748,6 @@ MachineRegisterInfo *MachineInstr::getRegInfo() {    return nullptr;  } -// Implement dummy setter and getter for type when -// global-isel is not built. -// The proper implementation is WIP and is tracked here: -// PR26576. -#ifndef LLVM_BUILD_GLOBAL_ISEL -void MachineInstr::setType(Type *Ty) {} - -Type *MachineInstr::getType() const { return nullptr; } - -#else -void MachineInstr::setType(Type *Ty) { -  assert((!Ty || isPreISelGenericOpcode(getOpcode())) && -         "Non generic instructions are not supposed to be typed"); -  this->Ty = Ty; -} - -Type *MachineInstr::getType() const { return Ty; } -#endif // LLVM_BUILD_GLOBAL_ISEL -  /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in  /// this instruction from their respective use lists.  This requires that the  /// operands already be on their use lists. @@ -976,16 +1000,24 @@ bool MachineInstr::isIdenticalTo(const MachineInstr &Other,      return false;    if (isBundle()) { -    // Both instructions are bundles, compare MIs inside the bundle. +    // We have passed the test above that both instructions have the same +    // opcode, so we know that both instructions are bundles here. Let's compare +    // MIs inside the bundle. +    assert(Other.isBundle() && "Expected that both instructions are bundles.");      MachineBasicBlock::const_instr_iterator I1 = getIterator(); -    MachineBasicBlock::const_instr_iterator E1 = getParent()->instr_end();      MachineBasicBlock::const_instr_iterator I2 = Other.getIterator(); -    MachineBasicBlock::const_instr_iterator E2 = Other.getParent()->instr_end(); -    while (++I1 != E1 && I1->isInsideBundle()) { +    // Loop until we analysed the last intruction inside at least one of the +    // bundles. +    while (I1->isBundledWithSucc() && I2->isBundledWithSucc()) { +      ++I1;        ++I2; -      if (I2 == E2 || !I2->isInsideBundle() || !I1->isIdenticalTo(*I2, Check)) +      if (!I1->isIdenticalTo(*I2, Check))          return false;      } +    // If we've reached the end of just one of the two bundles, but not both, +    // the instructions are not identical. +    if (I1->isBundledWithSucc() || I2->isBundledWithSucc()) +      return false;    }    // Check operands to make sure they match. @@ -1287,8 +1319,8 @@ bool MachineInstr::hasRegisterImplicitUseOperand(unsigned Reg) const {  /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of  /// the specific register or -1 if it is not found. It further tightens  /// the search criteria to a use that kills the register if isKill is true. -int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill, -                                          const TargetRegisterInfo *TRI) const { +int MachineInstr::findRegisterUseOperandIdx( +    unsigned Reg, bool isKill, const TargetRegisterInfo *TRI) const {    for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {      const MachineOperand &MO = getOperand(i);      if (!MO.isReg() || !MO.isUse()) @@ -1296,11 +1328,9 @@ int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill,      unsigned MOReg = MO.getReg();      if (!MOReg)        continue; -    if (MOReg == Reg || -        (TRI && -         TargetRegisterInfo::isPhysicalRegister(MOReg) && -         TargetRegisterInfo::isPhysicalRegister(Reg) && -         TRI->isSubRegister(MOReg, Reg))) +    if (MOReg == Reg || (TRI && TargetRegisterInfo::isPhysicalRegister(MOReg) && +                         TargetRegisterInfo::isPhysicalRegister(Reg) && +                         TRI->isSubRegister(MOReg, Reg)))        if (!isKill || MO.isKill())          return i;    } @@ -1533,7 +1563,7 @@ bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const {    // destination. The check for isInvariantLoad gives the targe the chance to    // classify the load as always returning a constant, e.g. a constant pool    // load. -  if (mayLoad() && !isInvariantLoad(AA)) +  if (mayLoad() && !isDereferenceableInvariantLoad(AA))      // Otherwise, this is a real load.  If there is a store between the load and      // end of block, we can't move it.      return !SawStore; @@ -1564,12 +1594,10 @@ bool MachineInstr::hasOrderedMemoryRef() const {    });  } -/// isInvariantLoad - Return true if this instruction is loading from a -/// location whose value is invariant across the function.  For example, -/// loading a value from the constant pool or from the argument area -/// of a function if it does not change.  This should only return true of -/// *all* loads the instruction does are invariant (if it does multiple loads). -bool MachineInstr::isInvariantLoad(AliasAnalysis *AA) const { +/// isDereferenceableInvariantLoad - Return true if this instruction will never +/// trap and is loading from a location whose value is invariant across a run of +/// this function. +bool MachineInstr::isDereferenceableInvariantLoad(AliasAnalysis *AA) const {    // If the instruction doesn't load at all, it isn't an invariant load.    if (!mayLoad())      return false; @@ -1579,16 +1607,17 @@ bool MachineInstr::isInvariantLoad(AliasAnalysis *AA) const {    if (memoperands_empty())      return false; -  const MachineFrameInfo *MFI = getParent()->getParent()->getFrameInfo(); +  const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo();    for (MachineMemOperand *MMO : memoperands()) {      if (MMO->isVolatile()) return false;      if (MMO->isStore()) return false; -    if (MMO->isInvariant()) continue; +    if (MMO->isInvariant() && MMO->isDereferenceable()) +      continue;      // A load from a constant PseudoSourceValue is invariant.      if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) -      if (PSV->isConstant(MFI)) +      if (PSV->isConstant(&MFI))          continue;      if (const Value *V = MMO->getValue()) { @@ -1663,35 +1692,40 @@ void MachineInstr::copyImplicitOps(MachineFunction &MF,    }  } -LLVM_DUMP_METHOD void MachineInstr::dump() const { +LLVM_DUMP_METHOD void MachineInstr::dump(const TargetInstrInfo *TII) const {  #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -  dbgs() << "  " << *this; +  dbgs() << "  "; +  print(dbgs(), false /* SkipOpers */, TII);  #endif  } -void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const { +void MachineInstr::print(raw_ostream &OS, bool SkipOpers, +                         const TargetInstrInfo *TII) const {    const Module *M = nullptr;    if (const MachineBasicBlock *MBB = getParent())      if (const MachineFunction *MF = MBB->getParent())        M = MF->getFunction()->getParent();    ModuleSlotTracker MST(M); -  print(OS, MST, SkipOpers); +  print(OS, MST, SkipOpers, TII);  }  void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, -                         bool SkipOpers) const { +                         bool SkipOpers, const TargetInstrInfo *TII) const {    // We can be a bit tidier if we know the MachineFunction.    const MachineFunction *MF = nullptr;    const TargetRegisterInfo *TRI = nullptr;    const MachineRegisterInfo *MRI = nullptr; -  const TargetInstrInfo *TII = nullptr; +  const TargetIntrinsicInfo *IntrinsicInfo = nullptr; +    if (const MachineBasicBlock *MBB = getParent()) {      MF = MBB->getParent();      if (MF) {        MRI = &MF->getRegInfo();        TRI = MF->getSubtarget().getRegisterInfo(); -      TII = MF->getSubtarget().getInstrInfo(); +      if (!TII) +        TII = MF->getSubtarget().getInstrInfo(); +      IntrinsicInfo = MF->getTarget().getIntrinsicInfo();      }    } @@ -1705,13 +1739,13 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,           !getOperand(StartOp).isImplicit();         ++StartOp) {      if (StartOp != 0) OS << ", "; -    getOperand(StartOp).print(OS, MST, TRI); +    getOperand(StartOp).print(OS, MST, TRI, IntrinsicInfo);      unsigned Reg = getOperand(StartOp).getReg();      if (TargetRegisterInfo::isVirtualRegister(Reg)) {        VirtRegs.push_back(Reg); -      unsigned Size; -      if (MRI && (Size = MRI->getSize(Reg))) -        OS << '(' << Size << ')'; +      LLT Ty = MRI ? MRI->getType(Reg) : LLT{}; +      if (Ty.isValid()) +        OS << '(' << Ty << ')';      }    } @@ -1724,12 +1758,6 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,    else      OS << "UNKNOWN"; -  if (getType()) { -    OS << ' '; -    getType()->print(OS, /*IsForDebug*/ false, /*NoDetails*/ true); -    OS << ' '; -  } -    if (SkipOpers)      return; @@ -2145,8 +2173,8 @@ void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs,      unsigned Reg = MO.getReg();      if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue;      // If there are no uses, including partial uses, the def is dead. -    if (std::none_of(UsedRegs.begin(), UsedRegs.end(), -                     [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); })) +    if (none_of(UsedRegs, +                [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); }))        MO.setIsDead();    } | 
