xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MachineOperand.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- lib/CodeGen/MachineOperand.cpp -------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric /// \file Methods common to all machine operands.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
145f757f3fSDimitry Andric #include "llvm/ADT/StableHashing.h"
150b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
160b57cec5SDimitry Andric #include "llvm/Analysis/Loads.h"
17480093f4SDimitry Andric #include "llvm/CodeGen/MIRFormatter.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
215f757f3fSDimitry Andric #include "llvm/CodeGen/PseudoSourceValueManager.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
240b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
250b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
260b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
275ffd83dbSDimitry Andric #include "llvm/IR/Instructions.h"
280b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
290b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h"
300b57cec5SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
310b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
32bdd1243dSDimitry Andric #include <optional>
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric using namespace llvm;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric static cl::opt<int>
370b57cec5SDimitry Andric     PrintRegMaskNumRegs("print-regmask-num-regs",
380b57cec5SDimitry Andric                         cl::desc("Number of registers to limit to when "
390b57cec5SDimitry Andric                                  "printing regmask operands in IR dumps. "
400b57cec5SDimitry Andric                                  "unlimited = -1"),
410b57cec5SDimitry Andric                         cl::init(32), cl::Hidden);
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineOperand &MO) {
440b57cec5SDimitry Andric   if (const MachineInstr *MI = MO.getParent())
450b57cec5SDimitry Andric     if (const MachineBasicBlock *MBB = MI->getParent())
460b57cec5SDimitry Andric       if (const MachineFunction *MF = MBB->getParent())
470b57cec5SDimitry Andric         return MF;
480b57cec5SDimitry Andric   return nullptr;
490b57cec5SDimitry Andric }
50bdd1243dSDimitry Andric 
510b57cec5SDimitry Andric static MachineFunction *getMFIfAvailable(MachineOperand &MO) {
520b57cec5SDimitry Andric   return const_cast<MachineFunction *>(
530b57cec5SDimitry Andric       getMFIfAvailable(const_cast<const MachineOperand &>(MO)));
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric 
5606c3fb27SDimitry Andric unsigned MachineOperand::getOperandNo() const {
5706c3fb27SDimitry Andric   assert(getParent() && "Operand does not belong to any instruction!");
5806c3fb27SDimitry Andric   return getParent()->getOperandNo(this);
5906c3fb27SDimitry Andric }
6006c3fb27SDimitry Andric 
618bcb0991SDimitry Andric void MachineOperand::setReg(Register Reg) {
620b57cec5SDimitry Andric   if (getReg() == Reg)
630b57cec5SDimitry Andric     return; // No change.
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric   // Clear the IsRenamable bit to keep it conservatively correct.
660b57cec5SDimitry Andric   IsRenamable = false;
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   // Otherwise, we have to change the register.  If this operand is embedded
690b57cec5SDimitry Andric   // into a machine function, we need to update the old and new register's
700b57cec5SDimitry Andric   // use/def lists.
710b57cec5SDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this)) {
720b57cec5SDimitry Andric     MachineRegisterInfo &MRI = MF->getRegInfo();
730b57cec5SDimitry Andric     MRI.removeRegOperandFromUseList(this);
740b57cec5SDimitry Andric     SmallContents.RegNo = Reg;
750b57cec5SDimitry Andric     MRI.addRegOperandToUseList(this);
760b57cec5SDimitry Andric     return;
770b57cec5SDimitry Andric   }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   // Otherwise, just change the register, no problem.  :)
800b57cec5SDimitry Andric   SmallContents.RegNo = Reg;
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric 
838bcb0991SDimitry Andric void MachineOperand::substVirtReg(Register Reg, unsigned SubIdx,
840b57cec5SDimitry Andric                                   const TargetRegisterInfo &TRI) {
858bcb0991SDimitry Andric   assert(Reg.isVirtual());
860b57cec5SDimitry Andric   if (SubIdx && getSubReg())
870b57cec5SDimitry Andric     SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg());
880b57cec5SDimitry Andric   setReg(Reg);
890b57cec5SDimitry Andric   if (SubIdx)
900b57cec5SDimitry Andric     setSubReg(SubIdx);
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
938bcb0991SDimitry Andric void MachineOperand::substPhysReg(MCRegister Reg, const TargetRegisterInfo &TRI) {
94e8d8bef9SDimitry Andric   assert(Register::isPhysicalRegister(Reg));
950b57cec5SDimitry Andric   if (getSubReg()) {
960b57cec5SDimitry Andric     Reg = TRI.getSubReg(Reg, getSubReg());
970b57cec5SDimitry Andric     // Note that getSubReg() may return 0 if the sub-register doesn't exist.
980b57cec5SDimitry Andric     // That won't happen in legal code.
990b57cec5SDimitry Andric     setSubReg(0);
1000b57cec5SDimitry Andric     if (isDef())
1010b57cec5SDimitry Andric       setIsUndef(false);
1020b57cec5SDimitry Andric   }
1030b57cec5SDimitry Andric   setReg(Reg);
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric /// Change a def to a use, or a use to a def.
1070b57cec5SDimitry Andric void MachineOperand::setIsDef(bool Val) {
1080b57cec5SDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
1090b57cec5SDimitry Andric   assert((!Val || !isDebug()) && "Marking a debug operation as def");
1100b57cec5SDimitry Andric   if (IsDef == Val)
1110b57cec5SDimitry Andric     return;
1120b57cec5SDimitry Andric   assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported");
1130b57cec5SDimitry Andric   // MRI may keep uses and defs in different list positions.
1140b57cec5SDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this)) {
1150b57cec5SDimitry Andric     MachineRegisterInfo &MRI = MF->getRegInfo();
1160b57cec5SDimitry Andric     MRI.removeRegOperandFromUseList(this);
1170b57cec5SDimitry Andric     IsDef = Val;
1180b57cec5SDimitry Andric     MRI.addRegOperandToUseList(this);
1190b57cec5SDimitry Andric     return;
1200b57cec5SDimitry Andric   }
1210b57cec5SDimitry Andric   IsDef = Val;
1220b57cec5SDimitry Andric }
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric bool MachineOperand::isRenamable() const {
1250b57cec5SDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
126bdd1243dSDimitry Andric   assert(getReg().isPhysical() &&
1270b57cec5SDimitry Andric          "isRenamable should only be checked on physical registers");
1280b57cec5SDimitry Andric   if (!IsRenamable)
1290b57cec5SDimitry Andric     return false;
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   const MachineInstr *MI = getParent();
1320b57cec5SDimitry Andric   if (!MI)
1330b57cec5SDimitry Andric     return true;
1340b57cec5SDimitry Andric 
1350b57cec5SDimitry Andric   if (isDef())
1360b57cec5SDimitry Andric     return !MI->hasExtraDefRegAllocReq(MachineInstr::IgnoreBundle);
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   assert(isUse() && "Reg is not def or use");
1390b57cec5SDimitry Andric   return !MI->hasExtraSrcRegAllocReq(MachineInstr::IgnoreBundle);
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric void MachineOperand::setIsRenamable(bool Val) {
1430b57cec5SDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
144bdd1243dSDimitry Andric   assert(getReg().isPhysical() &&
1450b57cec5SDimitry Andric          "setIsRenamable should only be called on physical registers");
1460b57cec5SDimitry Andric   IsRenamable = Val;
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric // If this operand is currently a register operand, and if this is in a
1500b57cec5SDimitry Andric // function, deregister the operand from the register's use/def list.
1510b57cec5SDimitry Andric void MachineOperand::removeRegFromUses() {
1520b57cec5SDimitry Andric   if (!isReg() || !isOnRegUseList())
1530b57cec5SDimitry Andric     return;
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this))
1560b57cec5SDimitry Andric     MF->getRegInfo().removeRegOperandFromUseList(this);
1570b57cec5SDimitry Andric }
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric /// ChangeToImmediate - Replace this operand with a new immediate operand of
1600b57cec5SDimitry Andric /// the specified value.  If an operand is known to be an immediate already,
1610b57cec5SDimitry Andric /// the setImm method should be used.
162e8d8bef9SDimitry Andric void MachineOperand::ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags) {
1630b57cec5SDimitry Andric   assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric   removeRegFromUses();
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   OpKind = MO_Immediate;
1680b57cec5SDimitry Andric   Contents.ImmVal = ImmVal;
169e8d8bef9SDimitry Andric   setTargetFlags(TargetFlags);
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric 
172e8d8bef9SDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm,
173e8d8bef9SDimitry Andric                                          unsigned TargetFlags) {
1740b57cec5SDimitry Andric   assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   removeRegFromUses();
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric   OpKind = MO_FPImmediate;
1790b57cec5SDimitry Andric   Contents.CFP = FPImm;
180e8d8bef9SDimitry Andric   setTargetFlags(TargetFlags);
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric void MachineOperand::ChangeToES(const char *SymName,
1848bcb0991SDimitry Andric                                 unsigned TargetFlags) {
1850b57cec5SDimitry Andric   assert((!isReg() || !isTied()) &&
1860b57cec5SDimitry Andric          "Cannot change a tied operand into an external symbol");
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric   removeRegFromUses();
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric   OpKind = MO_ExternalSymbol;
1910b57cec5SDimitry Andric   Contents.OffsetedInfo.Val.SymbolName = SymName;
1920b57cec5SDimitry Andric   setOffset(0); // Offset is always 0.
1930b57cec5SDimitry Andric   setTargetFlags(TargetFlags);
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric void MachineOperand::ChangeToGA(const GlobalValue *GV, int64_t Offset,
1978bcb0991SDimitry Andric                                 unsigned TargetFlags) {
1980b57cec5SDimitry Andric   assert((!isReg() || !isTied()) &&
1990b57cec5SDimitry Andric          "Cannot change a tied operand into a global address");
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric   removeRegFromUses();
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   OpKind = MO_GlobalAddress;
2040b57cec5SDimitry Andric   Contents.OffsetedInfo.Val.GV = GV;
2050b57cec5SDimitry Andric   setOffset(Offset);
2060b57cec5SDimitry Andric   setTargetFlags(TargetFlags);
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric 
2097a6dacacSDimitry Andric void MachineOperand::ChangeToBA(const BlockAddress *BA, int64_t Offset,
2107a6dacacSDimitry Andric                                 unsigned TargetFlags) {
2117a6dacacSDimitry Andric   assert((!isReg() || !isTied()) &&
2127a6dacacSDimitry Andric          "Cannot change a tied operand into a block address");
2137a6dacacSDimitry Andric 
2147a6dacacSDimitry Andric   removeRegFromUses();
2157a6dacacSDimitry Andric 
2167a6dacacSDimitry Andric   OpKind = MO_BlockAddress;
2177a6dacacSDimitry Andric   Contents.OffsetedInfo.Val.BA = BA;
2187a6dacacSDimitry Andric   setOffset(Offset);
2197a6dacacSDimitry Andric   setTargetFlags(TargetFlags);
2207a6dacacSDimitry Andric }
2217a6dacacSDimitry Andric 
222e8d8bef9SDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) {
2230b57cec5SDimitry Andric   assert((!isReg() || !isTied()) &&
2240b57cec5SDimitry Andric          "Cannot change a tied operand into an MCSymbol");
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   removeRegFromUses();
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   OpKind = MO_MCSymbol;
2290b57cec5SDimitry Andric   Contents.Sym = Sym;
230e8d8bef9SDimitry Andric   setTargetFlags(TargetFlags);
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric 
233e8d8bef9SDimitry Andric void MachineOperand::ChangeToFrameIndex(int Idx, unsigned TargetFlags) {
2340b57cec5SDimitry Andric   assert((!isReg() || !isTied()) &&
2350b57cec5SDimitry Andric          "Cannot change a tied operand into a FrameIndex");
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric   removeRegFromUses();
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   OpKind = MO_FrameIndex;
2400b57cec5SDimitry Andric   setIndex(Idx);
241e8d8bef9SDimitry Andric   setTargetFlags(TargetFlags);
2420b57cec5SDimitry Andric }
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset,
2458bcb0991SDimitry Andric                                          unsigned TargetFlags) {
2460b57cec5SDimitry Andric   assert((!isReg() || !isTied()) &&
2470b57cec5SDimitry Andric          "Cannot change a tied operand into a FrameIndex");
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric   removeRegFromUses();
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   OpKind = MO_TargetIndex;
2520b57cec5SDimitry Andric   setIndex(Idx);
2530b57cec5SDimitry Andric   setOffset(Offset);
2540b57cec5SDimitry Andric   setTargetFlags(TargetFlags);
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric 
257bdd1243dSDimitry Andric void MachineOperand::ChangeToDbgInstrRef(unsigned InstrIdx, unsigned OpIdx,
258bdd1243dSDimitry Andric                                          unsigned TargetFlags) {
259bdd1243dSDimitry Andric   assert((!isReg() || !isTied()) &&
260bdd1243dSDimitry Andric          "Cannot change a tied operand into a DbgInstrRef");
261bdd1243dSDimitry Andric 
262bdd1243dSDimitry Andric   removeRegFromUses();
263bdd1243dSDimitry Andric 
264bdd1243dSDimitry Andric   OpKind = MO_DbgInstrRef;
265bdd1243dSDimitry Andric   setInstrRefInstrIndex(InstrIdx);
266bdd1243dSDimitry Andric   setInstrRefOpIndex(OpIdx);
267bdd1243dSDimitry Andric   setTargetFlags(TargetFlags);
268bdd1243dSDimitry Andric }
269bdd1243dSDimitry Andric 
2700b57cec5SDimitry Andric /// ChangeToRegister - Replace this operand with a new register operand of
2710b57cec5SDimitry Andric /// the specified value.  If an operand is known to be an register already,
2720b57cec5SDimitry Andric /// the setReg method should be used.
2738bcb0991SDimitry Andric void MachineOperand::ChangeToRegister(Register Reg, bool isDef, bool isImp,
2740b57cec5SDimitry Andric                                       bool isKill, bool isDead, bool isUndef,
2750b57cec5SDimitry Andric                                       bool isDebug) {
2760b57cec5SDimitry Andric   MachineRegisterInfo *RegInfo = nullptr;
2770b57cec5SDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this))
2780b57cec5SDimitry Andric     RegInfo = &MF->getRegInfo();
2790b57cec5SDimitry Andric   // If this operand is already a register operand, remove it from the
2800b57cec5SDimitry Andric   // register's use/def lists.
2810b57cec5SDimitry Andric   bool WasReg = isReg();
2820b57cec5SDimitry Andric   if (RegInfo && WasReg)
2830b57cec5SDimitry Andric     RegInfo->removeRegOperandFromUseList(this);
2840b57cec5SDimitry Andric 
285349cc55cSDimitry Andric   // Ensure debug instructions set debug flag on register uses.
286349cc55cSDimitry Andric   const MachineInstr *MI = getParent();
287349cc55cSDimitry Andric   if (!isDef && MI && MI->isDebugInstr())
288349cc55cSDimitry Andric     isDebug = true;
289349cc55cSDimitry Andric 
2900b57cec5SDimitry Andric   // Change this to a register and set the reg#.
2910b57cec5SDimitry Andric   assert(!(isDead && !isDef) && "Dead flag on non-def");
2920b57cec5SDimitry Andric   assert(!(isKill && isDef) && "Kill flag on def");
2930b57cec5SDimitry Andric   OpKind = MO_Register;
2940b57cec5SDimitry Andric   SmallContents.RegNo = Reg;
2950b57cec5SDimitry Andric   SubReg_TargetFlags = 0;
2960b57cec5SDimitry Andric   IsDef = isDef;
2970b57cec5SDimitry Andric   IsImp = isImp;
2980b57cec5SDimitry Andric   IsDeadOrKill = isKill | isDead;
2990b57cec5SDimitry Andric   IsRenamable = false;
3000b57cec5SDimitry Andric   IsUndef = isUndef;
3010b57cec5SDimitry Andric   IsInternalRead = false;
3020b57cec5SDimitry Andric   IsEarlyClobber = false;
3030b57cec5SDimitry Andric   IsDebug = isDebug;
3040b57cec5SDimitry Andric   // Ensure isOnRegUseList() returns false.
3050b57cec5SDimitry Andric   Contents.Reg.Prev = nullptr;
3060b57cec5SDimitry Andric   // Preserve the tie when the operand was already a register.
3070b57cec5SDimitry Andric   if (!WasReg)
3080b57cec5SDimitry Andric     TiedTo = 0;
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   // If this operand is embedded in a function, add the operand to the
3110b57cec5SDimitry Andric   // register's use/def list.
3120b57cec5SDimitry Andric   if (RegInfo)
3130b57cec5SDimitry Andric     RegInfo->addRegOperandToUseList(this);
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric /// isIdenticalTo - Return true if this operand is identical to the specified
3170b57cec5SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload
3180b57cec5SDimitry Andric /// below.
3190b57cec5SDimitry Andric bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
3200b57cec5SDimitry Andric   if (getType() != Other.getType() ||
3210b57cec5SDimitry Andric       getTargetFlags() != Other.getTargetFlags())
3220b57cec5SDimitry Andric     return false;
3230b57cec5SDimitry Andric 
3240b57cec5SDimitry Andric   switch (getType()) {
3250b57cec5SDimitry Andric   case MachineOperand::MO_Register:
3260b57cec5SDimitry Andric     return getReg() == Other.getReg() && isDef() == Other.isDef() &&
3270b57cec5SDimitry Andric            getSubReg() == Other.getSubReg();
3280b57cec5SDimitry Andric   case MachineOperand::MO_Immediate:
3290b57cec5SDimitry Andric     return getImm() == Other.getImm();
3300b57cec5SDimitry Andric   case MachineOperand::MO_CImmediate:
3310b57cec5SDimitry Andric     return getCImm() == Other.getCImm();
3320b57cec5SDimitry Andric   case MachineOperand::MO_FPImmediate:
3330b57cec5SDimitry Andric     return getFPImm() == Other.getFPImm();
3340b57cec5SDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
3350b57cec5SDimitry Andric     return getMBB() == Other.getMBB();
3360b57cec5SDimitry Andric   case MachineOperand::MO_FrameIndex:
3370b57cec5SDimitry Andric     return getIndex() == Other.getIndex();
3380b57cec5SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
3390b57cec5SDimitry Andric   case MachineOperand::MO_TargetIndex:
3400b57cec5SDimitry Andric     return getIndex() == Other.getIndex() && getOffset() == Other.getOffset();
3410b57cec5SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
3420b57cec5SDimitry Andric     return getIndex() == Other.getIndex();
3430b57cec5SDimitry Andric   case MachineOperand::MO_GlobalAddress:
3440b57cec5SDimitry Andric     return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset();
3450b57cec5SDimitry Andric   case MachineOperand::MO_ExternalSymbol:
3460b57cec5SDimitry Andric     return strcmp(getSymbolName(), Other.getSymbolName()) == 0 &&
3470b57cec5SDimitry Andric            getOffset() == Other.getOffset();
3480b57cec5SDimitry Andric   case MachineOperand::MO_BlockAddress:
3490b57cec5SDimitry Andric     return getBlockAddress() == Other.getBlockAddress() &&
3500b57cec5SDimitry Andric            getOffset() == Other.getOffset();
3510b57cec5SDimitry Andric   case MachineOperand::MO_RegisterMask:
3520b57cec5SDimitry Andric   case MachineOperand::MO_RegisterLiveOut: {
3530b57cec5SDimitry Andric     // Shallow compare of the two RegMasks
3540b57cec5SDimitry Andric     const uint32_t *RegMask = getRegMask();
3550b57cec5SDimitry Andric     const uint32_t *OtherRegMask = Other.getRegMask();
3560b57cec5SDimitry Andric     if (RegMask == OtherRegMask)
3570b57cec5SDimitry Andric       return true;
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
3600b57cec5SDimitry Andric       const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
361bdd1243dSDimitry Andric       unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
3620b57cec5SDimitry Andric       // Deep compare of the two RegMasks
3630b57cec5SDimitry Andric       return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask);
3640b57cec5SDimitry Andric     }
3650b57cec5SDimitry Andric     // We don't know the size of the RegMask, so we can't deep compare the two
3660b57cec5SDimitry Andric     // reg masks.
3670b57cec5SDimitry Andric     return false;
3680b57cec5SDimitry Andric   }
3690b57cec5SDimitry Andric   case MachineOperand::MO_MCSymbol:
3700b57cec5SDimitry Andric     return getMCSymbol() == Other.getMCSymbol();
371bdd1243dSDimitry Andric   case MachineOperand::MO_DbgInstrRef:
372bdd1243dSDimitry Andric     return getInstrRefInstrIndex() == Other.getInstrRefInstrIndex() &&
373bdd1243dSDimitry Andric            getInstrRefOpIndex() == Other.getInstrRefOpIndex();
3740b57cec5SDimitry Andric   case MachineOperand::MO_CFIIndex:
3750b57cec5SDimitry Andric     return getCFIIndex() == Other.getCFIIndex();
3760b57cec5SDimitry Andric   case MachineOperand::MO_Metadata:
3770b57cec5SDimitry Andric     return getMetadata() == Other.getMetadata();
3780b57cec5SDimitry Andric   case MachineOperand::MO_IntrinsicID:
3790b57cec5SDimitry Andric     return getIntrinsicID() == Other.getIntrinsicID();
3800b57cec5SDimitry Andric   case MachineOperand::MO_Predicate:
3810b57cec5SDimitry Andric     return getPredicate() == Other.getPredicate();
3828bcb0991SDimitry Andric   case MachineOperand::MO_ShuffleMask:
3838bcb0991SDimitry Andric     return getShuffleMask() == Other.getShuffleMask();
3840b57cec5SDimitry Andric   }
3850b57cec5SDimitry Andric   llvm_unreachable("Invalid machine operand type");
3860b57cec5SDimitry Andric }
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above.
3890b57cec5SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) {
3900b57cec5SDimitry Andric   switch (MO.getType()) {
3910b57cec5SDimitry Andric   case MachineOperand::MO_Register:
3920b57cec5SDimitry Andric     // Register operands don't have target flags.
3930b57cec5SDimitry Andric     return hash_combine(MO.getType(), (unsigned)MO.getReg(), MO.getSubReg(), MO.isDef());
3940b57cec5SDimitry Andric   case MachineOperand::MO_Immediate:
3950b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
3960b57cec5SDimitry Andric   case MachineOperand::MO_CImmediate:
3970b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm());
3980b57cec5SDimitry Andric   case MachineOperand::MO_FPImmediate:
3990b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm());
4000b57cec5SDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
4010b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB());
4020b57cec5SDimitry Andric   case MachineOperand::MO_FrameIndex:
4030b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
4040b57cec5SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
4050b57cec5SDimitry Andric   case MachineOperand::MO_TargetIndex:
4060b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(),
4070b57cec5SDimitry Andric                         MO.getOffset());
4080b57cec5SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
4090b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
4100b57cec5SDimitry Andric   case MachineOperand::MO_ExternalSymbol:
4110b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
4120b57cec5SDimitry Andric                         StringRef(MO.getSymbolName()));
4130b57cec5SDimitry Andric   case MachineOperand::MO_GlobalAddress:
4140b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(),
4150b57cec5SDimitry Andric                         MO.getOffset());
4160b57cec5SDimitry Andric   case MachineOperand::MO_BlockAddress:
4170b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(),
4180b57cec5SDimitry Andric                         MO.getOffset());
4190b57cec5SDimitry Andric   case MachineOperand::MO_RegisterMask:
420bdd1243dSDimitry Andric   case MachineOperand::MO_RegisterLiveOut: {
421bdd1243dSDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(MO)) {
422bdd1243dSDimitry Andric       const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
423bdd1243dSDimitry Andric       unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
424bdd1243dSDimitry Andric       const uint32_t *RegMask = MO.getRegMask();
425bdd1243dSDimitry Andric       std::vector<stable_hash> RegMaskHashes(RegMask, RegMask + RegMaskSize);
426bdd1243dSDimitry Andric       return hash_combine(MO.getType(), MO.getTargetFlags(),
427bdd1243dSDimitry Andric                           stable_hash_combine_array(RegMaskHashes.data(),
428bdd1243dSDimitry Andric                                                     RegMaskHashes.size()));
429bdd1243dSDimitry Andric     }
430bdd1243dSDimitry Andric 
431bdd1243dSDimitry Andric     assert(0 && "MachineOperand not associated with any MachineFunction");
432bdd1243dSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags());
433bdd1243dSDimitry Andric   }
4340b57cec5SDimitry Andric   case MachineOperand::MO_Metadata:
4350b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata());
4360b57cec5SDimitry Andric   case MachineOperand::MO_MCSymbol:
4370b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol());
438bdd1243dSDimitry Andric   case MachineOperand::MO_DbgInstrRef:
439bdd1243dSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(),
440bdd1243dSDimitry Andric                         MO.getInstrRefInstrIndex(), MO.getInstrRefOpIndex());
4410b57cec5SDimitry Andric   case MachineOperand::MO_CFIIndex:
4420b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex());
4430b57cec5SDimitry Andric   case MachineOperand::MO_IntrinsicID:
4440b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID());
4450b57cec5SDimitry Andric   case MachineOperand::MO_Predicate:
4460b57cec5SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate());
4478bcb0991SDimitry Andric   case MachineOperand::MO_ShuffleMask:
4488bcb0991SDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getShuffleMask());
4490b57cec5SDimitry Andric   }
4500b57cec5SDimitry Andric   llvm_unreachable("Invalid machine operand type");
4510b57cec5SDimitry Andric }
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from
4540b57cec5SDimitry Andric // it.
4550b57cec5SDimitry Andric static void tryToGetTargetInfo(const MachineOperand &MO,
4560b57cec5SDimitry Andric                                const TargetRegisterInfo *&TRI,
4570b57cec5SDimitry Andric                                const TargetIntrinsicInfo *&IntrinsicInfo) {
4580b57cec5SDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(MO)) {
4590b57cec5SDimitry Andric     TRI = MF->getSubtarget().getRegisterInfo();
4600b57cec5SDimitry Andric     IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
4610b57cec5SDimitry Andric   }
4620b57cec5SDimitry Andric }
4630b57cec5SDimitry Andric 
4640b57cec5SDimitry Andric static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
4650b57cec5SDimitry Andric   const auto *TII = MF.getSubtarget().getInstrInfo();
4660b57cec5SDimitry Andric   assert(TII && "expected instruction info");
4670b57cec5SDimitry Andric   auto Indices = TII->getSerializableTargetIndices();
4680b57cec5SDimitry Andric   auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) {
4690b57cec5SDimitry Andric     return I.first == Index;
4700b57cec5SDimitry Andric   });
4710b57cec5SDimitry Andric   if (Found != Indices.end())
4720b57cec5SDimitry Andric     return Found->second;
4730b57cec5SDimitry Andric   return nullptr;
4740b57cec5SDimitry Andric }
4750b57cec5SDimitry Andric 
476e8d8bef9SDimitry Andric const char *MachineOperand::getTargetIndexName() const {
477e8d8bef9SDimitry Andric   const MachineFunction *MF = getMFIfAvailable(*this);
478e8d8bef9SDimitry Andric   return MF ? ::getTargetIndexName(*MF, this->getIndex()) : nullptr;
479e8d8bef9SDimitry Andric }
480e8d8bef9SDimitry Andric 
4810b57cec5SDimitry Andric static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
4820b57cec5SDimitry Andric   auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
4830b57cec5SDimitry Andric   for (const auto &I : Flags) {
4840b57cec5SDimitry Andric     if (I.first == TF) {
4850b57cec5SDimitry Andric       return I.second;
4860b57cec5SDimitry Andric     }
4870b57cec5SDimitry Andric   }
4880b57cec5SDimitry Andric   return nullptr;
4890b57cec5SDimitry Andric }
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
4920b57cec5SDimitry Andric                              const TargetRegisterInfo *TRI) {
4930b57cec5SDimitry Andric   if (!TRI) {
4940b57cec5SDimitry Andric     OS << "%dwarfreg." << DwarfReg;
4950b57cec5SDimitry Andric     return;
4960b57cec5SDimitry Andric   }
4970b57cec5SDimitry Andric 
498bdd1243dSDimitry Andric   if (std::optional<unsigned> Reg = TRI->getLLVMRegNum(DwarfReg, true))
4998bcb0991SDimitry Andric     OS << printReg(*Reg, TRI);
5008bcb0991SDimitry Andric   else
5010b57cec5SDimitry Andric     OS << "<badreg>";
5020b57cec5SDimitry Andric }
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB,
5050b57cec5SDimitry Andric                                   ModuleSlotTracker &MST) {
5060b57cec5SDimitry Andric   OS << "%ir-block.";
5070b57cec5SDimitry Andric   if (BB.hasName()) {
5080b57cec5SDimitry Andric     printLLVMNameWithoutPrefix(OS, BB.getName());
5090b57cec5SDimitry Andric     return;
5100b57cec5SDimitry Andric   }
511bdd1243dSDimitry Andric   std::optional<int> Slot;
5120b57cec5SDimitry Andric   if (const Function *F = BB.getParent()) {
5130b57cec5SDimitry Andric     if (F == MST.getCurrentFunction()) {
5140b57cec5SDimitry Andric       Slot = MST.getLocalSlot(&BB);
5150b57cec5SDimitry Andric     } else if (const Module *M = F->getParent()) {
5160b57cec5SDimitry Andric       ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false);
5170b57cec5SDimitry Andric       CustomMST.incorporateFunction(*F);
5180b57cec5SDimitry Andric       Slot = CustomMST.getLocalSlot(&BB);
5190b57cec5SDimitry Andric     }
5200b57cec5SDimitry Andric   }
5210b57cec5SDimitry Andric   if (Slot)
5220b57cec5SDimitry Andric     MachineOperand::printIRSlotNumber(OS, *Slot);
5230b57cec5SDimitry Andric   else
5240b57cec5SDimitry Andric     OS << "<unknown>";
5250b57cec5SDimitry Andric }
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric static void printSyncScope(raw_ostream &OS, const LLVMContext &Context,
5280b57cec5SDimitry Andric                            SyncScope::ID SSID,
5290b57cec5SDimitry Andric                            SmallVectorImpl<StringRef> &SSNs) {
5300b57cec5SDimitry Andric   switch (SSID) {
5310b57cec5SDimitry Andric   case SyncScope::System:
5320b57cec5SDimitry Andric     break;
5330b57cec5SDimitry Andric   default:
5340b57cec5SDimitry Andric     if (SSNs.empty())
5350b57cec5SDimitry Andric       Context.getSyncScopeNames(SSNs);
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric     OS << "syncscope(\"";
5380b57cec5SDimitry Andric     printEscapedString(SSNs[SSID], OS);
5390b57cec5SDimitry Andric     OS << "\") ";
5400b57cec5SDimitry Andric     break;
5410b57cec5SDimitry Andric   }
5420b57cec5SDimitry Andric }
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric static const char *getTargetMMOFlagName(const TargetInstrInfo &TII,
5450b57cec5SDimitry Andric                                         unsigned TMMOFlag) {
5460b57cec5SDimitry Andric   auto Flags = TII.getSerializableMachineMemOperandTargetFlags();
5470b57cec5SDimitry Andric   for (const auto &I : Flags) {
5480b57cec5SDimitry Andric     if (I.first == TMMOFlag) {
5490b57cec5SDimitry Andric       return I.second;
5500b57cec5SDimitry Andric     }
5510b57cec5SDimitry Andric   }
5520b57cec5SDimitry Andric   return nullptr;
5530b57cec5SDimitry Andric }
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric static void printFrameIndex(raw_ostream& OS, int FrameIndex, bool IsFixed,
5560b57cec5SDimitry Andric                             const MachineFrameInfo *MFI) {
5570b57cec5SDimitry Andric   StringRef Name;
5580b57cec5SDimitry Andric   if (MFI) {
5590b57cec5SDimitry Andric     IsFixed = MFI->isFixedObjectIndex(FrameIndex);
5600b57cec5SDimitry Andric     if (const AllocaInst *Alloca = MFI->getObjectAllocation(FrameIndex))
5610b57cec5SDimitry Andric       if (Alloca->hasName())
5620b57cec5SDimitry Andric         Name = Alloca->getName();
5630b57cec5SDimitry Andric     if (IsFixed)
5640b57cec5SDimitry Andric       FrameIndex -= MFI->getObjectIndexBegin();
5650b57cec5SDimitry Andric   }
5660b57cec5SDimitry Andric   MachineOperand::printStackObjectReference(OS, FrameIndex, IsFixed, Name);
5670b57cec5SDimitry Andric }
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index,
5700b57cec5SDimitry Andric                                     const TargetRegisterInfo *TRI) {
5710b57cec5SDimitry Andric   OS << "%subreg.";
572bdd1243dSDimitry Andric   if (TRI && Index != 0 && Index < TRI->getNumSubRegIndices())
5730b57cec5SDimitry Andric     OS << TRI->getSubRegIndexName(Index);
5740b57cec5SDimitry Andric   else
5750b57cec5SDimitry Andric     OS << Index;
5760b57cec5SDimitry Andric }
5770b57cec5SDimitry Andric 
5780b57cec5SDimitry Andric void MachineOperand::printTargetFlags(raw_ostream &OS,
5790b57cec5SDimitry Andric                                       const MachineOperand &Op) {
5800b57cec5SDimitry Andric   if (!Op.getTargetFlags())
5810b57cec5SDimitry Andric     return;
5820b57cec5SDimitry Andric   const MachineFunction *MF = getMFIfAvailable(Op);
5830b57cec5SDimitry Andric   if (!MF)
5840b57cec5SDimitry Andric     return;
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric   const auto *TII = MF->getSubtarget().getInstrInfo();
5870b57cec5SDimitry Andric   assert(TII && "expected instruction info");
5880b57cec5SDimitry Andric   auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
5890b57cec5SDimitry Andric   OS << "target-flags(";
5900b57cec5SDimitry Andric   const bool HasDirectFlags = Flags.first;
5910b57cec5SDimitry Andric   const bool HasBitmaskFlags = Flags.second;
5920b57cec5SDimitry Andric   if (!HasDirectFlags && !HasBitmaskFlags) {
5930b57cec5SDimitry Andric     OS << "<unknown>) ";
5940b57cec5SDimitry Andric     return;
5950b57cec5SDimitry Andric   }
5960b57cec5SDimitry Andric   if (HasDirectFlags) {
5970b57cec5SDimitry Andric     if (const auto *Name = getTargetFlagName(TII, Flags.first))
5980b57cec5SDimitry Andric       OS << Name;
5990b57cec5SDimitry Andric     else
6000b57cec5SDimitry Andric       OS << "<unknown target flag>";
6010b57cec5SDimitry Andric   }
6020b57cec5SDimitry Andric   if (!HasBitmaskFlags) {
6030b57cec5SDimitry Andric     OS << ") ";
6040b57cec5SDimitry Andric     return;
6050b57cec5SDimitry Andric   }
6060b57cec5SDimitry Andric   bool IsCommaNeeded = HasDirectFlags;
6070b57cec5SDimitry Andric   unsigned BitMask = Flags.second;
6080b57cec5SDimitry Andric   auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags();
6090b57cec5SDimitry Andric   for (const auto &Mask : BitMasks) {
6100b57cec5SDimitry Andric     // Check if the flag's bitmask has the bits of the current mask set.
6110b57cec5SDimitry Andric     if ((BitMask & Mask.first) == Mask.first) {
6120b57cec5SDimitry Andric       if (IsCommaNeeded)
6130b57cec5SDimitry Andric         OS << ", ";
6140b57cec5SDimitry Andric       IsCommaNeeded = true;
6150b57cec5SDimitry Andric       OS << Mask.second;
6160b57cec5SDimitry Andric       // Clear the bits which were serialized from the flag's bitmask.
6170b57cec5SDimitry Andric       BitMask &= ~(Mask.first);
6180b57cec5SDimitry Andric     }
6190b57cec5SDimitry Andric   }
6200b57cec5SDimitry Andric   if (BitMask) {
6210b57cec5SDimitry Andric     // When the resulting flag's bitmask isn't zero, we know that we didn't
6220b57cec5SDimitry Andric     // serialize all of the bit flags.
6230b57cec5SDimitry Andric     if (IsCommaNeeded)
6240b57cec5SDimitry Andric       OS << ", ";
6250b57cec5SDimitry Andric     OS << "<unknown bitmask target flag>";
6260b57cec5SDimitry Andric   }
6270b57cec5SDimitry Andric   OS << ") ";
6280b57cec5SDimitry Andric }
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) {
6310b57cec5SDimitry Andric   OS << "<mcsymbol " << Sym << ">";
6320b57cec5SDimitry Andric }
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric void MachineOperand::printStackObjectReference(raw_ostream &OS,
6350b57cec5SDimitry Andric                                                unsigned FrameIndex,
6360b57cec5SDimitry Andric                                                bool IsFixed, StringRef Name) {
6370b57cec5SDimitry Andric   if (IsFixed) {
6380b57cec5SDimitry Andric     OS << "%fixed-stack." << FrameIndex;
6390b57cec5SDimitry Andric     return;
6400b57cec5SDimitry Andric   }
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric   OS << "%stack." << FrameIndex;
6430b57cec5SDimitry Andric   if (!Name.empty())
6440b57cec5SDimitry Andric     OS << '.' << Name;
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) {
6480b57cec5SDimitry Andric   if (Offset == 0)
6490b57cec5SDimitry Andric     return;
6500b57cec5SDimitry Andric   if (Offset < 0) {
6510b57cec5SDimitry Andric     OS << " - " << -Offset;
6520b57cec5SDimitry Andric     return;
6530b57cec5SDimitry Andric   }
6540b57cec5SDimitry Andric   OS << " + " << Offset;
6550b57cec5SDimitry Andric }
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) {
6580b57cec5SDimitry Andric   if (Slot == -1)
6590b57cec5SDimitry Andric     OS << "<badref>";
6600b57cec5SDimitry Andric   else
6610b57cec5SDimitry Andric     OS << Slot;
6620b57cec5SDimitry Andric }
6630b57cec5SDimitry Andric 
6640b57cec5SDimitry Andric static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI,
6650b57cec5SDimitry Andric                      const TargetRegisterInfo *TRI) {
6660b57cec5SDimitry Andric   switch (CFI.getOperation()) {
6670b57cec5SDimitry Andric   case MCCFIInstruction::OpSameValue:
6680b57cec5SDimitry Andric     OS << "same_value ";
6690b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
6700b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
6710b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
6720b57cec5SDimitry Andric     break;
6730b57cec5SDimitry Andric   case MCCFIInstruction::OpRememberState:
6740b57cec5SDimitry Andric     OS << "remember_state ";
6750b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
6760b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
6770b57cec5SDimitry Andric     break;
6780b57cec5SDimitry Andric   case MCCFIInstruction::OpRestoreState:
6790b57cec5SDimitry Andric     OS << "restore_state ";
6800b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
6810b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
6820b57cec5SDimitry Andric     break;
6830b57cec5SDimitry Andric   case MCCFIInstruction::OpOffset:
6840b57cec5SDimitry Andric     OS << "offset ";
6850b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
6860b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
6870b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
6880b57cec5SDimitry Andric     OS << ", " << CFI.getOffset();
6890b57cec5SDimitry Andric     break;
6900b57cec5SDimitry Andric   case MCCFIInstruction::OpDefCfaRegister:
6910b57cec5SDimitry Andric     OS << "def_cfa_register ";
6920b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
6930b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
6940b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
6950b57cec5SDimitry Andric     break;
6960b57cec5SDimitry Andric   case MCCFIInstruction::OpDefCfaOffset:
6970b57cec5SDimitry Andric     OS << "def_cfa_offset ";
6980b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
6990b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
7000b57cec5SDimitry Andric     OS << CFI.getOffset();
7010b57cec5SDimitry Andric     break;
7020b57cec5SDimitry Andric   case MCCFIInstruction::OpDefCfa:
7030b57cec5SDimitry Andric     OS << "def_cfa ";
7040b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
7050b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
7060b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
7070b57cec5SDimitry Andric     OS << ", " << CFI.getOffset();
7080b57cec5SDimitry Andric     break;
709fe6060f1SDimitry Andric   case MCCFIInstruction::OpLLVMDefAspaceCfa:
710fe6060f1SDimitry Andric     OS << "llvm_def_aspace_cfa ";
711fe6060f1SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
712fe6060f1SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
713fe6060f1SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
714fe6060f1SDimitry Andric     OS << ", " << CFI.getOffset();
715fe6060f1SDimitry Andric     OS << ", " << CFI.getAddressSpace();
716fe6060f1SDimitry Andric     break;
7170b57cec5SDimitry Andric   case MCCFIInstruction::OpRelOffset:
7180b57cec5SDimitry Andric     OS << "rel_offset ";
7190b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
7200b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
7210b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
7220b57cec5SDimitry Andric     OS << ", " << CFI.getOffset();
7230b57cec5SDimitry Andric     break;
7240b57cec5SDimitry Andric   case MCCFIInstruction::OpAdjustCfaOffset:
7250b57cec5SDimitry Andric     OS << "adjust_cfa_offset ";
7260b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
7270b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
7280b57cec5SDimitry Andric     OS << CFI.getOffset();
7290b57cec5SDimitry Andric     break;
7300b57cec5SDimitry Andric   case MCCFIInstruction::OpRestore:
7310b57cec5SDimitry Andric     OS << "restore ";
7320b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
7330b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
7340b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
7350b57cec5SDimitry Andric     break;
7360b57cec5SDimitry Andric   case MCCFIInstruction::OpEscape: {
7370b57cec5SDimitry Andric     OS << "escape ";
7380b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
7390b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
7400b57cec5SDimitry Andric     if (!CFI.getValues().empty()) {
7410b57cec5SDimitry Andric       size_t e = CFI.getValues().size() - 1;
7420b57cec5SDimitry Andric       for (size_t i = 0; i < e; ++i)
7430b57cec5SDimitry Andric         OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", ";
7445ffd83dbSDimitry Andric       OS << format("0x%02x", uint8_t(CFI.getValues()[e]));
7450b57cec5SDimitry Andric     }
7460b57cec5SDimitry Andric     break;
7470b57cec5SDimitry Andric   }
7480b57cec5SDimitry Andric   case MCCFIInstruction::OpUndefined:
7490b57cec5SDimitry Andric     OS << "undefined ";
7500b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
7510b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
7520b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
7530b57cec5SDimitry Andric     break;
7540b57cec5SDimitry Andric   case MCCFIInstruction::OpRegister:
7550b57cec5SDimitry Andric     OS << "register ";
7560b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
7570b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
7580b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
7590b57cec5SDimitry Andric     OS << ", ";
7600b57cec5SDimitry Andric     printCFIRegister(CFI.getRegister2(), OS, TRI);
7610b57cec5SDimitry Andric     break;
7620b57cec5SDimitry Andric   case MCCFIInstruction::OpWindowSave:
7630b57cec5SDimitry Andric     OS << "window_save ";
7640b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
7650b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
7660b57cec5SDimitry Andric     break;
7670b57cec5SDimitry Andric   case MCCFIInstruction::OpNegateRAState:
7680b57cec5SDimitry Andric     OS << "negate_ra_sign_state ";
7690b57cec5SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
7700b57cec5SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
7710b57cec5SDimitry Andric     break;
7720b57cec5SDimitry Andric   default:
7730b57cec5SDimitry Andric     // TODO: Print the other CFI Operations.
7740b57cec5SDimitry Andric     OS << "<unserializable cfi directive>";
7750b57cec5SDimitry Andric     break;
7760b57cec5SDimitry Andric   }
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI,
7800b57cec5SDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
7810b57cec5SDimitry Andric   print(OS, LLT{}, TRI, IntrinsicInfo);
7820b57cec5SDimitry Andric }
7830b57cec5SDimitry Andric 
7840b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, LLT TypeToPrint,
7850b57cec5SDimitry Andric                            const TargetRegisterInfo *TRI,
7860b57cec5SDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
7870b57cec5SDimitry Andric   tryToGetTargetInfo(*this, TRI, IntrinsicInfo);
7880b57cec5SDimitry Andric   ModuleSlotTracker DummyMST(nullptr);
789bdd1243dSDimitry Andric   print(OS, DummyMST, TypeToPrint, std::nullopt, /*PrintDef=*/false,
790480093f4SDimitry Andric         /*IsStandalone=*/true,
7910b57cec5SDimitry Andric         /*ShouldPrintRegisterTies=*/true,
7920b57cec5SDimitry Andric         /*TiedOperandIdx=*/0, TRI, IntrinsicInfo);
7930b57cec5SDimitry Andric }
7940b57cec5SDimitry Andric 
7950b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
796bdd1243dSDimitry Andric                            LLT TypeToPrint, std::optional<unsigned> OpIdx,
797bdd1243dSDimitry Andric                            bool PrintDef, bool IsStandalone,
798bdd1243dSDimitry Andric                            bool ShouldPrintRegisterTies,
7990b57cec5SDimitry Andric                            unsigned TiedOperandIdx,
8000b57cec5SDimitry Andric                            const TargetRegisterInfo *TRI,
8010b57cec5SDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
8020b57cec5SDimitry Andric   printTargetFlags(OS, *this);
8030b57cec5SDimitry Andric   switch (getType()) {
8040b57cec5SDimitry Andric   case MachineOperand::MO_Register: {
8058bcb0991SDimitry Andric     Register Reg = getReg();
8060b57cec5SDimitry Andric     if (isImplicit())
8070b57cec5SDimitry Andric       OS << (isDef() ? "implicit-def " : "implicit ");
8080b57cec5SDimitry Andric     else if (PrintDef && isDef())
8090b57cec5SDimitry Andric       // Print the 'def' flag only when the operand is defined after '='.
8100b57cec5SDimitry Andric       OS << "def ";
8110b57cec5SDimitry Andric     if (isInternalRead())
8120b57cec5SDimitry Andric       OS << "internal ";
8130b57cec5SDimitry Andric     if (isDead())
8140b57cec5SDimitry Andric       OS << "dead ";
8150b57cec5SDimitry Andric     if (isKill())
8160b57cec5SDimitry Andric       OS << "killed ";
8170b57cec5SDimitry Andric     if (isUndef())
8180b57cec5SDimitry Andric       OS << "undef ";
8190b57cec5SDimitry Andric     if (isEarlyClobber())
8200b57cec5SDimitry Andric       OS << "early-clobber ";
821bdd1243dSDimitry Andric     if (getReg().isPhysical() && isRenamable())
8220b57cec5SDimitry Andric       OS << "renamable ";
8230b57cec5SDimitry Andric     // isDebug() is exactly true for register operands of a DBG_VALUE. So we
8240b57cec5SDimitry Andric     // simply infer it when parsing and do not need to print it.
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric     const MachineRegisterInfo *MRI = nullptr;
827bdd1243dSDimitry Andric     if (Reg.isVirtual()) {
8280b57cec5SDimitry Andric       if (const MachineFunction *MF = getMFIfAvailable(*this)) {
8290b57cec5SDimitry Andric         MRI = &MF->getRegInfo();
8300b57cec5SDimitry Andric       }
8310b57cec5SDimitry Andric     }
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric     OS << printReg(Reg, TRI, 0, MRI);
8340b57cec5SDimitry Andric     // Print the sub register.
8350b57cec5SDimitry Andric     if (unsigned SubReg = getSubReg()) {
8360b57cec5SDimitry Andric       if (TRI)
8370b57cec5SDimitry Andric         OS << '.' << TRI->getSubRegIndexName(SubReg);
8380b57cec5SDimitry Andric       else
8390b57cec5SDimitry Andric         OS << ".subreg" << SubReg;
8400b57cec5SDimitry Andric     }
8410b57cec5SDimitry Andric     // Print the register class / bank.
842bdd1243dSDimitry Andric     if (Reg.isVirtual()) {
8430b57cec5SDimitry Andric       if (const MachineFunction *MF = getMFIfAvailable(*this)) {
8440b57cec5SDimitry Andric         const MachineRegisterInfo &MRI = MF->getRegInfo();
8450b57cec5SDimitry Andric         if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) {
8460b57cec5SDimitry Andric           OS << ':';
8470b57cec5SDimitry Andric           OS << printRegClassOrBank(Reg, MRI, TRI);
8480b57cec5SDimitry Andric         }
8490b57cec5SDimitry Andric       }
8500b57cec5SDimitry Andric     }
8510b57cec5SDimitry Andric     // Print ties.
8520b57cec5SDimitry Andric     if (ShouldPrintRegisterTies && isTied() && !isDef())
8530b57cec5SDimitry Andric       OS << "(tied-def " << TiedOperandIdx << ")";
8540b57cec5SDimitry Andric     // Print types.
8550b57cec5SDimitry Andric     if (TypeToPrint.isValid())
8560b57cec5SDimitry Andric       OS << '(' << TypeToPrint << ')';
8570b57cec5SDimitry Andric     break;
8580b57cec5SDimitry Andric   }
859480093f4SDimitry Andric   case MachineOperand::MO_Immediate: {
860480093f4SDimitry Andric     const MIRFormatter *Formatter = nullptr;
861480093f4SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
862480093f4SDimitry Andric       const auto *TII = MF->getSubtarget().getInstrInfo();
863480093f4SDimitry Andric       assert(TII && "expected instruction info");
864480093f4SDimitry Andric       Formatter = TII->getMIRFormatter();
865480093f4SDimitry Andric     }
866480093f4SDimitry Andric     if (Formatter)
867480093f4SDimitry Andric       Formatter->printImm(OS, *getParent(), OpIdx, getImm());
868480093f4SDimitry Andric     else
8690b57cec5SDimitry Andric       OS << getImm();
8700b57cec5SDimitry Andric     break;
871480093f4SDimitry Andric   }
8720b57cec5SDimitry Andric   case MachineOperand::MO_CImmediate:
8730b57cec5SDimitry Andric     getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
8740b57cec5SDimitry Andric     break;
8750b57cec5SDimitry Andric   case MachineOperand::MO_FPImmediate:
8760b57cec5SDimitry Andric     getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST);
8770b57cec5SDimitry Andric     break;
8780b57cec5SDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
8790b57cec5SDimitry Andric     OS << printMBBReference(*getMBB());
8800b57cec5SDimitry Andric     break;
8810b57cec5SDimitry Andric   case MachineOperand::MO_FrameIndex: {
8820b57cec5SDimitry Andric     int FrameIndex = getIndex();
8830b57cec5SDimitry Andric     bool IsFixed = false;
8840b57cec5SDimitry Andric     const MachineFrameInfo *MFI = nullptr;
8850b57cec5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
8860b57cec5SDimitry Andric       MFI = &MF->getFrameInfo();
8870b57cec5SDimitry Andric     printFrameIndex(OS, FrameIndex, IsFixed, MFI);
8880b57cec5SDimitry Andric     break;
8890b57cec5SDimitry Andric   }
8900b57cec5SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
8910b57cec5SDimitry Andric     OS << "%const." << getIndex();
8920b57cec5SDimitry Andric     printOperandOffset(OS, getOffset());
8930b57cec5SDimitry Andric     break;
8940b57cec5SDimitry Andric   case MachineOperand::MO_TargetIndex: {
8950b57cec5SDimitry Andric     OS << "target-index(";
8960b57cec5SDimitry Andric     const char *Name = "<unknown>";
8970b57cec5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
898e8d8bef9SDimitry Andric       if (const auto *TargetIndexName = ::getTargetIndexName(*MF, getIndex()))
8990b57cec5SDimitry Andric         Name = TargetIndexName;
9000b57cec5SDimitry Andric     OS << Name << ')';
9010b57cec5SDimitry Andric     printOperandOffset(OS, getOffset());
9020b57cec5SDimitry Andric     break;
9030b57cec5SDimitry Andric   }
9040b57cec5SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
9050b57cec5SDimitry Andric     OS << printJumpTableEntryReference(getIndex());
9060b57cec5SDimitry Andric     break;
9070b57cec5SDimitry Andric   case MachineOperand::MO_GlobalAddress:
9080b57cec5SDimitry Andric     getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
9090b57cec5SDimitry Andric     printOperandOffset(OS, getOffset());
9100b57cec5SDimitry Andric     break;
9110b57cec5SDimitry Andric   case MachineOperand::MO_ExternalSymbol: {
9120b57cec5SDimitry Andric     StringRef Name = getSymbolName();
9130b57cec5SDimitry Andric     OS << '&';
9140b57cec5SDimitry Andric     if (Name.empty()) {
9150b57cec5SDimitry Andric       OS << "\"\"";
9160b57cec5SDimitry Andric     } else {
9170b57cec5SDimitry Andric       printLLVMNameWithoutPrefix(OS, Name);
9180b57cec5SDimitry Andric     }
9190b57cec5SDimitry Andric     printOperandOffset(OS, getOffset());
9200b57cec5SDimitry Andric     break;
9210b57cec5SDimitry Andric   }
9220b57cec5SDimitry Andric   case MachineOperand::MO_BlockAddress: {
9230b57cec5SDimitry Andric     OS << "blockaddress(";
9240b57cec5SDimitry Andric     getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
9250b57cec5SDimitry Andric                                                      MST);
9260b57cec5SDimitry Andric     OS << ", ";
9270b57cec5SDimitry Andric     printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST);
9280b57cec5SDimitry Andric     OS << ')';
9290b57cec5SDimitry Andric     MachineOperand::printOperandOffset(OS, getOffset());
9300b57cec5SDimitry Andric     break;
9310b57cec5SDimitry Andric   }
9320b57cec5SDimitry Andric   case MachineOperand::MO_RegisterMask: {
9330b57cec5SDimitry Andric     OS << "<regmask";
9340b57cec5SDimitry Andric     if (TRI) {
9350b57cec5SDimitry Andric       unsigned NumRegsInMask = 0;
9360b57cec5SDimitry Andric       unsigned NumRegsEmitted = 0;
9370b57cec5SDimitry Andric       for (unsigned i = 0; i < TRI->getNumRegs(); ++i) {
9380b57cec5SDimitry Andric         unsigned MaskWord = i / 32;
9390b57cec5SDimitry Andric         unsigned MaskBit = i % 32;
9400b57cec5SDimitry Andric         if (getRegMask()[MaskWord] & (1 << MaskBit)) {
9410b57cec5SDimitry Andric           if (PrintRegMaskNumRegs < 0 ||
9420b57cec5SDimitry Andric               NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) {
9430b57cec5SDimitry Andric             OS << " " << printReg(i, TRI);
9440b57cec5SDimitry Andric             NumRegsEmitted++;
9450b57cec5SDimitry Andric           }
9460b57cec5SDimitry Andric           NumRegsInMask++;
9470b57cec5SDimitry Andric         }
9480b57cec5SDimitry Andric       }
9490b57cec5SDimitry Andric       if (NumRegsEmitted != NumRegsInMask)
9500b57cec5SDimitry Andric         OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more...";
9510b57cec5SDimitry Andric     } else {
9520b57cec5SDimitry Andric       OS << " ...";
9530b57cec5SDimitry Andric     }
9540b57cec5SDimitry Andric     OS << ">";
9550b57cec5SDimitry Andric     break;
9560b57cec5SDimitry Andric   }
9570b57cec5SDimitry Andric   case MachineOperand::MO_RegisterLiveOut: {
9580b57cec5SDimitry Andric     const uint32_t *RegMask = getRegLiveOut();
9590b57cec5SDimitry Andric     OS << "liveout(";
9600b57cec5SDimitry Andric     if (!TRI) {
9610b57cec5SDimitry Andric       OS << "<unknown>";
9620b57cec5SDimitry Andric     } else {
9630b57cec5SDimitry Andric       bool IsCommaNeeded = false;
9640b57cec5SDimitry Andric       for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
9650b57cec5SDimitry Andric         if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
9660b57cec5SDimitry Andric           if (IsCommaNeeded)
9670b57cec5SDimitry Andric             OS << ", ";
9680b57cec5SDimitry Andric           OS << printReg(Reg, TRI);
9690b57cec5SDimitry Andric           IsCommaNeeded = true;
9700b57cec5SDimitry Andric         }
9710b57cec5SDimitry Andric       }
9720b57cec5SDimitry Andric     }
9730b57cec5SDimitry Andric     OS << ")";
9740b57cec5SDimitry Andric     break;
9750b57cec5SDimitry Andric   }
9760b57cec5SDimitry Andric   case MachineOperand::MO_Metadata:
9770b57cec5SDimitry Andric     getMetadata()->printAsOperand(OS, MST);
9780b57cec5SDimitry Andric     break;
9790b57cec5SDimitry Andric   case MachineOperand::MO_MCSymbol:
9800b57cec5SDimitry Andric     printSymbol(OS, *getMCSymbol());
9810b57cec5SDimitry Andric     break;
982bdd1243dSDimitry Andric   case MachineOperand::MO_DbgInstrRef: {
983bdd1243dSDimitry Andric     OS << "dbg-instr-ref(" << getInstrRefInstrIndex() << ", "
984bdd1243dSDimitry Andric        << getInstrRefOpIndex() << ')';
985bdd1243dSDimitry Andric     break;
986bdd1243dSDimitry Andric   }
9870b57cec5SDimitry Andric   case MachineOperand::MO_CFIIndex: {
9880b57cec5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
9890b57cec5SDimitry Andric       printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI);
9900b57cec5SDimitry Andric     else
9910b57cec5SDimitry Andric       OS << "<cfi directive>";
9920b57cec5SDimitry Andric     break;
9930b57cec5SDimitry Andric   }
9940b57cec5SDimitry Andric   case MachineOperand::MO_IntrinsicID: {
9950b57cec5SDimitry Andric     Intrinsic::ID ID = getIntrinsicID();
9960b57cec5SDimitry Andric     if (ID < Intrinsic::num_intrinsics)
997fe6060f1SDimitry Andric       OS << "intrinsic(@" << Intrinsic::getBaseName(ID) << ')';
9980b57cec5SDimitry Andric     else if (IntrinsicInfo)
9990b57cec5SDimitry Andric       OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')';
10000b57cec5SDimitry Andric     else
10010b57cec5SDimitry Andric       OS << "intrinsic(" << ID << ')';
10020b57cec5SDimitry Andric     break;
10030b57cec5SDimitry Andric   }
10040b57cec5SDimitry Andric   case MachineOperand::MO_Predicate: {
10050b57cec5SDimitry Andric     auto Pred = static_cast<CmpInst::Predicate>(getPredicate());
10060b57cec5SDimitry Andric     OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred("
100706c3fb27SDimitry Andric        << Pred << ')';
10080b57cec5SDimitry Andric     break;
10090b57cec5SDimitry Andric   }
10108bcb0991SDimitry Andric   case MachineOperand::MO_ShuffleMask:
10118bcb0991SDimitry Andric     OS << "shufflemask(";
1012480093f4SDimitry Andric     ArrayRef<int> Mask = getShuffleMask();
10138bcb0991SDimitry Andric     StringRef Separator;
1014480093f4SDimitry Andric     for (int Elt : Mask) {
1015480093f4SDimitry Andric       if (Elt == -1)
1016480093f4SDimitry Andric         OS << Separator << "undef";
1017480093f4SDimitry Andric       else
1018480093f4SDimitry Andric         OS << Separator << Elt;
10198bcb0991SDimitry Andric       Separator = ", ";
10208bcb0991SDimitry Andric     }
10218bcb0991SDimitry Andric 
10228bcb0991SDimitry Andric     OS << ')';
10238bcb0991SDimitry Andric     break;
10240b57cec5SDimitry Andric   }
10250b57cec5SDimitry Andric }
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
10280b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; }
10290b57cec5SDimitry Andric #endif
10300b57cec5SDimitry Andric 
10310b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10320b57cec5SDimitry Andric // MachineMemOperand Implementation
10330b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer
10360b57cec5SDimitry Andric /// points into.
10370b57cec5SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; }
10380b57cec5SDimitry Andric 
10390b57cec5SDimitry Andric /// isDereferenceable - Return true if V is always dereferenceable for
10400b57cec5SDimitry Andric /// Offset + Size byte.
10410b57cec5SDimitry Andric bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C,
10420b57cec5SDimitry Andric                                            const DataLayout &DL) const {
104306c3fb27SDimitry Andric   if (!isa<const Value *>(V))
10440b57cec5SDimitry Andric     return false;
10450b57cec5SDimitry Andric 
104606c3fb27SDimitry Andric   const Value *BasePtr = cast<const Value *>(V);
10470b57cec5SDimitry Andric   if (BasePtr == nullptr)
10480b57cec5SDimitry Andric     return false;
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   return isDereferenceableAndAlignedPointer(
10515ffd83dbSDimitry Andric       BasePtr, Align(1), APInt(DL.getPointerSizeInBits(), Offset + Size), DL);
10520b57cec5SDimitry Andric }
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the
10550b57cec5SDimitry Andric /// constant pool.
10560b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) {
10570b57cec5SDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getConstantPool());
10580b57cec5SDimitry Andric }
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the
10610b57cec5SDimitry Andric /// the specified FrameIndex.
10620b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF,
10630b57cec5SDimitry Andric                                                      int FI, int64_t Offset) {
10640b57cec5SDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset);
10650b57cec5SDimitry Andric }
10660b57cec5SDimitry Andric 
10670b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) {
10680b57cec5SDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getJumpTable());
10690b57cec5SDimitry Andric }
10700b57cec5SDimitry Andric 
10710b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) {
10720b57cec5SDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getGOT());
10730b57cec5SDimitry Andric }
10740b57cec5SDimitry Andric 
10750b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF,
10760b57cec5SDimitry Andric                                                 int64_t Offset, uint8_t ID) {
10770b57cec5SDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID);
10780b57cec5SDimitry Andric }
10790b57cec5SDimitry Andric 
10800b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) {
10810b57cec5SDimitry Andric   return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace());
10820b57cec5SDimitry Andric }
10830b57cec5SDimitry Andric 
10840b57cec5SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
1085fe6060f1SDimitry Andric                                      LLT type, Align a, const AAMDNodes &AAInfo,
10860b57cec5SDimitry Andric                                      const MDNode *Ranges, SyncScope::ID SSID,
10870b57cec5SDimitry Andric                                      AtomicOrdering Ordering,
10880b57cec5SDimitry Andric                                      AtomicOrdering FailureOrdering)
1089fe6060f1SDimitry Andric     : PtrInfo(ptrinfo), MemoryType(type), FlagVals(f), BaseAlign(a),
1090fe6060f1SDimitry Andric       AAInfo(AAInfo), Ranges(Ranges) {
109106c3fb27SDimitry Andric   assert((PtrInfo.V.isNull() || isa<const PseudoSourceValue *>(PtrInfo.V) ||
109206c3fb27SDimitry Andric           isa<PointerType>(cast<const Value *>(PtrInfo.V)->getType())) &&
10930b57cec5SDimitry Andric          "invalid pointer value");
10940b57cec5SDimitry Andric   assert((isLoad() || isStore()) && "Not a load/store!");
10950b57cec5SDimitry Andric 
10960b57cec5SDimitry Andric   AtomicInfo.SSID = static_cast<unsigned>(SSID);
10970b57cec5SDimitry Andric   assert(getSyncScopeID() == SSID && "Value truncated");
10980b57cec5SDimitry Andric   AtomicInfo.Ordering = static_cast<unsigned>(Ordering);
1099fe6060f1SDimitry Andric   assert(getSuccessOrdering() == Ordering && "Value truncated");
11000b57cec5SDimitry Andric   AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering);
11010b57cec5SDimitry Andric   assert(getFailureOrdering() == FailureOrdering && "Value truncated");
11020b57cec5SDimitry Andric }
11030b57cec5SDimitry Andric 
1104*0fca6ea1SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags F,
1105*0fca6ea1SDimitry Andric                                      LocationSize TS, Align BaseAlignment,
1106fe6060f1SDimitry Andric                                      const AAMDNodes &AAInfo,
1107fe6060f1SDimitry Andric                                      const MDNode *Ranges, SyncScope::ID SSID,
1108fe6060f1SDimitry Andric                                      AtomicOrdering Ordering,
1109fe6060f1SDimitry Andric                                      AtomicOrdering FailureOrdering)
1110*0fca6ea1SDimitry Andric     : MachineMemOperand(
1111*0fca6ea1SDimitry Andric           ptrinfo, F,
1112*0fca6ea1SDimitry Andric           !TS.hasValue() ? LLT()
1113*0fca6ea1SDimitry Andric           : TS.isScalable()
1114*0fca6ea1SDimitry Andric               ? LLT::scalable_vector(1, 8 * TS.getValue().getKnownMinValue())
1115*0fca6ea1SDimitry Andric               : LLT::scalar(8 * TS.getValue().getKnownMinValue()),
1116*0fca6ea1SDimitry Andric           BaseAlignment, AAInfo, Ranges, SSID, Ordering, FailureOrdering) {}
1117fe6060f1SDimitry Andric 
11180b57cec5SDimitry Andric void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
11190b57cec5SDimitry Andric   // The Value and Offset may differ due to CSE. But the flags and size
11200b57cec5SDimitry Andric   // should be the same.
11210b57cec5SDimitry Andric   assert(MMO->getFlags() == getFlags() && "Flags mismatch!");
1122*0fca6ea1SDimitry Andric   assert((!MMO->getSize().hasValue() || !getSize().hasValue() ||
11234824e7fdSDimitry Andric           MMO->getSize() == getSize()) &&
11244824e7fdSDimitry Andric          "Size mismatch!");
11255ffd83dbSDimitry Andric   if (MMO->getBaseAlign() >= getBaseAlign()) {
11260b57cec5SDimitry Andric     // Update the alignment value.
11275ffd83dbSDimitry Andric     BaseAlign = MMO->getBaseAlign();
11280b57cec5SDimitry Andric     // Also update the base and offset, because the new alignment may
11290b57cec5SDimitry Andric     // not be applicable with the old ones.
11300b57cec5SDimitry Andric     PtrInfo = MMO->PtrInfo;
11310b57cec5SDimitry Andric   }
11320b57cec5SDimitry Andric }
11330b57cec5SDimitry Andric 
11345ffd83dbSDimitry Andric /// getAlign - Return the minimum known alignment in bytes of the
11355ffd83dbSDimitry Andric /// actual memory reference.
11365ffd83dbSDimitry Andric Align MachineMemOperand::getAlign() const {
11375ffd83dbSDimitry Andric   return commonAlignment(getBaseAlign(), getOffset());
11380b57cec5SDimitry Andric }
11390b57cec5SDimitry Andric 
11400b57cec5SDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
11410b57cec5SDimitry Andric                               SmallVectorImpl<StringRef> &SSNs,
11420b57cec5SDimitry Andric                               const LLVMContext &Context,
11430b57cec5SDimitry Andric                               const MachineFrameInfo *MFI,
11440b57cec5SDimitry Andric                               const TargetInstrInfo *TII) const {
11450b57cec5SDimitry Andric   OS << '(';
11460b57cec5SDimitry Andric   if (isVolatile())
11470b57cec5SDimitry Andric     OS << "volatile ";
11480b57cec5SDimitry Andric   if (isNonTemporal())
11490b57cec5SDimitry Andric     OS << "non-temporal ";
11500b57cec5SDimitry Andric   if (isDereferenceable())
11510b57cec5SDimitry Andric     OS << "dereferenceable ";
11520b57cec5SDimitry Andric   if (isInvariant())
11530b57cec5SDimitry Andric     OS << "invariant ";
1154bdd1243dSDimitry Andric   if (TII) {
11550b57cec5SDimitry Andric     if (getFlags() & MachineMemOperand::MOTargetFlag1)
11560b57cec5SDimitry Andric       OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag1)
11570b57cec5SDimitry Andric          << "\" ";
11580b57cec5SDimitry Andric     if (getFlags() & MachineMemOperand::MOTargetFlag2)
11590b57cec5SDimitry Andric       OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag2)
11600b57cec5SDimitry Andric          << "\" ";
11610b57cec5SDimitry Andric     if (getFlags() & MachineMemOperand::MOTargetFlag3)
11620b57cec5SDimitry Andric       OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag3)
11630b57cec5SDimitry Andric          << "\" ";
1164bdd1243dSDimitry Andric   } else {
1165bdd1243dSDimitry Andric     if (getFlags() & MachineMemOperand::MOTargetFlag1)
1166bdd1243dSDimitry Andric       OS << "\"MOTargetFlag1\" ";
1167bdd1243dSDimitry Andric     if (getFlags() & MachineMemOperand::MOTargetFlag2)
1168bdd1243dSDimitry Andric       OS << "\"MOTargetFlag2\" ";
1169bdd1243dSDimitry Andric     if (getFlags() & MachineMemOperand::MOTargetFlag3)
1170bdd1243dSDimitry Andric       OS << "\"MOTargetFlag3\" ";
1171bdd1243dSDimitry Andric   }
11720b57cec5SDimitry Andric 
11730b57cec5SDimitry Andric   assert((isLoad() || isStore()) &&
11740b57cec5SDimitry Andric          "machine memory operand must be a load or store (or both)");
11750b57cec5SDimitry Andric   if (isLoad())
11760b57cec5SDimitry Andric     OS << "load ";
11770b57cec5SDimitry Andric   if (isStore())
11780b57cec5SDimitry Andric     OS << "store ";
11790b57cec5SDimitry Andric 
11800b57cec5SDimitry Andric   printSyncScope(OS, Context, getSyncScopeID(), SSNs);
11810b57cec5SDimitry Andric 
1182fe6060f1SDimitry Andric   if (getSuccessOrdering() != AtomicOrdering::NotAtomic)
1183fe6060f1SDimitry Andric     OS << toIRString(getSuccessOrdering()) << ' ';
11840b57cec5SDimitry Andric   if (getFailureOrdering() != AtomicOrdering::NotAtomic)
11850b57cec5SDimitry Andric     OS << toIRString(getFailureOrdering()) << ' ';
11860b57cec5SDimitry Andric 
1187fe6060f1SDimitry Andric   if (getMemoryType().isValid())
1188fe6060f1SDimitry Andric     OS << '(' << getMemoryType() << ')';
11890b57cec5SDimitry Andric   else
1190fe6060f1SDimitry Andric     OS << "unknown-size";
11910b57cec5SDimitry Andric 
11920b57cec5SDimitry Andric   if (const Value *Val = getValue()) {
11930b57cec5SDimitry Andric     OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
1194480093f4SDimitry Andric     MIRFormatter::printIRValue(OS, *Val, MST);
11950b57cec5SDimitry Andric   } else if (const PseudoSourceValue *PVal = getPseudoValue()) {
11960b57cec5SDimitry Andric     OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
11970b57cec5SDimitry Andric     assert(PVal && "Expected a pseudo source value");
11980b57cec5SDimitry Andric     switch (PVal->kind()) {
11990b57cec5SDimitry Andric     case PseudoSourceValue::Stack:
12000b57cec5SDimitry Andric       OS << "stack";
12010b57cec5SDimitry Andric       break;
12020b57cec5SDimitry Andric     case PseudoSourceValue::GOT:
12030b57cec5SDimitry Andric       OS << "got";
12040b57cec5SDimitry Andric       break;
12050b57cec5SDimitry Andric     case PseudoSourceValue::JumpTable:
12060b57cec5SDimitry Andric       OS << "jump-table";
12070b57cec5SDimitry Andric       break;
12080b57cec5SDimitry Andric     case PseudoSourceValue::ConstantPool:
12090b57cec5SDimitry Andric       OS << "constant-pool";
12100b57cec5SDimitry Andric       break;
12110b57cec5SDimitry Andric     case PseudoSourceValue::FixedStack: {
12120b57cec5SDimitry Andric       int FrameIndex = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
12130b57cec5SDimitry Andric       bool IsFixed = true;
12140b57cec5SDimitry Andric       printFrameIndex(OS, FrameIndex, IsFixed, MFI);
12150b57cec5SDimitry Andric       break;
12160b57cec5SDimitry Andric     }
12170b57cec5SDimitry Andric     case PseudoSourceValue::GlobalValueCallEntry:
12180b57cec5SDimitry Andric       OS << "call-entry ";
12190b57cec5SDimitry Andric       cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand(
12200b57cec5SDimitry Andric           OS, /*PrintType=*/false, MST);
12210b57cec5SDimitry Andric       break;
12220b57cec5SDimitry Andric     case PseudoSourceValue::ExternalSymbolCallEntry:
12230b57cec5SDimitry Andric       OS << "call-entry &";
12240b57cec5SDimitry Andric       printLLVMNameWithoutPrefix(
12250b57cec5SDimitry Andric           OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol());
12260b57cec5SDimitry Andric       break;
1227480093f4SDimitry Andric     default: {
1228480093f4SDimitry Andric       const MIRFormatter *Formatter = TII->getMIRFormatter();
12290b57cec5SDimitry Andric       // FIXME: This is not necessarily the correct MIR serialization format for
12300b57cec5SDimitry Andric       // a custom pseudo source value, but at least it allows
1231e8d8bef9SDimitry Andric       // MIR printing to work on a target with custom pseudo source
12320b57cec5SDimitry Andric       // values.
1233480093f4SDimitry Andric       OS << "custom \"";
1234480093f4SDimitry Andric       Formatter->printCustomPseudoSourceValue(OS, MST, *PVal);
1235480093f4SDimitry Andric       OS << '\"';
12360b57cec5SDimitry Andric       break;
12370b57cec5SDimitry Andric     }
12380b57cec5SDimitry Andric     }
1239fe6060f1SDimitry Andric   } else if (getOpaqueValue() == nullptr && getOffset() != 0) {
1240fe6060f1SDimitry Andric     OS << ((isLoad() && isStore()) ? " on "
1241fe6060f1SDimitry Andric            : isLoad()              ? " from "
1242fe6060f1SDimitry Andric                                    : " into ")
1243fe6060f1SDimitry Andric        << "unknown-address";
1244480093f4SDimitry Andric   }
12450b57cec5SDimitry Andric   MachineOperand::printOperandOffset(OS, getOffset());
1246*0fca6ea1SDimitry Andric   if (!getSize().hasValue() ||
1247*0fca6ea1SDimitry Andric       getAlign() != getSize().getValue().getKnownMinValue())
1248e8d8bef9SDimitry Andric     OS << ", align " << getAlign().value();
1249e8d8bef9SDimitry Andric   if (getAlign() != getBaseAlign())
1250e8d8bef9SDimitry Andric     OS << ", basealign " << getBaseAlign().value();
12510b57cec5SDimitry Andric   auto AAInfo = getAAInfo();
12520b57cec5SDimitry Andric   if (AAInfo.TBAA) {
12530b57cec5SDimitry Andric     OS << ", !tbaa ";
12540b57cec5SDimitry Andric     AAInfo.TBAA->printAsOperand(OS, MST);
12550b57cec5SDimitry Andric   }
12560b57cec5SDimitry Andric   if (AAInfo.Scope) {
12570b57cec5SDimitry Andric     OS << ", !alias.scope ";
12580b57cec5SDimitry Andric     AAInfo.Scope->printAsOperand(OS, MST);
12590b57cec5SDimitry Andric   }
12600b57cec5SDimitry Andric   if (AAInfo.NoAlias) {
12610b57cec5SDimitry Andric     OS << ", !noalias ";
12620b57cec5SDimitry Andric     AAInfo.NoAlias->printAsOperand(OS, MST);
12630b57cec5SDimitry Andric   }
12640b57cec5SDimitry Andric   if (getRanges()) {
12650b57cec5SDimitry Andric     OS << ", !range ";
12660b57cec5SDimitry Andric     getRanges()->printAsOperand(OS, MST);
12670b57cec5SDimitry Andric   }
12680b57cec5SDimitry Andric   // FIXME: Implement addrspace printing/parsing in MIR.
12690b57cec5SDimitry Andric   // For now, print this even though parsing it is not available in MIR.
12700b57cec5SDimitry Andric   if (unsigned AS = getAddrSpace())
12710b57cec5SDimitry Andric     OS << ", addrspace " << AS;
12720b57cec5SDimitry Andric 
12730b57cec5SDimitry Andric   OS << ')';
12740b57cec5SDimitry Andric }
1275