X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FMachineInstr.cpp;h=6dca74d60026ff2044bb50a497f1a42d99e7c57e;hp=f863bb8197e2e45838fbfb7f6ba770e097be24aa;hb=20a42bb20d43b80e322c95dd99b64a5a4566fe08;hpb=a602c106862be2af0241b20ff5d3449b59264ed0 diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index f863bb8197e..6dca74d6002 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -28,10 +28,12 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" +#include "llvm/IR/ModuleSlotTracker.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" @@ -42,6 +44,11 @@ #include "llvm/Target/TargetSubtargetInfo.h" using namespace llvm; +static cl::opt PrintWholeRegMask( + "print-whole-regmask", + cl::desc("Print the full contents of regmask operands in IR dumps"), + cl::init(true), cl::Hidden); + //===----------------------------------------------------------------------===// // MachineOperand Implementation //===----------------------------------------------------------------------===// @@ -141,6 +148,28 @@ void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) { Contents.CFP = FPImm; } +void MachineOperand::ChangeToES(const char *SymName, unsigned char TargetFlags) { + assert((!isReg() || !isTied()) && + "Cannot change a tied operand into an external symbol"); + + removeRegFromUses(); + + OpKind = MO_ExternalSymbol; + Contents.OffsetedInfo.Val.SymbolName = SymName; + setOffset(0); // Offset is always 0. + setTargetFlags(TargetFlags); +} + +void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) { + assert((!isReg() || !isTied()) && + "Cannot change a tied operand into an MCSymbol"); + + removeRegFromUses(); + + OpKind = MO_MCSymbol; + Contents.Sym = Sym; +} + /// 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. @@ -274,19 +303,14 @@ hash_code llvm::hash_value(const MachineOperand &MO) { llvm_unreachable("Invalid machine operand type"); } -/// print - Print the specified machine operand. -/// -void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { - // If the instruction is embedded into a basic block, we can find the - // target info for the instruction. - if (!TM) - if (const MachineInstr *MI = getParent()) - if (const MachineBasicBlock *MBB = MI->getParent()) - if (const MachineFunction *MF = MBB->getParent()) - TM = &MF->getTarget(); - const TargetRegisterInfo *TRI = - TM ? TM->getSubtargetImpl()->getRegisterInfo() : nullptr; +void MachineOperand::print(raw_ostream &OS, + const TargetRegisterInfo *TRI) const { + ModuleSlotTracker DummyMST(nullptr); + print(OS, DummyMST, TRI); +} +void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, + const TargetRegisterInfo *TRI) const { switch (getType()) { case MachineOperand::MO_Register: OS << PrintReg(getReg(), TRI, getSubReg()); @@ -308,8 +332,8 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { if (isUndef() && getSubReg()) OS << ",read-undef"; } else if (isImplicit()) { - OS << "imp-use"; - NeedComma = true; + OS << "imp-use"; + NeedComma = true; } if (isKill()) { @@ -374,7 +398,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { break; case MachineOperand::MO_GlobalAddress: OS << "printAsOperand(OS, /*PrintType=*/false); + getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); if (getOffset()) OS << "+" << getOffset(); OS << '>'; break; @@ -385,19 +409,36 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { break; case MachineOperand::MO_BlockAddress: OS << '<'; - getBlockAddress()->printAsOperand(OS, /*PrintType=*/false); + getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST); if (getOffset()) OS << "+" << getOffset(); OS << '>'; break; - case MachineOperand::MO_RegisterMask: - OS << ""; + case MachineOperand::MO_RegisterMask: { + unsigned NumRegsInMask = 0; + unsigned NumRegsEmitted = 0; + OS << "getNumRegs(); ++i) { + unsigned MaskWord = i / 32; + unsigned MaskBit = i % 32; + if (getRegMask()[MaskWord] & (1 << MaskBit)) { + if (PrintWholeRegMask || NumRegsEmitted <= 10) { + OS << " " << PrintReg(i, TRI); + NumRegsEmitted++; + } + NumRegsInMask++; + } + } + if (NumRegsEmitted != NumRegsInMask) + OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; + OS << ">"; break; + } case MachineOperand::MO_RegisterLiveOut: OS << ""; break; case MachineOperand::MO_Metadata: OS << '<'; - getMetadata()->printAsOperand(OS); + getMetadata()->printAsOperand(OS, MST); OS << '>'; break; case MachineOperand::MO_MCSymbol: @@ -425,26 +466,28 @@ unsigned MachinePointerInfo::getAddrSpace() const { /// getConstantPool - Return a MachinePointerInfo record that refers to the /// constant pool. -MachinePointerInfo MachinePointerInfo::getConstantPool() { - return MachinePointerInfo(PseudoSourceValue::getConstantPool()); +MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { + return MachinePointerInfo(MF.getPSVManager().getConstantPool()); } /// getFixedStack - Return a MachinePointerInfo record that refers to the /// the specified FrameIndex. -MachinePointerInfo MachinePointerInfo::getFixedStack(int FI, int64_t offset) { - return MachinePointerInfo(PseudoSourceValue::getFixedStack(FI), offset); +MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, + int FI, int64_t Offset) { + return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); } -MachinePointerInfo MachinePointerInfo::getJumpTable() { - return MachinePointerInfo(PseudoSourceValue::getJumpTable()); +MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { + return MachinePointerInfo(MF.getPSVManager().getJumpTable()); } -MachinePointerInfo MachinePointerInfo::getGOT() { - return MachinePointerInfo(PseudoSourceValue::getGOT()); +MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { + return MachinePointerInfo(MF.getPSVManager().getGOT()); } -MachinePointerInfo MachinePointerInfo::getStack(int64_t Offset) { - return MachinePointerInfo(PseudoSourceValue::getStack(), Offset); +MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, + int64_t Offset) { + return MachinePointerInfo(MF.getPSVManager().getStack(), Offset); } MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, unsigned f, @@ -492,63 +535,66 @@ uint64_t MachineMemOperand::getAlignment() const { return MinAlign(getBaseAlignment(), getOffset()); } -raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { - assert((MMO.isLoad() || MMO.isStore()) && +void MachineMemOperand::print(raw_ostream &OS) const { + ModuleSlotTracker DummyMST(nullptr); + print(OS, DummyMST); +} +void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const { + assert((isLoad() || isStore()) && "SV has to be a load, store or both."); - if (MMO.isVolatile()) + if (isVolatile()) OS << "Volatile "; - if (MMO.isLoad()) + if (isLoad()) OS << "LD"; - if (MMO.isStore()) + if (isStore()) OS << "ST"; - OS << MMO.getSize(); + OS << getSize(); // Print the address information. OS << "["; - if (const Value *V = MMO.getValue()) - V->printAsOperand(OS, /*PrintType=*/false); - else if (const PseudoSourceValue *PSV = MMO.getPseudoValue()) + if (const Value *V = getValue()) + V->printAsOperand(OS, /*PrintType=*/false, MST); + else if (const PseudoSourceValue *PSV = getPseudoValue()) PSV->printCustom(OS); else OS << ""; - unsigned AS = MMO.getAddrSpace(); + unsigned AS = getAddrSpace(); if (AS != 0) OS << "(addrspace=" << AS << ')'; // If the alignment of the memory reference itself differs from the alignment // of the base pointer, print the base alignment explicitly, next to the base // pointer. - if (MMO.getBaseAlignment() != MMO.getAlignment()) - OS << "(align=" << MMO.getBaseAlignment() << ")"; + if (getBaseAlignment() != getAlignment()) + OS << "(align=" << getBaseAlignment() << ")"; - if (MMO.getOffset() != 0) - OS << "+" << MMO.getOffset(); + if (getOffset() != 0) + OS << "+" << getOffset(); OS << "]"; // Print the alignment of the reference. - if (MMO.getBaseAlignment() != MMO.getAlignment() || - MMO.getBaseAlignment() != MMO.getSize()) - OS << "(align=" << MMO.getAlignment() << ")"; + if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize()) + OS << "(align=" << getAlignment() << ")"; // Print TBAA info. - if (const MDNode *TBAAInfo = MMO.getAAInfo().TBAA) { + if (const MDNode *TBAAInfo = getAAInfo().TBAA) { OS << "(tbaa="; if (TBAAInfo->getNumOperands() > 0) - TBAAInfo->getOperand(0)->printAsOperand(OS); + TBAAInfo->getOperand(0)->printAsOperand(OS, MST); else OS << ""; OS << ")"; } // Print AA scope info. - if (const MDNode *ScopeInfo = MMO.getAAInfo().Scope) { + if (const MDNode *ScopeInfo = getAAInfo().Scope) { OS << "(alias.scope="; if (ScopeInfo->getNumOperands() > 0) for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { - ScopeInfo->getOperand(i)->printAsOperand(OS); + ScopeInfo->getOperand(i)->printAsOperand(OS, MST); if (i != ie-1) OS << ","; } @@ -558,11 +604,11 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { } // Print AA noalias scope info. - if (const MDNode *NoAliasInfo = MMO.getAAInfo().NoAlias) { + if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) { OS << "(noalias="; if (NoAliasInfo->getNumOperands() > 0) for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { - NoAliasInfo->getOperand(i)->printAsOperand(OS); + NoAliasInfo->getOperand(i)->printAsOperand(OS, MST); if (i != ie-1) OS << ","; } @@ -572,10 +618,11 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { } // Print nontemporal info. - if (MMO.isNonTemporal()) + if (isNonTemporal()) OS << "(nontemporal)"; - return OS; + if (isInvariant()) + OS << "(invariant)"; } //===----------------------------------------------------------------------===// @@ -584,10 +631,12 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { if (MCID->ImplicitDefs) - for (const uint16_t *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; ++ImpDefs) + for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; + ++ImpDefs) addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true)); if (MCID->ImplicitUses) - for (const uint16_t *ImpUses = MCID->getImplicitUses(); *ImpUses; ++ImpUses) + for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses; + ++ImpUses) addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true)); } @@ -595,10 +644,10 @@ void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { /// implicit operands. It reserves space for the number of operands specified by /// the MCInstrDesc. MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid, - const DebugLoc dl, bool NoImp) - : MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), - Flags(0), AsmPrinterFlags(0), - NumMemRefs(0), MemRefs(nullptr), debugLoc(dl) { + DebugLoc dl, bool NoImp) + : MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), Flags(0), + AsmPrinterFlags(0), NumMemRefs(0), MemRefs(nullptr), + debugLoc(std::move(dl)) { assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); // Reserve space for the expected number of operands. @@ -625,8 +674,8 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) Operands = MF.allocateOperandArray(CapOperands); // Copy operands. - for (unsigned i = 0; i != MI.getNumOperands(); ++i) - addOperand(MF, MI.getOperand(i)); + for (const MachineOperand &MO : MI.operands()) + addOperand(MF, MO); // Copy all the sensible flags. setFlags(MI.Flags); @@ -645,18 +694,18 @@ MachineRegisterInfo *MachineInstr::getRegInfo() { /// this instruction from their respective use lists. This requires that the /// operands already be on their use lists. void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (Operands[i].isReg()) - MRI.removeRegOperandFromUseList(&Operands[i]); + for (MachineOperand &MO : operands()) + if (MO.isReg()) + MRI.removeRegOperandFromUseList(&MO); } /// AddRegOperandsToUseLists - Add all of the register operands in /// this instruction from their respective use lists. This requires that the /// operands not be on their use lists yet. void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) - if (Operands[i].isReg()) - MRI.addRegOperandToUseList(&Operands[i]); + for (MachineOperand &MO : operands()) + if (MO.isReg()) + MRI.addRegOperandToUseList(&MO); } void MachineInstr::addOperand(const MachineOperand &Op) { @@ -674,14 +723,8 @@ static void moveOperands(MachineOperand *Dst, MachineOperand *Src, if (MRI) return MRI->moveOperands(Dst, Src, NumOps); - // Here it would be convenient to call memmove, so that isn't allowed because - // MachineOperand has a constructor and so isn't a POD type. - if (Dst < Src) - for (unsigned i = 0; i != NumOps; ++i) - new (Dst + i) MachineOperand(Src[i]); - else - for (unsigned i = NumOps; i ; --i) - new (Dst + i - 1) MachineOperand(Src[i - 1]); + // MachineOperand is a trivially copyable type so we can just use memmove. + std::memmove(Dst, Src, NumOps * sizeof(MachineOperand)); } /// addOperand - Add the specified operand to the instruction. If it is an @@ -823,9 +866,60 @@ void MachineInstr::addMemOperand(MachineFunction &MF, setMemRefs(NewMemRefs, NewMemRefs + NewNum); } +/// Check to see if the MMOs pointed to by the two MemRefs arrays are +/// identical. +static bool hasIdenticalMMOs(const MachineInstr &MI1, const MachineInstr &MI2) { + auto I1 = MI1.memoperands_begin(), E1 = MI1.memoperands_end(); + auto I2 = MI2.memoperands_begin(), E2 = MI2.memoperands_end(); + if ((E1 - I1) != (E2 - I2)) + return false; + for (; I1 != E1; ++I1, ++I2) { + if (**I1 != **I2) + return false; + } + return true; +} + +std::pair +MachineInstr::mergeMemRefsWith(const MachineInstr& Other) { + + // If either of the incoming memrefs are empty, we must be conservative and + // treat this as if we've exhausted our space for memrefs and dropped them. + if (memoperands_empty() || Other.memoperands_empty()) + return std::make_pair(nullptr, 0); + + // If both instructions have identical memrefs, we don't need to merge them. + // Since many instructions have a single memref, and we tend to merge things + // like pairs of loads from the same location, this catches a large number of + // cases in practice. + if (hasIdenticalMMOs(*this, Other)) + return std::make_pair(MemRefs, NumMemRefs); + + // TODO: consider uniquing elements within the operand lists to reduce + // space usage and fall back to conservative information less often. + size_t CombinedNumMemRefs = NumMemRefs + Other.NumMemRefs; + + // If we don't have enough room to store this many memrefs, be conservative + // and drop them. Otherwise, we'd fail asserts when trying to add them to + // the new instruction. + if (CombinedNumMemRefs != uint8_t(CombinedNumMemRefs)) + return std::make_pair(nullptr, 0); + + MachineFunction *MF = getParent()->getParent(); + mmo_iterator MemBegin = MF->allocateMemRefsArray(CombinedNumMemRefs); + mmo_iterator MemEnd = std::copy(memoperands_begin(), memoperands_end(), + MemBegin); + MemEnd = std::copy(Other.memoperands_begin(), Other.memoperands_end(), + MemEnd); + assert(MemEnd - MemBegin == (ptrdiff_t)CombinedNumMemRefs && + "missing memrefs"); + + return std::make_pair(MemBegin, CombinedNumMemRefs); +} + bool MachineInstr::hasPropertyInBundle(unsigned Mask, QueryType Type) const { assert(!isBundledWithPred() && "Must be called on bundle header"); - for (MachineBasicBlock::const_instr_iterator MII = this;; ++MII) { + for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) { if (MII->getDesc().getFlags() & Mask) { if (Type == AnyInBundle) return true; @@ -849,13 +943,13 @@ bool MachineInstr::isIdenticalTo(const MachineInstr *Other, if (isBundle()) { // Both instructions are bundles, compare MIs inside the bundle. - MachineBasicBlock::const_instr_iterator I1 = *this; + MachineBasicBlock::const_instr_iterator I1 = getIterator(); MachineBasicBlock::const_instr_iterator E1 = getParent()->instr_end(); - MachineBasicBlock::const_instr_iterator I2 = *Other; + MachineBasicBlock::const_instr_iterator I2 = Other->getIterator(); MachineBasicBlock::const_instr_iterator E2= Other->getParent()->instr_end(); while (++I1 != E1 && I1->isInsideBundle()) { ++I2; - if (I2 == E2 || !I2->isInsideBundle() || !I1->isIdenticalTo(I2, Check)) + if (I2 == E2 || !I2->isInsideBundle() || !I1->isIdenticalTo(&*I2, Check)) return false; } } @@ -896,8 +990,8 @@ bool MachineInstr::isIdenticalTo(const MachineInstr *Other, } // If DebugLoc does not match then two dbg.values are not identical. if (isDebugValue()) - if (!getDebugLoc().isUnknown() && !Other->getDebugLoc().isUnknown() - && getDebugLoc() != Other->getDebugLoc()) + if (getDebugLoc() && Other->getDebugLoc() && + getDebugLoc() != Other->getDebugLoc()) return false; return true; } @@ -926,8 +1020,7 @@ void MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval() { MachineInstr *MI = (MachineInstr *)this; MachineRegisterInfo &MRI = MF->getRegInfo(); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); + for (const MachineOperand &MO : MI->operands()) { if (!MO.isReg() || !MO.isDef()) continue; unsigned Reg = MO.getReg(); @@ -961,7 +1054,7 @@ unsigned MachineInstr::getNumExplicitOperands() const { void MachineInstr::bundleWithPred() { assert(!isBundledWithPred() && "MI is already bundled with its predecessor"); setFlag(BundledPred); - MachineBasicBlock::instr_iterator Pred = this; + MachineBasicBlock::instr_iterator Pred = getIterator(); --Pred; assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags"); Pred->setFlag(BundledSucc); @@ -970,7 +1063,7 @@ void MachineInstr::bundleWithPred() { void MachineInstr::bundleWithSucc() { assert(!isBundledWithSucc() && "MI is already bundled with its successor"); setFlag(BundledSucc); - MachineBasicBlock::instr_iterator Succ = this; + MachineBasicBlock::instr_iterator Succ = getIterator(); ++Succ; assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags"); Succ->setFlag(BundledPred); @@ -979,7 +1072,7 @@ void MachineInstr::bundleWithSucc() { void MachineInstr::unbundleFromPred() { assert(isBundledWithPred() && "MI isn't bundled with its predecessor"); clearFlag(BundledPred); - MachineBasicBlock::instr_iterator Pred = this; + MachineBasicBlock::instr_iterator Pred = getIterator(); --Pred; assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags"); Pred->clearFlag(BundledSucc); @@ -988,7 +1081,7 @@ void MachineInstr::unbundleFromPred() { void MachineInstr::unbundleFromSucc() { assert(isBundledWithSucc() && "MI isn't bundled with its successor"); clearFlag(BundledSucc); - MachineBasicBlock::instr_iterator Succ = this; + MachineBasicBlock::instr_iterator Succ = getIterator(); ++Succ; assert(Succ->isBundledWithPred() && "Inconsistent bundle flags"); Succ->clearFlag(BundledPred); @@ -1086,9 +1179,8 @@ const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); else // Otherwise, just check the current operands. - for (ConstMIOperands OpndIt(this); OpndIt.isValid() && CurRC; ++OpndIt) - CurRC = getRegClassConstraintEffectForVRegImpl(OpndIt.getOperandNo(), Reg, - CurRC, TII, TRI); + for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) + CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); return CurRC; } @@ -1125,7 +1217,7 @@ const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( /// Return the number of instructions inside the MI bundle, not counting the /// header instruction. unsigned MachineInstr::getBundleSize() const { - MachineBasicBlock::const_instr_iterator I = this; + MachineBasicBlock::const_instr_iterator I = getIterator(); unsigned Size = 0; while (I->isBundledWithSucc()) ++Size, ++I; @@ -1330,8 +1422,7 @@ unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const { /// clearKillInfo - Clears kill flags on all operands. /// void MachineInstr::clearKillInfo() { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - MachineOperand &MO = getOperand(i); + for (MachineOperand &MO : operands()) { if (MO.isReg() && MO.isUse()) MO.setIsKill(false); } @@ -1344,15 +1435,13 @@ void MachineInstr::substituteRegister(unsigned FromReg, if (TargetRegisterInfo::isPhysicalRegister(ToReg)) { if (SubIdx) ToReg = RegInfo.getSubReg(ToReg, SubIdx); - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - MachineOperand &MO = getOperand(i); + for (MachineOperand &MO : operands()) { if (!MO.isReg() || MO.getReg() != FromReg) continue; MO.substPhysReg(ToReg, RegInfo); } } else { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - MachineOperand &MO = getOperand(i); + for (MachineOperand &MO : operands()) { if (!MO.isReg() || MO.getReg() != FromReg) continue; MO.substVirtReg(ToReg, SubIdx, RegInfo); @@ -1363,9 +1452,7 @@ void MachineInstr::substituteRegister(unsigned FromReg, /// isSafeToMove - Return true if it is safe to move this instruction. If /// SawStore is set to true, it means that there is a store (or call) between /// the instruction's location and its intended destination. -bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII, - AliasAnalysis *AA, - bool &SawStore) const { +bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const { // Ignore stuff that we obviously can't move. // // Treat volatile loads as stores. This is not strictly necessary for @@ -1450,9 +1537,9 @@ bool MachineInstr::isInvariantLoad(AliasAnalysis *AA) const { if (const Value *V = (*I)->getValue()) { // If we have an AliasAnalysis, ask it whether the memory is constant. - if (AA && AA->pointsToConstantMemory( - AliasAnalysis::Location(V, (*I)->getSize(), - (*I)->getAAInfo()))) + if (AA && + AA->pointsToConstantMemory( + MemoryLocation(V, (*I)->getSize(), (*I)->getAAInfo()))) continue; } @@ -1492,11 +1579,14 @@ bool MachineInstr::hasUnmodeledSideEffects() const { return false; } +bool MachineInstr::isLoadFoldBarrier() const { + return mayStore() || isCall() || hasUnmodeledSideEffects(); +} + /// allDefsAreDead - Return true if all the defs of this instruction are dead. /// bool MachineInstr::allDefsAreDead() const { - for (unsigned i = 0, e = getNumOperands(); i < e; ++i) { - const MachineOperand &MO = getOperand(i); + for (const MachineOperand &MO : operands()) { if (!MO.isReg() || MO.isUse()) continue; if (!MO.isDead()) @@ -1523,23 +1613,30 @@ void MachineInstr::dump() const { #endif } -static void printDebugLoc(DebugLoc DL, const MachineFunction *MF, - raw_ostream &CommentOS) { - const LLVMContext &Ctx = MF->getFunction()->getContext(); - DL.print(Ctx, CommentOS); +void MachineInstr::print(raw_ostream &OS, bool SkipOpers) 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); } -void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, +void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, bool SkipOpers) const { - // We can be a bit tidier if we know the TargetMachine and/or MachineFunction. + // 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; if (const MachineBasicBlock *MBB = getParent()) { MF = MBB->getParent(); - if (!TM && MF) - TM = &MF->getTarget(); - if (MF) + if (MF) { MRI = &MF->getRegInfo(); + TRI = MF->getSubtarget().getRegisterInfo(); + TII = MF->getSubtarget().getInstrInfo(); + } } // Save a list of virtual registers. @@ -1552,7 +1649,7 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, !getOperand(StartOp).isImplicit(); ++StartOp) { if (StartOp != 0) OS << ", "; - getOperand(StartOp).print(OS, TM); + getOperand(StartOp).print(OS, MST, TRI); unsigned Reg = getOperand(StartOp).getReg(); if (TargetRegisterInfo::isVirtualRegister(Reg)) VirtRegs.push_back(Reg); @@ -1562,8 +1659,8 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, OS << " = "; // Print the opcode name. - if (TM && TM->getSubtargetImpl()->getInstrInfo()) - OS << TM->getSubtargetImpl()->getInstrInfo()->getName(getOpcode()); + if (TII) + OS << TII->getName(getOpcode()); else OS << "UNKNOWN"; @@ -1579,7 +1676,7 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { // Print asm string. OS << " "; - getOperand(InlineAsm::MIOp_AsmString).print(OS, TM); + getOperand(InlineAsm::MIOp_AsmString).print(OS, MST, TRI); // Print HasSideEffects, MayLoad, MayStore, IsAlignStack unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); @@ -1600,7 +1697,6 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, FirstOp = false; } - for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { const MachineOperand &MO = getOperand(i); @@ -1617,9 +1713,7 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, if (TargetRegisterInfo::isPhysicalRegister(Reg)) { if (MRI->use_empty(Reg)) { bool HasAliasLive = false; - for (MCRegAliasIterator AI( - Reg, TM->getSubtargetImpl()->getRegisterInfo(), true); - AI.isValid(); ++AI) { + for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { unsigned AliasReg = *AI; if (!MRI->use_empty(AliasReg)) { HasAliasLive = true; @@ -1645,17 +1739,13 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, } if (isDebugValue() && MO.isMetadata()) { // Pretty print DBG_VALUE instructions. - const MDNode *MD = MO.getMetadata(); - DIDescriptor DI(MD); - DIVariable DIV(MD); - - if (DI.isVariable() && !DIV.getName().empty()) - OS << "!\"" << DIV.getName() << '\"'; + auto *DIV = dyn_cast(MO.getMetadata()); + if (DIV && !DIV->getName().empty()) + OS << "!\"" << DIV->getName() << '\"'; else - MO.print(OS, TM); - } else if (TM && (isInsertSubreg() || isRegSequence()) && MO.isImm()) { - OS << TM->getSubtargetImpl()->getRegisterInfo()->getSubRegIndexName( - MO.getImm()); + MO.print(OS, MST, TRI); + } else if (TRI && (isInsertSubreg() || isRegSequence()) && MO.isImm()) { + OS << TRI->getSubRegIndexName(MO.getImm()); } else if (i == AsmDescOp && MO.isImm()) { // Pretty print the inline asm operand descriptor. OS << '$' << AsmOpCount++; @@ -1672,11 +1762,8 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, unsigned RCID = 0; if (InlineAsm::hasRegClassConstraint(Flag, RCID)) { - if (TM) { - const TargetRegisterInfo *TRI = - TM->getSubtargetImpl()->getRegisterInfo(); - OS << ':' - << TRI->getRegClassName(TRI->getRegClass(RCID)); + if (TRI) { + OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID)); } else OS << ":RC" << RCID; } @@ -1690,7 +1777,7 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, // Compute the index of the next operand descriptor. AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); } else - MO.print(OS, TM); + MO.print(OS, MST, TRI); } // Briefly indicate whether any call clobbers were omitted. @@ -1700,22 +1787,31 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, } bool HaveSemi = false; - const unsigned PrintableFlags = FrameSetup; + const unsigned PrintableFlags = FrameSetup | FrameDestroy; if (Flags & PrintableFlags) { - if (!HaveSemi) OS << ";"; HaveSemi = true; + if (!HaveSemi) { + OS << ";"; + HaveSemi = true; + } OS << " flags: "; if (Flags & FrameSetup) OS << "FrameSetup"; + + if (Flags & FrameDestroy) + OS << "FrameDestroy"; } if (!memoperands_empty()) { - if (!HaveSemi) OS << ";"; HaveSemi = true; + if (!HaveSemi) { + OS << ";"; + HaveSemi = true; + } OS << " mem:"; for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); i != e; ++i) { - OS << **i; + (*i)->print(OS, MST); if (std::next(i) != e) OS << " "; } @@ -1723,10 +1819,13 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, // Print the regclass of any virtual registers encountered. if (MRI && !VirtRegs.empty()) { - if (!HaveSemi) OS << ";"; HaveSemi = true; + if (!HaveSemi) { + OS << ";"; + HaveSemi = true; + } for (unsigned i = 0; i != VirtRegs.size(); ++i) { const TargetRegisterClass *RC = MRI->getRegClass(VirtRegs[i]); - OS << " " << MRI->getTargetRegisterInfo()->getRegClassName(RC) + OS << " " << TRI->getRegClassName(RC) << ':' << PrintReg(VirtRegs[i]); for (unsigned j = i+1; j != VirtRegs.size();) { if (MRI->getRegClass(VirtRegs[j]) != RC) { @@ -1741,24 +1840,26 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, } // Print debug location information. - if (isDebugValue() && getOperand(e - 1).isMetadata()) { - if (!HaveSemi) OS << ";"; - DIVariable DV(getOperand(e - 1).getMetadata()); - OS << " line no:" << DV.getLineNumber(); - if (MDNode *InlinedAt = DV.getInlinedAt()) { - DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt); - if (!InlinedAtDL.isUnknown() && MF) { + if (isDebugValue() && getOperand(e - 2).isMetadata()) { + if (!HaveSemi) + OS << ";"; + auto *DV = cast(getOperand(e - 2).getMetadata()); + OS << " line no:" << DV->getLine(); + if (auto *InlinedAt = debugLoc->getInlinedAt()) { + DebugLoc InlinedAtDL(InlinedAt); + if (InlinedAtDL && MF) { OS << " inlined @[ "; - printDebugLoc(InlinedAtDL, MF, OS); + InlinedAtDL.print(OS); OS << " ]"; } } if (isIndirectDebugValue()) OS << " indirect"; - } else if (!debugLoc.isUnknown() && MF) { - if (!HaveSemi) OS << ";"; + } else if (debugLoc && MF) { + if (!HaveSemi) + OS << ";"; OS << " dbg:"; - printDebugLoc(debugLoc, MF, OS); + debugLoc.print(OS); } OS << '\n'; @@ -1827,8 +1928,7 @@ void MachineInstr::clearRegisterKills(unsigned Reg, const TargetRegisterInfo *RegInfo) { if (!TargetRegisterInfo::isPhysicalRegister(Reg)) RegInfo = nullptr; - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - MachineOperand &MO = getOperand(i); + for (MachineOperand &MO : operands()) { if (!MO.isReg() || !MO.isUse() || !MO.isKill()) continue; unsigned OpReg = MO.getReg(); @@ -1897,11 +1997,11 @@ void MachineInstr::clearRegisterDeads(unsigned Reg) { } } -void MachineInstr::addRegisterDefReadUndef(unsigned Reg) { +void MachineInstr::setRegisterDefReadUndef(unsigned Reg, bool IsUndef) { for (MachineOperand &MO : operands()) { if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0) continue; - MO.setIsUndef(); + MO.setIsUndef(IsUndef); } } @@ -1912,8 +2012,7 @@ void MachineInstr::addRegisterDefined(unsigned Reg, if (MO) return; } else { - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - const MachineOperand &MO = getOperand(i); + for (const MachineOperand &MO : operands()) { if (MO.isReg() && MO.getReg() == Reg && MO.isDef() && MO.getSubReg() == 0) return; @@ -1927,8 +2026,7 @@ void MachineInstr::addRegisterDefined(unsigned Reg, void MachineInstr::setPhysRegsDeadExcept(ArrayRef UsedRegs, const TargetRegisterInfo &TRI) { bool HasRegMask = false; - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { - MachineOperand &MO = getOperand(i); + for (MachineOperand &MO : operands()) { if (MO.isRegMask()) { HasRegMask = true; continue; @@ -1936,15 +2034,10 @@ void MachineInstr::setPhysRegsDeadExcept(ArrayRef UsedRegs, if (!MO.isReg() || !MO.isDef()) continue; unsigned Reg = MO.getReg(); if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; - bool Dead = true; - for (ArrayRef::iterator I = UsedRegs.begin(), E = UsedRegs.end(); - I != E; ++I) - if (TRI.regsOverlap(*I, Reg)) { - Dead = false; - break; - } // If there are no uses, including partial uses, the def is dead. - if (Dead) MO.setIsDead(); + if (std::none_of(UsedRegs.begin(), UsedRegs.end(), + [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); })) + MO.setIsDead(); } // This is a call with a register mask operand. @@ -1961,8 +2054,7 @@ MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { SmallVector HashComponents; HashComponents.reserve(MI->getNumOperands() + 1); HashComponents.push_back(MI->getOpcode()); - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); + for (const MachineOperand &MO : MI->operands()) { if (MO.isReg() && MO.isDef() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue; // Skip virtual register defs.