12cab237bSDimitry Andric //===- lib/CodeGen/MachineOperand.cpp -------------------------------------===//
22cab237bSDimitry Andric //
32cab237bSDimitry Andric //                     The LLVM Compiler Infrastructure
42cab237bSDimitry Andric //
52cab237bSDimitry Andric // This file is distributed under the University of Illinois Open Source
62cab237bSDimitry Andric // License. See LICENSE.TXT for details.
72cab237bSDimitry Andric //
82cab237bSDimitry Andric //===----------------------------------------------------------------------===//
92cab237bSDimitry Andric //
102cab237bSDimitry Andric /// \file Methods common to all machine operands.
112cab237bSDimitry Andric //
122cab237bSDimitry Andric //===----------------------------------------------------------------------===//
132cab237bSDimitry Andric 
142cab237bSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
154ba319b5SDimitry Andric #include "llvm/ADT/StringExtras.h"
162cab237bSDimitry Andric #include "llvm/Analysis/Loads.h"
17*b5893f02SDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
182cab237bSDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
192cab237bSDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
202cab237bSDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h"
212cab237bSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
222cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
232cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
244ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
252cab237bSDimitry Andric #include "llvm/IR/Constants.h"
262cab237bSDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
272cab237bSDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
282cab237bSDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
292cab237bSDimitry Andric #include "llvm/Target/TargetMachine.h"
302cab237bSDimitry Andric 
312cab237bSDimitry Andric using namespace llvm;
322cab237bSDimitry Andric 
332cab237bSDimitry Andric static cl::opt<int>
342cab237bSDimitry Andric     PrintRegMaskNumRegs("print-regmask-num-regs",
352cab237bSDimitry Andric                         cl::desc("Number of registers to limit to when "
362cab237bSDimitry Andric                                  "printing regmask operands in IR dumps. "
372cab237bSDimitry Andric                                  "unlimited = -1"),
382cab237bSDimitry Andric                         cl::init(32), cl::Hidden);
392cab237bSDimitry Andric 
getMFIfAvailable(const MachineOperand & MO)402cab237bSDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineOperand &MO) {
412cab237bSDimitry Andric   if (const MachineInstr *MI = MO.getParent())
422cab237bSDimitry Andric     if (const MachineBasicBlock *MBB = MI->getParent())
432cab237bSDimitry Andric       if (const MachineFunction *MF = MBB->getParent())
442cab237bSDimitry Andric         return MF;
452cab237bSDimitry Andric   return nullptr;
462cab237bSDimitry Andric }
getMFIfAvailable(MachineOperand & MO)472cab237bSDimitry Andric static MachineFunction *getMFIfAvailable(MachineOperand &MO) {
482cab237bSDimitry Andric   return const_cast<MachineFunction *>(
492cab237bSDimitry Andric       getMFIfAvailable(const_cast<const MachineOperand &>(MO)));
502cab237bSDimitry Andric }
512cab237bSDimitry Andric 
setReg(unsigned Reg)522cab237bSDimitry Andric void MachineOperand::setReg(unsigned Reg) {
532cab237bSDimitry Andric   if (getReg() == Reg)
542cab237bSDimitry Andric     return; // No change.
552cab237bSDimitry Andric 
564ba319b5SDimitry Andric   // Clear the IsRenamable bit to keep it conservatively correct.
574ba319b5SDimitry Andric   IsRenamable = false;
584ba319b5SDimitry Andric 
592cab237bSDimitry Andric   // Otherwise, we have to change the register.  If this operand is embedded
602cab237bSDimitry Andric   // into a machine function, we need to update the old and new register's
612cab237bSDimitry Andric   // use/def lists.
622cab237bSDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this)) {
632cab237bSDimitry Andric     MachineRegisterInfo &MRI = MF->getRegInfo();
642cab237bSDimitry Andric     MRI.removeRegOperandFromUseList(this);
652cab237bSDimitry Andric     SmallContents.RegNo = Reg;
662cab237bSDimitry Andric     MRI.addRegOperandToUseList(this);
672cab237bSDimitry Andric     return;
682cab237bSDimitry Andric   }
692cab237bSDimitry Andric 
702cab237bSDimitry Andric   // Otherwise, just change the register, no problem.  :)
712cab237bSDimitry Andric   SmallContents.RegNo = Reg;
722cab237bSDimitry Andric }
732cab237bSDimitry Andric 
substVirtReg(unsigned Reg,unsigned SubIdx,const TargetRegisterInfo & TRI)742cab237bSDimitry Andric void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx,
752cab237bSDimitry Andric                                   const TargetRegisterInfo &TRI) {
762cab237bSDimitry Andric   assert(TargetRegisterInfo::isVirtualRegister(Reg));
772cab237bSDimitry Andric   if (SubIdx && getSubReg())
782cab237bSDimitry Andric     SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg());
792cab237bSDimitry Andric   setReg(Reg);
802cab237bSDimitry Andric   if (SubIdx)
812cab237bSDimitry Andric     setSubReg(SubIdx);
822cab237bSDimitry Andric }
832cab237bSDimitry Andric 
substPhysReg(unsigned Reg,const TargetRegisterInfo & TRI)842cab237bSDimitry Andric void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) {
852cab237bSDimitry Andric   assert(TargetRegisterInfo::isPhysicalRegister(Reg));
862cab237bSDimitry Andric   if (getSubReg()) {
872cab237bSDimitry Andric     Reg = TRI.getSubReg(Reg, getSubReg());
882cab237bSDimitry Andric     // Note that getSubReg() may return 0 if the sub-register doesn't exist.
892cab237bSDimitry Andric     // That won't happen in legal code.
902cab237bSDimitry Andric     setSubReg(0);
912cab237bSDimitry Andric     if (isDef())
922cab237bSDimitry Andric       setIsUndef(false);
932cab237bSDimitry Andric   }
942cab237bSDimitry Andric   setReg(Reg);
952cab237bSDimitry Andric }
962cab237bSDimitry Andric 
972cab237bSDimitry Andric /// Change a def to a use, or a use to a def.
setIsDef(bool Val)982cab237bSDimitry Andric void MachineOperand::setIsDef(bool Val) {
992cab237bSDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
1002cab237bSDimitry Andric   assert((!Val || !isDebug()) && "Marking a debug operation as def");
1012cab237bSDimitry Andric   if (IsDef == Val)
1022cab237bSDimitry Andric     return;
1032cab237bSDimitry Andric   assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported");
1042cab237bSDimitry Andric   // MRI may keep uses and defs in different list positions.
1052cab237bSDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this)) {
1062cab237bSDimitry Andric     MachineRegisterInfo &MRI = MF->getRegInfo();
1072cab237bSDimitry Andric     MRI.removeRegOperandFromUseList(this);
1082cab237bSDimitry Andric     IsDef = Val;
1092cab237bSDimitry Andric     MRI.addRegOperandToUseList(this);
1102cab237bSDimitry Andric     return;
1112cab237bSDimitry Andric   }
1122cab237bSDimitry Andric   IsDef = Val;
1132cab237bSDimitry Andric }
1142cab237bSDimitry Andric 
isRenamable() const1152cab237bSDimitry Andric bool MachineOperand::isRenamable() const {
1162cab237bSDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
1172cab237bSDimitry Andric   assert(TargetRegisterInfo::isPhysicalRegister(getReg()) &&
1182cab237bSDimitry Andric          "isRenamable should only be checked on physical registers");
1194ba319b5SDimitry Andric   if (!IsRenamable)
1204ba319b5SDimitry Andric     return false;
1214ba319b5SDimitry Andric 
1224ba319b5SDimitry Andric   const MachineInstr *MI = getParent();
1234ba319b5SDimitry Andric   if (!MI)
1244ba319b5SDimitry Andric     return true;
1254ba319b5SDimitry Andric 
1264ba319b5SDimitry Andric   if (isDef())
1274ba319b5SDimitry Andric     return !MI->hasExtraDefRegAllocReq(MachineInstr::IgnoreBundle);
1284ba319b5SDimitry Andric 
1294ba319b5SDimitry Andric   assert(isUse() && "Reg is not def or use");
1304ba319b5SDimitry Andric   return !MI->hasExtraSrcRegAllocReq(MachineInstr::IgnoreBundle);
1312cab237bSDimitry Andric }
1322cab237bSDimitry Andric 
setIsRenamable(bool Val)1332cab237bSDimitry Andric void MachineOperand::setIsRenamable(bool Val) {
1342cab237bSDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
1352cab237bSDimitry Andric   assert(TargetRegisterInfo::isPhysicalRegister(getReg()) &&
1362cab237bSDimitry Andric          "setIsRenamable should only be called on physical registers");
1372cab237bSDimitry Andric   IsRenamable = Val;
1382cab237bSDimitry Andric }
1392cab237bSDimitry Andric 
1402cab237bSDimitry Andric // If this operand is currently a register operand, and if this is in a
1412cab237bSDimitry Andric // function, deregister the operand from the register's use/def list.
removeRegFromUses()1422cab237bSDimitry Andric void MachineOperand::removeRegFromUses() {
1432cab237bSDimitry Andric   if (!isReg() || !isOnRegUseList())
1442cab237bSDimitry Andric     return;
1452cab237bSDimitry Andric 
1462cab237bSDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this))
1472cab237bSDimitry Andric     MF->getRegInfo().removeRegOperandFromUseList(this);
1482cab237bSDimitry Andric }
1492cab237bSDimitry Andric 
1502cab237bSDimitry Andric /// ChangeToImmediate - Replace this operand with a new immediate operand of
1512cab237bSDimitry Andric /// the specified value.  If an operand is known to be an immediate already,
1522cab237bSDimitry Andric /// the setImm method should be used.
ChangeToImmediate(int64_t ImmVal)1532cab237bSDimitry Andric void MachineOperand::ChangeToImmediate(int64_t ImmVal) {
1542cab237bSDimitry Andric   assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
1552cab237bSDimitry Andric 
1562cab237bSDimitry Andric   removeRegFromUses();
1572cab237bSDimitry Andric 
1582cab237bSDimitry Andric   OpKind = MO_Immediate;
1592cab237bSDimitry Andric   Contents.ImmVal = ImmVal;
1602cab237bSDimitry Andric }
1612cab237bSDimitry Andric 
ChangeToFPImmediate(const ConstantFP * FPImm)1622cab237bSDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) {
1632cab237bSDimitry Andric   assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
1642cab237bSDimitry Andric 
1652cab237bSDimitry Andric   removeRegFromUses();
1662cab237bSDimitry Andric 
1672cab237bSDimitry Andric   OpKind = MO_FPImmediate;
1682cab237bSDimitry Andric   Contents.CFP = FPImm;
1692cab237bSDimitry Andric }
1702cab237bSDimitry Andric 
ChangeToES(const char * SymName,unsigned char TargetFlags)1712cab237bSDimitry Andric void MachineOperand::ChangeToES(const char *SymName,
1722cab237bSDimitry Andric                                 unsigned char TargetFlags) {
1732cab237bSDimitry Andric   assert((!isReg() || !isTied()) &&
1742cab237bSDimitry Andric          "Cannot change a tied operand into an external symbol");
1752cab237bSDimitry Andric 
1762cab237bSDimitry Andric   removeRegFromUses();
1772cab237bSDimitry Andric 
1782cab237bSDimitry Andric   OpKind = MO_ExternalSymbol;
1792cab237bSDimitry Andric   Contents.OffsetedInfo.Val.SymbolName = SymName;
1802cab237bSDimitry Andric   setOffset(0); // Offset is always 0.
1812cab237bSDimitry Andric   setTargetFlags(TargetFlags);
1822cab237bSDimitry Andric }
1832cab237bSDimitry Andric 
ChangeToMCSymbol(MCSymbol * Sym)1842cab237bSDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) {
1852cab237bSDimitry Andric   assert((!isReg() || !isTied()) &&
1862cab237bSDimitry Andric          "Cannot change a tied operand into an MCSymbol");
1872cab237bSDimitry Andric 
1882cab237bSDimitry Andric   removeRegFromUses();
1892cab237bSDimitry Andric 
1902cab237bSDimitry Andric   OpKind = MO_MCSymbol;
1912cab237bSDimitry Andric   Contents.Sym = Sym;
1922cab237bSDimitry Andric }
1932cab237bSDimitry Andric 
ChangeToFrameIndex(int Idx)1942cab237bSDimitry Andric void MachineOperand::ChangeToFrameIndex(int Idx) {
1952cab237bSDimitry Andric   assert((!isReg() || !isTied()) &&
1962cab237bSDimitry Andric          "Cannot change a tied operand into a FrameIndex");
1972cab237bSDimitry Andric 
1982cab237bSDimitry Andric   removeRegFromUses();
1992cab237bSDimitry Andric 
2002cab237bSDimitry Andric   OpKind = MO_FrameIndex;
2012cab237bSDimitry Andric   setIndex(Idx);
2022cab237bSDimitry Andric }
2032cab237bSDimitry Andric 
ChangeToTargetIndex(unsigned Idx,int64_t Offset,unsigned char TargetFlags)2042cab237bSDimitry Andric void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset,
2052cab237bSDimitry Andric                                          unsigned char TargetFlags) {
2062cab237bSDimitry Andric   assert((!isReg() || !isTied()) &&
2072cab237bSDimitry Andric          "Cannot change a tied operand into a FrameIndex");
2082cab237bSDimitry Andric 
2092cab237bSDimitry Andric   removeRegFromUses();
2102cab237bSDimitry Andric 
2112cab237bSDimitry Andric   OpKind = MO_TargetIndex;
2122cab237bSDimitry Andric   setIndex(Idx);
2132cab237bSDimitry Andric   setOffset(Offset);
2142cab237bSDimitry Andric   setTargetFlags(TargetFlags);
2152cab237bSDimitry Andric }
2162cab237bSDimitry Andric 
2172cab237bSDimitry Andric /// ChangeToRegister - Replace this operand with a new register operand of
2182cab237bSDimitry Andric /// the specified value.  If an operand is known to be an register already,
2192cab237bSDimitry Andric /// the setReg method should be used.
ChangeToRegister(unsigned Reg,bool isDef,bool isImp,bool isKill,bool isDead,bool isUndef,bool isDebug)2202cab237bSDimitry Andric void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
2212cab237bSDimitry Andric                                       bool isKill, bool isDead, bool isUndef,
2222cab237bSDimitry Andric                                       bool isDebug) {
2232cab237bSDimitry Andric   MachineRegisterInfo *RegInfo = nullptr;
2242cab237bSDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this))
2252cab237bSDimitry Andric     RegInfo = &MF->getRegInfo();
2262cab237bSDimitry Andric   // If this operand is already a register operand, remove it from the
2272cab237bSDimitry Andric   // register's use/def lists.
2282cab237bSDimitry Andric   bool WasReg = isReg();
2292cab237bSDimitry Andric   if (RegInfo && WasReg)
2302cab237bSDimitry Andric     RegInfo->removeRegOperandFromUseList(this);
2312cab237bSDimitry Andric 
2322cab237bSDimitry Andric   // Change this to a register and set the reg#.
2332cab237bSDimitry Andric   assert(!(isDead && !isDef) && "Dead flag on non-def");
2342cab237bSDimitry Andric   assert(!(isKill && isDef) && "Kill flag on def");
2352cab237bSDimitry Andric   OpKind = MO_Register;
2362cab237bSDimitry Andric   SmallContents.RegNo = Reg;
2372cab237bSDimitry Andric   SubReg_TargetFlags = 0;
2382cab237bSDimitry Andric   IsDef = isDef;
2392cab237bSDimitry Andric   IsImp = isImp;
2402cab237bSDimitry Andric   IsDeadOrKill = isKill | isDead;
2412cab237bSDimitry Andric   IsRenamable = false;
2422cab237bSDimitry Andric   IsUndef = isUndef;
2432cab237bSDimitry Andric   IsInternalRead = false;
2442cab237bSDimitry Andric   IsEarlyClobber = false;
2452cab237bSDimitry Andric   IsDebug = isDebug;
2462cab237bSDimitry Andric   // Ensure isOnRegUseList() returns false.
2472cab237bSDimitry Andric   Contents.Reg.Prev = nullptr;
2482cab237bSDimitry Andric   // Preserve the tie when the operand was already a register.
2492cab237bSDimitry Andric   if (!WasReg)
2502cab237bSDimitry Andric     TiedTo = 0;
2512cab237bSDimitry Andric 
2522cab237bSDimitry Andric   // If this operand is embedded in a function, add the operand to the
2532cab237bSDimitry Andric   // register's use/def list.
2542cab237bSDimitry Andric   if (RegInfo)
2552cab237bSDimitry Andric     RegInfo->addRegOperandToUseList(this);
2562cab237bSDimitry Andric }
2572cab237bSDimitry Andric 
2582cab237bSDimitry Andric /// isIdenticalTo - Return true if this operand is identical to the specified
2592cab237bSDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload
2602cab237bSDimitry Andric /// below.
isIdenticalTo(const MachineOperand & Other) const2612cab237bSDimitry Andric bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
2622cab237bSDimitry Andric   if (getType() != Other.getType() ||
2632cab237bSDimitry Andric       getTargetFlags() != Other.getTargetFlags())
2642cab237bSDimitry Andric     return false;
2652cab237bSDimitry Andric 
2662cab237bSDimitry Andric   switch (getType()) {
2672cab237bSDimitry Andric   case MachineOperand::MO_Register:
2682cab237bSDimitry Andric     return getReg() == Other.getReg() && isDef() == Other.isDef() &&
2692cab237bSDimitry Andric            getSubReg() == Other.getSubReg();
2702cab237bSDimitry Andric   case MachineOperand::MO_Immediate:
2712cab237bSDimitry Andric     return getImm() == Other.getImm();
2722cab237bSDimitry Andric   case MachineOperand::MO_CImmediate:
2732cab237bSDimitry Andric     return getCImm() == Other.getCImm();
2742cab237bSDimitry Andric   case MachineOperand::MO_FPImmediate:
2752cab237bSDimitry Andric     return getFPImm() == Other.getFPImm();
2762cab237bSDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
2772cab237bSDimitry Andric     return getMBB() == Other.getMBB();
2782cab237bSDimitry Andric   case MachineOperand::MO_FrameIndex:
2792cab237bSDimitry Andric     return getIndex() == Other.getIndex();
2802cab237bSDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
2812cab237bSDimitry Andric   case MachineOperand::MO_TargetIndex:
2822cab237bSDimitry Andric     return getIndex() == Other.getIndex() && getOffset() == Other.getOffset();
2832cab237bSDimitry Andric   case MachineOperand::MO_JumpTableIndex:
2842cab237bSDimitry Andric     return getIndex() == Other.getIndex();
2852cab237bSDimitry Andric   case MachineOperand::MO_GlobalAddress:
2862cab237bSDimitry Andric     return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset();
2872cab237bSDimitry Andric   case MachineOperand::MO_ExternalSymbol:
2882cab237bSDimitry Andric     return strcmp(getSymbolName(), Other.getSymbolName()) == 0 &&
2892cab237bSDimitry Andric            getOffset() == Other.getOffset();
2902cab237bSDimitry Andric   case MachineOperand::MO_BlockAddress:
2912cab237bSDimitry Andric     return getBlockAddress() == Other.getBlockAddress() &&
2922cab237bSDimitry Andric            getOffset() == Other.getOffset();
2932cab237bSDimitry Andric   case MachineOperand::MO_RegisterMask:
2942cab237bSDimitry Andric   case MachineOperand::MO_RegisterLiveOut: {
2952cab237bSDimitry Andric     // Shallow compare of the two RegMasks
2962cab237bSDimitry Andric     const uint32_t *RegMask = getRegMask();
2972cab237bSDimitry Andric     const uint32_t *OtherRegMask = Other.getRegMask();
2982cab237bSDimitry Andric     if (RegMask == OtherRegMask)
2992cab237bSDimitry Andric       return true;
3002cab237bSDimitry Andric 
3012cab237bSDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
3022cab237bSDimitry Andric       // Calculate the size of the RegMask
3032cab237bSDimitry Andric       const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
3042cab237bSDimitry Andric       unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32;
3052cab237bSDimitry Andric 
3062cab237bSDimitry Andric       // Deep compare of the two RegMasks
3072cab237bSDimitry Andric       return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask);
3082cab237bSDimitry Andric     }
3092cab237bSDimitry Andric     // We don't know the size of the RegMask, so we can't deep compare the two
3102cab237bSDimitry Andric     // reg masks.
3112cab237bSDimitry Andric     return false;
3122cab237bSDimitry Andric   }
3132cab237bSDimitry Andric   case MachineOperand::MO_MCSymbol:
3142cab237bSDimitry Andric     return getMCSymbol() == Other.getMCSymbol();
3152cab237bSDimitry Andric   case MachineOperand::MO_CFIIndex:
3162cab237bSDimitry Andric     return getCFIIndex() == Other.getCFIIndex();
3172cab237bSDimitry Andric   case MachineOperand::MO_Metadata:
3182cab237bSDimitry Andric     return getMetadata() == Other.getMetadata();
3192cab237bSDimitry Andric   case MachineOperand::MO_IntrinsicID:
3202cab237bSDimitry Andric     return getIntrinsicID() == Other.getIntrinsicID();
3212cab237bSDimitry Andric   case MachineOperand::MO_Predicate:
3222cab237bSDimitry Andric     return getPredicate() == Other.getPredicate();
3232cab237bSDimitry Andric   }
3242cab237bSDimitry Andric   llvm_unreachable("Invalid machine operand type");
3252cab237bSDimitry Andric }
3262cab237bSDimitry Andric 
3272cab237bSDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above.
hash_value(const MachineOperand & MO)3282cab237bSDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) {
3292cab237bSDimitry Andric   switch (MO.getType()) {
3302cab237bSDimitry Andric   case MachineOperand::MO_Register:
3312cab237bSDimitry Andric     // Register operands don't have target flags.
3322cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef());
3332cab237bSDimitry Andric   case MachineOperand::MO_Immediate:
3342cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
3352cab237bSDimitry Andric   case MachineOperand::MO_CImmediate:
3362cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm());
3372cab237bSDimitry Andric   case MachineOperand::MO_FPImmediate:
3382cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm());
3392cab237bSDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
3402cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB());
3412cab237bSDimitry Andric   case MachineOperand::MO_FrameIndex:
3422cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
3432cab237bSDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
3442cab237bSDimitry Andric   case MachineOperand::MO_TargetIndex:
3452cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(),
3462cab237bSDimitry Andric                         MO.getOffset());
3472cab237bSDimitry Andric   case MachineOperand::MO_JumpTableIndex:
3482cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
3492cab237bSDimitry Andric   case MachineOperand::MO_ExternalSymbol:
3502cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
3512cab237bSDimitry Andric                         MO.getSymbolName());
3522cab237bSDimitry Andric   case MachineOperand::MO_GlobalAddress:
3532cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(),
3542cab237bSDimitry Andric                         MO.getOffset());
3552cab237bSDimitry Andric   case MachineOperand::MO_BlockAddress:
3562cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(),
3572cab237bSDimitry Andric                         MO.getOffset());
3582cab237bSDimitry Andric   case MachineOperand::MO_RegisterMask:
3592cab237bSDimitry Andric   case MachineOperand::MO_RegisterLiveOut:
3602cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
3612cab237bSDimitry Andric   case MachineOperand::MO_Metadata:
3622cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata());
3632cab237bSDimitry Andric   case MachineOperand::MO_MCSymbol:
3642cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol());
3652cab237bSDimitry Andric   case MachineOperand::MO_CFIIndex:
3662cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex());
3672cab237bSDimitry Andric   case MachineOperand::MO_IntrinsicID:
3682cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID());
3692cab237bSDimitry Andric   case MachineOperand::MO_Predicate:
3702cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate());
3712cab237bSDimitry Andric   }
3722cab237bSDimitry Andric   llvm_unreachable("Invalid machine operand type");
3732cab237bSDimitry Andric }
3742cab237bSDimitry Andric 
3752cab237bSDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from
3762cab237bSDimitry Andric // it.
tryToGetTargetInfo(const MachineOperand & MO,const TargetRegisterInfo * & TRI,const TargetIntrinsicInfo * & IntrinsicInfo)3772cab237bSDimitry Andric static void tryToGetTargetInfo(const MachineOperand &MO,
3782cab237bSDimitry Andric                                const TargetRegisterInfo *&TRI,
3792cab237bSDimitry Andric                                const TargetIntrinsicInfo *&IntrinsicInfo) {
3802cab237bSDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(MO)) {
3812cab237bSDimitry Andric     TRI = MF->getSubtarget().getRegisterInfo();
3822cab237bSDimitry Andric     IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
3832cab237bSDimitry Andric   }
3842cab237bSDimitry Andric }
3852cab237bSDimitry Andric 
getTargetIndexName(const MachineFunction & MF,int Index)3862cab237bSDimitry Andric static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
3872cab237bSDimitry Andric   const auto *TII = MF.getSubtarget().getInstrInfo();
3882cab237bSDimitry Andric   assert(TII && "expected instruction info");
3892cab237bSDimitry Andric   auto Indices = TII->getSerializableTargetIndices();
3902cab237bSDimitry Andric   auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) {
3912cab237bSDimitry Andric     return I.first == Index;
3922cab237bSDimitry Andric   });
3932cab237bSDimitry Andric   if (Found != Indices.end())
3942cab237bSDimitry Andric     return Found->second;
3952cab237bSDimitry Andric   return nullptr;
3962cab237bSDimitry Andric }
3972cab237bSDimitry Andric 
getTargetFlagName(const TargetInstrInfo * TII,unsigned TF)3982cab237bSDimitry Andric static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
3992cab237bSDimitry Andric   auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
4002cab237bSDimitry Andric   for (const auto &I : Flags) {
4012cab237bSDimitry Andric     if (I.first == TF) {
4022cab237bSDimitry Andric       return I.second;
4032cab237bSDimitry Andric     }
4042cab237bSDimitry Andric   }
4052cab237bSDimitry Andric   return nullptr;
4062cab237bSDimitry Andric }
4072cab237bSDimitry Andric 
printCFIRegister(unsigned DwarfReg,raw_ostream & OS,const TargetRegisterInfo * TRI)408da09e106SDimitry Andric static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
409da09e106SDimitry Andric                              const TargetRegisterInfo *TRI) {
410da09e106SDimitry Andric   if (!TRI) {
411da09e106SDimitry Andric     OS << "%dwarfreg." << DwarfReg;
412da09e106SDimitry Andric     return;
413da09e106SDimitry Andric   }
414da09e106SDimitry Andric 
415da09e106SDimitry Andric   int Reg = TRI->getLLVMRegNum(DwarfReg, true);
416da09e106SDimitry Andric   if (Reg == -1) {
417da09e106SDimitry Andric     OS << "<badreg>";
418da09e106SDimitry Andric     return;
419da09e106SDimitry Andric   }
420da09e106SDimitry Andric   OS << printReg(Reg, TRI);
421da09e106SDimitry Andric }
422da09e106SDimitry Andric 
printIRBlockReference(raw_ostream & OS,const BasicBlock & BB,ModuleSlotTracker & MST)423da09e106SDimitry Andric static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB,
424da09e106SDimitry Andric                                   ModuleSlotTracker &MST) {
425da09e106SDimitry Andric   OS << "%ir-block.";
426da09e106SDimitry Andric   if (BB.hasName()) {
427da09e106SDimitry Andric     printLLVMNameWithoutPrefix(OS, BB.getName());
428da09e106SDimitry Andric     return;
429da09e106SDimitry Andric   }
430da09e106SDimitry Andric   Optional<int> Slot;
431da09e106SDimitry Andric   if (const Function *F = BB.getParent()) {
432da09e106SDimitry Andric     if (F == MST.getCurrentFunction()) {
433da09e106SDimitry Andric       Slot = MST.getLocalSlot(&BB);
434da09e106SDimitry Andric     } else if (const Module *M = F->getParent()) {
435da09e106SDimitry Andric       ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false);
436da09e106SDimitry Andric       CustomMST.incorporateFunction(*F);
437da09e106SDimitry Andric       Slot = CustomMST.getLocalSlot(&BB);
438da09e106SDimitry Andric     }
439da09e106SDimitry Andric   }
440da09e106SDimitry Andric   if (Slot)
441da09e106SDimitry Andric     MachineOperand::printIRSlotNumber(OS, *Slot);
442da09e106SDimitry Andric   else
443da09e106SDimitry Andric     OS << "<unknown>";
444da09e106SDimitry Andric }
445da09e106SDimitry Andric 
printIRValueReference(raw_ostream & OS,const Value & V,ModuleSlotTracker & MST)4464ba319b5SDimitry Andric static void printIRValueReference(raw_ostream &OS, const Value &V,
4474ba319b5SDimitry Andric                                   ModuleSlotTracker &MST) {
4484ba319b5SDimitry Andric   if (isa<GlobalValue>(V)) {
4494ba319b5SDimitry Andric     V.printAsOperand(OS, /*PrintType=*/false, MST);
4504ba319b5SDimitry Andric     return;
4514ba319b5SDimitry Andric   }
4524ba319b5SDimitry Andric   if (isa<Constant>(V)) {
4534ba319b5SDimitry Andric     // Machine memory operands can load/store to/from constant value pointers.
4544ba319b5SDimitry Andric     OS << '`';
4554ba319b5SDimitry Andric     V.printAsOperand(OS, /*PrintType=*/true, MST);
4564ba319b5SDimitry Andric     OS << '`';
4574ba319b5SDimitry Andric     return;
4584ba319b5SDimitry Andric   }
4594ba319b5SDimitry Andric   OS << "%ir.";
4604ba319b5SDimitry Andric   if (V.hasName()) {
4614ba319b5SDimitry Andric     printLLVMNameWithoutPrefix(OS, V.getName());
4624ba319b5SDimitry Andric     return;
4634ba319b5SDimitry Andric   }
464*b5893f02SDimitry Andric   int Slot = MST.getCurrentFunction() ? MST.getLocalSlot(&V) : -1;
465*b5893f02SDimitry Andric   MachineOperand::printIRSlotNumber(OS, Slot);
4664ba319b5SDimitry Andric }
4674ba319b5SDimitry Andric 
printSyncScope(raw_ostream & OS,const LLVMContext & Context,SyncScope::ID SSID,SmallVectorImpl<StringRef> & SSNs)4684ba319b5SDimitry Andric static void printSyncScope(raw_ostream &OS, const LLVMContext &Context,
4694ba319b5SDimitry Andric                            SyncScope::ID SSID,
4704ba319b5SDimitry Andric                            SmallVectorImpl<StringRef> &SSNs) {
4714ba319b5SDimitry Andric   switch (SSID) {
4724ba319b5SDimitry Andric   case SyncScope::System:
4734ba319b5SDimitry Andric     break;
4744ba319b5SDimitry Andric   default:
4754ba319b5SDimitry Andric     if (SSNs.empty())
4764ba319b5SDimitry Andric       Context.getSyncScopeNames(SSNs);
4774ba319b5SDimitry Andric 
4784ba319b5SDimitry Andric     OS << "syncscope(\"";
4794ba319b5SDimitry Andric     printEscapedString(SSNs[SSID], OS);
4804ba319b5SDimitry Andric     OS << "\") ";
4814ba319b5SDimitry Andric     break;
4824ba319b5SDimitry Andric   }
4834ba319b5SDimitry Andric }
4844ba319b5SDimitry Andric 
getTargetMMOFlagName(const TargetInstrInfo & TII,unsigned TMMOFlag)4854ba319b5SDimitry Andric static const char *getTargetMMOFlagName(const TargetInstrInfo &TII,
4864ba319b5SDimitry Andric                                         unsigned TMMOFlag) {
4874ba319b5SDimitry Andric   auto Flags = TII.getSerializableMachineMemOperandTargetFlags();
4884ba319b5SDimitry Andric   for (const auto &I : Flags) {
4894ba319b5SDimitry Andric     if (I.first == TMMOFlag) {
4904ba319b5SDimitry Andric       return I.second;
4914ba319b5SDimitry Andric     }
4924ba319b5SDimitry Andric   }
4934ba319b5SDimitry Andric   return nullptr;
4944ba319b5SDimitry Andric }
4954ba319b5SDimitry Andric 
printFrameIndex(raw_ostream & OS,int FrameIndex,bool IsFixed,const MachineFrameInfo * MFI)4964ba319b5SDimitry Andric static void printFrameIndex(raw_ostream& OS, int FrameIndex, bool IsFixed,
4974ba319b5SDimitry Andric                             const MachineFrameInfo *MFI) {
4984ba319b5SDimitry Andric   StringRef Name;
4994ba319b5SDimitry Andric   if (MFI) {
5004ba319b5SDimitry Andric     IsFixed = MFI->isFixedObjectIndex(FrameIndex);
5014ba319b5SDimitry Andric     if (const AllocaInst *Alloca = MFI->getObjectAllocation(FrameIndex))
5024ba319b5SDimitry Andric       if (Alloca->hasName())
5034ba319b5SDimitry Andric         Name = Alloca->getName();
5044ba319b5SDimitry Andric     if (IsFixed)
5054ba319b5SDimitry Andric       FrameIndex -= MFI->getObjectIndexBegin();
5064ba319b5SDimitry Andric   }
5074ba319b5SDimitry Andric   MachineOperand::printStackObjectReference(OS, FrameIndex, IsFixed, Name);
5084ba319b5SDimitry Andric }
5094ba319b5SDimitry Andric 
printSubRegIdx(raw_ostream & OS,uint64_t Index,const TargetRegisterInfo * TRI)5104ba319b5SDimitry Andric void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index,
5112cab237bSDimitry Andric                                     const TargetRegisterInfo *TRI) {
5122cab237bSDimitry Andric   OS << "%subreg.";
5132cab237bSDimitry Andric   if (TRI)
5142cab237bSDimitry Andric     OS << TRI->getSubRegIndexName(Index);
5152cab237bSDimitry Andric   else
5162cab237bSDimitry Andric     OS << Index;
5172cab237bSDimitry Andric }
5182cab237bSDimitry Andric 
printTargetFlags(raw_ostream & OS,const MachineOperand & Op)5192cab237bSDimitry Andric void MachineOperand::printTargetFlags(raw_ostream &OS,
5202cab237bSDimitry Andric                                       const MachineOperand &Op) {
5212cab237bSDimitry Andric   if (!Op.getTargetFlags())
5222cab237bSDimitry Andric     return;
5232cab237bSDimitry Andric   const MachineFunction *MF = getMFIfAvailable(Op);
5242cab237bSDimitry Andric   if (!MF)
5252cab237bSDimitry Andric     return;
5262cab237bSDimitry Andric 
5272cab237bSDimitry Andric   const auto *TII = MF->getSubtarget().getInstrInfo();
5282cab237bSDimitry Andric   assert(TII && "expected instruction info");
5292cab237bSDimitry Andric   auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
5302cab237bSDimitry Andric   OS << "target-flags(";
5312cab237bSDimitry Andric   const bool HasDirectFlags = Flags.first;
5322cab237bSDimitry Andric   const bool HasBitmaskFlags = Flags.second;
5332cab237bSDimitry Andric   if (!HasDirectFlags && !HasBitmaskFlags) {
5342cab237bSDimitry Andric     OS << "<unknown>) ";
5352cab237bSDimitry Andric     return;
5362cab237bSDimitry Andric   }
5372cab237bSDimitry Andric   if (HasDirectFlags) {
5382cab237bSDimitry Andric     if (const auto *Name = getTargetFlagName(TII, Flags.first))
5392cab237bSDimitry Andric       OS << Name;
5402cab237bSDimitry Andric     else
5412cab237bSDimitry Andric       OS << "<unknown target flag>";
5422cab237bSDimitry Andric   }
5432cab237bSDimitry Andric   if (!HasBitmaskFlags) {
5442cab237bSDimitry Andric     OS << ") ";
5452cab237bSDimitry Andric     return;
5462cab237bSDimitry Andric   }
5472cab237bSDimitry Andric   bool IsCommaNeeded = HasDirectFlags;
5482cab237bSDimitry Andric   unsigned BitMask = Flags.second;
5492cab237bSDimitry Andric   auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags();
5502cab237bSDimitry Andric   for (const auto &Mask : BitMasks) {
5512cab237bSDimitry Andric     // Check if the flag's bitmask has the bits of the current mask set.
5522cab237bSDimitry Andric     if ((BitMask & Mask.first) == Mask.first) {
5532cab237bSDimitry Andric       if (IsCommaNeeded)
5542cab237bSDimitry Andric         OS << ", ";
5552cab237bSDimitry Andric       IsCommaNeeded = true;
5562cab237bSDimitry Andric       OS << Mask.second;
5572cab237bSDimitry Andric       // Clear the bits which were serialized from the flag's bitmask.
5582cab237bSDimitry Andric       BitMask &= ~(Mask.first);
5592cab237bSDimitry Andric     }
5602cab237bSDimitry Andric   }
5612cab237bSDimitry Andric   if (BitMask) {
5622cab237bSDimitry Andric     // When the resulting flag's bitmask isn't zero, we know that we didn't
5632cab237bSDimitry Andric     // serialize all of the bit flags.
5642cab237bSDimitry Andric     if (IsCommaNeeded)
5652cab237bSDimitry Andric       OS << ", ";
5662cab237bSDimitry Andric     OS << "<unknown bitmask target flag>";
5672cab237bSDimitry Andric   }
5682cab237bSDimitry Andric   OS << ") ";
5692cab237bSDimitry Andric }
5702cab237bSDimitry Andric 
printSymbol(raw_ostream & OS,MCSymbol & Sym)5712cab237bSDimitry Andric void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) {
5722cab237bSDimitry Andric   OS << "<mcsymbol " << Sym << ">";
5732cab237bSDimitry Andric }
5742cab237bSDimitry Andric 
printStackObjectReference(raw_ostream & OS,unsigned FrameIndex,bool IsFixed,StringRef Name)5752cab237bSDimitry Andric void MachineOperand::printStackObjectReference(raw_ostream &OS,
5762cab237bSDimitry Andric                                                unsigned FrameIndex,
5772cab237bSDimitry Andric                                                bool IsFixed, StringRef Name) {
5782cab237bSDimitry Andric   if (IsFixed) {
5792cab237bSDimitry Andric     OS << "%fixed-stack." << FrameIndex;
5802cab237bSDimitry Andric     return;
5812cab237bSDimitry Andric   }
5822cab237bSDimitry Andric 
5832cab237bSDimitry Andric   OS << "%stack." << FrameIndex;
5842cab237bSDimitry Andric   if (!Name.empty())
5852cab237bSDimitry Andric     OS << '.' << Name;
5862cab237bSDimitry Andric }
5872cab237bSDimitry Andric 
printOperandOffset(raw_ostream & OS,int64_t Offset)588da09e106SDimitry Andric void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) {
589da09e106SDimitry Andric   if (Offset == 0)
590da09e106SDimitry Andric     return;
591da09e106SDimitry Andric   if (Offset < 0) {
592da09e106SDimitry Andric     OS << " - " << -Offset;
593da09e106SDimitry Andric     return;
594da09e106SDimitry Andric   }
595da09e106SDimitry Andric   OS << " + " << Offset;
596da09e106SDimitry Andric }
597da09e106SDimitry Andric 
printIRSlotNumber(raw_ostream & OS,int Slot)598da09e106SDimitry Andric void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) {
599da09e106SDimitry Andric   if (Slot == -1)
600da09e106SDimitry Andric     OS << "<badref>";
601da09e106SDimitry Andric   else
602da09e106SDimitry Andric     OS << Slot;
603da09e106SDimitry Andric }
604da09e106SDimitry Andric 
printCFI(raw_ostream & OS,const MCCFIInstruction & CFI,const TargetRegisterInfo * TRI)605da09e106SDimitry Andric static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI,
606da09e106SDimitry Andric                      const TargetRegisterInfo *TRI) {
607da09e106SDimitry Andric   switch (CFI.getOperation()) {
608da09e106SDimitry Andric   case MCCFIInstruction::OpSameValue:
609da09e106SDimitry Andric     OS << "same_value ";
610da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
611da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
612da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
613da09e106SDimitry Andric     break;
614da09e106SDimitry Andric   case MCCFIInstruction::OpRememberState:
615da09e106SDimitry Andric     OS << "remember_state ";
616da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
617da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
618da09e106SDimitry Andric     break;
619da09e106SDimitry Andric   case MCCFIInstruction::OpRestoreState:
620da09e106SDimitry Andric     OS << "restore_state ";
621da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
622da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
623da09e106SDimitry Andric     break;
624da09e106SDimitry Andric   case MCCFIInstruction::OpOffset:
625da09e106SDimitry Andric     OS << "offset ";
626da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
627da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
628da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
629da09e106SDimitry Andric     OS << ", " << CFI.getOffset();
630da09e106SDimitry Andric     break;
631da09e106SDimitry Andric   case MCCFIInstruction::OpDefCfaRegister:
632da09e106SDimitry Andric     OS << "def_cfa_register ";
633da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
634da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
635da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
636da09e106SDimitry Andric     break;
637da09e106SDimitry Andric   case MCCFIInstruction::OpDefCfaOffset:
638da09e106SDimitry Andric     OS << "def_cfa_offset ";
639da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
640da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
641da09e106SDimitry Andric     OS << CFI.getOffset();
642da09e106SDimitry Andric     break;
643da09e106SDimitry Andric   case MCCFIInstruction::OpDefCfa:
644da09e106SDimitry Andric     OS << "def_cfa ";
645da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
646da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
647da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
648da09e106SDimitry Andric     OS << ", " << CFI.getOffset();
649da09e106SDimitry Andric     break;
650da09e106SDimitry Andric   case MCCFIInstruction::OpRelOffset:
651da09e106SDimitry Andric     OS << "rel_offset ";
652da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
653da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
654da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
655da09e106SDimitry Andric     OS << ", " << CFI.getOffset();
656da09e106SDimitry Andric     break;
657da09e106SDimitry Andric   case MCCFIInstruction::OpAdjustCfaOffset:
658da09e106SDimitry Andric     OS << "adjust_cfa_offset ";
659da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
660da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
661da09e106SDimitry Andric     OS << CFI.getOffset();
662da09e106SDimitry Andric     break;
663da09e106SDimitry Andric   case MCCFIInstruction::OpRestore:
664da09e106SDimitry Andric     OS << "restore ";
665da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
666da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
667da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
668da09e106SDimitry Andric     break;
669da09e106SDimitry Andric   case MCCFIInstruction::OpEscape: {
670da09e106SDimitry Andric     OS << "escape ";
671da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
672da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
673da09e106SDimitry Andric     if (!CFI.getValues().empty()) {
674da09e106SDimitry Andric       size_t e = CFI.getValues().size() - 1;
675da09e106SDimitry Andric       for (size_t i = 0; i < e; ++i)
676da09e106SDimitry Andric         OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", ";
677da09e106SDimitry Andric       OS << format("0x%02x", uint8_t(CFI.getValues()[e])) << ", ";
678da09e106SDimitry Andric     }
679da09e106SDimitry Andric     break;
680da09e106SDimitry Andric   }
681da09e106SDimitry Andric   case MCCFIInstruction::OpUndefined:
682da09e106SDimitry Andric     OS << "undefined ";
683da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
684da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
685da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
686da09e106SDimitry Andric     break;
687da09e106SDimitry Andric   case MCCFIInstruction::OpRegister:
688da09e106SDimitry Andric     OS << "register ";
689da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
690da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
691da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
692da09e106SDimitry Andric     OS << ", ";
693da09e106SDimitry Andric     printCFIRegister(CFI.getRegister2(), OS, TRI);
694da09e106SDimitry Andric     break;
695da09e106SDimitry Andric   case MCCFIInstruction::OpWindowSave:
696da09e106SDimitry Andric     OS << "window_save ";
697da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
698da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
699da09e106SDimitry Andric     break;
700*b5893f02SDimitry Andric   case MCCFIInstruction::OpNegateRAState:
701*b5893f02SDimitry Andric     OS << "negate_ra_sign_state ";
702*b5893f02SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
703*b5893f02SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
704*b5893f02SDimitry Andric     break;
705da09e106SDimitry Andric   default:
706da09e106SDimitry Andric     // TODO: Print the other CFI Operations.
707da09e106SDimitry Andric     OS << "<unserializable cfi directive>";
708da09e106SDimitry Andric     break;
709da09e106SDimitry Andric   }
710da09e106SDimitry Andric }
711da09e106SDimitry Andric 
print(raw_ostream & OS,const TargetRegisterInfo * TRI,const TargetIntrinsicInfo * IntrinsicInfo) const7122cab237bSDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI,
7132cab237bSDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
7144ba319b5SDimitry Andric   print(OS, LLT{}, TRI, IntrinsicInfo);
7154ba319b5SDimitry Andric }
7164ba319b5SDimitry Andric 
print(raw_ostream & OS,LLT TypeToPrint,const TargetRegisterInfo * TRI,const TargetIntrinsicInfo * IntrinsicInfo) const7174ba319b5SDimitry Andric void MachineOperand::print(raw_ostream &OS, LLT TypeToPrint,
7184ba319b5SDimitry Andric                            const TargetRegisterInfo *TRI,
7194ba319b5SDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
7202cab237bSDimitry Andric   tryToGetTargetInfo(*this, TRI, IntrinsicInfo);
7212cab237bSDimitry Andric   ModuleSlotTracker DummyMST(nullptr);
7224ba319b5SDimitry Andric   print(OS, DummyMST, TypeToPrint, /*PrintDef=*/false, /*IsStandalone=*/true,
7232cab237bSDimitry Andric         /*ShouldPrintRegisterTies=*/true,
7242cab237bSDimitry Andric         /*TiedOperandIdx=*/0, TRI, IntrinsicInfo);
7252cab237bSDimitry Andric }
7262cab237bSDimitry Andric 
print(raw_ostream & OS,ModuleSlotTracker & MST,LLT TypeToPrint,bool PrintDef,bool IsStandalone,bool ShouldPrintRegisterTies,unsigned TiedOperandIdx,const TargetRegisterInfo * TRI,const TargetIntrinsicInfo * IntrinsicInfo) const7272cab237bSDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
7284ba319b5SDimitry Andric                            LLT TypeToPrint, bool PrintDef, bool IsStandalone,
7292cab237bSDimitry Andric                            bool ShouldPrintRegisterTies,
7302cab237bSDimitry Andric                            unsigned TiedOperandIdx,
7312cab237bSDimitry Andric                            const TargetRegisterInfo *TRI,
7322cab237bSDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
7332cab237bSDimitry Andric   printTargetFlags(OS, *this);
7342cab237bSDimitry Andric   switch (getType()) {
7352cab237bSDimitry Andric   case MachineOperand::MO_Register: {
7362cab237bSDimitry Andric     unsigned Reg = getReg();
7372cab237bSDimitry Andric     if (isImplicit())
7382cab237bSDimitry Andric       OS << (isDef() ? "implicit-def " : "implicit ");
7392cab237bSDimitry Andric     else if (PrintDef && isDef())
7402cab237bSDimitry Andric       // Print the 'def' flag only when the operand is defined after '='.
7412cab237bSDimitry Andric       OS << "def ";
7422cab237bSDimitry Andric     if (isInternalRead())
7432cab237bSDimitry Andric       OS << "internal ";
7442cab237bSDimitry Andric     if (isDead())
7452cab237bSDimitry Andric       OS << "dead ";
7462cab237bSDimitry Andric     if (isKill())
7472cab237bSDimitry Andric       OS << "killed ";
7482cab237bSDimitry Andric     if (isUndef())
7492cab237bSDimitry Andric       OS << "undef ";
7502cab237bSDimitry Andric     if (isEarlyClobber())
7512cab237bSDimitry Andric       OS << "early-clobber ";
7522cab237bSDimitry Andric     if (TargetRegisterInfo::isPhysicalRegister(getReg()) && isRenamable())
7532cab237bSDimitry Andric       OS << "renamable ";
754*b5893f02SDimitry Andric     // isDebug() is exactly true for register operands of a DBG_VALUE. So we
755*b5893f02SDimitry Andric     // simply infer it when parsing and do not need to print it.
7564ba319b5SDimitry Andric 
7574ba319b5SDimitry Andric     const MachineRegisterInfo *MRI = nullptr;
7584ba319b5SDimitry Andric     if (TargetRegisterInfo::isVirtualRegister(Reg)) {
7594ba319b5SDimitry Andric       if (const MachineFunction *MF = getMFIfAvailable(*this)) {
7604ba319b5SDimitry Andric         MRI = &MF->getRegInfo();
7614ba319b5SDimitry Andric       }
7624ba319b5SDimitry Andric     }
7634ba319b5SDimitry Andric 
7644ba319b5SDimitry Andric     OS << printReg(Reg, TRI, 0, MRI);
7652cab237bSDimitry Andric     // Print the sub register.
7662cab237bSDimitry Andric     if (unsigned SubReg = getSubReg()) {
7672cab237bSDimitry Andric       if (TRI)
7682cab237bSDimitry Andric         OS << '.' << TRI->getSubRegIndexName(SubReg);
7692cab237bSDimitry Andric       else
7702cab237bSDimitry Andric         OS << ".subreg" << SubReg;
7712cab237bSDimitry Andric     }
7722cab237bSDimitry Andric     // Print the register class / bank.
7732cab237bSDimitry Andric     if (TargetRegisterInfo::isVirtualRegister(Reg)) {
7742cab237bSDimitry Andric       if (const MachineFunction *MF = getMFIfAvailable(*this)) {
7752cab237bSDimitry Andric         const MachineRegisterInfo &MRI = MF->getRegInfo();
7764ba319b5SDimitry Andric         if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) {
7772cab237bSDimitry Andric           OS << ':';
7782cab237bSDimitry Andric           OS << printRegClassOrBank(Reg, MRI, TRI);
7792cab237bSDimitry Andric         }
7802cab237bSDimitry Andric       }
7812cab237bSDimitry Andric     }
7822cab237bSDimitry Andric     // Print ties.
7832cab237bSDimitry Andric     if (ShouldPrintRegisterTies && isTied() && !isDef())
7842cab237bSDimitry Andric       OS << "(tied-def " << TiedOperandIdx << ")";
7852cab237bSDimitry Andric     // Print types.
7862cab237bSDimitry Andric     if (TypeToPrint.isValid())
7872cab237bSDimitry Andric       OS << '(' << TypeToPrint << ')';
7882cab237bSDimitry Andric     break;
7892cab237bSDimitry Andric   }
7902cab237bSDimitry Andric   case MachineOperand::MO_Immediate:
7912cab237bSDimitry Andric     OS << getImm();
7922cab237bSDimitry Andric     break;
7932cab237bSDimitry Andric   case MachineOperand::MO_CImmediate:
7942cab237bSDimitry Andric     getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
7952cab237bSDimitry Andric     break;
7962cab237bSDimitry Andric   case MachineOperand::MO_FPImmediate:
797da09e106SDimitry Andric     getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST);
7982cab237bSDimitry Andric     break;
7992cab237bSDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
8002cab237bSDimitry Andric     OS << printMBBReference(*getMBB());
8012cab237bSDimitry Andric     break;
8022cab237bSDimitry Andric   case MachineOperand::MO_FrameIndex: {
8032cab237bSDimitry Andric     int FrameIndex = getIndex();
8042cab237bSDimitry Andric     bool IsFixed = false;
8054ba319b5SDimitry Andric     const MachineFrameInfo *MFI = nullptr;
8064ba319b5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
8074ba319b5SDimitry Andric       MFI = &MF->getFrameInfo();
8084ba319b5SDimitry Andric     printFrameIndex(OS, FrameIndex, IsFixed, MFI);
8092cab237bSDimitry Andric     break;
8102cab237bSDimitry Andric   }
8112cab237bSDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
8122cab237bSDimitry Andric     OS << "%const." << getIndex();
813da09e106SDimitry Andric     printOperandOffset(OS, getOffset());
8142cab237bSDimitry Andric     break;
8152cab237bSDimitry Andric   case MachineOperand::MO_TargetIndex: {
8162cab237bSDimitry Andric     OS << "target-index(";
8172cab237bSDimitry Andric     const char *Name = "<unknown>";
8182cab237bSDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
8192cab237bSDimitry Andric       if (const auto *TargetIndexName = getTargetIndexName(*MF, getIndex()))
8202cab237bSDimitry Andric         Name = TargetIndexName;
8212cab237bSDimitry Andric     OS << Name << ')';
822da09e106SDimitry Andric     printOperandOffset(OS, getOffset());
8232cab237bSDimitry Andric     break;
8242cab237bSDimitry Andric   }
8252cab237bSDimitry Andric   case MachineOperand::MO_JumpTableIndex:
8262cab237bSDimitry Andric     OS << printJumpTableEntryReference(getIndex());
8272cab237bSDimitry Andric     break;
8282cab237bSDimitry Andric   case MachineOperand::MO_GlobalAddress:
8292cab237bSDimitry Andric     getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
830da09e106SDimitry Andric     printOperandOffset(OS, getOffset());
8312cab237bSDimitry Andric     break;
8322cab237bSDimitry Andric   case MachineOperand::MO_ExternalSymbol: {
8332cab237bSDimitry Andric     StringRef Name = getSymbolName();
8344ba319b5SDimitry Andric     OS << '&';
8352cab237bSDimitry Andric     if (Name.empty()) {
8362cab237bSDimitry Andric       OS << "\"\"";
8372cab237bSDimitry Andric     } else {
8382cab237bSDimitry Andric       printLLVMNameWithoutPrefix(OS, Name);
8392cab237bSDimitry Andric     }
840da09e106SDimitry Andric     printOperandOffset(OS, getOffset());
8412cab237bSDimitry Andric     break;
8422cab237bSDimitry Andric   }
843da09e106SDimitry Andric   case MachineOperand::MO_BlockAddress: {
844da09e106SDimitry Andric     OS << "blockaddress(";
845da09e106SDimitry Andric     getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
846da09e106SDimitry Andric                                                      MST);
847da09e106SDimitry Andric     OS << ", ";
848da09e106SDimitry Andric     printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST);
849da09e106SDimitry Andric     OS << ')';
850da09e106SDimitry Andric     MachineOperand::printOperandOffset(OS, getOffset());
8512cab237bSDimitry Andric     break;
852da09e106SDimitry Andric   }
8532cab237bSDimitry Andric   case MachineOperand::MO_RegisterMask: {
8542cab237bSDimitry Andric     OS << "<regmask";
8552cab237bSDimitry Andric     if (TRI) {
8562cab237bSDimitry Andric       unsigned NumRegsInMask = 0;
8572cab237bSDimitry Andric       unsigned NumRegsEmitted = 0;
8582cab237bSDimitry Andric       for (unsigned i = 0; i < TRI->getNumRegs(); ++i) {
8592cab237bSDimitry Andric         unsigned MaskWord = i / 32;
8602cab237bSDimitry Andric         unsigned MaskBit = i % 32;
8612cab237bSDimitry Andric         if (getRegMask()[MaskWord] & (1 << MaskBit)) {
8622cab237bSDimitry Andric           if (PrintRegMaskNumRegs < 0 ||
8632cab237bSDimitry Andric               NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) {
8642cab237bSDimitry Andric             OS << " " << printReg(i, TRI);
8652cab237bSDimitry Andric             NumRegsEmitted++;
8662cab237bSDimitry Andric           }
8672cab237bSDimitry Andric           NumRegsInMask++;
8682cab237bSDimitry Andric         }
8692cab237bSDimitry Andric       }
8702cab237bSDimitry Andric       if (NumRegsEmitted != NumRegsInMask)
8712cab237bSDimitry Andric         OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more...";
8722cab237bSDimitry Andric     } else {
8732cab237bSDimitry Andric       OS << " ...";
8742cab237bSDimitry Andric     }
8752cab237bSDimitry Andric     OS << ">";
8762cab237bSDimitry Andric     break;
8772cab237bSDimitry Andric   }
8782cab237bSDimitry Andric   case MachineOperand::MO_RegisterLiveOut: {
8792cab237bSDimitry Andric     const uint32_t *RegMask = getRegLiveOut();
8802cab237bSDimitry Andric     OS << "liveout(";
8812cab237bSDimitry Andric     if (!TRI) {
8822cab237bSDimitry Andric       OS << "<unknown>";
8832cab237bSDimitry Andric     } else {
8842cab237bSDimitry Andric       bool IsCommaNeeded = false;
8852cab237bSDimitry Andric       for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
8862cab237bSDimitry Andric         if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
8872cab237bSDimitry Andric           if (IsCommaNeeded)
8882cab237bSDimitry Andric             OS << ", ";
8892cab237bSDimitry Andric           OS << printReg(Reg, TRI);
8902cab237bSDimitry Andric           IsCommaNeeded = true;
8912cab237bSDimitry Andric         }
8922cab237bSDimitry Andric       }
8932cab237bSDimitry Andric     }
8942cab237bSDimitry Andric     OS << ")";
8952cab237bSDimitry Andric     break;
8962cab237bSDimitry Andric   }
8972cab237bSDimitry Andric   case MachineOperand::MO_Metadata:
8982cab237bSDimitry Andric     getMetadata()->printAsOperand(OS, MST);
8992cab237bSDimitry Andric     break;
9002cab237bSDimitry Andric   case MachineOperand::MO_MCSymbol:
9012cab237bSDimitry Andric     printSymbol(OS, *getMCSymbol());
9022cab237bSDimitry Andric     break;
903da09e106SDimitry Andric   case MachineOperand::MO_CFIIndex: {
904da09e106SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
905da09e106SDimitry Andric       printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI);
906da09e106SDimitry Andric     else
907da09e106SDimitry Andric       OS << "<cfi directive>";
9082cab237bSDimitry Andric     break;
909da09e106SDimitry Andric   }
9102cab237bSDimitry Andric   case MachineOperand::MO_IntrinsicID: {
9112cab237bSDimitry Andric     Intrinsic::ID ID = getIntrinsicID();
9122cab237bSDimitry Andric     if (ID < Intrinsic::num_intrinsics)
913da09e106SDimitry Andric       OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')';
9142cab237bSDimitry Andric     else if (IntrinsicInfo)
915da09e106SDimitry Andric       OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')';
9162cab237bSDimitry Andric     else
917da09e106SDimitry Andric       OS << "intrinsic(" << ID << ')';
9182cab237bSDimitry Andric     break;
9192cab237bSDimitry Andric   }
9202cab237bSDimitry Andric   case MachineOperand::MO_Predicate: {
9212cab237bSDimitry Andric     auto Pred = static_cast<CmpInst::Predicate>(getPredicate());
922da09e106SDimitry Andric     OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred("
923da09e106SDimitry Andric        << CmpInst::getPredicateName(Pred) << ')';
9242cab237bSDimitry Andric     break;
9252cab237bSDimitry Andric   }
9262cab237bSDimitry Andric   }
9272cab237bSDimitry Andric }
9282cab237bSDimitry Andric 
9292cab237bSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const9302cab237bSDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; }
9312cab237bSDimitry Andric #endif
9322cab237bSDimitry Andric 
9332cab237bSDimitry Andric //===----------------------------------------------------------------------===//
9342cab237bSDimitry Andric // MachineMemOperand Implementation
9352cab237bSDimitry Andric //===----------------------------------------------------------------------===//
9362cab237bSDimitry Andric 
9372cab237bSDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer
9382cab237bSDimitry Andric /// points into.
getAddrSpace() const9392cab237bSDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; }
9402cab237bSDimitry Andric 
9412cab237bSDimitry Andric /// isDereferenceable - Return true if V is always dereferenceable for
9422cab237bSDimitry Andric /// Offset + Size byte.
isDereferenceable(unsigned Size,LLVMContext & C,const DataLayout & DL) const9432cab237bSDimitry Andric bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C,
9442cab237bSDimitry Andric                                            const DataLayout &DL) const {
9452cab237bSDimitry Andric   if (!V.is<const Value *>())
9462cab237bSDimitry Andric     return false;
9472cab237bSDimitry Andric 
9482cab237bSDimitry Andric   const Value *BasePtr = V.get<const Value *>();
9492cab237bSDimitry Andric   if (BasePtr == nullptr)
9502cab237bSDimitry Andric     return false;
9512cab237bSDimitry Andric 
9522cab237bSDimitry Andric   return isDereferenceableAndAlignedPointer(
9532cab237bSDimitry Andric       BasePtr, 1, APInt(DL.getPointerSizeInBits(), Offset + Size), DL);
9542cab237bSDimitry Andric }
9552cab237bSDimitry Andric 
9562cab237bSDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the
9572cab237bSDimitry Andric /// constant pool.
getConstantPool(MachineFunction & MF)9582cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) {
9592cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getConstantPool());
9602cab237bSDimitry Andric }
9612cab237bSDimitry Andric 
9622cab237bSDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the
9632cab237bSDimitry Andric /// the specified FrameIndex.
getFixedStack(MachineFunction & MF,int FI,int64_t Offset)9642cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF,
9652cab237bSDimitry Andric                                                      int FI, int64_t Offset) {
9662cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset);
9672cab237bSDimitry Andric }
9682cab237bSDimitry Andric 
getJumpTable(MachineFunction & MF)9692cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) {
9702cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getJumpTable());
9712cab237bSDimitry Andric }
9722cab237bSDimitry Andric 
getGOT(MachineFunction & MF)9732cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) {
9742cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getGOT());
9752cab237bSDimitry Andric }
9762cab237bSDimitry Andric 
getStack(MachineFunction & MF,int64_t Offset,uint8_t ID)9772cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF,
9782cab237bSDimitry Andric                                                 int64_t Offset, uint8_t ID) {
9792cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID);
9802cab237bSDimitry Andric }
9812cab237bSDimitry Andric 
getUnknownStack(MachineFunction & MF)9822cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) {
9832cab237bSDimitry Andric   return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace());
9842cab237bSDimitry Andric }
9852cab237bSDimitry Andric 
MachineMemOperand(MachinePointerInfo ptrinfo,Flags f,uint64_t s,uint64_t a,const AAMDNodes & AAInfo,const MDNode * Ranges,SyncScope::ID SSID,AtomicOrdering Ordering,AtomicOrdering FailureOrdering)9862cab237bSDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
9874ba319b5SDimitry Andric                                      uint64_t s, uint64_t a,
9882cab237bSDimitry Andric                                      const AAMDNodes &AAInfo,
9892cab237bSDimitry Andric                                      const MDNode *Ranges, SyncScope::ID SSID,
9902cab237bSDimitry Andric                                      AtomicOrdering Ordering,
9912cab237bSDimitry Andric                                      AtomicOrdering FailureOrdering)
9922cab237bSDimitry Andric     : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1),
9932cab237bSDimitry Andric       AAInfo(AAInfo), Ranges(Ranges) {
9942cab237bSDimitry Andric   assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() ||
9952cab237bSDimitry Andric           isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) &&
9962cab237bSDimitry Andric          "invalid pointer value");
9972cab237bSDimitry Andric   assert(getBaseAlignment() == a && "Alignment is not a power of 2!");
9982cab237bSDimitry Andric   assert((isLoad() || isStore()) && "Not a load/store!");
9992cab237bSDimitry Andric 
10002cab237bSDimitry Andric   AtomicInfo.SSID = static_cast<unsigned>(SSID);
10012cab237bSDimitry Andric   assert(getSyncScopeID() == SSID && "Value truncated");
10022cab237bSDimitry Andric   AtomicInfo.Ordering = static_cast<unsigned>(Ordering);
10032cab237bSDimitry Andric   assert(getOrdering() == Ordering && "Value truncated");
10042cab237bSDimitry Andric   AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering);
10052cab237bSDimitry Andric   assert(getFailureOrdering() == FailureOrdering && "Value truncated");
10062cab237bSDimitry Andric }
10072cab237bSDimitry Andric 
10082cab237bSDimitry Andric /// Profile - Gather unique data for the object.
10092cab237bSDimitry Andric ///
Profile(FoldingSetNodeID & ID) const10102cab237bSDimitry Andric void MachineMemOperand::Profile(FoldingSetNodeID &ID) const {
10112cab237bSDimitry Andric   ID.AddInteger(getOffset());
10122cab237bSDimitry Andric   ID.AddInteger(Size);
10132cab237bSDimitry Andric   ID.AddPointer(getOpaqueValue());
10142cab237bSDimitry Andric   ID.AddInteger(getFlags());
10152cab237bSDimitry Andric   ID.AddInteger(getBaseAlignment());
10162cab237bSDimitry Andric }
10172cab237bSDimitry Andric 
refineAlignment(const MachineMemOperand * MMO)10182cab237bSDimitry Andric void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
10192cab237bSDimitry Andric   // The Value and Offset may differ due to CSE. But the flags and size
10202cab237bSDimitry Andric   // should be the same.
10212cab237bSDimitry Andric   assert(MMO->getFlags() == getFlags() && "Flags mismatch!");
10222cab237bSDimitry Andric   assert(MMO->getSize() == getSize() && "Size mismatch!");
10232cab237bSDimitry Andric 
10242cab237bSDimitry Andric   if (MMO->getBaseAlignment() >= getBaseAlignment()) {
10252cab237bSDimitry Andric     // Update the alignment value.
10262cab237bSDimitry Andric     BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1;
10272cab237bSDimitry Andric     // Also update the base and offset, because the new alignment may
10282cab237bSDimitry Andric     // not be applicable with the old ones.
10292cab237bSDimitry Andric     PtrInfo = MMO->PtrInfo;
10302cab237bSDimitry Andric   }
10312cab237bSDimitry Andric }
10322cab237bSDimitry Andric 
10332cab237bSDimitry Andric /// getAlignment - Return the minimum known alignment in bytes of the
10342cab237bSDimitry Andric /// actual memory reference.
getAlignment() const10352cab237bSDimitry Andric uint64_t MachineMemOperand::getAlignment() const {
10362cab237bSDimitry Andric   return MinAlign(getBaseAlignment(), getOffset());
10372cab237bSDimitry Andric }
10382cab237bSDimitry Andric 
print(raw_ostream & OS) const10392cab237bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS) const {
10402cab237bSDimitry Andric   ModuleSlotTracker DummyMST(nullptr);
10412cab237bSDimitry Andric   print(OS, DummyMST);
10422cab237bSDimitry Andric }
10434ba319b5SDimitry Andric 
print(raw_ostream & OS,ModuleSlotTracker & MST) const10442cab237bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const {
10454ba319b5SDimitry Andric   SmallVector<StringRef, 0> SSNs;
10464ba319b5SDimitry Andric   LLVMContext Ctx;
10474ba319b5SDimitry Andric   print(OS, MST, SSNs, Ctx, nullptr, nullptr);
10484ba319b5SDimitry Andric }
10492cab237bSDimitry Andric 
print(raw_ostream & OS,ModuleSlotTracker & MST,SmallVectorImpl<StringRef> & SSNs,const LLVMContext & Context,const MachineFrameInfo * MFI,const TargetInstrInfo * TII) const10504ba319b5SDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
10514ba319b5SDimitry Andric                               SmallVectorImpl<StringRef> &SSNs,
10524ba319b5SDimitry Andric                               const LLVMContext &Context,
10534ba319b5SDimitry Andric                               const MachineFrameInfo *MFI,
10544ba319b5SDimitry Andric                               const TargetInstrInfo *TII) const {
10554ba319b5SDimitry Andric   OS << '(';
10562cab237bSDimitry Andric   if (isVolatile())
10574ba319b5SDimitry Andric     OS << "volatile ";
10584ba319b5SDimitry Andric   if (isNonTemporal())
10594ba319b5SDimitry Andric     OS << "non-temporal ";
10604ba319b5SDimitry Andric   if (isDereferenceable())
10614ba319b5SDimitry Andric     OS << "dereferenceable ";
10624ba319b5SDimitry Andric   if (isInvariant())
10634ba319b5SDimitry Andric     OS << "invariant ";
10644ba319b5SDimitry Andric   if (getFlags() & MachineMemOperand::MOTargetFlag1)
10654ba319b5SDimitry Andric     OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag1)
10664ba319b5SDimitry Andric        << "\" ";
10674ba319b5SDimitry Andric   if (getFlags() & MachineMemOperand::MOTargetFlag2)
10684ba319b5SDimitry Andric     OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag2)
10694ba319b5SDimitry Andric        << "\" ";
10704ba319b5SDimitry Andric   if (getFlags() & MachineMemOperand::MOTargetFlag3)
10714ba319b5SDimitry Andric     OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag3)
10724ba319b5SDimitry Andric        << "\" ";
10732cab237bSDimitry Andric 
10744ba319b5SDimitry Andric   assert((isLoad() || isStore()) &&
10754ba319b5SDimitry Andric          "machine memory operand must be a load or store (or both)");
10762cab237bSDimitry Andric   if (isLoad())
10774ba319b5SDimitry Andric     OS << "load ";
10782cab237bSDimitry Andric   if (isStore())
10794ba319b5SDimitry Andric     OS << "store ";
10804ba319b5SDimitry Andric 
10814ba319b5SDimitry Andric   printSyncScope(OS, Context, getSyncScopeID(), SSNs);
10824ba319b5SDimitry Andric 
10834ba319b5SDimitry Andric   if (getOrdering() != AtomicOrdering::NotAtomic)
10844ba319b5SDimitry Andric     OS << toIRString(getOrdering()) << ' ';
10854ba319b5SDimitry Andric   if (getFailureOrdering() != AtomicOrdering::NotAtomic)
10864ba319b5SDimitry Andric     OS << toIRString(getFailureOrdering()) << ' ';
10874ba319b5SDimitry Andric 
1088*b5893f02SDimitry Andric   if (getSize() == MemoryLocation::UnknownSize)
1089*b5893f02SDimitry Andric     OS << "unknown-size";
1090*b5893f02SDimitry Andric   else
10912cab237bSDimitry Andric     OS << getSize();
1092*b5893f02SDimitry Andric 
10934ba319b5SDimitry Andric   if (const Value *Val = getValue()) {
10944ba319b5SDimitry Andric     OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
10954ba319b5SDimitry Andric     printIRValueReference(OS, *Val, MST);
10964ba319b5SDimitry Andric   } else if (const PseudoSourceValue *PVal = getPseudoValue()) {
10974ba319b5SDimitry Andric     OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into ");
10984ba319b5SDimitry Andric     assert(PVal && "Expected a pseudo source value");
10994ba319b5SDimitry Andric     switch (PVal->kind()) {
11004ba319b5SDimitry Andric     case PseudoSourceValue::Stack:
11014ba319b5SDimitry Andric       OS << "stack";
11024ba319b5SDimitry Andric       break;
11034ba319b5SDimitry Andric     case PseudoSourceValue::GOT:
11044ba319b5SDimitry Andric       OS << "got";
11054ba319b5SDimitry Andric       break;
11064ba319b5SDimitry Andric     case PseudoSourceValue::JumpTable:
11074ba319b5SDimitry Andric       OS << "jump-table";
11084ba319b5SDimitry Andric       break;
11094ba319b5SDimitry Andric     case PseudoSourceValue::ConstantPool:
11104ba319b5SDimitry Andric       OS << "constant-pool";
11114ba319b5SDimitry Andric       break;
11124ba319b5SDimitry Andric     case PseudoSourceValue::FixedStack: {
11134ba319b5SDimitry Andric       int FrameIndex = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
11144ba319b5SDimitry Andric       bool IsFixed = true;
11154ba319b5SDimitry Andric       printFrameIndex(OS, FrameIndex, IsFixed, MFI);
11164ba319b5SDimitry Andric       break;
11172cab237bSDimitry Andric     }
11184ba319b5SDimitry Andric     case PseudoSourceValue::GlobalValueCallEntry:
11194ba319b5SDimitry Andric       OS << "call-entry ";
11204ba319b5SDimitry Andric       cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand(
11214ba319b5SDimitry Andric           OS, /*PrintType=*/false, MST);
11224ba319b5SDimitry Andric       break;
11234ba319b5SDimitry Andric     case PseudoSourceValue::ExternalSymbolCallEntry:
11244ba319b5SDimitry Andric       OS << "call-entry &";
11254ba319b5SDimitry Andric       printLLVMNameWithoutPrefix(
11264ba319b5SDimitry Andric           OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol());
11274ba319b5SDimitry Andric       break;
11284ba319b5SDimitry Andric     case PseudoSourceValue::TargetCustom:
11294ba319b5SDimitry Andric       // FIXME: This is not necessarily the correct MIR serialization format for
11304ba319b5SDimitry Andric       // a custom pseudo source value, but at least it allows
11314ba319b5SDimitry Andric       // -print-machineinstrs to work on a target with custom pseudo source
11324ba319b5SDimitry Andric       // values.
11334ba319b5SDimitry Andric       OS << "custom ";
11344ba319b5SDimitry Andric       PVal->printCustom(OS);
11354ba319b5SDimitry Andric       break;
11362cab237bSDimitry Andric     }
11372cab237bSDimitry Andric   }
11384ba319b5SDimitry Andric   MachineOperand::printOperandOffset(OS, getOffset());
11394ba319b5SDimitry Andric   if (getBaseAlignment() != getSize())
11404ba319b5SDimitry Andric     OS << ", align " << getBaseAlignment();
11414ba319b5SDimitry Andric   auto AAInfo = getAAInfo();
11424ba319b5SDimitry Andric   if (AAInfo.TBAA) {
11434ba319b5SDimitry Andric     OS << ", !tbaa ";
11444ba319b5SDimitry Andric     AAInfo.TBAA->printAsOperand(OS, MST);
11452cab237bSDimitry Andric   }
11464ba319b5SDimitry Andric   if (AAInfo.Scope) {
11474ba319b5SDimitry Andric     OS << ", !alias.scope ";
11484ba319b5SDimitry Andric     AAInfo.Scope->printAsOperand(OS, MST);
11492cab237bSDimitry Andric   }
11504ba319b5SDimitry Andric   if (AAInfo.NoAlias) {
11514ba319b5SDimitry Andric     OS << ", !noalias ";
11524ba319b5SDimitry Andric     AAInfo.NoAlias->printAsOperand(OS, MST);
11532cab237bSDimitry Andric   }
11544ba319b5SDimitry Andric   if (getRanges()) {
11554ba319b5SDimitry Andric     OS << ", !range ";
11564ba319b5SDimitry Andric     getRanges()->printAsOperand(OS, MST);
11574ba319b5SDimitry Andric   }
11584ba319b5SDimitry Andric   // FIXME: Implement addrspace printing/parsing in MIR.
11594ba319b5SDimitry Andric   // For now, print this even though parsing it is not available in MIR.
11604ba319b5SDimitry Andric   if (unsigned AS = getAddrSpace())
11614ba319b5SDimitry Andric     OS << ", addrspace " << AS;
11622cab237bSDimitry Andric 
11632cab237bSDimitry Andric   OS << ')';
11642cab237bSDimitry Andric }
1165