summaryrefslogtreecommitdiff
path: root/lib/CodeGen/MachineOperand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/MachineOperand.cpp')
-rw-r--r--lib/CodeGen/MachineOperand.cpp335
1 files changed, 210 insertions, 125 deletions
diff --git a/lib/CodeGen/MachineOperand.cpp b/lib/CodeGen/MachineOperand.cpp
index ec81c6391171..8098333832b4 100644
--- a/lib/CodeGen/MachineOperand.cpp
+++ b/lib/CodeGen/MachineOperand.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/Loads.h"
#include "llvm/CodeGen/MIRPrinter.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -19,6 +20,7 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/ModuleSlotTracker.h"
@@ -50,6 +52,9 @@ void MachineOperand::setReg(unsigned Reg) {
if (getReg() == Reg)
return; // No change.
+ // Clear the IsRenamable bit to keep it conservatively correct.
+ IsRenamable = false;
+
// Otherwise, we have to change the register. If this operand is embedded
// into a machine function, we need to update the old and new register's
// use/def lists.
@@ -110,30 +115,27 @@ bool MachineOperand::isRenamable() const {
assert(isReg() && "Wrong MachineOperand accessor");
assert(TargetRegisterInfo::isPhysicalRegister(getReg()) &&
"isRenamable should only be checked on physical registers");
- return IsRenamable;
+ if (!IsRenamable)
+ return false;
+
+ const MachineInstr *MI = getParent();
+ if (!MI)
+ return true;
+
+ if (isDef())
+ return !MI->hasExtraDefRegAllocReq(MachineInstr::IgnoreBundle);
+
+ assert(isUse() && "Reg is not def or use");
+ return !MI->hasExtraSrcRegAllocReq(MachineInstr::IgnoreBundle);
}
void MachineOperand::setIsRenamable(bool Val) {
assert(isReg() && "Wrong MachineOperand accessor");
assert(TargetRegisterInfo::isPhysicalRegister(getReg()) &&
"setIsRenamable should only be called on physical registers");
- if (const MachineInstr *MI = getParent())
- if ((isDef() && MI->hasExtraDefRegAllocReq()) ||
- (isUse() && MI->hasExtraSrcRegAllocReq()))
- assert(!Val && "isRenamable should be false for "
- "hasExtraDefRegAllocReq/hasExtraSrcRegAllocReq opcodes");
IsRenamable = Val;
}
-void MachineOperand::setIsRenamableIfNoExtraRegAllocReq() {
- if (const MachineInstr *MI = getParent())
- if ((isDef() && MI->hasExtraDefRegAllocReq()) ||
- (isUse() && MI->hasExtraSrcRegAllocReq()))
- return;
-
- setIsRenamable(true);
-}
-
// If this operand is currently a register operand, and if this is in a
// function, deregister the operand from the register's use/def list.
void MachineOperand::removeRegFromUses() {
@@ -440,7 +442,70 @@ static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB,
OS << "<unknown>";
}
-void MachineOperand::printSubregIdx(raw_ostream &OS, uint64_t Index,
+static void printIRValueReference(raw_ostream &OS, const Value &V,
+ ModuleSlotTracker &MST) {
+ if (isa<GlobalValue>(V)) {
+ V.printAsOperand(OS, /*PrintType=*/false, MST);
+ return;
+ }
+ if (isa<Constant>(V)) {
+ // Machine memory operands can load/store to/from constant value pointers.
+ OS << '`';
+ V.printAsOperand(OS, /*PrintType=*/true, MST);
+ OS << '`';
+ return;
+ }
+ OS << "%ir.";
+ if (V.hasName()) {
+ printLLVMNameWithoutPrefix(OS, V.getName());
+ return;
+ }
+ MachineOperand::printIRSlotNumber(OS, MST.getLocalSlot(&V));
+}
+
+static void printSyncScope(raw_ostream &OS, const LLVMContext &Context,
+ SyncScope::ID SSID,
+ SmallVectorImpl<StringRef> &SSNs) {
+ switch (SSID) {
+ case SyncScope::System:
+ break;
+ default:
+ if (SSNs.empty())
+ Context.getSyncScopeNames(SSNs);
+
+ OS << "syncscope(\"";
+ printEscapedString(SSNs[SSID], OS);
+ OS << "\") ";
+ break;
+ }
+}
+
+static const char *getTargetMMOFlagName(const TargetInstrInfo &TII,
+ unsigned TMMOFlag) {
+ auto Flags = TII.getSerializableMachineMemOperandTargetFlags();
+ for (const auto &I : Flags) {
+ if (I.first == TMMOFlag) {
+ return I.second;
+ }
+ }
+ return nullptr;
+}
+
+static void printFrameIndex(raw_ostream& OS, int FrameIndex, bool IsFixed,
+ const MachineFrameInfo *MFI) {
+ StringRef Name;
+ if (MFI) {
+ IsFixed = MFI->isFixedObjectIndex(FrameIndex);
+ if (const AllocaInst *Alloca = MFI->getObjectAllocation(FrameIndex))
+ if (Alloca->hasName())
+ Name = Alloca->getName();
+ if (IsFixed)
+ FrameIndex -= MFI->getObjectIndexBegin();
+ }
+ MachineOperand::printStackObjectReference(OS, FrameIndex, IsFixed, Name);
+}
+
+void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index,
const TargetRegisterInfo *TRI) {
OS << "%subreg.";
if (TRI)
@@ -639,15 +704,21 @@ static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI,
void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI,
const TargetIntrinsicInfo *IntrinsicInfo) const {
+ print(OS, LLT{}, TRI, IntrinsicInfo);
+}
+
+void MachineOperand::print(raw_ostream &OS, LLT TypeToPrint,
+ const TargetRegisterInfo *TRI,
+ const TargetIntrinsicInfo *IntrinsicInfo) const {
tryToGetTargetInfo(*this, TRI, IntrinsicInfo);
ModuleSlotTracker DummyMST(nullptr);
- print(OS, DummyMST, LLT{}, /*PrintDef=*/false,
+ print(OS, DummyMST, TypeToPrint, /*PrintDef=*/false, /*IsStandalone=*/true,
/*ShouldPrintRegisterTies=*/true,
/*TiedOperandIdx=*/0, TRI, IntrinsicInfo);
}
void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
- LLT TypeToPrint, bool PrintDef,
+ LLT TypeToPrint, bool PrintDef, bool IsStandalone,
bool ShouldPrintRegisterTies,
unsigned TiedOperandIdx,
const TargetRegisterInfo *TRI,
@@ -675,7 +746,15 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
OS << "debug-use ";
if (TargetRegisterInfo::isPhysicalRegister(getReg()) && isRenamable())
OS << "renamable ";
- OS << printReg(Reg, TRI);
+
+ const MachineRegisterInfo *MRI = nullptr;
+ if (TargetRegisterInfo::isVirtualRegister(Reg)) {
+ if (const MachineFunction *MF = getMFIfAvailable(*this)) {
+ MRI = &MF->getRegInfo();
+ }
+ }
+
+ OS << printReg(Reg, TRI, 0, MRI);
// Print the sub register.
if (unsigned SubReg = getSubReg()) {
if (TRI)
@@ -687,7 +766,7 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
if (const MachineFunction *MF = getMFIfAvailable(*this)) {
const MachineRegisterInfo &MRI = MF->getRegInfo();
- if (!PrintDef || MRI.def_empty(Reg)) {
+ if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) {
OS << ':';
OS << printRegClassOrBank(Reg, MRI, TRI);
}
@@ -716,17 +795,10 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
case MachineOperand::MO_FrameIndex: {
int FrameIndex = getIndex();
bool IsFixed = false;
- StringRef Name;
- if (const MachineFunction *MF = getMFIfAvailable(*this)) {
- const MachineFrameInfo &MFI = MF->getFrameInfo();
- IsFixed = MFI.isFixedObjectIndex(FrameIndex);
- if (const AllocaInst *Alloca = MFI.getObjectAllocation(FrameIndex))
- if (Alloca->hasName())
- Name = Alloca->getName();
- if (IsFixed)
- FrameIndex -= MFI.getObjectIndexBegin();
- }
- printStackObjectReference(OS, FrameIndex, IsFixed, Name);
+ const MachineFrameInfo *MFI = nullptr;
+ if (const MachineFunction *MF = getMFIfAvailable(*this))
+ MFI = &MF->getFrameInfo();
+ printFrameIndex(OS, FrameIndex, IsFixed, MFI);
break;
}
case MachineOperand::MO_ConstantPoolIndex:
@@ -752,7 +824,7 @@ void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
break;
case MachineOperand::MO_ExternalSymbol: {
StringRef Name = getSymbolName();
- OS << '$';
+ OS << '&';
if (Name.empty()) {
OS << "\"\"";
} else {
@@ -905,7 +977,7 @@ MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) {
}
MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
- uint64_t s, unsigned int a,
+ uint64_t s, uint64_t a,
const AAMDNodes &AAInfo,
const MDNode *Ranges, SyncScope::ID SSID,
AtomicOrdering Ordering,
@@ -961,108 +1033,121 @@ 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.");
+ SmallVector<StringRef, 0> SSNs;
+ LLVMContext Ctx;
+ print(OS, MST, SSNs, Ctx, nullptr, nullptr);
+}
+void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
+ SmallVectorImpl<StringRef> &SSNs,
+ const LLVMContext &Context,
+ const MachineFrameInfo *MFI,
+ const TargetInstrInfo *TII) const {
+ OS << '(';
if (isVolatile())
- OS << "Volatile ";
-
+ OS << "volatile ";
+ if (isNonTemporal())
+ OS << "non-temporal ";
+ if (isDereferenceable())
+ OS << "dereferenceable ";
+ if (isInvariant())
+ OS << "invariant ";
+ if (getFlags() & MachineMemOperand::MOTargetFlag1)
+ OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag1)
+ << "\" ";
+ if (getFlags() & MachineMemOperand::MOTargetFlag2)
+ OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag2)
+ << "\" ";
+ if (getFlags() & MachineMemOperand::MOTargetFlag3)
+ OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag3)
+ << "\" ";
+
+ assert((isLoad() || isStore()) &&
+ "machine memory operand must be a load or store (or both)");
if (isLoad())
- OS << "LD";
+ OS << "load ";
if (isStore())
- OS << "ST";
- OS << getSize();
+ OS << "store ";
- // Print the address information.
- OS << "[";
- if (const Value *V = getValue())
- V->printAsOperand(OS, /*PrintType=*/false, MST);
- else if (const PseudoSourceValue *PSV = getPseudoValue())
- PSV->printCustom(OS);
- else
- OS << "<unknown>";
+ printSyncScope(OS, Context, getSyncScopeID(), SSNs);
- 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 (getBaseAlignment() != getAlignment())
- OS << "(align=" << getBaseAlignment() << ")";
-
- if (getOffset() != 0)
- OS << "+" << getOffset();
- OS << "]";
-
- // Print the alignment of the reference.
- if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize())
- OS << "(align=" << getAlignment() << ")";
-
- // Print TBAA info.
- if (const MDNode *TBAAInfo = getAAInfo().TBAA) {
- OS << "(tbaa=";
- if (TBAAInfo->getNumOperands() > 0)
- TBAAInfo->getOperand(0)->printAsOperand(OS, MST);
- else
- OS << "<unknown>";
- OS << ")";
- }
+ if (getOrdering() != AtomicOrdering::NotAtomic)
+ OS << toIRString(getOrdering()) << ' ';
+ if (getFailureOrdering() != AtomicOrdering::NotAtomic)
+ OS << toIRString(getFailureOrdering()) << ' ';
- // Print AA scope info.
- 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, MST);
- if (i != ie - 1)
- OS << ",";
- }
- else
- OS << "<unknown>";
- OS << ")";
+ OS << getSize();
+ if (const Value *Val = getValue()) {
+ OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
+ printIRValueReference(OS, *Val, MST);
+ } else if (const PseudoSourceValue *PVal = getPseudoValue()) {
+ OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
+ assert(PVal && "Expected a pseudo source value");
+ switch (PVal->kind()) {
+ case PseudoSourceValue::Stack:
+ OS << "stack";
+ break;
+ case PseudoSourceValue::GOT:
+ OS << "got";
+ break;
+ case PseudoSourceValue::JumpTable:
+ OS << "jump-table";
+ break;
+ case PseudoSourceValue::ConstantPool:
+ OS << "constant-pool";
+ break;
+ case PseudoSourceValue::FixedStack: {
+ int FrameIndex = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
+ bool IsFixed = true;
+ printFrameIndex(OS, FrameIndex, IsFixed, MFI);
+ break;
+ }
+ case PseudoSourceValue::GlobalValueCallEntry:
+ OS << "call-entry ";
+ cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand(
+ OS, /*PrintType=*/false, MST);
+ break;
+ case PseudoSourceValue::ExternalSymbolCallEntry:
+ OS << "call-entry &";
+ printLLVMNameWithoutPrefix(
+ OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol());
+ break;
+ case PseudoSourceValue::TargetCustom:
+ // FIXME: This is not necessarily the correct MIR serialization format for
+ // a custom pseudo source value, but at least it allows
+ // -print-machineinstrs to work on a target with custom pseudo source
+ // values.
+ OS << "custom ";
+ PVal->printCustom(OS);
+ break;
+ }
}
-
- // Print AA noalias scope info.
- 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, MST);
- if (i != ie - 1)
- OS << ",";
- }
- else
- OS << "<unknown>";
- OS << ")";
+ MachineOperand::printOperandOffset(OS, getOffset());
+ if (getBaseAlignment() != getSize())
+ OS << ", align " << getBaseAlignment();
+ auto AAInfo = getAAInfo();
+ if (AAInfo.TBAA) {
+ OS << ", !tbaa ";
+ AAInfo.TBAA->printAsOperand(OS, MST);
}
-
- if (const MDNode *Ranges = getRanges()) {
- unsigned NumRanges = Ranges->getNumOperands();
- if (NumRanges != 0) {
- OS << "(ranges=";
-
- for (unsigned I = 0; I != NumRanges; ++I) {
- Ranges->getOperand(I)->printAsOperand(OS, MST);
- if (I != NumRanges - 1)
- OS << ',';
- }
-
- OS << ')';
- }
+ if (AAInfo.Scope) {
+ OS << ", !alias.scope ";
+ AAInfo.Scope->printAsOperand(OS, MST);
}
+ if (AAInfo.NoAlias) {
+ OS << ", !noalias ";
+ AAInfo.NoAlias->printAsOperand(OS, MST);
+ }
+ if (getRanges()) {
+ OS << ", !range ";
+ getRanges()->printAsOperand(OS, MST);
+ }
+ // FIXME: Implement addrspace printing/parsing in MIR.
+ // For now, print this even though parsing it is not available in MIR.
+ if (unsigned AS = getAddrSpace())
+ OS << ", addrspace " << AS;
- if (isNonTemporal())
- OS << "(nontemporal)";
- if (isDereferenceable())
- OS << "(dereferenceable)";
- if (isInvariant())
- OS << "(invariant)";
- if (getFlags() & MOTargetFlag1)
- OS << "(flag1)";
- if (getFlags() & MOTargetFlag2)
- OS << "(flag2)";
- if (getFlags() & MOTargetFlag3)
- OS << "(flag3)";
+ OS << ')';
}