#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"
#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
+static cl::opt<bool> PrintWholeRegMask(
+ "print-whole-regmask",
+ cl::desc("Print the full contents of regmask operands in IR dumps"),
+ cl::init(true), cl::Hidden);
+
//===----------------------------------------------------------------------===//
// MachineOperand Implementation
//===----------------------------------------------------------------------===//
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.
llvm_unreachable("Invalid machine operand type");
}
-/// print - Print the specified machine operand.
-///
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());
if (isUndef() && getSubReg())
OS << ",read-undef";
} else if (isImplicit()) {
- OS << "imp-use";
- NeedComma = true;
+ OS << "imp-use";
+ NeedComma = true;
}
if (isKill()) {
break;
case MachineOperand::MO_GlobalAddress:
OS << "<ga:";
- getGlobal()->printAsOperand(OS, /*PrintType=*/false);
+ getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
if (getOffset()) OS << "+" << getOffset();
OS << '>';
break;
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 << "<regmask>";
+ case MachineOperand::MO_RegisterMask: {
+ unsigned NumRegsInMask = 0;
+ unsigned NumRegsEmitted = 0;
+ OS << "<regmask";
+ for (unsigned i = 0; i < TRI->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 << "<regliveout>";
break;
case MachineOperand::MO_Metadata:
OS << '<';
- getMetadata()->printAsOperand(OS);
+ getMetadata()->printAsOperand(OS, MST);
OS << '>';
break;
case MachineOperand::MO_MCSymbol:
/// 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,
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 << "<unknown>";
- 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 << "<unknown>";
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 << ",";
}
}
// 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 << ",";
}
}
// Print nontemporal info.
- if (MMO.isNonTemporal())
+ if (isNonTemporal())
OS << "(nontemporal)";
- return OS;
+ if (isInvariant())
+ OS << "(invariant)";
}
//===----------------------------------------------------------------------===//
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));
}
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;
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;
}
}
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);
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);
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);
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);
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;
}
/// 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;
/// 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
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;
}
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 {
}
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, ModuleSlotTracker &MST,
+ bool SkipOpers) const {
// We can be a bit tidier if we know the MachineFunction.
const MachineFunction *MF = nullptr;
const TargetRegisterInfo *TRI = nullptr;
!getOperand(StartOp).isImplicit();
++StartOp) {
if (StartOp != 0) OS << ", ";
- getOperand(StartOp).print(OS, TRI);
+ getOperand(StartOp).print(OS, MST, TRI);
unsigned Reg = getOperand(StartOp).getReg();
if (TargetRegisterInfo::isVirtualRegister(Reg))
VirtRegs.push_back(Reg);
if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) {
// Print asm string.
OS << " ";
- getOperand(InlineAsm::MIOp_AsmString).print(OS, TRI);
+ getOperand(InlineAsm::MIOp_AsmString).print(OS, MST, TRI);
// Print HasSideEffects, MayLoad, MayStore, IsAlignStack
unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
FirstOp = false;
}
-
for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
const MachineOperand &MO = getOperand(i);
}
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<DILocalVariable>(MO.getMetadata());
+ if (DIV && !DIV->getName().empty())
+ OS << "!\"" << DIV->getName() << '\"';
else
- MO.print(OS, TRI);
+ MO.print(OS, MST, TRI);
} else if (TRI && (isInsertSubreg() || isRegSequence()) && MO.isImm()) {
OS << TRI->getSubRegIndexName(MO.getImm());
} else if (i == AsmDescOp && MO.isImm()) {
// Compute the index of the next operand descriptor.
AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag);
} else
- MO.print(OS, TRI);
+ MO.print(OS, MST, TRI);
}
// Briefly indicate whether any call clobbers were omitted.
}
bool HaveSemi = false;
- const unsigned PrintableFlags = FrameSetup;
+ const unsigned PrintableFlags = FrameSetup | FrameDestroy;
if (Flags & PrintableFlags) {
if (!HaveSemi) OS << ";"; HaveSemi = true;
OS << " flags: ";
if (Flags & FrameSetup)
OS << "FrameSetup";
+
+ if (Flags & FrameDestroy)
+ OS << "FrameDestroy";
}
if (!memoperands_empty()) {
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 << " ";
}
// Print debug location information.
if (isDebugValue() && getOperand(e - 2).isMetadata()) {
if (!HaveSemi) OS << ";";
- DIVariable DV(getOperand(e - 2).getMetadata());
- OS << " line no:" << DV.getLineNumber();
- if (auto *InlinedAt = DV.getInlinedAt()) {
+ auto *DV = cast<DILocalVariable>(getOperand(e - 2).getMetadata());
+ OS << " line no:" << DV->getLine();
+ if (auto *InlinedAt = debugLoc->getInlinedAt()) {
DebugLoc InlinedAtDL(InlinedAt);
if (InlinedAtDL && MF) {
OS << " inlined @[ ";
- InlinedAtDL.print(OS);
+ InlinedAtDL.print(OS);
OS << " ]";
}
}
}
}
-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);
}
}