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