diff options
Diffstat (limited to 'lib/CodeGen/MachineOperand.cpp')
-rw-r--r-- | lib/CodeGen/MachineOperand.cpp | 335 |
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 << ')'; } |