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 const char *getTargetIndexName(const MachineFunction &MF, int Index) {
3842cab237bSDimitry Andric   const auto *TII = MF.getSubtarget().getInstrInfo();
3852cab237bSDimitry Andric   assert(TII && "expected instruction info");
3862cab237bSDimitry Andric   auto Indices = TII->getSerializableTargetIndices();
3872cab237bSDimitry Andric   auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) {
3882cab237bSDimitry Andric     return I.first == Index;
3892cab237bSDimitry Andric   });
3902cab237bSDimitry Andric   if (Found != Indices.end())
3912cab237bSDimitry Andric     return Found->second;
3922cab237bSDimitry Andric   return nullptr;
3932cab237bSDimitry Andric }
3942cab237bSDimitry Andric 
3952cab237bSDimitry Andric static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) {
3962cab237bSDimitry Andric   auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
3972cab237bSDimitry Andric   for (const auto &I : Flags) {
3982cab237bSDimitry Andric     if (I.first == TF) {
3992cab237bSDimitry Andric       return I.second;
4002cab237bSDimitry Andric     }
4012cab237bSDimitry Andric   }
4022cab237bSDimitry Andric   return nullptr;
4032cab237bSDimitry Andric }
4042cab237bSDimitry Andric 
405da09e106SDimitry Andric static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS,
406da09e106SDimitry Andric                              const TargetRegisterInfo *TRI) {
407da09e106SDimitry Andric   if (!TRI) {
408da09e106SDimitry Andric     OS << "%dwarfreg." << DwarfReg;
409da09e106SDimitry Andric     return;
410da09e106SDimitry Andric   }
411da09e106SDimitry Andric 
412da09e106SDimitry Andric   int Reg = TRI->getLLVMRegNum(DwarfReg, true);
413da09e106SDimitry Andric   if (Reg == -1) {
414da09e106SDimitry Andric     OS << "<badreg>";
415da09e106SDimitry Andric     return;
416da09e106SDimitry Andric   }
417da09e106SDimitry Andric   OS << printReg(Reg, TRI);
418da09e106SDimitry Andric }
419da09e106SDimitry Andric 
420da09e106SDimitry Andric static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB,
421da09e106SDimitry Andric                                   ModuleSlotTracker &MST) {
422da09e106SDimitry Andric   OS << "%ir-block.";
423da09e106SDimitry Andric   if (BB.hasName()) {
424da09e106SDimitry Andric     printLLVMNameWithoutPrefix(OS, BB.getName());
425da09e106SDimitry Andric     return;
426da09e106SDimitry Andric   }
427da09e106SDimitry Andric   Optional<int> Slot;
428da09e106SDimitry Andric   if (const Function *F = BB.getParent()) {
429da09e106SDimitry Andric     if (F == MST.getCurrentFunction()) {
430da09e106SDimitry Andric       Slot = MST.getLocalSlot(&BB);
431da09e106SDimitry Andric     } else if (const Module *M = F->getParent()) {
432da09e106SDimitry Andric       ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false);
433da09e106SDimitry Andric       CustomMST.incorporateFunction(*F);
434da09e106SDimitry Andric       Slot = CustomMST.getLocalSlot(&BB);
435da09e106SDimitry Andric     }
436da09e106SDimitry Andric   }
437da09e106SDimitry Andric   if (Slot)
438da09e106SDimitry Andric     MachineOperand::printIRSlotNumber(OS, *Slot);
439da09e106SDimitry Andric   else
440da09e106SDimitry Andric     OS << "<unknown>";
441da09e106SDimitry Andric }
442da09e106SDimitry Andric 
4432cab237bSDimitry Andric void MachineOperand::printSubregIdx(raw_ostream &OS, uint64_t Index,
4442cab237bSDimitry Andric                                     const TargetRegisterInfo *TRI) {
4452cab237bSDimitry Andric   OS << "%subreg.";
4462cab237bSDimitry Andric   if (TRI)
4472cab237bSDimitry Andric     OS << TRI->getSubRegIndexName(Index);
4482cab237bSDimitry Andric   else
4492cab237bSDimitry Andric     OS << Index;
4502cab237bSDimitry Andric }
4512cab237bSDimitry Andric 
4522cab237bSDimitry Andric void MachineOperand::printTargetFlags(raw_ostream &OS,
4532cab237bSDimitry Andric                                       const MachineOperand &Op) {
4542cab237bSDimitry Andric   if (!Op.getTargetFlags())
4552cab237bSDimitry Andric     return;
4562cab237bSDimitry Andric   const MachineFunction *MF = getMFIfAvailable(Op);
4572cab237bSDimitry Andric   if (!MF)
4582cab237bSDimitry Andric     return;
4592cab237bSDimitry Andric 
4602cab237bSDimitry Andric   const auto *TII = MF->getSubtarget().getInstrInfo();
4612cab237bSDimitry Andric   assert(TII && "expected instruction info");
4622cab237bSDimitry Andric   auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags());
4632cab237bSDimitry Andric   OS << "target-flags(";
4642cab237bSDimitry Andric   const bool HasDirectFlags = Flags.first;
4652cab237bSDimitry Andric   const bool HasBitmaskFlags = Flags.second;
4662cab237bSDimitry Andric   if (!HasDirectFlags && !HasBitmaskFlags) {
4672cab237bSDimitry Andric     OS << "<unknown>) ";
4682cab237bSDimitry Andric     return;
4692cab237bSDimitry Andric   }
4702cab237bSDimitry Andric   if (HasDirectFlags) {
4712cab237bSDimitry Andric     if (const auto *Name = getTargetFlagName(TII, Flags.first))
4722cab237bSDimitry Andric       OS << Name;
4732cab237bSDimitry Andric     else
4742cab237bSDimitry Andric       OS << "<unknown target flag>";
4752cab237bSDimitry Andric   }
4762cab237bSDimitry Andric   if (!HasBitmaskFlags) {
4772cab237bSDimitry Andric     OS << ") ";
4782cab237bSDimitry Andric     return;
4792cab237bSDimitry Andric   }
4802cab237bSDimitry Andric   bool IsCommaNeeded = HasDirectFlags;
4812cab237bSDimitry Andric   unsigned BitMask = Flags.second;
4822cab237bSDimitry Andric   auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags();
4832cab237bSDimitry Andric   for (const auto &Mask : BitMasks) {
4842cab237bSDimitry Andric     // Check if the flag's bitmask has the bits of the current mask set.
4852cab237bSDimitry Andric     if ((BitMask & Mask.first) == Mask.first) {
4862cab237bSDimitry Andric       if (IsCommaNeeded)
4872cab237bSDimitry Andric         OS << ", ";
4882cab237bSDimitry Andric       IsCommaNeeded = true;
4892cab237bSDimitry Andric       OS << Mask.second;
4902cab237bSDimitry Andric       // Clear the bits which were serialized from the flag's bitmask.
4912cab237bSDimitry Andric       BitMask &= ~(Mask.first);
4922cab237bSDimitry Andric     }
4932cab237bSDimitry Andric   }
4942cab237bSDimitry Andric   if (BitMask) {
4952cab237bSDimitry Andric     // When the resulting flag's bitmask isn't zero, we know that we didn't
4962cab237bSDimitry Andric     // serialize all of the bit flags.
4972cab237bSDimitry Andric     if (IsCommaNeeded)
4982cab237bSDimitry Andric       OS << ", ";
4992cab237bSDimitry Andric     OS << "<unknown bitmask target flag>";
5002cab237bSDimitry Andric   }
5012cab237bSDimitry Andric   OS << ") ";
5022cab237bSDimitry Andric }
5032cab237bSDimitry Andric 
5042cab237bSDimitry Andric void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) {
5052cab237bSDimitry Andric   OS << "<mcsymbol " << Sym << ">";
5062cab237bSDimitry Andric }
5072cab237bSDimitry Andric 
5082cab237bSDimitry Andric void MachineOperand::printStackObjectReference(raw_ostream &OS,
5092cab237bSDimitry Andric                                                unsigned FrameIndex,
5102cab237bSDimitry Andric                                                bool IsFixed, StringRef Name) {
5112cab237bSDimitry Andric   if (IsFixed) {
5122cab237bSDimitry Andric     OS << "%fixed-stack." << FrameIndex;
5132cab237bSDimitry Andric     return;
5142cab237bSDimitry Andric   }
5152cab237bSDimitry Andric 
5162cab237bSDimitry Andric   OS << "%stack." << FrameIndex;
5172cab237bSDimitry Andric   if (!Name.empty())
5182cab237bSDimitry Andric     OS << '.' << Name;
5192cab237bSDimitry Andric }
5202cab237bSDimitry Andric 
521da09e106SDimitry Andric void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) {
522da09e106SDimitry Andric   if (Offset == 0)
523da09e106SDimitry Andric     return;
524da09e106SDimitry Andric   if (Offset < 0) {
525da09e106SDimitry Andric     OS << " - " << -Offset;
526da09e106SDimitry Andric     return;
527da09e106SDimitry Andric   }
528da09e106SDimitry Andric   OS << " + " << Offset;
529da09e106SDimitry Andric }
530da09e106SDimitry Andric 
531da09e106SDimitry Andric void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) {
532da09e106SDimitry Andric   if (Slot == -1)
533da09e106SDimitry Andric     OS << "<badref>";
534da09e106SDimitry Andric   else
535da09e106SDimitry Andric     OS << Slot;
536da09e106SDimitry Andric }
537da09e106SDimitry Andric 
538da09e106SDimitry Andric static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI,
539da09e106SDimitry Andric                      const TargetRegisterInfo *TRI) {
540da09e106SDimitry Andric   switch (CFI.getOperation()) {
541da09e106SDimitry Andric   case MCCFIInstruction::OpSameValue:
542da09e106SDimitry Andric     OS << "same_value ";
543da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
544da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
545da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
546da09e106SDimitry Andric     break;
547da09e106SDimitry Andric   case MCCFIInstruction::OpRememberState:
548da09e106SDimitry Andric     OS << "remember_state ";
549da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
550da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
551da09e106SDimitry Andric     break;
552da09e106SDimitry Andric   case MCCFIInstruction::OpRestoreState:
553da09e106SDimitry Andric     OS << "restore_state ";
554da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
555da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
556da09e106SDimitry Andric     break;
557da09e106SDimitry Andric   case MCCFIInstruction::OpOffset:
558da09e106SDimitry Andric     OS << "offset ";
559da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
560da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
561da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
562da09e106SDimitry Andric     OS << ", " << CFI.getOffset();
563da09e106SDimitry Andric     break;
564da09e106SDimitry Andric   case MCCFIInstruction::OpDefCfaRegister:
565da09e106SDimitry Andric     OS << "def_cfa_register ";
566da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
567da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
568da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
569da09e106SDimitry Andric     break;
570da09e106SDimitry Andric   case MCCFIInstruction::OpDefCfaOffset:
571da09e106SDimitry Andric     OS << "def_cfa_offset ";
572da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
573da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
574da09e106SDimitry Andric     OS << CFI.getOffset();
575da09e106SDimitry Andric     break;
576da09e106SDimitry Andric   case MCCFIInstruction::OpDefCfa:
577da09e106SDimitry Andric     OS << "def_cfa ";
578da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
579da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
580da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
581da09e106SDimitry Andric     OS << ", " << CFI.getOffset();
582da09e106SDimitry Andric     break;
583da09e106SDimitry Andric   case MCCFIInstruction::OpRelOffset:
584da09e106SDimitry Andric     OS << "rel_offset ";
585da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
586da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
587da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
588da09e106SDimitry Andric     OS << ", " << CFI.getOffset();
589da09e106SDimitry Andric     break;
590da09e106SDimitry Andric   case MCCFIInstruction::OpAdjustCfaOffset:
591da09e106SDimitry Andric     OS << "adjust_cfa_offset ";
592da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
593da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
594da09e106SDimitry Andric     OS << CFI.getOffset();
595da09e106SDimitry Andric     break;
596da09e106SDimitry Andric   case MCCFIInstruction::OpRestore:
597da09e106SDimitry Andric     OS << "restore ";
598da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
599da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
600da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
601da09e106SDimitry Andric     break;
602da09e106SDimitry Andric   case MCCFIInstruction::OpEscape: {
603da09e106SDimitry Andric     OS << "escape ";
604da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
605da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
606da09e106SDimitry Andric     if (!CFI.getValues().empty()) {
607da09e106SDimitry Andric       size_t e = CFI.getValues().size() - 1;
608da09e106SDimitry Andric       for (size_t i = 0; i < e; ++i)
609da09e106SDimitry Andric         OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", ";
610da09e106SDimitry Andric       OS << format("0x%02x", uint8_t(CFI.getValues()[e])) << ", ";
611da09e106SDimitry Andric     }
612da09e106SDimitry Andric     break;
613da09e106SDimitry Andric   }
614da09e106SDimitry Andric   case MCCFIInstruction::OpUndefined:
615da09e106SDimitry Andric     OS << "undefined ";
616da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
617da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
618da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
619da09e106SDimitry Andric     break;
620da09e106SDimitry Andric   case MCCFIInstruction::OpRegister:
621da09e106SDimitry Andric     OS << "register ";
622da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
623da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
624da09e106SDimitry Andric     printCFIRegister(CFI.getRegister(), OS, TRI);
625da09e106SDimitry Andric     OS << ", ";
626da09e106SDimitry Andric     printCFIRegister(CFI.getRegister2(), OS, TRI);
627da09e106SDimitry Andric     break;
628da09e106SDimitry Andric   case MCCFIInstruction::OpWindowSave:
629da09e106SDimitry Andric     OS << "window_save ";
630da09e106SDimitry Andric     if (MCSymbol *Label = CFI.getLabel())
631da09e106SDimitry Andric       MachineOperand::printSymbol(OS, *Label);
632da09e106SDimitry Andric     break;
633da09e106SDimitry Andric   default:
634da09e106SDimitry Andric     // TODO: Print the other CFI Operations.
635da09e106SDimitry Andric     OS << "<unserializable cfi directive>";
636da09e106SDimitry Andric     break;
637da09e106SDimitry Andric   }
638da09e106SDimitry Andric }
639da09e106SDimitry Andric 
6402cab237bSDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI,
6412cab237bSDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
6422cab237bSDimitry Andric   tryToGetTargetInfo(*this, TRI, IntrinsicInfo);
6432cab237bSDimitry Andric   ModuleSlotTracker DummyMST(nullptr);
6442cab237bSDimitry Andric   print(OS, DummyMST, LLT{}, /*PrintDef=*/false,
6452cab237bSDimitry Andric         /*ShouldPrintRegisterTies=*/true,
6462cab237bSDimitry Andric         /*TiedOperandIdx=*/0, TRI, IntrinsicInfo);
6472cab237bSDimitry Andric }
6482cab237bSDimitry Andric 
6492cab237bSDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST,
6502cab237bSDimitry Andric                            LLT TypeToPrint, bool PrintDef,
6512cab237bSDimitry Andric                            bool ShouldPrintRegisterTies,
6522cab237bSDimitry Andric                            unsigned TiedOperandIdx,
6532cab237bSDimitry Andric                            const TargetRegisterInfo *TRI,
6542cab237bSDimitry Andric                            const TargetIntrinsicInfo *IntrinsicInfo) const {
6552cab237bSDimitry Andric   printTargetFlags(OS, *this);
6562cab237bSDimitry Andric   switch (getType()) {
6572cab237bSDimitry Andric   case MachineOperand::MO_Register: {
6582cab237bSDimitry Andric     unsigned Reg = getReg();
6592cab237bSDimitry Andric     if (isImplicit())
6602cab237bSDimitry Andric       OS << (isDef() ? "implicit-def " : "implicit ");
6612cab237bSDimitry Andric     else if (PrintDef && isDef())
6622cab237bSDimitry Andric       // Print the 'def' flag only when the operand is defined after '='.
6632cab237bSDimitry Andric       OS << "def ";
6642cab237bSDimitry Andric     if (isInternalRead())
6652cab237bSDimitry Andric       OS << "internal ";
6662cab237bSDimitry Andric     if (isDead())
6672cab237bSDimitry Andric       OS << "dead ";
6682cab237bSDimitry Andric     if (isKill())
6692cab237bSDimitry Andric       OS << "killed ";
6702cab237bSDimitry Andric     if (isUndef())
6712cab237bSDimitry Andric       OS << "undef ";
6722cab237bSDimitry Andric     if (isEarlyClobber())
6732cab237bSDimitry Andric       OS << "early-clobber ";
6742cab237bSDimitry Andric     if (isDebug())
6752cab237bSDimitry Andric       OS << "debug-use ";
6762cab237bSDimitry Andric     if (TargetRegisterInfo::isPhysicalRegister(getReg()) && isRenamable())
6772cab237bSDimitry Andric       OS << "renamable ";
6782cab237bSDimitry Andric     OS << printReg(Reg, TRI);
6792cab237bSDimitry Andric     // Print the sub register.
6802cab237bSDimitry Andric     if (unsigned SubReg = getSubReg()) {
6812cab237bSDimitry Andric       if (TRI)
6822cab237bSDimitry Andric         OS << '.' << TRI->getSubRegIndexName(SubReg);
6832cab237bSDimitry Andric       else
6842cab237bSDimitry Andric         OS << ".subreg" << SubReg;
6852cab237bSDimitry Andric     }
6862cab237bSDimitry Andric     // Print the register class / bank.
6872cab237bSDimitry Andric     if (TargetRegisterInfo::isVirtualRegister(Reg)) {
6882cab237bSDimitry Andric       if (const MachineFunction *MF = getMFIfAvailable(*this)) {
6892cab237bSDimitry Andric         const MachineRegisterInfo &MRI = MF->getRegInfo();
6902cab237bSDimitry Andric         if (!PrintDef || MRI.def_empty(Reg)) {
6912cab237bSDimitry Andric           OS << ':';
6922cab237bSDimitry Andric           OS << printRegClassOrBank(Reg, MRI, TRI);
6932cab237bSDimitry Andric         }
6942cab237bSDimitry Andric       }
6952cab237bSDimitry Andric     }
6962cab237bSDimitry Andric     // Print ties.
6972cab237bSDimitry Andric     if (ShouldPrintRegisterTies && isTied() && !isDef())
6982cab237bSDimitry Andric       OS << "(tied-def " << TiedOperandIdx << ")";
6992cab237bSDimitry Andric     // Print types.
7002cab237bSDimitry Andric     if (TypeToPrint.isValid())
7012cab237bSDimitry Andric       OS << '(' << TypeToPrint << ')';
7022cab237bSDimitry Andric     break;
7032cab237bSDimitry Andric   }
7042cab237bSDimitry Andric   case MachineOperand::MO_Immediate:
7052cab237bSDimitry Andric     OS << getImm();
7062cab237bSDimitry Andric     break;
7072cab237bSDimitry Andric   case MachineOperand::MO_CImmediate:
7082cab237bSDimitry Andric     getCImm()->printAsOperand(OS, /*PrintType=*/true, MST);
7092cab237bSDimitry Andric     break;
7102cab237bSDimitry Andric   case MachineOperand::MO_FPImmediate:
711da09e106SDimitry Andric     getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST);
7122cab237bSDimitry Andric     break;
7132cab237bSDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
7142cab237bSDimitry Andric     OS << printMBBReference(*getMBB());
7152cab237bSDimitry Andric     break;
7162cab237bSDimitry Andric   case MachineOperand::MO_FrameIndex: {
7172cab237bSDimitry Andric     int FrameIndex = getIndex();
7182cab237bSDimitry Andric     bool IsFixed = false;
7192cab237bSDimitry Andric     StringRef Name;
7202cab237bSDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
7212cab237bSDimitry Andric       const MachineFrameInfo &MFI = MF->getFrameInfo();
7222cab237bSDimitry Andric       IsFixed = MFI.isFixedObjectIndex(FrameIndex);
7232cab237bSDimitry Andric       if (const AllocaInst *Alloca = MFI.getObjectAllocation(FrameIndex))
7242cab237bSDimitry Andric         if (Alloca->hasName())
7252cab237bSDimitry Andric           Name = Alloca->getName();
7262cab237bSDimitry Andric       if (IsFixed)
7272cab237bSDimitry Andric         FrameIndex -= MFI.getObjectIndexBegin();
7282cab237bSDimitry Andric     }
7292cab237bSDimitry Andric     printStackObjectReference(OS, FrameIndex, IsFixed, Name);
7302cab237bSDimitry Andric     break;
7312cab237bSDimitry Andric   }
7322cab237bSDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
7332cab237bSDimitry Andric     OS << "%const." << getIndex();
734da09e106SDimitry Andric     printOperandOffset(OS, getOffset());
7352cab237bSDimitry Andric     break;
7362cab237bSDimitry Andric   case MachineOperand::MO_TargetIndex: {
7372cab237bSDimitry Andric     OS << "target-index(";
7382cab237bSDimitry Andric     const char *Name = "<unknown>";
7392cab237bSDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
7402cab237bSDimitry Andric       if (const auto *TargetIndexName = getTargetIndexName(*MF, getIndex()))
7412cab237bSDimitry Andric         Name = TargetIndexName;
7422cab237bSDimitry Andric     OS << Name << ')';
743da09e106SDimitry Andric     printOperandOffset(OS, getOffset());
7442cab237bSDimitry Andric     break;
7452cab237bSDimitry Andric   }
7462cab237bSDimitry Andric   case MachineOperand::MO_JumpTableIndex:
7472cab237bSDimitry Andric     OS << printJumpTableEntryReference(getIndex());
7482cab237bSDimitry Andric     break;
7492cab237bSDimitry Andric   case MachineOperand::MO_GlobalAddress:
7502cab237bSDimitry Andric     getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST);
751da09e106SDimitry Andric     printOperandOffset(OS, getOffset());
7522cab237bSDimitry Andric     break;
7532cab237bSDimitry Andric   case MachineOperand::MO_ExternalSymbol: {
7542cab237bSDimitry Andric     StringRef Name = getSymbolName();
7552cab237bSDimitry Andric     OS << '$';
7562cab237bSDimitry Andric     if (Name.empty()) {
7572cab237bSDimitry Andric       OS << "\"\"";
7582cab237bSDimitry Andric     } else {
7592cab237bSDimitry Andric       printLLVMNameWithoutPrefix(OS, Name);
7602cab237bSDimitry Andric     }
761da09e106SDimitry Andric     printOperandOffset(OS, getOffset());
7622cab237bSDimitry Andric     break;
7632cab237bSDimitry Andric   }
764da09e106SDimitry Andric   case MachineOperand::MO_BlockAddress: {
765da09e106SDimitry Andric     OS << "blockaddress(";
766da09e106SDimitry Andric     getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false,
767da09e106SDimitry Andric                                                      MST);
768da09e106SDimitry Andric     OS << ", ";
769da09e106SDimitry Andric     printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST);
770da09e106SDimitry Andric     OS << ')';
771da09e106SDimitry Andric     MachineOperand::printOperandOffset(OS, getOffset());
7722cab237bSDimitry Andric     break;
773da09e106SDimitry Andric   }
7742cab237bSDimitry Andric   case MachineOperand::MO_RegisterMask: {
7752cab237bSDimitry Andric     OS << "<regmask";
7762cab237bSDimitry Andric     if (TRI) {
7772cab237bSDimitry Andric       unsigned NumRegsInMask = 0;
7782cab237bSDimitry Andric       unsigned NumRegsEmitted = 0;
7792cab237bSDimitry Andric       for (unsigned i = 0; i < TRI->getNumRegs(); ++i) {
7802cab237bSDimitry Andric         unsigned MaskWord = i / 32;
7812cab237bSDimitry Andric         unsigned MaskBit = i % 32;
7822cab237bSDimitry Andric         if (getRegMask()[MaskWord] & (1 << MaskBit)) {
7832cab237bSDimitry Andric           if (PrintRegMaskNumRegs < 0 ||
7842cab237bSDimitry Andric               NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) {
7852cab237bSDimitry Andric             OS << " " << printReg(i, TRI);
7862cab237bSDimitry Andric             NumRegsEmitted++;
7872cab237bSDimitry Andric           }
7882cab237bSDimitry Andric           NumRegsInMask++;
7892cab237bSDimitry Andric         }
7902cab237bSDimitry Andric       }
7912cab237bSDimitry Andric       if (NumRegsEmitted != NumRegsInMask)
7922cab237bSDimitry Andric         OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more...";
7932cab237bSDimitry Andric     } else {
7942cab237bSDimitry Andric       OS << " ...";
7952cab237bSDimitry Andric     }
7962cab237bSDimitry Andric     OS << ">";
7972cab237bSDimitry Andric     break;
7982cab237bSDimitry Andric   }
7992cab237bSDimitry Andric   case MachineOperand::MO_RegisterLiveOut: {
8002cab237bSDimitry Andric     const uint32_t *RegMask = getRegLiveOut();
8012cab237bSDimitry Andric     OS << "liveout(";
8022cab237bSDimitry Andric     if (!TRI) {
8032cab237bSDimitry Andric       OS << "<unknown>";
8042cab237bSDimitry Andric     } else {
8052cab237bSDimitry Andric       bool IsCommaNeeded = false;
8062cab237bSDimitry Andric       for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) {
8072cab237bSDimitry Andric         if (RegMask[Reg / 32] & (1U << (Reg % 32))) {
8082cab237bSDimitry Andric           if (IsCommaNeeded)
8092cab237bSDimitry Andric             OS << ", ";
8102cab237bSDimitry Andric           OS << printReg(Reg, TRI);
8112cab237bSDimitry Andric           IsCommaNeeded = true;
8122cab237bSDimitry Andric         }
8132cab237bSDimitry Andric       }
8142cab237bSDimitry Andric     }
8152cab237bSDimitry Andric     OS << ")";
8162cab237bSDimitry Andric     break;
8172cab237bSDimitry Andric   }
8182cab237bSDimitry Andric   case MachineOperand::MO_Metadata:
8192cab237bSDimitry Andric     getMetadata()->printAsOperand(OS, MST);
8202cab237bSDimitry Andric     break;
8212cab237bSDimitry Andric   case MachineOperand::MO_MCSymbol:
8222cab237bSDimitry Andric     printSymbol(OS, *getMCSymbol());
8232cab237bSDimitry Andric     break;
824da09e106SDimitry Andric   case MachineOperand::MO_CFIIndex: {
825da09e106SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this))
826da09e106SDimitry Andric       printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI);
827da09e106SDimitry Andric     else
828da09e106SDimitry Andric       OS << "<cfi directive>";
8292cab237bSDimitry Andric     break;
830da09e106SDimitry Andric   }
8312cab237bSDimitry Andric   case MachineOperand::MO_IntrinsicID: {
8322cab237bSDimitry Andric     Intrinsic::ID ID = getIntrinsicID();
8332cab237bSDimitry Andric     if (ID < Intrinsic::num_intrinsics)
834da09e106SDimitry Andric       OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')';
8352cab237bSDimitry Andric     else if (IntrinsicInfo)
836da09e106SDimitry Andric       OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')';
8372cab237bSDimitry Andric     else
838da09e106SDimitry Andric       OS << "intrinsic(" << ID << ')';
8392cab237bSDimitry Andric     break;
8402cab237bSDimitry Andric   }
8412cab237bSDimitry Andric   case MachineOperand::MO_Predicate: {
8422cab237bSDimitry Andric     auto Pred = static_cast<CmpInst::Predicate>(getPredicate());
843da09e106SDimitry Andric     OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred("
844da09e106SDimitry Andric        << CmpInst::getPredicateName(Pred) << ')';
8452cab237bSDimitry Andric     break;
8462cab237bSDimitry Andric   }
8472cab237bSDimitry Andric   }
8482cab237bSDimitry Andric }
8492cab237bSDimitry Andric 
8502cab237bSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
8512cab237bSDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; }
8522cab237bSDimitry Andric #endif
8532cab237bSDimitry Andric 
8542cab237bSDimitry Andric //===----------------------------------------------------------------------===//
8552cab237bSDimitry Andric // MachineMemOperand Implementation
8562cab237bSDimitry Andric //===----------------------------------------------------------------------===//
8572cab237bSDimitry Andric 
8582cab237bSDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer
8592cab237bSDimitry Andric /// points into.
8602cab237bSDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; }
8612cab237bSDimitry Andric 
8622cab237bSDimitry Andric /// isDereferenceable - Return true if V is always dereferenceable for
8632cab237bSDimitry Andric /// Offset + Size byte.
8642cab237bSDimitry Andric bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C,
8652cab237bSDimitry Andric                                            const DataLayout &DL) const {
8662cab237bSDimitry Andric   if (!V.is<const Value *>())
8672cab237bSDimitry Andric     return false;
8682cab237bSDimitry Andric 
8692cab237bSDimitry Andric   const Value *BasePtr = V.get<const Value *>();
8702cab237bSDimitry Andric   if (BasePtr == nullptr)
8712cab237bSDimitry Andric     return false;
8722cab237bSDimitry Andric 
8732cab237bSDimitry Andric   return isDereferenceableAndAlignedPointer(
8742cab237bSDimitry Andric       BasePtr, 1, APInt(DL.getPointerSizeInBits(), Offset + Size), DL);
8752cab237bSDimitry Andric }
8762cab237bSDimitry Andric 
8772cab237bSDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the
8782cab237bSDimitry Andric /// constant pool.
8792cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) {
8802cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getConstantPool());
8812cab237bSDimitry Andric }
8822cab237bSDimitry Andric 
8832cab237bSDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the
8842cab237bSDimitry Andric /// the specified FrameIndex.
8852cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF,
8862cab237bSDimitry Andric                                                      int FI, int64_t Offset) {
8872cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset);
8882cab237bSDimitry Andric }
8892cab237bSDimitry Andric 
8902cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) {
8912cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getJumpTable());
8922cab237bSDimitry Andric }
8932cab237bSDimitry Andric 
8942cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) {
8952cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getGOT());
8962cab237bSDimitry Andric }
8972cab237bSDimitry Andric 
8982cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF,
8992cab237bSDimitry Andric                                                 int64_t Offset, uint8_t ID) {
9002cab237bSDimitry Andric   return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID);
9012cab237bSDimitry Andric }
9022cab237bSDimitry Andric 
9032cab237bSDimitry Andric MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) {
9042cab237bSDimitry Andric   return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace());
9052cab237bSDimitry Andric }
9062cab237bSDimitry Andric 
9072cab237bSDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f,
9082cab237bSDimitry Andric                                      uint64_t s, unsigned int a,
9092cab237bSDimitry Andric                                      const AAMDNodes &AAInfo,
9102cab237bSDimitry Andric                                      const MDNode *Ranges, SyncScope::ID SSID,
9112cab237bSDimitry Andric                                      AtomicOrdering Ordering,
9122cab237bSDimitry Andric                                      AtomicOrdering FailureOrdering)
9132cab237bSDimitry Andric     : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1),
9142cab237bSDimitry Andric       AAInfo(AAInfo), Ranges(Ranges) {
9152cab237bSDimitry Andric   assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() ||
9162cab237bSDimitry Andric           isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) &&
9172cab237bSDimitry Andric          "invalid pointer value");
9182cab237bSDimitry Andric   assert(getBaseAlignment() == a && "Alignment is not a power of 2!");
9192cab237bSDimitry Andric   assert((isLoad() || isStore()) && "Not a load/store!");
9202cab237bSDimitry Andric 
9212cab237bSDimitry Andric   AtomicInfo.SSID = static_cast<unsigned>(SSID);
9222cab237bSDimitry Andric   assert(getSyncScopeID() == SSID && "Value truncated");
9232cab237bSDimitry Andric   AtomicInfo.Ordering = static_cast<unsigned>(Ordering);
9242cab237bSDimitry Andric   assert(getOrdering() == Ordering && "Value truncated");
9252cab237bSDimitry Andric   AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering);
9262cab237bSDimitry Andric   assert(getFailureOrdering() == FailureOrdering && "Value truncated");
9272cab237bSDimitry Andric }
9282cab237bSDimitry Andric 
9292cab237bSDimitry Andric /// Profile - Gather unique data for the object.
9302cab237bSDimitry Andric ///
9312cab237bSDimitry Andric void MachineMemOperand::Profile(FoldingSetNodeID &ID) const {
9322cab237bSDimitry Andric   ID.AddInteger(getOffset());
9332cab237bSDimitry Andric   ID.AddInteger(Size);
9342cab237bSDimitry Andric   ID.AddPointer(getOpaqueValue());
9352cab237bSDimitry Andric   ID.AddInteger(getFlags());
9362cab237bSDimitry Andric   ID.AddInteger(getBaseAlignment());
9372cab237bSDimitry Andric }
9382cab237bSDimitry Andric 
9392cab237bSDimitry Andric void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) {
9402cab237bSDimitry Andric   // The Value and Offset may differ due to CSE. But the flags and size
9412cab237bSDimitry Andric   // should be the same.
9422cab237bSDimitry Andric   assert(MMO->getFlags() == getFlags() && "Flags mismatch!");
9432cab237bSDimitry Andric   assert(MMO->getSize() == getSize() && "Size mismatch!");
9442cab237bSDimitry Andric 
9452cab237bSDimitry Andric   if (MMO->getBaseAlignment() >= getBaseAlignment()) {
9462cab237bSDimitry Andric     // Update the alignment value.
9472cab237bSDimitry Andric     BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1;
9482cab237bSDimitry Andric     // Also update the base and offset, because the new alignment may
9492cab237bSDimitry Andric     // not be applicable with the old ones.
9502cab237bSDimitry Andric     PtrInfo = MMO->PtrInfo;
9512cab237bSDimitry Andric   }
9522cab237bSDimitry Andric }
9532cab237bSDimitry Andric 
9542cab237bSDimitry Andric /// getAlignment - Return the minimum known alignment in bytes of the
9552cab237bSDimitry Andric /// actual memory reference.
9562cab237bSDimitry Andric uint64_t MachineMemOperand::getAlignment() const {
9572cab237bSDimitry Andric   return MinAlign(getBaseAlignment(), getOffset());
9582cab237bSDimitry Andric }
9592cab237bSDimitry Andric 
9602cab237bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS) const {
9612cab237bSDimitry Andric   ModuleSlotTracker DummyMST(nullptr);
9622cab237bSDimitry Andric   print(OS, DummyMST);
9632cab237bSDimitry Andric }
9642cab237bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const {
9652cab237bSDimitry Andric   assert((isLoad() || isStore()) && "SV has to be a load, store or both.");
9662cab237bSDimitry Andric 
9672cab237bSDimitry Andric   if (isVolatile())
9682cab237bSDimitry Andric     OS << "Volatile ";
9692cab237bSDimitry Andric 
9702cab237bSDimitry Andric   if (isLoad())
9712cab237bSDimitry Andric     OS << "LD";
9722cab237bSDimitry Andric   if (isStore())
9732cab237bSDimitry Andric     OS << "ST";
9742cab237bSDimitry Andric   OS << getSize();
9752cab237bSDimitry Andric 
9762cab237bSDimitry Andric   // Print the address information.
9772cab237bSDimitry Andric   OS << "[";
9782cab237bSDimitry Andric   if (const Value *V = getValue())
9792cab237bSDimitry Andric     V->printAsOperand(OS, /*PrintType=*/false, MST);
9802cab237bSDimitry Andric   else if (const PseudoSourceValue *PSV = getPseudoValue())
9812cab237bSDimitry Andric     PSV->printCustom(OS);
9822cab237bSDimitry Andric   else
9832cab237bSDimitry Andric     OS << "<unknown>";
9842cab237bSDimitry Andric 
9852cab237bSDimitry Andric   unsigned AS = getAddrSpace();
9862cab237bSDimitry Andric   if (AS != 0)
9872cab237bSDimitry Andric     OS << "(addrspace=" << AS << ')';
9882cab237bSDimitry Andric 
9892cab237bSDimitry Andric   // If the alignment of the memory reference itself differs from the alignment
9902cab237bSDimitry Andric   // of the base pointer, print the base alignment explicitly, next to the base
9912cab237bSDimitry Andric   // pointer.
9922cab237bSDimitry Andric   if (getBaseAlignment() != getAlignment())
9932cab237bSDimitry Andric     OS << "(align=" << getBaseAlignment() << ")";
9942cab237bSDimitry Andric 
9952cab237bSDimitry Andric   if (getOffset() != 0)
9962cab237bSDimitry Andric     OS << "+" << getOffset();
9972cab237bSDimitry Andric   OS << "]";
9982cab237bSDimitry Andric 
9992cab237bSDimitry Andric   // Print the alignment of the reference.
10002cab237bSDimitry Andric   if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize())
10012cab237bSDimitry Andric     OS << "(align=" << getAlignment() << ")";
10022cab237bSDimitry Andric 
10032cab237bSDimitry Andric   // Print TBAA info.
10042cab237bSDimitry Andric   if (const MDNode *TBAAInfo = getAAInfo().TBAA) {
10052cab237bSDimitry Andric     OS << "(tbaa=";
10062cab237bSDimitry Andric     if (TBAAInfo->getNumOperands() > 0)
10072cab237bSDimitry Andric       TBAAInfo->getOperand(0)->printAsOperand(OS, MST);
10082cab237bSDimitry Andric     else
10092cab237bSDimitry Andric       OS << "<unknown>";
10102cab237bSDimitry Andric     OS << ")";
10112cab237bSDimitry Andric   }
10122cab237bSDimitry Andric 
10132cab237bSDimitry Andric   // Print AA scope info.
10142cab237bSDimitry Andric   if (const MDNode *ScopeInfo = getAAInfo().Scope) {
10152cab237bSDimitry Andric     OS << "(alias.scope=";
10162cab237bSDimitry Andric     if (ScopeInfo->getNumOperands() > 0)
10172cab237bSDimitry Andric       for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) {
10182cab237bSDimitry Andric         ScopeInfo->getOperand(i)->printAsOperand(OS, MST);
10192cab237bSDimitry Andric         if (i != ie - 1)
10202cab237bSDimitry Andric           OS << ",";
10212cab237bSDimitry Andric       }
10222cab237bSDimitry Andric     else
10232cab237bSDimitry Andric       OS << "<unknown>";
10242cab237bSDimitry Andric     OS << ")";
10252cab237bSDimitry Andric   }
10262cab237bSDimitry Andric 
10272cab237bSDimitry Andric   // Print AA noalias scope info.
10282cab237bSDimitry Andric   if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) {
10292cab237bSDimitry Andric     OS << "(noalias=";
10302cab237bSDimitry Andric     if (NoAliasInfo->getNumOperands() > 0)
10312cab237bSDimitry Andric       for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) {
10322cab237bSDimitry Andric         NoAliasInfo->getOperand(i)->printAsOperand(OS, MST);
10332cab237bSDimitry Andric         if (i != ie - 1)
10342cab237bSDimitry Andric           OS << ",";
10352cab237bSDimitry Andric       }
10362cab237bSDimitry Andric     else
10372cab237bSDimitry Andric       OS << "<unknown>";
10382cab237bSDimitry Andric     OS << ")";
10392cab237bSDimitry Andric   }
10402cab237bSDimitry Andric 
10412cab237bSDimitry Andric   if (const MDNode *Ranges = getRanges()) {
10422cab237bSDimitry Andric     unsigned NumRanges = Ranges->getNumOperands();
10432cab237bSDimitry Andric     if (NumRanges != 0) {
10442cab237bSDimitry Andric       OS << "(ranges=";
10452cab237bSDimitry Andric 
10462cab237bSDimitry Andric       for (unsigned I = 0; I != NumRanges; ++I) {
10472cab237bSDimitry Andric         Ranges->getOperand(I)->printAsOperand(OS, MST);
10482cab237bSDimitry Andric         if (I != NumRanges - 1)
10492cab237bSDimitry Andric           OS << ',';
10502cab237bSDimitry Andric       }
10512cab237bSDimitry Andric 
10522cab237bSDimitry Andric       OS << ')';
10532cab237bSDimitry Andric     }
10542cab237bSDimitry Andric   }
10552cab237bSDimitry Andric 
10562cab237bSDimitry Andric   if (isNonTemporal())
10572cab237bSDimitry Andric     OS << "(nontemporal)";
10582cab237bSDimitry Andric   if (isDereferenceable())
10592cab237bSDimitry Andric     OS << "(dereferenceable)";
10602cab237bSDimitry Andric   if (isInvariant())
10612cab237bSDimitry Andric     OS << "(invariant)";
10622cab237bSDimitry Andric   if (getFlags() & MOTargetFlag1)
10632cab237bSDimitry Andric     OS << "(flag1)";
10642cab237bSDimitry Andric   if (getFlags() & MOTargetFlag2)
10652cab237bSDimitry Andric     OS << "(flag2)";
10662cab237bSDimitry Andric   if (getFlags() & MOTargetFlag3)
10672cab237bSDimitry Andric     OS << "(flag3)";
10682cab237bSDimitry Andric }
1069