12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262 |
- //===- lib/CodeGen/MachineOperand.cpp -------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- /// \file Methods common to all machine operands.
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/CodeGen/MachineOperand.h"
- #include "llvm/ADT/FoldingSet.h"
- #include "llvm/ADT/StringExtras.h"
- #include "llvm/Analysis/Loads.h"
- #include "llvm/CodeGen/MIRFormatter.h"
- #include "llvm/CodeGen/MachineFrameInfo.h"
- #include "llvm/CodeGen/MachineJumpTableInfo.h"
- #include "llvm/CodeGen/MachineRegisterInfo.h"
- #include "llvm/CodeGen/StableHashing.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/Instructions.h"
- #include "llvm/IR/ModuleSlotTracker.h"
- #include "llvm/MC/MCDwarf.h"
- #include "llvm/Target/TargetIntrinsicInfo.h"
- #include "llvm/Target/TargetMachine.h"
- #include <optional>
- using namespace llvm;
- static cl::opt<int>
- PrintRegMaskNumRegs("print-regmask-num-regs",
- cl::desc("Number of registers to limit to when "
- "printing regmask operands in IR dumps. "
- "unlimited = -1"),
- cl::init(32), cl::Hidden);
- static const MachineFunction *getMFIfAvailable(const MachineOperand &MO) {
- if (const MachineInstr *MI = MO.getParent())
- if (const MachineBasicBlock *MBB = MI->getParent())
- if (const MachineFunction *MF = MBB->getParent())
- return MF;
- return nullptr;
- }
- static MachineFunction *getMFIfAvailable(MachineOperand &MO) {
- return const_cast<MachineFunction *>(
- getMFIfAvailable(const_cast<const MachineOperand &>(MO)));
- }
- void MachineOperand::setReg(Register 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.
- if (MachineFunction *MF = getMFIfAvailable(*this)) {
- MachineRegisterInfo &MRI = MF->getRegInfo();
- MRI.removeRegOperandFromUseList(this);
- SmallContents.RegNo = Reg;
- MRI.addRegOperandToUseList(this);
- return;
- }
- // Otherwise, just change the register, no problem. :)
- SmallContents.RegNo = Reg;
- }
- void MachineOperand::substVirtReg(Register Reg, unsigned SubIdx,
- const TargetRegisterInfo &TRI) {
- assert(Reg.isVirtual());
- if (SubIdx && getSubReg())
- SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg());
- setReg(Reg);
- if (SubIdx)
- setSubReg(SubIdx);
- }
- void MachineOperand::substPhysReg(MCRegister Reg, const TargetRegisterInfo &TRI) {
- assert(Register::isPhysicalRegister(Reg));
- if (getSubReg()) {
- Reg = TRI.getSubReg(Reg, getSubReg());
- // 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);
- }
- /// Change a def to a use, or a use to a def.
- void MachineOperand::setIsDef(bool Val) {
- assert(isReg() && "Wrong MachineOperand accessor");
- assert((!Val || !isDebug()) && "Marking a debug operation as def");
- if (IsDef == Val)
- return;
- assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported");
- // MRI may keep uses and defs in different list positions.
- if (MachineFunction *MF = getMFIfAvailable(*this)) {
- MachineRegisterInfo &MRI = MF->getRegInfo();
- MRI.removeRegOperandFromUseList(this);
- IsDef = Val;
- MRI.addRegOperandToUseList(this);
- return;
- }
- IsDef = Val;
- }
- bool MachineOperand::isRenamable() const {
- assert(isReg() && "Wrong MachineOperand accessor");
- assert(getReg().isPhysical() &&
- "isRenamable should only be checked on physical registers");
- 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(getReg().isPhysical() &&
- "setIsRenamable should only be called on physical registers");
- IsRenamable = Val;
- }
- // 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() {
- if (!isReg() || !isOnRegUseList())
- return;
- if (MachineFunction *MF = getMFIfAvailable(*this))
- MF->getRegInfo().removeRegOperandFromUseList(this);
- }
- /// ChangeToImmediate - Replace this operand with a new immediate operand of
- /// the specified value. If an operand is known to be an immediate already,
- /// the setImm method should be used.
- void MachineOperand::ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags) {
- assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
- removeRegFromUses();
- OpKind = MO_Immediate;
- Contents.ImmVal = ImmVal;
- setTargetFlags(TargetFlags);
- }
- void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm,
- unsigned TargetFlags) {
- assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
- removeRegFromUses();
- OpKind = MO_FPImmediate;
- Contents.CFP = FPImm;
- setTargetFlags(TargetFlags);
- }
- void MachineOperand::ChangeToES(const char *SymName,
- unsigned 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::ChangeToGA(const GlobalValue *GV, int64_t Offset,
- unsigned TargetFlags) {
- assert((!isReg() || !isTied()) &&
- "Cannot change a tied operand into a global address");
- removeRegFromUses();
- OpKind = MO_GlobalAddress;
- Contents.OffsetedInfo.Val.GV = GV;
- setOffset(Offset);
- setTargetFlags(TargetFlags);
- }
- void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) {
- assert((!isReg() || !isTied()) &&
- "Cannot change a tied operand into an MCSymbol");
- removeRegFromUses();
- OpKind = MO_MCSymbol;
- Contents.Sym = Sym;
- setTargetFlags(TargetFlags);
- }
- void MachineOperand::ChangeToFrameIndex(int Idx, unsigned TargetFlags) {
- assert((!isReg() || !isTied()) &&
- "Cannot change a tied operand into a FrameIndex");
- removeRegFromUses();
- OpKind = MO_FrameIndex;
- setIndex(Idx);
- setTargetFlags(TargetFlags);
- }
- void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset,
- unsigned TargetFlags) {
- assert((!isReg() || !isTied()) &&
- "Cannot change a tied operand into a FrameIndex");
- removeRegFromUses();
- OpKind = MO_TargetIndex;
- setIndex(Idx);
- setOffset(Offset);
- setTargetFlags(TargetFlags);
- }
- void MachineOperand::ChangeToDbgInstrRef(unsigned InstrIdx, unsigned OpIdx,
- unsigned TargetFlags) {
- assert((!isReg() || !isTied()) &&
- "Cannot change a tied operand into a DbgInstrRef");
- removeRegFromUses();
- OpKind = MO_DbgInstrRef;
- setInstrRefInstrIndex(InstrIdx);
- setInstrRefOpIndex(OpIdx);
- setTargetFlags(TargetFlags);
- }
- /// 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.
- void MachineOperand::ChangeToRegister(Register Reg, bool isDef, bool isImp,
- bool isKill, bool isDead, bool isUndef,
- bool isDebug) {
- MachineRegisterInfo *RegInfo = nullptr;
- if (MachineFunction *MF = getMFIfAvailable(*this))
- RegInfo = &MF->getRegInfo();
- // If this operand is already a register operand, remove it from the
- // register's use/def lists.
- bool WasReg = isReg();
- if (RegInfo && WasReg)
- RegInfo->removeRegOperandFromUseList(this);
- // Ensure debug instructions set debug flag on register uses.
- const MachineInstr *MI = getParent();
- if (!isDef && MI && MI->isDebugInstr())
- isDebug = true;
- // Change this to a register and set the reg#.
- assert(!(isDead && !isDef) && "Dead flag on non-def");
- assert(!(isKill && isDef) && "Kill flag on def");
- OpKind = MO_Register;
- SmallContents.RegNo = Reg;
- SubReg_TargetFlags = 0;
- IsDef = isDef;
- IsImp = isImp;
- IsDeadOrKill = isKill | isDead;
- IsRenamable = false;
- IsUndef = isUndef;
- IsInternalRead = false;
- IsEarlyClobber = false;
- IsDebug = isDebug;
- // Ensure isOnRegUseList() returns false.
- Contents.Reg.Prev = nullptr;
- // Preserve the tie when the operand was already a register.
- if (!WasReg)
- TiedTo = 0;
- // If this operand is embedded in a function, add the operand to the
- // register's use/def list.
- if (RegInfo)
- RegInfo->addRegOperandToUseList(this);
- }
- /// isIdenticalTo - Return true if this operand is identical to the specified
- /// operand. Note that this should stay in sync with the hash_value overload
- /// below.
- bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
- if (getType() != Other.getType() ||
- getTargetFlags() != Other.getTargetFlags())
- return false;
- switch (getType()) {
- case MachineOperand::MO_Register:
- return getReg() == Other.getReg() && isDef() == Other.isDef() &&
- getSubReg() == Other.getSubReg();
- case MachineOperand::MO_Immediate:
- return getImm() == Other.getImm();
- case MachineOperand::MO_CImmediate:
- return getCImm() == Other.getCImm();
- case MachineOperand::MO_FPImmediate:
- return getFPImm() == Other.getFPImm();
- case MachineOperand::MO_MachineBasicBlock:
- return getMBB() == Other.getMBB();
- case MachineOperand::MO_FrameIndex:
- return getIndex() == Other.getIndex();
- case MachineOperand::MO_ConstantPoolIndex:
- case MachineOperand::MO_TargetIndex:
- return getIndex() == Other.getIndex() && getOffset() == Other.getOffset();
- case MachineOperand::MO_JumpTableIndex:
- return getIndex() == Other.getIndex();
- case MachineOperand::MO_GlobalAddress:
- return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset();
- case MachineOperand::MO_ExternalSymbol:
- return strcmp(getSymbolName(), Other.getSymbolName()) == 0 &&
- getOffset() == Other.getOffset();
- case MachineOperand::MO_BlockAddress:
- return getBlockAddress() == Other.getBlockAddress() &&
- getOffset() == Other.getOffset();
- case MachineOperand::MO_RegisterMask:
- case MachineOperand::MO_RegisterLiveOut: {
- // Shallow compare of the two RegMasks
- const uint32_t *RegMask = getRegMask();
- const uint32_t *OtherRegMask = Other.getRegMask();
- if (RegMask == OtherRegMask)
- return true;
- if (const MachineFunction *MF = getMFIfAvailable(*this)) {
- const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
- unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
- // Deep compare of the two RegMasks
- return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask);
- }
- // We don't know the size of the RegMask, so we can't deep compare the two
- // reg masks.
- return false;
- }
- case MachineOperand::MO_MCSymbol:
- return getMCSymbol() == Other.getMCSymbol();
- case MachineOperand::MO_DbgInstrRef:
- return getInstrRefInstrIndex() == Other.getInstrRefInstrIndex() &&
- getInstrRefOpIndex() == Other.getInstrRefOpIndex();
- case MachineOperand::MO_CFIIndex:
- 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();
- case MachineOperand::MO_ShuffleMask:
- return getShuffleMask() == Other.getShuffleMask();
- }
- llvm_unreachable("Invalid machine operand type");
- }
- // Note: this must stay exactly in sync with isIdenticalTo above.
- hash_code llvm::hash_value(const MachineOperand &MO) {
- switch (MO.getType()) {
- case MachineOperand::MO_Register:
- // Register operands don't have target flags.
- return hash_combine(MO.getType(), (unsigned)MO.getReg(), MO.getSubReg(), MO.isDef());
- case MachineOperand::MO_Immediate:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
- case MachineOperand::MO_CImmediate:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm());
- case MachineOperand::MO_FPImmediate:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm());
- case MachineOperand::MO_MachineBasicBlock:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB());
- case MachineOperand::MO_FrameIndex:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
- case MachineOperand::MO_ConstantPoolIndex:
- case MachineOperand::MO_TargetIndex:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(),
- MO.getOffset());
- case MachineOperand::MO_JumpTableIndex:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
- case MachineOperand::MO_ExternalSymbol:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
- StringRef(MO.getSymbolName()));
- case MachineOperand::MO_GlobalAddress:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(),
- MO.getOffset());
- case MachineOperand::MO_BlockAddress:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(),
- MO.getOffset());
- case MachineOperand::MO_RegisterMask:
- case MachineOperand::MO_RegisterLiveOut: {
- if (const MachineFunction *MF = getMFIfAvailable(MO)) {
- const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
- unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
- const uint32_t *RegMask = MO.getRegMask();
- std::vector<stable_hash> RegMaskHashes(RegMask, RegMask + RegMaskSize);
- return hash_combine(MO.getType(), MO.getTargetFlags(),
- stable_hash_combine_array(RegMaskHashes.data(),
- RegMaskHashes.size()));
- }
- assert(0 && "MachineOperand not associated with any MachineFunction");
- return hash_combine(MO.getType(), MO.getTargetFlags());
- }
- case MachineOperand::MO_Metadata:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata());
- case MachineOperand::MO_MCSymbol:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol());
- case MachineOperand::MO_DbgInstrRef:
- return hash_combine(MO.getType(), MO.getTargetFlags(),
- MO.getInstrRefInstrIndex(), MO.getInstrRefOpIndex());
- 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());
- case MachineOperand::MO_ShuffleMask:
- return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getShuffleMask());
- }
- llvm_unreachable("Invalid machine operand type");
- }
- // Try to crawl up to the machine function and get TRI and IntrinsicInfo from
- // it.
- static void tryToGetTargetInfo(const MachineOperand &MO,
- const TargetRegisterInfo *&TRI,
- const TargetIntrinsicInfo *&IntrinsicInfo) {
- if (const MachineFunction *MF = getMFIfAvailable(MO)) {
- TRI = MF->getSubtarget().getRegisterInfo();
- IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
- }
- }
- static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
- const auto *TII = MF.getSubtarget().getInstrInfo();
- assert(TII && "expected instruction info");
- auto Indices = TII->getSerializableTargetIndices();
- auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) {
- return I.first == Index;
- });
- if (Found != Indices.end())
- return Found->second;
- return nullptr;
- }
- const char *MachineOperand::getTargetIndexName() const {
- const MachineFunction *MF = getMFIfAvailable(*this);
- return MF ? ::getTargetIndexName(*MF, this->getIndex()) : nullptr;
- }
- static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
- auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
- for (const auto &I : Flags) {
- if (I.first == TF) {
- return I.second;
- }
- }
- return nullptr;
- }
- static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
- const TargetRegisterInfo *TRI) {
- if (!TRI) {
- OS << "%dwarfreg." << DwarfReg;
- return;
- }
- if (std::optional<unsigned> Reg = TRI->getLLVMRegNum(DwarfReg, true))
- OS << printReg(*Reg, TRI);
- else
- OS << "<badreg>";
- }
- static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB,
- ModuleSlotTracker &MST) {
- OS << "%ir-block.";
- if (BB.hasName()) {
- printLLVMNameWithoutPrefix(OS, BB.getName());
- return;
- }
- std::optional<int> Slot;
- if (const Function *F = BB.getParent()) {
- if (F == MST.getCurrentFunction()) {
- Slot = MST.getLocalSlot(&BB);
- } else if (const Module *M = F->getParent()) {
- ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false);
- CustomMST.incorporateFunction(*F);
- Slot = CustomMST.getLocalSlot(&BB);
- }
- }
- if (Slot)
- MachineOperand::printIRSlotNumber(OS, *Slot);
- else
- OS << "<unknown>";
- }
- 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 && Index != 0 && Index < TRI->getNumSubRegIndices())
- OS << TRI->getSubRegIndexName(Index);
- else
- OS << Index;
- }
- void MachineOperand::printTargetFlags(raw_ostream &OS,
- const MachineOperand &Op) {
- if (!Op.getTargetFlags())
- return;
- const MachineFunction *MF = getMFIfAvailable(Op);
- if (!MF)
- return;
- const auto *TII = MF->getSubtarget().getInstrInfo();
- assert(TII && "expected instruction info");
- auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
- OS << "target-flags(";
- const bool HasDirectFlags = Flags.first;
- const bool HasBitmaskFlags = Flags.second;
- if (!HasDirectFlags && !HasBitmaskFlags) {
- OS << "<unknown>) ";
- return;
- }
- if (HasDirectFlags) {
- if (const auto *Name = getTargetFlagName(TII, Flags.first))
- OS << Name;
- else
- OS << "<unknown target flag>";
- }
- if (!HasBitmaskFlags) {
- OS << ") ";
- return;
- }
- bool IsCommaNeeded = HasDirectFlags;
- unsigned BitMask = Flags.second;
- auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags();
- for (const auto &Mask : BitMasks) {
- // Check if the flag's bitmask has the bits of the current mask set.
- if ((BitMask & Mask.first) == Mask.first) {
- if (IsCommaNeeded)
- OS << ", ";
- IsCommaNeeded = true;
- OS << Mask.second;
- // Clear the bits which were serialized from the flag's bitmask.
- BitMask &= ~(Mask.first);
- }
- }
- if (BitMask) {
- // When the resulting flag's bitmask isn't zero, we know that we didn't
- // serialize all of the bit flags.
- if (IsCommaNeeded)
- OS << ", ";
- OS << "<unknown bitmask target flag>";
- }
- OS << ") ";
- }
- void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) {
- OS << "<mcsymbol " << Sym << ">";
- }
- void MachineOperand::printStackObjectReference(raw_ostream &OS,
- unsigned FrameIndex,
- bool IsFixed, StringRef Name) {
- if (IsFixed) {
- OS << "%fixed-stack." << FrameIndex;
- return;
- }
- OS << "%stack." << FrameIndex;
- if (!Name.empty())
- OS << '.' << Name;
- }
- void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) {
- if (Offset == 0)
- return;
- if (Offset < 0) {
- OS << " - " << -Offset;
- return;
- }
- OS << " + " << Offset;
- }
- void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) {
- if (Slot == -1)
- OS << "<badref>";
- else
- OS << Slot;
- }
- static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI,
- const TargetRegisterInfo *TRI) {
- switch (CFI.getOperation()) {
- case MCCFIInstruction::OpSameValue:
- OS << "same_value ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- printCFIRegister(CFI.getRegister(), OS, TRI);
- break;
- case MCCFIInstruction::OpRememberState:
- OS << "remember_state ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- break;
- case MCCFIInstruction::OpRestoreState:
- OS << "restore_state ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- break;
- case MCCFIInstruction::OpOffset:
- OS << "offset ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- printCFIRegister(CFI.getRegister(), OS, TRI);
- OS << ", " << CFI.getOffset();
- break;
- case MCCFIInstruction::OpDefCfaRegister:
- OS << "def_cfa_register ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- printCFIRegister(CFI.getRegister(), OS, TRI);
- break;
- case MCCFIInstruction::OpDefCfaOffset:
- OS << "def_cfa_offset ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- OS << CFI.getOffset();
- break;
- case MCCFIInstruction::OpDefCfa:
- OS << "def_cfa ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- printCFIRegister(CFI.getRegister(), OS, TRI);
- OS << ", " << CFI.getOffset();
- break;
- case MCCFIInstruction::OpLLVMDefAspaceCfa:
- OS << "llvm_def_aspace_cfa ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- printCFIRegister(CFI.getRegister(), OS, TRI);
- OS << ", " << CFI.getOffset();
- OS << ", " << CFI.getAddressSpace();
- break;
- case MCCFIInstruction::OpRelOffset:
- OS << "rel_offset ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- printCFIRegister(CFI.getRegister(), OS, TRI);
- OS << ", " << CFI.getOffset();
- break;
- case MCCFIInstruction::OpAdjustCfaOffset:
- OS << "adjust_cfa_offset ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- OS << CFI.getOffset();
- break;
- case MCCFIInstruction::OpRestore:
- OS << "restore ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- printCFIRegister(CFI.getRegister(), OS, TRI);
- break;
- case MCCFIInstruction::OpEscape: {
- OS << "escape ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- if (!CFI.getValues().empty()) {
- size_t e = CFI.getValues().size() - 1;
- for (size_t i = 0; i < e; ++i)
- OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", ";
- OS << format("0x%02x", uint8_t(CFI.getValues()[e]));
- }
- break;
- }
- case MCCFIInstruction::OpUndefined:
- OS << "undefined ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- printCFIRegister(CFI.getRegister(), OS, TRI);
- break;
- case MCCFIInstruction::OpRegister:
- OS << "register ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- printCFIRegister(CFI.getRegister(), OS, TRI);
- OS << ", ";
- printCFIRegister(CFI.getRegister2(), OS, TRI);
- break;
- case MCCFIInstruction::OpWindowSave:
- OS << "window_save ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- break;
- case MCCFIInstruction::OpNegateRAState:
- OS << "negate_ra_sign_state ";
- if (MCSymbol *Label = CFI.getLabel())
- MachineOperand::printSymbol(OS, *Label);
- break;
- default:
- // TODO: Print the other CFI Operations.
- OS << "<unserializable cfi directive>";
- break;
- }
- }
- 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, TypeToPrint, std::nullopt, /*PrintDef=*/false,
- /*IsStandalone=*/true,
- /*ShouldPrintRegisterTies=*/true,
- /*TiedOperandIdx=*/0, TRI, IntrinsicInfo);
- }
- void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
- LLT TypeToPrint, std::optional<unsigned> OpIdx,
- bool PrintDef, bool IsStandalone,
- bool ShouldPrintRegisterTies,
- unsigned TiedOperandIdx,
- const TargetRegisterInfo *TRI,
- const TargetIntrinsicInfo *IntrinsicInfo) const {
- printTargetFlags(OS, *this);
- switch (getType()) {
- case MachineOperand::MO_Register: {
- Register Reg = getReg();
- if (isImplicit())
- OS << (isDef() ? "implicit-def " : "implicit ");
- else if (PrintDef && isDef())
- // Print the 'def' flag only when the operand is defined after '='.
- OS << "def ";
- if (isInternalRead())
- OS << "internal ";
- if (isDead())
- OS << "dead ";
- if (isKill())
- OS << "killed ";
- if (isUndef())
- OS << "undef ";
- if (isEarlyClobber())
- OS << "early-clobber ";
- if (getReg().isPhysical() && isRenamable())
- OS << "renamable ";
- // isDebug() is exactly true for register operands of a DBG_VALUE. So we
- // simply infer it when parsing and do not need to print it.
- const MachineRegisterInfo *MRI = nullptr;
- if (Reg.isVirtual()) {
- 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)
- OS << '.' << TRI->getSubRegIndexName(SubReg);
- else
- OS << ".subreg" << SubReg;
- }
- // Print the register class / bank.
- if (Reg.isVirtual()) {
- if (const MachineFunction *MF = getMFIfAvailable(*this)) {
- const MachineRegisterInfo &MRI = MF->getRegInfo();
- if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) {
- OS << ':';
- OS << printRegClassOrBank(Reg, MRI, TRI);
- }
- }
- }
- // Print ties.
- if (ShouldPrintRegisterTies && isTied() && !isDef())
- OS << "(tied-def " << TiedOperandIdx << ")";
- // Print types.
- if (TypeToPrint.isValid())
- OS << '(' << TypeToPrint << ')';
- break;
- }
- case MachineOperand::MO_Immediate: {
- const MIRFormatter *Formatter = nullptr;
- if (const MachineFunction *MF = getMFIfAvailable(*this)) {
- const auto *TII = MF->getSubtarget().getInstrInfo();
- assert(TII && "expected instruction info");
- Formatter = TII->getMIRFormatter();
- }
- if (Formatter)
- Formatter->printImm(OS, *getParent(), OpIdx, getImm());
- else
- OS << getImm();
- break;
- }
- case MachineOperand::MO_CImmediate:
- getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
- break;
- case MachineOperand::MO_FPImmediate:
- getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST);
- break;
- case MachineOperand::MO_MachineBasicBlock:
- OS << printMBBReference(*getMBB());
- break;
- case MachineOperand::MO_FrameIndex: {
- int FrameIndex = getIndex();
- bool IsFixed = false;
- const MachineFrameInfo *MFI = nullptr;
- if (const MachineFunction *MF = getMFIfAvailable(*this))
- MFI = &MF->getFrameInfo();
- printFrameIndex(OS, FrameIndex, IsFixed, MFI);
- break;
- }
- case MachineOperand::MO_ConstantPoolIndex:
- OS << "%const." << getIndex();
- printOperandOffset(OS, getOffset());
- break;
- case MachineOperand::MO_TargetIndex: {
- OS << "target-index(";
- const char *Name = "<unknown>";
- if (const MachineFunction *MF = getMFIfAvailable(*this))
- if (const auto *TargetIndexName = ::getTargetIndexName(*MF, getIndex()))
- Name = TargetIndexName;
- OS << Name << ')';
- printOperandOffset(OS, getOffset());
- break;
- }
- case MachineOperand::MO_JumpTableIndex:
- OS << printJumpTableEntryReference(getIndex());
- break;
- case MachineOperand::MO_GlobalAddress:
- getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
- printOperandOffset(OS, getOffset());
- break;
- case MachineOperand::MO_ExternalSymbol: {
- StringRef Name = getSymbolName();
- OS << '&';
- if (Name.empty()) {
- OS << "\"\"";
- } else {
- printLLVMNameWithoutPrefix(OS, Name);
- }
- printOperandOffset(OS, getOffset());
- break;
- }
- case MachineOperand::MO_BlockAddress: {
- OS << "blockaddress(";
- getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
- MST);
- OS << ", ";
- printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST);
- OS << ')';
- MachineOperand::printOperandOffset(OS, getOffset());
- break;
- }
- case MachineOperand::MO_RegisterMask: {
- OS << "<regmask";
- if (TRI) {
- unsigned NumRegsInMask = 0;
- unsigned NumRegsEmitted = 0;
- for (unsigned i = 0; i < TRI->getNumRegs(); ++i) {
- unsigned MaskWord = i / 32;
- unsigned MaskBit = i % 32;
- if (getRegMask()[MaskWord] & (1 << MaskBit)) {
- if (PrintRegMaskNumRegs < 0 ||
- NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) {
- OS << " " << printReg(i, TRI);
- NumRegsEmitted++;
- }
- NumRegsInMask++;
- }
- }
- if (NumRegsEmitted != NumRegsInMask)
- OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more...";
- } else {
- OS << " ...";
- }
- OS << ">";
- break;
- }
- case MachineOperand::MO_RegisterLiveOut: {
- const uint32_t *RegMask = getRegLiveOut();
- OS << "liveout(";
- if (!TRI) {
- OS << "<unknown>";
- } else {
- bool IsCommaNeeded = false;
- for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
- if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
- if (IsCommaNeeded)
- OS << ", ";
- OS << printReg(Reg, TRI);
- IsCommaNeeded = true;
- }
- }
- }
- OS << ")";
- break;
- }
- case MachineOperand::MO_Metadata:
- getMetadata()->printAsOperand(OS, MST);
- break;
- case MachineOperand::MO_MCSymbol:
- printSymbol(OS, *getMCSymbol());
- break;
- case MachineOperand::MO_DbgInstrRef: {
- OS << "dbg-instr-ref(" << getInstrRefInstrIndex() << ", "
- << getInstrRefOpIndex() << ')';
- break;
- }
- case MachineOperand::MO_CFIIndex: {
- if (const MachineFunction *MF = getMFIfAvailable(*this))
- printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI);
- else
- OS << "<cfi directive>";
- break;
- }
- case MachineOperand::MO_IntrinsicID: {
- Intrinsic::ID ID = getIntrinsicID();
- if (ID < Intrinsic::num_intrinsics)
- OS << "intrinsic(@" << Intrinsic::getBaseName(ID) << ')';
- 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) ? "int" : "float") << "pred("
- << CmpInst::getPredicateName(Pred) << ')';
- break;
- }
- case MachineOperand::MO_ShuffleMask:
- OS << "shufflemask(";
- ArrayRef<int> Mask = getShuffleMask();
- StringRef Separator;
- for (int Elt : Mask) {
- if (Elt == -1)
- OS << Separator << "undef";
- else
- OS << Separator << Elt;
- Separator = ", ";
- }
- OS << ')';
- break;
- }
- }
- #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; }
- #endif
- //===----------------------------------------------------------------------===//
- // MachineMemOperand Implementation
- //===----------------------------------------------------------------------===//
- /// getAddrSpace - Return the LLVM IR address space number that this pointer
- /// points into.
- unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; }
- /// isDereferenceable - Return true if V is always dereferenceable for
- /// Offset + Size byte.
- bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C,
- const DataLayout &DL) const {
- if (!V.is<const Value *>())
- return false;
- const Value *BasePtr = V.get<const Value *>();
- if (BasePtr == nullptr)
- return false;
- return isDereferenceableAndAlignedPointer(
- BasePtr, Align(1), APInt(DL.getPointerSizeInBits(), Offset + Size), DL);
- }
- /// getConstantPool - Return a MachinePointerInfo record that refers to the
- /// constant pool.
- 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(MachineFunction &MF,
- int FI, int64_t Offset) {
- return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset);
- }
- MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) {
- return MachinePointerInfo(MF.getPSVManager().getJumpTable());
- }
- MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) {
- return MachinePointerInfo(MF.getPSVManager().getGOT());
- }
- MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF,
- int64_t Offset, uint8_t ID) {
- return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID);
- }
- MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) {
- return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace());
- }
- MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
- LLT type, Align a, const AAMDNodes &AAInfo,
- const MDNode *Ranges, SyncScope::ID SSID,
- AtomicOrdering Ordering,
- AtomicOrdering FailureOrdering)
- : PtrInfo(ptrinfo), MemoryType(type), FlagVals(f), BaseAlign(a),
- AAInfo(AAInfo), Ranges(Ranges) {
- assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() ||
- isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) &&
- "invalid pointer value");
- assert((isLoad() || isStore()) && "Not a load/store!");
- AtomicInfo.SSID = static_cast<unsigned>(SSID);
- assert(getSyncScopeID() == SSID && "Value truncated");
- AtomicInfo.Ordering = static_cast<unsigned>(Ordering);
- assert(getSuccessOrdering() == Ordering && "Value truncated");
- AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering);
- assert(getFailureOrdering() == FailureOrdering && "Value truncated");
- }
- MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
- uint64_t s, Align a,
- const AAMDNodes &AAInfo,
- const MDNode *Ranges, SyncScope::ID SSID,
- AtomicOrdering Ordering,
- AtomicOrdering FailureOrdering)
- : MachineMemOperand(ptrinfo, f,
- s == ~UINT64_C(0) ? LLT() : LLT::scalar(8 * s), a,
- AAInfo, Ranges, SSID, Ordering, FailureOrdering) {}
- /// Profile - Gather unique data for the object.
- ///
- void MachineMemOperand::Profile(FoldingSetNodeID &ID) const {
- ID.AddInteger(getOffset());
- ID.AddInteger(getMemoryType().getUniqueRAWLLTData());
- ID.AddPointer(getOpaqueValue());
- ID.AddInteger(getFlags());
- ID.AddInteger(getBaseAlign().value());
- }
- void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
- // The Value and Offset may differ due to CSE. But the flags and size
- // should be the same.
- assert(MMO->getFlags() == getFlags() && "Flags mismatch!");
- assert((MMO->getSize() == ~UINT64_C(0) || getSize() == ~UINT64_C(0) ||
- MMO->getSize() == getSize()) &&
- "Size mismatch!");
- if (MMO->getBaseAlign() >= getBaseAlign()) {
- // Update the alignment value.
- BaseAlign = MMO->getBaseAlign();
- // Also update the base and offset, because the new alignment may
- // not be applicable with the old ones.
- PtrInfo = MMO->PtrInfo;
- }
- }
- /// getAlign - Return the minimum known alignment in bytes of the
- /// actual memory reference.
- Align MachineMemOperand::getAlign() const {
- return commonAlignment(getBaseAlign(), getOffset());
- }
- 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 ";
- if (isNonTemporal())
- OS << "non-temporal ";
- if (isDereferenceable())
- OS << "dereferenceable ";
- if (isInvariant())
- OS << "invariant ";
- if (TII) {
- 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)
- << "\" ";
- } else {
- if (getFlags() & MachineMemOperand::MOTargetFlag1)
- OS << "\"MOTargetFlag1\" ";
- if (getFlags() & MachineMemOperand::MOTargetFlag2)
- OS << "\"MOTargetFlag2\" ";
- if (getFlags() & MachineMemOperand::MOTargetFlag3)
- OS << "\"MOTargetFlag3\" ";
- }
- assert((isLoad() || isStore()) &&
- "machine memory operand must be a load or store (or both)");
- if (isLoad())
- OS << "load ";
- if (isStore())
- OS << "store ";
- printSyncScope(OS, Context, getSyncScopeID(), SSNs);
- if (getSuccessOrdering() != AtomicOrdering::NotAtomic)
- OS << toIRString(getSuccessOrdering()) << ' ';
- if (getFailureOrdering() != AtomicOrdering::NotAtomic)
- OS << toIRString(getFailureOrdering()) << ' ';
- if (getMemoryType().isValid())
- OS << '(' << getMemoryType() << ')';
- else
- OS << "unknown-size";
- if (const Value *Val = getValue()) {
- OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
- MIRFormatter::printIRValue(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;
- default: {
- const MIRFormatter *Formatter = TII->getMIRFormatter();
- // FIXME: This is not necessarily the correct MIR serialization format for
- // a custom pseudo source value, but at least it allows
- // MIR printing to work on a target with custom pseudo source
- // values.
- OS << "custom \"";
- Formatter->printCustomPseudoSourceValue(OS, MST, *PVal);
- OS << '\"';
- break;
- }
- }
- } else if (getOpaqueValue() == nullptr && getOffset() != 0) {
- OS << ((isLoad() && isStore()) ? " on "
- : isLoad() ? " from "
- : " into ")
- << "unknown-address";
- }
- MachineOperand::printOperandOffset(OS, getOffset());
- if (getSize() > 0 && getAlign() != getSize())
- OS << ", align " << getAlign().value();
- if (getAlign() != getBaseAlign())
- OS << ", basealign " << getBaseAlign().value();
- auto AAInfo = getAAInfo();
- if (AAInfo.TBAA) {
- OS << ", !tbaa ";
- AAInfo.TBAA->printAsOperand(OS, MST);
- }
- 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;
- OS << ')';
- }
|