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