diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/MachineInstr.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/MachineInstr.cpp | 193 |
1 files changed, 111 insertions, 82 deletions
diff --git a/contrib/llvm/lib/CodeGen/MachineInstr.cpp b/contrib/llvm/lib/CodeGen/MachineInstr.cpp index 3cdf8d2..2f2e3b3 100644 --- a/contrib/llvm/lib/CodeGen/MachineInstr.cpp +++ b/contrib/llvm/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; @@ -1812,7 +1840,8 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, OS << "!\"" << DIV->getName() << '\"'; else MO.print(OS, MST, TRI); - } else if (TRI && (isInsertSubreg() || isRegSequence()) && MO.isImm()) { + } else if (TRI && (isInsertSubreg() || isRegSequence() || + (isSubregToReg() && i == 3)) && MO.isImm()) { OS << TRI->getSubRegIndexName(MO.getImm()); } else if (i == AsmDescOp && MO.isImm()) { // Pretty print the inline asm operand descriptor. @@ -2145,8 +2174,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(); } |