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"
152cab237bSDimitry Andric #include "llvm/Analysis/Loads.h"
162cab237bSDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
172cab237bSDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
182cab237bSDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h"
192cab237bSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
202cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
212cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
222cab237bSDimitry Andric #include "llvm/IR/Constants.h"
232cab237bSDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
242cab237bSDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
252cab237bSDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
262cab237bSDimitry Andric #include "llvm/Target/TargetMachine.h"
272cab237bSDimitry Andric 
282cab237bSDimitry Andric using namespace llvm;
292cab237bSDimitry Andric 
302cab237bSDimitry Andric static cl::opt<int>
312cab237bSDimitry Andric     PrintRegMaskNumRegs("print-regmask-num-regs",
322cab237bSDimitry Andric                         cl::desc("Number of registers to limit to when "
332cab237bSDimitry Andric                                  "printing regmask operands in IR dumps. "
342cab237bSDimitry Andric                                  "unlimited = -1"),
352cab237bSDimitry Andric                         cl::init(32), cl::Hidden);
362cab237bSDimitry Andric 
372cab237bSDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineOperand &MO) {
382cab237bSDimitry Andric   if (const MachineInstr *MI = MO.getParent())
392cab237bSDimitry Andric     if (const MachineBasicBlock *MBB = MI->getParent())
402cab237bSDimitry Andric       if (const MachineFunction *MF = MBB->getParent())
412cab237bSDimitry Andric         return MF;
422cab237bSDimitry Andric   return nullptr;
432cab237bSDimitry Andric }
442cab237bSDimitry Andric static MachineFunction *getMFIfAvailable(MachineOperand &MO) {
452cab237bSDimitry Andric   return const_cast<MachineFunction *>(
462cab237bSDimitry Andric       getMFIfAvailable(const_cast<const MachineOperand &>(MO)));
472cab237bSDimitry Andric }
482cab237bSDimitry Andric 
492cab237bSDimitry Andric void MachineOperand::setReg(unsigned Reg) {
502cab237bSDimitry Andric   if (getReg() == Reg)
512cab237bSDimitry Andric     return; // No change.
522cab237bSDimitry Andric 
532cab237bSDimitry Andric   // Otherwise, we have to change the register.  If this operand is embedded
542cab237bSDimitry Andric   // into a machine function, we need to update the old and new register's
552cab237bSDimitry Andric   // use/def lists.
562cab237bSDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this)) {
572cab237bSDimitry Andric     MachineRegisterInfo &MRI = MF->getRegInfo();
582cab237bSDimitry Andric     MRI.removeRegOperandFromUseList(this);
592cab237bSDimitry Andric     SmallContents.RegNo = Reg;
602cab237bSDimitry Andric     MRI.addRegOperandToUseList(this);
612cab237bSDimitry Andric     return;
622cab237bSDimitry Andric   }
632cab237bSDimitry Andric 
642cab237bSDimitry Andric   // Otherwise, just change the register, no problem.  :)
652cab237bSDimitry Andric   SmallContents.RegNo = Reg;
662cab237bSDimitry Andric }
672cab237bSDimitry Andric 
682cab237bSDimitry Andric void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx,
692cab237bSDimitry Andric                                   const TargetRegisterInfo &TRI) {
702cab237bSDimitry Andric   assert(TargetRegisterInfo::isVirtualRegister(Reg));
712cab237bSDimitry Andric   if (SubIdx && getSubReg())
722cab237bSDimitry Andric     SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg());
732cab237bSDimitry Andric   setReg(Reg);
742cab237bSDimitry Andric   if (SubIdx)
752cab237bSDimitry Andric     setSubReg(SubIdx);
762cab237bSDimitry Andric }
772cab237bSDimitry Andric 
782cab237bSDimitry Andric void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) {
792cab237bSDimitry Andric   assert(TargetRegisterInfo::isPhysicalRegister(Reg));
802cab237bSDimitry Andric   if (getSubReg()) {
812cab237bSDimitry Andric     Reg = TRI.getSubReg(Reg, getSubReg());
822cab237bSDimitry Andric     // Note that getSubReg() may return 0 if the sub-register doesn't exist.
832cab237bSDimitry Andric     // That won't happen in legal code.
842cab237bSDimitry Andric     setSubReg(0);
852cab237bSDimitry Andric     if (isDef())
862cab237bSDimitry Andric       setIsUndef(false);
872cab237bSDimitry Andric   }
882cab237bSDimitry Andric   setReg(Reg);
892cab237bSDimitry Andric }
902cab237bSDimitry Andric 
912cab237bSDimitry Andric /// Change a def to a use, or a use to a def.
922cab237bSDimitry Andric void MachineOperand::setIsDef(bool Val) {
932cab237bSDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
942cab237bSDimitry Andric   assert((!Val || !isDebug()) && "Marking a debug operation as def");
952cab237bSDimitry Andric   if (IsDef == Val)
962cab237bSDimitry Andric     return;
972cab237bSDimitry Andric   assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported");
982cab237bSDimitry Andric   // MRI may keep uses and defs in different list positions.
992cab237bSDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this)) {
1002cab237bSDimitry Andric     MachineRegisterInfo &MRI = MF->getRegInfo();
1012cab237bSDimitry Andric     MRI.removeRegOperandFromUseList(this);
1022cab237bSDimitry Andric     IsDef = Val;
1032cab237bSDimitry Andric     MRI.addRegOperandToUseList(this);
1042cab237bSDimitry Andric     return;
1052cab237bSDimitry Andric   }
1062cab237bSDimitry Andric   IsDef = Val;
1072cab237bSDimitry Andric }
1082cab237bSDimitry Andric 
1092cab237bSDimitry Andric bool MachineOperand::isRenamable() const {
1102cab237bSDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
1112cab237bSDimitry Andric   assert(TargetRegisterInfo::isPhysicalRegister(getReg()) &&
1122cab237bSDimitry Andric          "isRenamable should only be checked on physical registers");
1132cab237bSDimitry Andric   return IsRenamable;
1142cab237bSDimitry Andric }
1152cab237bSDimitry Andric 
1162cab237bSDimitry Andric void MachineOperand::setIsRenamable(bool Val) {
1172cab237bSDimitry Andric   assert(isReg() && "Wrong MachineOperand accessor");
1182cab237bSDimitry Andric   assert(TargetRegisterInfo::isPhysicalRegister(getReg()) &&
1192cab237bSDimitry Andric          "setIsRenamable should only be called on physical registers");
1202cab237bSDimitry Andric   if (const MachineInstr *MI = getParent())
1212cab237bSDimitry Andric     if ((isDef() && MI->hasExtraDefRegAllocReq()) ||
1222cab237bSDimitry Andric         (isUse() && MI->hasExtraSrcRegAllocReq()))
1232cab237bSDimitry Andric       assert(!Val && "isRenamable should be false for "
1242cab237bSDimitry Andric                      "hasExtraDefRegAllocReq/hasExtraSrcRegAllocReq opcodes");
1252cab237bSDimitry Andric   IsRenamable = Val;
1262cab237bSDimitry Andric }
1272cab237bSDimitry Andric 
1282cab237bSDimitry Andric void MachineOperand::setIsRenamableIfNoExtraRegAllocReq() {
1292cab237bSDimitry Andric   if (const MachineInstr *MI = getParent())
1302cab237bSDimitry Andric     if ((isDef() && MI->hasExtraDefRegAllocReq()) ||
1312cab237bSDimitry Andric         (isUse() && MI->hasExtraSrcRegAllocReq()))
1322cab237bSDimitry Andric       return;
1332cab237bSDimitry Andric 
1342cab237bSDimitry Andric   setIsRenamable(true);
1352cab237bSDimitry Andric }
1362cab237bSDimitry Andric 
1372cab237bSDimitry Andric // If this operand is currently a register operand, and if this is in a
1382cab237bSDimitry Andric // function, deregister the operand from the register's use/def list.
1392cab237bSDimitry Andric void MachineOperand::removeRegFromUses() {
1402cab237bSDimitry Andric   if (!isReg() || !isOnRegUseList())
1412cab237bSDimitry Andric     return;
1422cab237bSDimitry Andric 
1432cab237bSDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this))
1442cab237bSDimitry Andric     MF->getRegInfo().removeRegOperandFromUseList(this);
1452cab237bSDimitry Andric }
1462cab237bSDimitry Andric 
1472cab237bSDimitry Andric /// ChangeToImmediate - Replace this operand with a new immediate operand of
1482cab237bSDimitry Andric /// the specified value.  If an operand is known to be an immediate already,
1492cab237bSDimitry Andric /// the setImm method should be used.
1502cab237bSDimitry Andric void MachineOperand::ChangeToImmediate(int64_t ImmVal) {
1512cab237bSDimitry Andric   assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
1522cab237bSDimitry Andric 
1532cab237bSDimitry Andric   removeRegFromUses();
1542cab237bSDimitry Andric 
1552cab237bSDimitry Andric   OpKind = MO_Immediate;
1562cab237bSDimitry Andric   Contents.ImmVal = ImmVal;
1572cab237bSDimitry Andric }
1582cab237bSDimitry Andric 
1592cab237bSDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) {
1602cab237bSDimitry Andric   assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm");
1612cab237bSDimitry Andric 
1622cab237bSDimitry Andric   removeRegFromUses();
1632cab237bSDimitry Andric 
1642cab237bSDimitry Andric   OpKind = MO_FPImmediate;
1652cab237bSDimitry Andric   Contents.CFP = FPImm;
1662cab237bSDimitry Andric }
1672cab237bSDimitry Andric 
1682cab237bSDimitry Andric void MachineOperand::ChangeToES(const char *SymName,
1692cab237bSDimitry Andric                                 unsigned char TargetFlags) {
1702cab237bSDimitry Andric   assert((!isReg() || !isTied()) &&
1712cab237bSDimitry Andric          "Cannot change a tied operand into an external symbol");
1722cab237bSDimitry Andric 
1732cab237bSDimitry Andric   removeRegFromUses();
1742cab237bSDimitry Andric 
1752cab237bSDimitry Andric   OpKind = MO_ExternalSymbol;
1762cab237bSDimitry Andric   Contents.OffsetedInfo.Val.SymbolName = SymName;
1772cab237bSDimitry Andric   setOffset(0); // Offset is always 0.
1782cab237bSDimitry Andric   setTargetFlags(TargetFlags);
1792cab237bSDimitry Andric }
1802cab237bSDimitry Andric 
1812cab237bSDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) {
1822cab237bSDimitry Andric   assert((!isReg() || !isTied()) &&
1832cab237bSDimitry Andric          "Cannot change a tied operand into an MCSymbol");
1842cab237bSDimitry Andric 
1852cab237bSDimitry Andric   removeRegFromUses();
1862cab237bSDimitry Andric 
1872cab237bSDimitry Andric   OpKind = MO_MCSymbol;
1882cab237bSDimitry Andric   Contents.Sym = Sym;
1892cab237bSDimitry Andric }
1902cab237bSDimitry Andric 
1912cab237bSDimitry Andric void MachineOperand::ChangeToFrameIndex(int Idx) {
1922cab237bSDimitry Andric   assert((!isReg() || !isTied()) &&
1932cab237bSDimitry Andric          "Cannot change a tied operand into a FrameIndex");
1942cab237bSDimitry Andric 
1952cab237bSDimitry Andric   removeRegFromUses();
1962cab237bSDimitry Andric 
1972cab237bSDimitry Andric   OpKind = MO_FrameIndex;
1982cab237bSDimitry Andric   setIndex(Idx);
1992cab237bSDimitry Andric }
2002cab237bSDimitry Andric 
2012cab237bSDimitry Andric void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset,
2022cab237bSDimitry Andric                                          unsigned char TargetFlags) {
2032cab237bSDimitry Andric   assert((!isReg() || !isTied()) &&
2042cab237bSDimitry Andric          "Cannot change a tied operand into a FrameIndex");
2052cab237bSDimitry Andric 
2062cab237bSDimitry Andric   removeRegFromUses();
2072cab237bSDimitry Andric 
2082cab237bSDimitry Andric   OpKind = MO_TargetIndex;
2092cab237bSDimitry Andric   setIndex(Idx);
2102cab237bSDimitry Andric   setOffset(Offset);
2112cab237bSDimitry Andric   setTargetFlags(TargetFlags);
2122cab237bSDimitry Andric }
2132cab237bSDimitry Andric 
2142cab237bSDimitry Andric /// ChangeToRegister - Replace this operand with a new register operand of
2152cab237bSDimitry Andric /// the specified value.  If an operand is known to be an register already,
2162cab237bSDimitry Andric /// the setReg method should be used.
2172cab237bSDimitry Andric void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
2182cab237bSDimitry Andric                                       bool isKill, bool isDead, bool isUndef,
2192cab237bSDimitry Andric                                       bool isDebug) {
2202cab237bSDimitry Andric   MachineRegisterInfo *RegInfo = nullptr;
2212cab237bSDimitry Andric   if (MachineFunction *MF = getMFIfAvailable(*this))
2222cab237bSDimitry Andric     RegInfo = &MF->getRegInfo();
2232cab237bSDimitry Andric   // If this operand is already a register operand, remove it from the
2242cab237bSDimitry Andric   // register's use/def lists.
2252cab237bSDimitry Andric   bool WasReg = isReg();
2262cab237bSDimitry Andric   if (RegInfo && WasReg)
2272cab237bSDimitry Andric     RegInfo->removeRegOperandFromUseList(this);
2282cab237bSDimitry Andric 
2292cab237bSDimitry Andric   // Change this to a register and set the reg#.
2302cab237bSDimitry Andric   assert(!(isDead && !isDef) && "Dead flag on non-def");
2312cab237bSDimitry Andric   assert(!(isKill && isDef) && "Kill flag on def");
2322cab237bSDimitry Andric   OpKind = MO_Register;
2332cab237bSDimitry Andric   SmallContents.RegNo = Reg;
2342cab237bSDimitry Andric   SubReg_TargetFlags = 0;
2352cab237bSDimitry Andric   IsDef = isDef;
2362cab237bSDimitry Andric   IsImp = isImp;
2372cab237bSDimitry Andric   IsDeadOrKill = isKill | isDead;
2382cab237bSDimitry Andric   IsRenamable = false;
2392cab237bSDimitry Andric   IsUndef = isUndef;
2402cab237bSDimitry Andric   IsInternalRead = false;
2412cab237bSDimitry Andric   IsEarlyClobber = false;
2422cab237bSDimitry Andric   IsDebug = isDebug;
2432cab237bSDimitry Andric   // Ensure isOnRegUseList() returns false.
2442cab237bSDimitry Andric   Contents.Reg.Prev = nullptr;
2452cab237bSDimitry Andric   // Preserve the tie when the operand was already a register.
2462cab237bSDimitry Andric   if (!WasReg)
2472cab237bSDimitry Andric     TiedTo = 0;
2482cab237bSDimitry Andric 
2492cab237bSDimitry Andric   // If this operand is embedded in a function, add the operand to the
2502cab237bSDimitry Andric   // register's use/def list.
2512cab237bSDimitry Andric   if (RegInfo)
2522cab237bSDimitry Andric     RegInfo->addRegOperandToUseList(this);
2532cab237bSDimitry Andric }
2542cab237bSDimitry Andric 
2552cab237bSDimitry Andric /// isIdenticalTo - Return true if this operand is identical to the specified
2562cab237bSDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload
2572cab237bSDimitry Andric /// below.
2582cab237bSDimitry Andric bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
2592cab237bSDimitry Andric   if (getType() != Other.getType() ||
2602cab237bSDimitry Andric       getTargetFlags() != Other.getTargetFlags())
2612cab237bSDimitry Andric     return false;
2622cab237bSDimitry Andric 
2632cab237bSDimitry Andric   switch (getType()) {
2642cab237bSDimitry Andric   case MachineOperand::MO_Register:
2652cab237bSDimitry Andric     return getReg() == Other.getReg() && isDef() == Other.isDef() &&
2662cab237bSDimitry Andric            getSubReg() == Other.getSubReg();
2672cab237bSDimitry Andric   case MachineOperand::MO_Immediate:
2682cab237bSDimitry Andric     return getImm() == Other.getImm();
2692cab237bSDimitry Andric   case MachineOperand::MO_CImmediate:
2702cab237bSDimitry Andric     return getCImm() == Other.getCImm();
2712cab237bSDimitry Andric   case MachineOperand::MO_FPImmediate:
2722cab237bSDimitry Andric     return getFPImm() == Other.getFPImm();
2732cab237bSDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
2742cab237bSDimitry Andric     return getMBB() == Other.getMBB();
2752cab237bSDimitry Andric   case MachineOperand::MO_FrameIndex:
2762cab237bSDimitry Andric     return getIndex() == Other.getIndex();
2772cab237bSDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
2782cab237bSDimitry Andric   case MachineOperand::MO_TargetIndex:
2792cab237bSDimitry Andric     return getIndex() == Other.getIndex() && getOffset() == Other.getOffset();
2802cab237bSDimitry Andric   case MachineOperand::MO_JumpTableIndex:
2812cab237bSDimitry Andric     return getIndex() == Other.getIndex();
2822cab237bSDimitry Andric   case MachineOperand::MO_GlobalAddress:
2832cab237bSDimitry Andric     return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset();
2842cab237bSDimitry Andric   case MachineOperand::MO_ExternalSymbol:
2852cab237bSDimitry Andric     return strcmp(getSymbolName(), Other.getSymbolName()) == 0 &&
2862cab237bSDimitry Andric            getOffset() == Other.getOffset();
2872cab237bSDimitry Andric   case MachineOperand::MO_BlockAddress:
2882cab237bSDimitry Andric     return getBlockAddress() == Other.getBlockAddress() &&
2892cab237bSDimitry Andric            getOffset() == Other.getOffset();
2902cab237bSDimitry Andric   case MachineOperand::MO_RegisterMask:
2912cab237bSDimitry Andric   case MachineOperand::MO_RegisterLiveOut: {
2922cab237bSDimitry Andric     // Shallow compare of the two RegMasks
2932cab237bSDimitry Andric     const uint32_t *RegMask = getRegMask();
2942cab237bSDimitry Andric     const uint32_t *OtherRegMask = Other.getRegMask();
2952cab237bSDimitry Andric     if (RegMask == OtherRegMask)
2962cab237bSDimitry Andric       return true;
2972cab237bSDimitry Andric 
2982cab237bSDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
2992cab237bSDimitry Andric       // Calculate the size of the RegMask
3002cab237bSDimitry Andric       const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
3012cab237bSDimitry Andric       unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32;
3022cab237bSDimitry Andric 
3032cab237bSDimitry Andric       // Deep compare of the two RegMasks
3042cab237bSDimitry Andric       return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask);
3052cab237bSDimitry Andric     }
3062cab237bSDimitry Andric     // We don't know the size of the RegMask, so we can't deep compare the two
3072cab237bSDimitry Andric     // reg masks.
3082cab237bSDimitry Andric     return false;
3092cab237bSDimitry Andric   }
3102cab237bSDimitry Andric   case MachineOperand::MO_MCSymbol:
3112cab237bSDimitry Andric     return getMCSymbol() == Other.getMCSymbol();
3122cab237bSDimitry Andric   case MachineOperand::MO_CFIIndex:
3132cab237bSDimitry Andric     return getCFIIndex() == Other.getCFIIndex();
3142cab237bSDimitry Andric   case MachineOperand::MO_Metadata:
3152cab237bSDimitry Andric     return getMetadata() == Other.getMetadata();
3162cab237bSDimitry Andric   case MachineOperand::MO_IntrinsicID:
3172cab237bSDimitry Andric     return getIntrinsicID() == Other.getIntrinsicID();
3182cab237bSDimitry Andric   case MachineOperand::MO_Predicate:
3192cab237bSDimitry Andric     return getPredicate() == Other.getPredicate();
3202cab237bSDimitry Andric   }
3212cab237bSDimitry Andric   llvm_unreachable("Invalid machine operand type");
3222cab237bSDimitry Andric }
3232cab237bSDimitry Andric 
3242cab237bSDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above.
3252cab237bSDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) {
3262cab237bSDimitry Andric   switch (MO.getType()) {
3272cab237bSDimitry Andric   case MachineOperand::MO_Register:
3282cab237bSDimitry Andric     // Register operands don't have target flags.
3292cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef());
3302cab237bSDimitry Andric   case MachineOperand::MO_Immediate:
3312cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm());
3322cab237bSDimitry Andric   case MachineOperand::MO_CImmediate:
3332cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm());
3342cab237bSDimitry Andric   case MachineOperand::MO_FPImmediate:
3352cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm());
3362cab237bSDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
3372cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB());
3382cab237bSDimitry Andric   case MachineOperand::MO_FrameIndex:
3392cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
3402cab237bSDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
3412cab237bSDimitry Andric   case MachineOperand::MO_TargetIndex:
3422cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(),
3432cab237bSDimitry Andric                         MO.getOffset());
3442cab237bSDimitry Andric   case MachineOperand::MO_JumpTableIndex:
3452cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex());
3462cab237bSDimitry Andric   case MachineOperand::MO_ExternalSymbol:
3472cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(),
3482cab237bSDimitry Andric                         MO.getSymbolName());
3492cab237bSDimitry Andric   case MachineOperand::MO_GlobalAddress:
3502cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(),
3512cab237bSDimitry Andric                         MO.getOffset());
3522cab237bSDimitry Andric   case MachineOperand::MO_BlockAddress:
3532cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(),
3542cab237bSDimitry Andric                         MO.getOffset());
3552cab237bSDimitry Andric   case MachineOperand::MO_RegisterMask:
3562cab237bSDimitry Andric   case MachineOperand::MO_RegisterLiveOut:
3572cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
3582cab237bSDimitry Andric   case MachineOperand::MO_Metadata:
3592cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata());
3602cab237bSDimitry Andric   case MachineOperand::MO_MCSymbol:
3612cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol());
3622cab237bSDimitry Andric   case MachineOperand::MO_CFIIndex:
3632cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex());
3642cab237bSDimitry Andric   case MachineOperand::MO_IntrinsicID:
3652cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID());
3662cab237bSDimitry Andric   case MachineOperand::MO_Predicate:
3672cab237bSDimitry Andric     return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate());
3682cab237bSDimitry Andric   }
3692cab237bSDimitry Andric   llvm_unreachable("Invalid machine operand type");
3702cab237bSDimitry Andric }
3712cab237bSDimitry Andric 
3722cab237bSDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from
3732cab237bSDimitry Andric // it.
3742cab237bSDimitry Andric static void tryToGetTargetInfo(const MachineOperand &MO,
3752cab237bSDimitry Andric                                const TargetRegisterInfo *&TRI,
3762cab237bSDimitry Andric                                const TargetIntrinsicInfo *&IntrinsicInfo) {
3772cab237bSDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(MO)) {
3782cab237bSDimitry Andric     TRI = MF->getSubtarget().getRegisterInfo();
3792cab237bSDimitry Andric     IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
3802cab237bSDimitry Andric   }
3812cab237bSDimitry Andric }
3822cab237bSDimitry Andric 
3832cab237bSDimitry Andric static void printOffset(raw_ostream &OS, int64_t Offset) {
3842cab237bSDimitry Andric   if (Offset == 0)
3852cab237bSDimitry Andric     return;
3862cab237bSDimitry Andric   if (Offset < 0) {
3872cab237bSDimitry Andric     OS << " - " << -Offset;
3882cab237bSDimitry Andric     return;
3892cab237bSDimitry Andric   }
3902cab237bSDimitry Andric   OS << " + " << Offset;
3912cab237bSDimitry Andric }
3922cab237bSDimitry Andric 
3932cab237bSDimitry Andric static const char *getTargetIndexName(const MachineFunction &MF, int Index) {
3942cab237bSDimitry Andric   const auto *TII = MF.getSubtarget().getInstrInfo();
3952cab237bSDimitry Andric   assert(TII && "expected instruction info");
3962cab237bSDimitry Andric   auto Indices = TII->getSerializableTargetIndices();
3972cab237bSDimitry Andric   auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) {
3982cab237bSDimitry Andric     return I.first == Index;
3992cab237bSDimitry Andric   });
4002cab237bSDimitry Andric   if (Found != Indices.end())
4012cab237bSDimitry Andric     return Found->second;
4022cab237bSDimitry Andric   return nullptr;
4032cab237bSDimitry Andric }
4042cab237bSDimitry Andric 
4052cab237bSDimitry Andric static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
4062cab237bSDimitry Andric   auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
4072cab237bSDimitry Andric   for (const auto &I : Flags) {
4082cab237bSDimitry Andric     if (I.first == TF) {
4092cab237bSDimitry Andric       return I.second;
4102cab237bSDimitry Andric     }
4112cab237bSDimitry Andric   }
4122cab237bSDimitry Andric   return nullptr;
4132cab237bSDimitry Andric }
4142cab237bSDimitry Andric 
4152cab237bSDimitry Andric void MachineOperand::printSubregIdx(raw_ostream &OS, uint64_t Index,
4162cab237bSDimitry Andric                                     const TargetRegisterInfo *TRI) {
4172cab237bSDimitry Andric   OS << "%subreg.";
4182cab237bSDimitry Andric   if (TRI)
4192cab237bSDimitry Andric     OS << TRI->getSubRegIndexName(Index);
4202cab237bSDimitry Andric   else
4212cab237bSDimitry Andric     OS << Index;
4222cab237bSDimitry Andric }
4232cab237bSDimitry Andric 
4242cab237bSDimitry Andric void MachineOperand::printTargetFlags(raw_ostream &OS,
4252cab237bSDimitry Andric                                       const MachineOperand &Op) {
4262cab237bSDimitry Andric   if (!Op.getTargetFlags())
4272cab237bSDimitry Andric     return;
4282cab237bSDimitry Andric   const MachineFunction *MF = getMFIfAvailable(Op);
4292cab237bSDimitry Andric   if (!MF)
4302cab237bSDimitry Andric     return;
4312cab237bSDimitry Andric 
4322cab237bSDimitry Andric   const auto *TII = MF->getSubtarget().getInstrInfo();
4332cab237bSDimitry Andric   assert(TII && "expected instruction info");
4342cab237bSDimitry Andric   auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
4352cab237bSDimitry Andric   OS << "target-flags(";
4362cab237bSDimitry Andric   const bool HasDirectFlags = Flags.first;
4372cab237bSDimitry Andric   const bool HasBitmaskFlags = Flags.second;
4382cab237bSDimitry Andric   if (!HasDirectFlags && !HasBitmaskFlags) {
4392cab237bSDimitry Andric     OS << "<unknown>) ";
4402cab237bSDimitry Andric     return;
4412cab237bSDimitry Andric   }
4422cab237bSDimitry Andric   if (HasDirectFlags) {
4432cab237bSDimitry Andric     if (const auto *Name = getTargetFlagName(TII, Flags.first))
4442cab237bSDimitry Andric       OS << Name;
4452cab237bSDimitry Andric     else
4462cab237bSDimitry Andric       OS << "<unknown target flag>";
4472cab237bSDimitry Andric   }
4482cab237bSDimitry Andric   if (!HasBitmaskFlags) {
4492cab237bSDimitry Andric     OS << ") ";
4502cab237bSDimitry Andric     return;
4512cab237bSDimitry Andric   }
4522cab237bSDimitry Andric   bool IsCommaNeeded = HasDirectFlags;
4532cab237bSDimitry Andric   unsigned BitMask = Flags.second;
4542cab237bSDimitry Andric   auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags();
4552cab237bSDimitry Andric   for (const auto &Mask : BitMasks) {
4562cab237bSDimitry Andric     // Check if the flag's bitmask has the bits of the current mask set.
4572cab237bSDimitry Andric     if ((BitMask & Mask.first) == Mask.first) {
4582cab237bSDimitry Andric       if (IsCommaNeeded)
4592cab237bSDimitry Andric         OS << ", ";
4602cab237bSDimitry Andric       IsCommaNeeded = true;
4612cab237bSDimitry Andric       OS << Mask.second;
4622cab237bSDimitry Andric       // Clear the bits which were serialized from the flag's bitmask.
4632cab237bSDimitry Andric       BitMask &= ~(Mask.first);
4642cab237bSDimitry Andric     }
4652cab237bSDimitry Andric   }
4662cab237bSDimitry Andric   if (BitMask) {
4672cab237bSDimitry Andric     // When the resulting flag's bitmask isn't zero, we know that we didn't
4682cab237bSDimitry Andric     // serialize all of the bit flags.
4692cab237bSDimitry Andric     if (IsCommaNeeded)
4702cab237bSDimitry Andric       OS << ", ";
4712cab237bSDimitry Andric     OS << "<unknown bitmask target flag>";
4722cab237bSDimitry Andric   }
4732cab237bSDimitry Andric   OS << ") ";
4742cab237bSDimitry Andric }
4752cab237bSDimitry Andric 
4762cab237bSDimitry Andric void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) {
4772cab237bSDimitry Andric   OS << "<mcsymbol " << Sym << ">";
4782cab237bSDimitry Andric }
4792cab237bSDimitry Andric 
4802cab237bSDimitry Andric void MachineOperand::printStackObjectReference(raw_ostream &OS,
4812cab237bSDimitry Andric                                                unsigned FrameIndex,
4822cab237bSDimitry Andric                                                bool IsFixed, StringRef Name) {
4832cab237bSDimitry Andric   if (IsFixed) {
4842cab237bSDimitry Andric     OS << "%fixed-stack." << FrameIndex;
4852cab237bSDimitry Andric     return;
4862cab237bSDimitry Andric   }
4872cab237bSDimitry Andric 
4882cab237bSDimitry Andric   OS << "%stack." << FrameIndex;
4892cab237bSDimitry Andric   if (!Name.empty())
4902cab237bSDimitry Andric     OS << '.' << Name;
4912cab237bSDimitry Andric }
4922cab237bSDimitry Andric 
4932cab237bSDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI,
4942cab237bSDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
4952cab237bSDimitry Andric   tryToGetTargetInfo(*this, TRI, IntrinsicInfo);
4962cab237bSDimitry Andric   ModuleSlotTracker DummyMST(nullptr);
4972cab237bSDimitry Andric   print(OS, DummyMST, LLT{}, /*PrintDef=*/false,
4982cab237bSDimitry Andric         /*ShouldPrintRegisterTies=*/true,
4992cab237bSDimitry Andric         /*TiedOperandIdx=*/0, TRI, IntrinsicInfo);
5002cab237bSDimitry Andric }
5012cab237bSDimitry Andric 
5022cab237bSDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
5032cab237bSDimitry Andric                            LLT TypeToPrint, bool PrintDef,
5042cab237bSDimitry Andric                            bool ShouldPrintRegisterTies,
5052cab237bSDimitry Andric                            unsigned TiedOperandIdx,
5062cab237bSDimitry Andric                            const TargetRegisterInfo *TRI,
5072cab237bSDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
5082cab237bSDimitry Andric   printTargetFlags(OS, *this);
5092cab237bSDimitry Andric   switch (getType()) {
5102cab237bSDimitry Andric   case MachineOperand::MO_Register: {
5112cab237bSDimitry Andric     unsigned Reg = getReg();
5122cab237bSDimitry Andric     if (isImplicit())
5132cab237bSDimitry Andric       OS << (isDef() ? "implicit-def " : "implicit ");
5142cab237bSDimitry Andric     else if (PrintDef && isDef())
5152cab237bSDimitry Andric       // Print the 'def' flag only when the operand is defined after '='.
5162cab237bSDimitry Andric       OS << "def ";
5172cab237bSDimitry Andric     if (isInternalRead())
5182cab237bSDimitry Andric       OS << "internal ";
5192cab237bSDimitry Andric     if (isDead())
5202cab237bSDimitry Andric       OS << "dead ";
5212cab237bSDimitry Andric     if (isKill())
5222cab237bSDimitry Andric       OS << "killed ";
5232cab237bSDimitry Andric     if (isUndef())
5242cab237bSDimitry Andric       OS << "undef ";
5252cab237bSDimitry Andric     if (isEarlyClobber())
5262cab237bSDimitry Andric       OS << "early-clobber ";
5272cab237bSDimitry Andric     if (isDebug())
5282cab237bSDimitry Andric       OS << "debug-use ";
5292cab237bSDimitry Andric     if (TargetRegisterInfo::isPhysicalRegister(getReg()) && isRenamable())
5302cab237bSDimitry Andric       OS << "renamable ";
5312cab237bSDimitry Andric     OS << printReg(Reg, TRI);
5322cab237bSDimitry Andric     // Print the sub register.
5332cab237bSDimitry Andric     if (unsigned SubReg = getSubReg()) {
5342cab237bSDimitry Andric       if (TRI)
5352cab237bSDimitry Andric         OS << '.' << TRI->getSubRegIndexName(SubReg);
5362cab237bSDimitry Andric       else
5372cab237bSDimitry Andric         OS << ".subreg" << SubReg;
5382cab237bSDimitry Andric     }
5392cab237bSDimitry Andric     // Print the register class / bank.
5402cab237bSDimitry Andric     if (TargetRegisterInfo::isVirtualRegister(Reg)) {
5412cab237bSDimitry Andric       if (const MachineFunction *MF = getMFIfAvailable(*this)) {
5422cab237bSDimitry Andric         const MachineRegisterInfo &MRI = MF->getRegInfo();
5432cab237bSDimitry Andric         if (!PrintDef || MRI.def_empty(Reg)) {
5442cab237bSDimitry Andric           OS << ':';
5452cab237bSDimitry Andric           OS << printRegClassOrBank(Reg, MRI, TRI);
5462cab237bSDimitry Andric         }
5472cab237bSDimitry Andric       }
5482cab237bSDimitry Andric     }
5492cab237bSDimitry Andric     // Print ties.
5502cab237bSDimitry Andric     if (ShouldPrintRegisterTies && isTied() && !isDef())
5512cab237bSDimitry Andric       OS << "(tied-def " << TiedOperandIdx << ")";
5522cab237bSDimitry Andric     // Print types.
5532cab237bSDimitry Andric     if (TypeToPrint.isValid())
5542cab237bSDimitry Andric       OS << '(' << TypeToPrint << ')';
5552cab237bSDimitry Andric     break;
5562cab237bSDimitry Andric   }
5572cab237bSDimitry Andric   case MachineOperand::MO_Immediate:
5582cab237bSDimitry Andric     OS << getImm();
5592cab237bSDimitry Andric     break;
5602cab237bSDimitry Andric   case MachineOperand::MO_CImmediate:
5612cab237bSDimitry Andric     getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
5622cab237bSDimitry Andric     break;
5632cab237bSDimitry Andric   case MachineOperand::MO_FPImmediate:
5642cab237bSDimitry Andric     if (getFPImm()->getType()->isFloatTy()) {
5652cab237bSDimitry Andric       OS << getFPImm()->getValueAPF().convertToFloat();
5662cab237bSDimitry Andric     } else if (getFPImm()->getType()->isHalfTy()) {
5672cab237bSDimitry Andric       APFloat APF = getFPImm()->getValueAPF();
5682cab237bSDimitry Andric       bool Unused;
5692cab237bSDimitry Andric       APF.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &Unused);
5702cab237bSDimitry Andric       OS << "half " << APF.convertToFloat();
5712cab237bSDimitry Andric     } else if (getFPImm()->getType()->isFP128Ty()) {
5722cab237bSDimitry Andric       APFloat APF = getFPImm()->getValueAPF();
5732cab237bSDimitry Andric       SmallString<16> Str;
5742cab237bSDimitry Andric       getFPImm()->getValueAPF().toString(Str);
5752cab237bSDimitry Andric       OS << "quad " << Str;
5762cab237bSDimitry Andric     } else if (getFPImm()->getType()->isX86_FP80Ty()) {
5772cab237bSDimitry Andric       APFloat APF = getFPImm()->getValueAPF();
5782cab237bSDimitry Andric       OS << "x86_fp80 0xK";
5792cab237bSDimitry Andric       APInt API = APF.bitcastToAPInt();
5802cab237bSDimitry Andric       OS << format_hex_no_prefix(API.getHiBits(16).getZExtValue(), 4,
5812cab237bSDimitry Andric                                  /*Upper=*/true);
5822cab237bSDimitry Andric       OS << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16,
5832cab237bSDimitry Andric                                  /*Upper=*/true);
5842cab237bSDimitry Andric     } else {
5852cab237bSDimitry Andric       OS << getFPImm()->getValueAPF().convertToDouble();
5862cab237bSDimitry Andric     }
5872cab237bSDimitry Andric     break;
5882cab237bSDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
5892cab237bSDimitry Andric     OS << printMBBReference(*getMBB());
5902cab237bSDimitry Andric     break;
5912cab237bSDimitry Andric   case MachineOperand::MO_FrameIndex: {
5922cab237bSDimitry Andric     int FrameIndex = getIndex();
5932cab237bSDimitry Andric     bool IsFixed = false;
5942cab237bSDimitry Andric     StringRef Name;
5952cab237bSDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
5962cab237bSDimitry Andric       const MachineFrameInfo &MFI = MF->getFrameInfo();
5972cab237bSDimitry Andric       IsFixed = MFI.isFixedObjectIndex(FrameIndex);
5982cab237bSDimitry Andric       if (const AllocaInst *Alloca = MFI.getObjectAllocation(FrameIndex))
5992cab237bSDimitry Andric         if (Alloca->hasName())
6002cab237bSDimitry Andric           Name = Alloca->getName();
6012cab237bSDimitry Andric       if (IsFixed)
6022cab237bSDimitry Andric         FrameIndex -= MFI.getObjectIndexBegin();
6032cab237bSDimitry Andric     }
6042cab237bSDimitry Andric     printStackObjectReference(OS, FrameIndex, IsFixed, Name);
6052cab237bSDimitry Andric     break;
6062cab237bSDimitry Andric   }
6072cab237bSDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
6082cab237bSDimitry Andric     OS << "%const." << getIndex();
6092cab237bSDimitry Andric     printOffset(OS, getOffset());
6102cab237bSDimitry Andric     break;
6112cab237bSDimitry Andric   case MachineOperand::MO_TargetIndex: {
6122cab237bSDimitry Andric     OS << "target-index(";
6132cab237bSDimitry Andric     const char *Name = "<unknown>";
6142cab237bSDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
6152cab237bSDimitry Andric       if (const auto *TargetIndexName = getTargetIndexName(*MF, getIndex()))
6162cab237bSDimitry Andric         Name = TargetIndexName;
6172cab237bSDimitry Andric     OS << Name << ')';
6182cab237bSDimitry Andric     printOffset(OS, getOffset());
6192cab237bSDimitry Andric     break;
6202cab237bSDimitry Andric   }
6212cab237bSDimitry Andric   case MachineOperand::MO_JumpTableIndex:
6222cab237bSDimitry Andric     OS << printJumpTableEntryReference(getIndex());
6232cab237bSDimitry Andric     break;
6242cab237bSDimitry Andric   case MachineOperand::MO_GlobalAddress:
6252cab237bSDimitry Andric     getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
6262cab237bSDimitry Andric     printOffset(OS, getOffset());
6272cab237bSDimitry Andric     break;
6282cab237bSDimitry Andric   case MachineOperand::MO_ExternalSymbol: {
6292cab237bSDimitry Andric     StringRef Name = getSymbolName();
6302cab237bSDimitry Andric     OS << '$';
6312cab237bSDimitry Andric     if (Name.empty()) {
6322cab237bSDimitry Andric       OS << "\"\"";
6332cab237bSDimitry Andric     } else {
6342cab237bSDimitry Andric       printLLVMNameWithoutPrefix(OS, Name);
6352cab237bSDimitry Andric     }
6362cab237bSDimitry Andric     printOffset(OS, getOffset());
6372cab237bSDimitry Andric     break;
6382cab237bSDimitry Andric   }
6392cab237bSDimitry Andric   case MachineOperand::MO_BlockAddress:
6402cab237bSDimitry Andric     OS << '<';
6412cab237bSDimitry Andric     getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST);
6422cab237bSDimitry Andric     if (getOffset())
6432cab237bSDimitry Andric       OS << "+" << getOffset();
6442cab237bSDimitry Andric     OS << '>';
6452cab237bSDimitry Andric     break;
6462cab237bSDimitry Andric   case MachineOperand::MO_RegisterMask: {
6472cab237bSDimitry Andric     OS << "<regmask";
6482cab237bSDimitry Andric     if (TRI) {
6492cab237bSDimitry Andric       unsigned NumRegsInMask = 0;
6502cab237bSDimitry Andric       unsigned NumRegsEmitted = 0;
6512cab237bSDimitry Andric       for (unsigned i = 0; i < TRI->getNumRegs(); ++i) {
6522cab237bSDimitry Andric         unsigned MaskWord = i / 32;
6532cab237bSDimitry Andric         unsigned MaskBit = i % 32;
6542cab237bSDimitry Andric         if (getRegMask()[MaskWord] & (1 << MaskBit)) {
6552cab237bSDimitry Andric           if (PrintRegMaskNumRegs < 0 ||
6562cab237bSDimitry Andric               NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) {
6572cab237bSDimitry Andric             OS << " " << printReg(i, TRI);
6582cab237bSDimitry Andric             NumRegsEmitted++;
6592cab237bSDimitry Andric           }
6602cab237bSDimitry Andric           NumRegsInMask++;
6612cab237bSDimitry Andric         }
6622cab237bSDimitry Andric       }
6632cab237bSDimitry Andric       if (NumRegsEmitted != NumRegsInMask)
6642cab237bSDimitry Andric         OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more...";
6652cab237bSDimitry Andric     } else {
6662cab237bSDimitry Andric       OS << " ...";
6672cab237bSDimitry Andric     }
6682cab237bSDimitry Andric     OS << ">";
6692cab237bSDimitry Andric     break;
6702cab237bSDimitry Andric   }
6712cab237bSDimitry Andric   case MachineOperand::MO_RegisterLiveOut: {
6722cab237bSDimitry Andric     const uint32_t *RegMask = getRegLiveOut();
6732cab237bSDimitry Andric     OS << "liveout(";
6742cab237bSDimitry Andric     if (!TRI) {
6752cab237bSDimitry Andric       OS << "<unknown>";
6762cab237bSDimitry Andric     } else {
6772cab237bSDimitry Andric       bool IsCommaNeeded = false;
6782cab237bSDimitry Andric       for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
6792cab237bSDimitry Andric         if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
6802cab237bSDimitry Andric           if (IsCommaNeeded)
6812cab237bSDimitry Andric             OS << ", ";
6822cab237bSDimitry Andric           OS << printReg(Reg, TRI);
6832cab237bSDimitry Andric           IsCommaNeeded = true;
6842cab237bSDimitry Andric         }
6852cab237bSDimitry Andric       }
6862cab237bSDimitry Andric     }
6872cab237bSDimitry Andric     OS << ")";
6882cab237bSDimitry Andric     break;
6892cab237bSDimitry Andric   }
6902cab237bSDimitry Andric   case MachineOperand::MO_Metadata:
6912cab237bSDimitry Andric     getMetadata()->printAsOperand(OS, MST);
6922cab237bSDimitry Andric     break;
6932cab237bSDimitry Andric   case MachineOperand::MO_MCSymbol:
6942cab237bSDimitry Andric     printSymbol(OS, *getMCSymbol());
6952cab237bSDimitry Andric     break;
6962cab237bSDimitry Andric   case MachineOperand::MO_CFIIndex:
6972cab237bSDimitry Andric     OS << "<call frame instruction>";
6982cab237bSDimitry Andric     break;
6992cab237bSDimitry Andric   case MachineOperand::MO_IntrinsicID: {
7002cab237bSDimitry Andric     Intrinsic::ID ID = getIntrinsicID();
7012cab237bSDimitry Andric     if (ID < Intrinsic::num_intrinsics)
7022cab237bSDimitry Andric       OS << "<intrinsic:@" << Intrinsic::getName(ID, None) << '>';
7032cab237bSDimitry Andric     else if (IntrinsicInfo)
7042cab237bSDimitry Andric       OS << "<intrinsic:@" << IntrinsicInfo->getName(ID) << '>';
7052cab237bSDimitry Andric     else
7062cab237bSDimitry Andric       OS << "<intrinsic:" << ID << '>';
7072cab237bSDimitry Andric     break;
7082cab237bSDimitry Andric   }
7092cab237bSDimitry Andric   case MachineOperand::MO_Predicate: {
7102cab237bSDimitry Andric     auto Pred = static_cast<CmpInst::Predicate>(getPredicate());
7112cab237bSDimitry Andric     OS << '<' << (CmpInst::isIntPredicate(Pred) ? "intpred" : "floatpred")
7122cab237bSDimitry Andric        << CmpInst::getPredicateName(Pred) << '>';
7132cab237bSDimitry Andric     break;
7142cab237bSDimitry Andric   }
7152cab237bSDimitry Andric   }
7162cab237bSDimitry Andric }
7172cab237bSDimitry Andric 
7182cab237bSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
7192cab237bSDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; }
7202cab237bSDimitry Andric #endif
7212cab237bSDimitry Andric 
7222cab237bSDimitry Andric //===----------------------------------------------------------------------===//
7232cab237bSDimitry Andric // MachineMemOperand Implementation
7242cab237bSDimitry Andric //===----------------------------------------------------------------------===//
7252cab237bSDimitry Andric 
7262cab237bSDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer
7272cab237bSDimitry Andric /// points into.
7282cab237bSDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; }
7292cab237bSDimitry Andric 
7302cab237bSDimitry Andric /// isDereferenceable - Return true if V is always dereferenceable for
7312cab237bSDimitry Andric /// Offset + Size byte.
7322cab237bSDimitry Andric bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C,
7332cab237bSDimitry Andric                                            const DataLayout &DL) const {
7342cab237bSDimitry Andric   if (!V.is<const Value *>())
7352cab237bSDimitry Andric     return false;
7362cab237bSDimitry Andric 
7372cab237bSDimitry Andric   const Value *BasePtr = V.get<const Value *>();
7382cab237bSDimitry Andric   if (BasePtr == nullptr)
7392cab237bSDimitry Andric     return false;
7402cab237bSDimitry Andric 
7412cab237bSDimitry Andric   return isDereferenceableAndAlignedPointer(
7422cab237bSDimitry Andric       BasePtr, 1, APInt(DL.getPointerSizeInBits(), Offset + Size), DL);
7432cab237bSDimitry Andric }
7442cab237bSDimitry Andric 
7452cab237bSDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the
7462cab237bSDimitry Andric /// constant pool.
7472cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) {
7482cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getConstantPool());
7492cab237bSDimitry Andric }
7502cab237bSDimitry Andric 
7512cab237bSDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the
7522cab237bSDimitry Andric /// the specified FrameIndex.
7532cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF,
7542cab237bSDimitry Andric                                                      int FI, int64_t Offset) {
7552cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset);
7562cab237bSDimitry Andric }
7572cab237bSDimitry Andric 
7582cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) {
7592cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getJumpTable());
7602cab237bSDimitry Andric }
7612cab237bSDimitry Andric 
7622cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) {
7632cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getGOT());
7642cab237bSDimitry Andric }
7652cab237bSDimitry Andric 
7662cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF,
7672cab237bSDimitry Andric                                                 int64_t Offset, uint8_t ID) {
7682cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID);
7692cab237bSDimitry Andric }
7702cab237bSDimitry Andric 
7712cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) {
7722cab237bSDimitry Andric   return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace());
7732cab237bSDimitry Andric }
7742cab237bSDimitry Andric 
7752cab237bSDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
7762cab237bSDimitry Andric                                      uint64_t s, unsigned int a,
7772cab237bSDimitry Andric                                      const AAMDNodes &AAInfo,
7782cab237bSDimitry Andric                                      const MDNode *Ranges, SyncScope::ID SSID,
7792cab237bSDimitry Andric                                      AtomicOrdering Ordering,
7802cab237bSDimitry Andric                                      AtomicOrdering FailureOrdering)
7812cab237bSDimitry Andric     : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1),
7822cab237bSDimitry Andric       AAInfo(AAInfo), Ranges(Ranges) {
7832cab237bSDimitry Andric   assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() ||
7842cab237bSDimitry Andric           isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) &&
7852cab237bSDimitry Andric          "invalid pointer value");
7862cab237bSDimitry Andric   assert(getBaseAlignment() == a && "Alignment is not a power of 2!");
7872cab237bSDimitry Andric   assert((isLoad() || isStore()) && "Not a load/store!");
7882cab237bSDimitry Andric 
7892cab237bSDimitry Andric   AtomicInfo.SSID = static_cast<unsigned>(SSID);
7902cab237bSDimitry Andric   assert(getSyncScopeID() == SSID && "Value truncated");
7912cab237bSDimitry Andric   AtomicInfo.Ordering = static_cast<unsigned>(Ordering);
7922cab237bSDimitry Andric   assert(getOrdering() == Ordering && "Value truncated");
7932cab237bSDimitry Andric   AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering);
7942cab237bSDimitry Andric   assert(getFailureOrdering() == FailureOrdering && "Value truncated");
7952cab237bSDimitry Andric }
7962cab237bSDimitry Andric 
7972cab237bSDimitry Andric /// Profile - Gather unique data for the object.
7982cab237bSDimitry Andric ///
7992cab237bSDimitry Andric void MachineMemOperand::Profile(FoldingSetNodeID &ID) const {
8002cab237bSDimitry Andric   ID.AddInteger(getOffset());
8012cab237bSDimitry Andric   ID.AddInteger(Size);
8022cab237bSDimitry Andric   ID.AddPointer(getOpaqueValue());
8032cab237bSDimitry Andric   ID.AddInteger(getFlags());
8042cab237bSDimitry Andric   ID.AddInteger(getBaseAlignment());
8052cab237bSDimitry Andric }
8062cab237bSDimitry Andric 
8072cab237bSDimitry Andric void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
8082cab237bSDimitry Andric   // The Value and Offset may differ due to CSE. But the flags and size
8092cab237bSDimitry Andric   // should be the same.
8102cab237bSDimitry Andric   assert(MMO->getFlags() == getFlags() && "Flags mismatch!");
8112cab237bSDimitry Andric   assert(MMO->getSize() == getSize() && "Size mismatch!");
8122cab237bSDimitry Andric 
8132cab237bSDimitry Andric   if (MMO->getBaseAlignment() >= getBaseAlignment()) {
8142cab237bSDimitry Andric     // Update the alignment value.
8152cab237bSDimitry Andric     BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1;
8162cab237bSDimitry Andric     // Also update the base and offset, because the new alignment may
8172cab237bSDimitry Andric     // not be applicable with the old ones.
8182cab237bSDimitry Andric     PtrInfo = MMO->PtrInfo;
8192cab237bSDimitry Andric   }
8202cab237bSDimitry Andric }
8212cab237bSDimitry Andric 
8222cab237bSDimitry Andric /// getAlignment - Return the minimum known alignment in bytes of the
8232cab237bSDimitry Andric /// actual memory reference.
8242cab237bSDimitry Andric uint64_t MachineMemOperand::getAlignment() const {
8252cab237bSDimitry Andric   return MinAlign(getBaseAlignment(), getOffset());
8262cab237bSDimitry Andric }
8272cab237bSDimitry Andric 
8282cab237bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS) const {
8292cab237bSDimitry Andric   ModuleSlotTracker DummyMST(nullptr);
8302cab237bSDimitry Andric   print(OS, DummyMST);
8312cab237bSDimitry Andric }
8322cab237bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const {
8332cab237bSDimitry Andric   assert((isLoad() || isStore()) && "SV has to be a load, store or both.");
8342cab237bSDimitry Andric 
8352cab237bSDimitry Andric   if (isVolatile())
8362cab237bSDimitry Andric     OS << "Volatile ";
8372cab237bSDimitry Andric 
8382cab237bSDimitry Andric   if (isLoad())
8392cab237bSDimitry Andric     OS << "LD";
8402cab237bSDimitry Andric   if (isStore())
8412cab237bSDimitry Andric     OS << "ST";
8422cab237bSDimitry Andric   OS << getSize();
8432cab237bSDimitry Andric 
8442cab237bSDimitry Andric   // Print the address information.
8452cab237bSDimitry Andric   OS << "[";
8462cab237bSDimitry Andric   if (const Value *V = getValue())
8472cab237bSDimitry Andric     V->printAsOperand(OS, /*PrintType=*/false, MST);
8482cab237bSDimitry Andric   else if (const PseudoSourceValue *PSV = getPseudoValue())
8492cab237bSDimitry Andric     PSV->printCustom(OS);
8502cab237bSDimitry Andric   else
8512cab237bSDimitry Andric     OS << "<unknown>";
8522cab237bSDimitry Andric 
8532cab237bSDimitry Andric   unsigned AS = getAddrSpace();
8542cab237bSDimitry Andric   if (AS != 0)
8552cab237bSDimitry Andric     OS << "(addrspace=" << AS << ')';
8562cab237bSDimitry Andric 
8572cab237bSDimitry Andric   // If the alignment of the memory reference itself differs from the alignment
8582cab237bSDimitry Andric   // of the base pointer, print the base alignment explicitly, next to the base
8592cab237bSDimitry Andric   // pointer.
8602cab237bSDimitry Andric   if (getBaseAlignment() != getAlignment())
8612cab237bSDimitry Andric     OS << "(align=" << getBaseAlignment() << ")";
8622cab237bSDimitry Andric 
8632cab237bSDimitry Andric   if (getOffset() != 0)
8642cab237bSDimitry Andric     OS << "+" << getOffset();
8652cab237bSDimitry Andric   OS << "]";
8662cab237bSDimitry Andric 
8672cab237bSDimitry Andric   // Print the alignment of the reference.
8682cab237bSDimitry Andric   if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize())
8692cab237bSDimitry Andric     OS << "(align=" << getAlignment() << ")";
8702cab237bSDimitry Andric 
8712cab237bSDimitry Andric   // Print TBAA info.
8722cab237bSDimitry Andric   if (const MDNode *TBAAInfo = getAAInfo().TBAA) {
8732cab237bSDimitry Andric     OS << "(tbaa=";
8742cab237bSDimitry Andric     if (TBAAInfo->getNumOperands() > 0)
8752cab237bSDimitry Andric       TBAAInfo->getOperand(0)->printAsOperand(OS, MST);
8762cab237bSDimitry Andric     else
8772cab237bSDimitry Andric       OS << "<unknown>";
8782cab237bSDimitry Andric     OS << ")";
8792cab237bSDimitry Andric   }
8802cab237bSDimitry Andric 
8812cab237bSDimitry Andric   // Print AA scope info.
8822cab237bSDimitry Andric   if (const MDNode *ScopeInfo = getAAInfo().Scope) {
8832cab237bSDimitry Andric     OS << "(alias.scope=";
8842cab237bSDimitry Andric     if (ScopeInfo->getNumOperands() > 0)
8852cab237bSDimitry Andric       for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) {
8862cab237bSDimitry Andric         ScopeInfo->getOperand(i)->printAsOperand(OS, MST);
8872cab237bSDimitry Andric         if (i != ie - 1)
8882cab237bSDimitry Andric           OS << ",";
8892cab237bSDimitry Andric       }
8902cab237bSDimitry Andric     else
8912cab237bSDimitry Andric       OS << "<unknown>";
8922cab237bSDimitry Andric     OS << ")";
8932cab237bSDimitry Andric   }
8942cab237bSDimitry Andric 
8952cab237bSDimitry Andric   // Print AA noalias scope info.
8962cab237bSDimitry Andric   if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) {
8972cab237bSDimitry Andric     OS << "(noalias=";
8982cab237bSDimitry Andric     if (NoAliasInfo->getNumOperands() > 0)
8992cab237bSDimitry Andric       for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) {
9002cab237bSDimitry Andric         NoAliasInfo->getOperand(i)->printAsOperand(OS, MST);
9012cab237bSDimitry Andric         if (i != ie - 1)
9022cab237bSDimitry Andric           OS << ",";
9032cab237bSDimitry Andric       }
9042cab237bSDimitry Andric     else
9052cab237bSDimitry Andric       OS << "<unknown>";
9062cab237bSDimitry Andric     OS << ")";
9072cab237bSDimitry Andric   }
9082cab237bSDimitry Andric 
9092cab237bSDimitry Andric   if (const MDNode *Ranges = getRanges()) {
9102cab237bSDimitry Andric     unsigned NumRanges = Ranges->getNumOperands();
9112cab237bSDimitry Andric     if (NumRanges != 0) {
9122cab237bSDimitry Andric       OS << "(ranges=";
9132cab237bSDimitry Andric 
9142cab237bSDimitry Andric       for (unsigned I = 0; I != NumRanges; ++I) {
9152cab237bSDimitry Andric         Ranges->getOperand(I)->printAsOperand(OS, MST);
9162cab237bSDimitry Andric         if (I != NumRanges - 1)
9172cab237bSDimitry Andric           OS << ',';
9182cab237bSDimitry Andric       }
9192cab237bSDimitry Andric 
9202cab237bSDimitry Andric       OS << ')';
9212cab237bSDimitry Andric     }
9222cab237bSDimitry Andric   }
9232cab237bSDimitry Andric 
9242cab237bSDimitry Andric   if (isNonTemporal())
9252cab237bSDimitry Andric     OS << "(nontemporal)";
9262cab237bSDimitry Andric   if (isDereferenceable())
9272cab237bSDimitry Andric     OS << "(dereferenceable)";
9282cab237bSDimitry Andric   if (isInvariant())
9292cab237bSDimitry Andric     OS << "(invariant)";
9302cab237bSDimitry Andric   if (getFlags() & MOTargetFlag1)
9312cab237bSDimitry Andric     OS << "(flag1)";
9322cab237bSDimitry Andric   if (getFlags() & MOTargetFlag2)
9332cab237bSDimitry Andric     OS << "(flag2)";
9342cab237bSDimitry Andric   if (getFlags() & MOTargetFlag3)
9352cab237bSDimitry Andric     OS << "(flag3)";
9362cab237bSDimitry Andric }
937