1*0b57cec5SDimitry Andric //===- lib/CodeGen/MachineOperand.cpp -------------------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric /// \file Methods common to all machine operands. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 14*0b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 15*0b57cec5SDimitry Andric #include "llvm/Analysis/Loads.h" 16*0b57cec5SDimitry Andric #include "llvm/Analysis/MemoryLocation.h" 17*0b57cec5SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h" 18*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 19*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineJumpTableInfo.h" 20*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 21*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 22*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 23*0b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h" 24*0b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 25*0b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h" 26*0b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h" 27*0b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h" 28*0b57cec5SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h" 29*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric using namespace llvm; 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric static cl::opt<int> 34*0b57cec5SDimitry Andric PrintRegMaskNumRegs("print-regmask-num-regs", 35*0b57cec5SDimitry Andric cl::desc("Number of registers to limit to when " 36*0b57cec5SDimitry Andric "printing regmask operands in IR dumps. " 37*0b57cec5SDimitry Andric "unlimited = -1"), 38*0b57cec5SDimitry Andric cl::init(32), cl::Hidden); 39*0b57cec5SDimitry Andric 40*0b57cec5SDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineOperand &MO) { 41*0b57cec5SDimitry Andric if (const MachineInstr *MI = MO.getParent()) 42*0b57cec5SDimitry Andric if (const MachineBasicBlock *MBB = MI->getParent()) 43*0b57cec5SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 44*0b57cec5SDimitry Andric return MF; 45*0b57cec5SDimitry Andric return nullptr; 46*0b57cec5SDimitry Andric } 47*0b57cec5SDimitry Andric static MachineFunction *getMFIfAvailable(MachineOperand &MO) { 48*0b57cec5SDimitry Andric return const_cast<MachineFunction *>( 49*0b57cec5SDimitry Andric getMFIfAvailable(const_cast<const MachineOperand &>(MO))); 50*0b57cec5SDimitry Andric } 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric void MachineOperand::setReg(unsigned Reg) { 53*0b57cec5SDimitry Andric if (getReg() == Reg) 54*0b57cec5SDimitry Andric return; // No change. 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric // Clear the IsRenamable bit to keep it conservatively correct. 57*0b57cec5SDimitry Andric IsRenamable = false; 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric // Otherwise, we have to change the register. If this operand is embedded 60*0b57cec5SDimitry Andric // into a machine function, we need to update the old and new register's 61*0b57cec5SDimitry Andric // use/def lists. 62*0b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) { 63*0b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 64*0b57cec5SDimitry Andric MRI.removeRegOperandFromUseList(this); 65*0b57cec5SDimitry Andric SmallContents.RegNo = Reg; 66*0b57cec5SDimitry Andric MRI.addRegOperandToUseList(this); 67*0b57cec5SDimitry Andric return; 68*0b57cec5SDimitry Andric } 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric // Otherwise, just change the register, no problem. :) 71*0b57cec5SDimitry Andric SmallContents.RegNo = Reg; 72*0b57cec5SDimitry Andric } 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, 75*0b57cec5SDimitry Andric const TargetRegisterInfo &TRI) { 76*0b57cec5SDimitry Andric assert(TargetRegisterInfo::isVirtualRegister(Reg)); 77*0b57cec5SDimitry Andric if (SubIdx && getSubReg()) 78*0b57cec5SDimitry Andric SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); 79*0b57cec5SDimitry Andric setReg(Reg); 80*0b57cec5SDimitry Andric if (SubIdx) 81*0b57cec5SDimitry Andric setSubReg(SubIdx); 82*0b57cec5SDimitry Andric } 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { 85*0b57cec5SDimitry Andric assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 86*0b57cec5SDimitry Andric if (getSubReg()) { 87*0b57cec5SDimitry Andric Reg = TRI.getSubReg(Reg, getSubReg()); 88*0b57cec5SDimitry Andric // Note that getSubReg() may return 0 if the sub-register doesn't exist. 89*0b57cec5SDimitry Andric // That won't happen in legal code. 90*0b57cec5SDimitry Andric setSubReg(0); 91*0b57cec5SDimitry Andric if (isDef()) 92*0b57cec5SDimitry Andric setIsUndef(false); 93*0b57cec5SDimitry Andric } 94*0b57cec5SDimitry Andric setReg(Reg); 95*0b57cec5SDimitry Andric } 96*0b57cec5SDimitry Andric 97*0b57cec5SDimitry Andric /// Change a def to a use, or a use to a def. 98*0b57cec5SDimitry Andric void MachineOperand::setIsDef(bool Val) { 99*0b57cec5SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 100*0b57cec5SDimitry Andric assert((!Val || !isDebug()) && "Marking a debug operation as def"); 101*0b57cec5SDimitry Andric if (IsDef == Val) 102*0b57cec5SDimitry Andric return; 103*0b57cec5SDimitry Andric assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported"); 104*0b57cec5SDimitry Andric // MRI may keep uses and defs in different list positions. 105*0b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) { 106*0b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 107*0b57cec5SDimitry Andric MRI.removeRegOperandFromUseList(this); 108*0b57cec5SDimitry Andric IsDef = Val; 109*0b57cec5SDimitry Andric MRI.addRegOperandToUseList(this); 110*0b57cec5SDimitry Andric return; 111*0b57cec5SDimitry Andric } 112*0b57cec5SDimitry Andric IsDef = Val; 113*0b57cec5SDimitry Andric } 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andric bool MachineOperand::isRenamable() const { 116*0b57cec5SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 117*0b57cec5SDimitry Andric assert(TargetRegisterInfo::isPhysicalRegister(getReg()) && 118*0b57cec5SDimitry Andric "isRenamable should only be checked on physical registers"); 119*0b57cec5SDimitry Andric if (!IsRenamable) 120*0b57cec5SDimitry Andric return false; 121*0b57cec5SDimitry Andric 122*0b57cec5SDimitry Andric const MachineInstr *MI = getParent(); 123*0b57cec5SDimitry Andric if (!MI) 124*0b57cec5SDimitry Andric return true; 125*0b57cec5SDimitry Andric 126*0b57cec5SDimitry Andric if (isDef()) 127*0b57cec5SDimitry Andric return !MI->hasExtraDefRegAllocReq(MachineInstr::IgnoreBundle); 128*0b57cec5SDimitry Andric 129*0b57cec5SDimitry Andric assert(isUse() && "Reg is not def or use"); 130*0b57cec5SDimitry Andric return !MI->hasExtraSrcRegAllocReq(MachineInstr::IgnoreBundle); 131*0b57cec5SDimitry Andric } 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric void MachineOperand::setIsRenamable(bool Val) { 134*0b57cec5SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 135*0b57cec5SDimitry Andric assert(TargetRegisterInfo::isPhysicalRegister(getReg()) && 136*0b57cec5SDimitry Andric "setIsRenamable should only be called on physical registers"); 137*0b57cec5SDimitry Andric IsRenamable = Val; 138*0b57cec5SDimitry Andric } 139*0b57cec5SDimitry Andric 140*0b57cec5SDimitry Andric // If this operand is currently a register operand, and if this is in a 141*0b57cec5SDimitry Andric // function, deregister the operand from the register's use/def list. 142*0b57cec5SDimitry Andric void MachineOperand::removeRegFromUses() { 143*0b57cec5SDimitry Andric if (!isReg() || !isOnRegUseList()) 144*0b57cec5SDimitry Andric return; 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) 147*0b57cec5SDimitry Andric MF->getRegInfo().removeRegOperandFromUseList(this); 148*0b57cec5SDimitry Andric } 149*0b57cec5SDimitry Andric 150*0b57cec5SDimitry Andric /// ChangeToImmediate - Replace this operand with a new immediate operand of 151*0b57cec5SDimitry Andric /// the specified value. If an operand is known to be an immediate already, 152*0b57cec5SDimitry Andric /// the setImm method should be used. 153*0b57cec5SDimitry Andric void MachineOperand::ChangeToImmediate(int64_t ImmVal) { 154*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 155*0b57cec5SDimitry Andric 156*0b57cec5SDimitry Andric removeRegFromUses(); 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric OpKind = MO_Immediate; 159*0b57cec5SDimitry Andric Contents.ImmVal = ImmVal; 160*0b57cec5SDimitry Andric } 161*0b57cec5SDimitry Andric 162*0b57cec5SDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) { 163*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric removeRegFromUses(); 166*0b57cec5SDimitry Andric 167*0b57cec5SDimitry Andric OpKind = MO_FPImmediate; 168*0b57cec5SDimitry Andric Contents.CFP = FPImm; 169*0b57cec5SDimitry Andric } 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andric void MachineOperand::ChangeToES(const char *SymName, 172*0b57cec5SDimitry Andric unsigned char TargetFlags) { 173*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 174*0b57cec5SDimitry Andric "Cannot change a tied operand into an external symbol"); 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric removeRegFromUses(); 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric OpKind = MO_ExternalSymbol; 179*0b57cec5SDimitry Andric Contents.OffsetedInfo.Val.SymbolName = SymName; 180*0b57cec5SDimitry Andric setOffset(0); // Offset is always 0. 181*0b57cec5SDimitry Andric setTargetFlags(TargetFlags); 182*0b57cec5SDimitry Andric } 183*0b57cec5SDimitry Andric 184*0b57cec5SDimitry Andric void MachineOperand::ChangeToGA(const GlobalValue *GV, int64_t Offset, 185*0b57cec5SDimitry Andric unsigned char TargetFlags) { 186*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 187*0b57cec5SDimitry Andric "Cannot change a tied operand into a global address"); 188*0b57cec5SDimitry Andric 189*0b57cec5SDimitry Andric removeRegFromUses(); 190*0b57cec5SDimitry Andric 191*0b57cec5SDimitry Andric OpKind = MO_GlobalAddress; 192*0b57cec5SDimitry Andric Contents.OffsetedInfo.Val.GV = GV; 193*0b57cec5SDimitry Andric setOffset(Offset); 194*0b57cec5SDimitry Andric setTargetFlags(TargetFlags); 195*0b57cec5SDimitry Andric } 196*0b57cec5SDimitry Andric 197*0b57cec5SDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) { 198*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 199*0b57cec5SDimitry Andric "Cannot change a tied operand into an MCSymbol"); 200*0b57cec5SDimitry Andric 201*0b57cec5SDimitry Andric removeRegFromUses(); 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric OpKind = MO_MCSymbol; 204*0b57cec5SDimitry Andric Contents.Sym = Sym; 205*0b57cec5SDimitry Andric } 206*0b57cec5SDimitry Andric 207*0b57cec5SDimitry Andric void MachineOperand::ChangeToFrameIndex(int Idx) { 208*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 209*0b57cec5SDimitry Andric "Cannot change a tied operand into a FrameIndex"); 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric removeRegFromUses(); 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric OpKind = MO_FrameIndex; 214*0b57cec5SDimitry Andric setIndex(Idx); 215*0b57cec5SDimitry Andric } 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset, 218*0b57cec5SDimitry Andric unsigned char TargetFlags) { 219*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 220*0b57cec5SDimitry Andric "Cannot change a tied operand into a FrameIndex"); 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric removeRegFromUses(); 223*0b57cec5SDimitry Andric 224*0b57cec5SDimitry Andric OpKind = MO_TargetIndex; 225*0b57cec5SDimitry Andric setIndex(Idx); 226*0b57cec5SDimitry Andric setOffset(Offset); 227*0b57cec5SDimitry Andric setTargetFlags(TargetFlags); 228*0b57cec5SDimitry Andric } 229*0b57cec5SDimitry Andric 230*0b57cec5SDimitry Andric /// ChangeToRegister - Replace this operand with a new register operand of 231*0b57cec5SDimitry Andric /// the specified value. If an operand is known to be an register already, 232*0b57cec5SDimitry Andric /// the setReg method should be used. 233*0b57cec5SDimitry Andric void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, 234*0b57cec5SDimitry Andric bool isKill, bool isDead, bool isUndef, 235*0b57cec5SDimitry Andric bool isDebug) { 236*0b57cec5SDimitry Andric MachineRegisterInfo *RegInfo = nullptr; 237*0b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) 238*0b57cec5SDimitry Andric RegInfo = &MF->getRegInfo(); 239*0b57cec5SDimitry Andric // If this operand is already a register operand, remove it from the 240*0b57cec5SDimitry Andric // register's use/def lists. 241*0b57cec5SDimitry Andric bool WasReg = isReg(); 242*0b57cec5SDimitry Andric if (RegInfo && WasReg) 243*0b57cec5SDimitry Andric RegInfo->removeRegOperandFromUseList(this); 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andric // Change this to a register and set the reg#. 246*0b57cec5SDimitry Andric assert(!(isDead && !isDef) && "Dead flag on non-def"); 247*0b57cec5SDimitry Andric assert(!(isKill && isDef) && "Kill flag on def"); 248*0b57cec5SDimitry Andric OpKind = MO_Register; 249*0b57cec5SDimitry Andric SmallContents.RegNo = Reg; 250*0b57cec5SDimitry Andric SubReg_TargetFlags = 0; 251*0b57cec5SDimitry Andric IsDef = isDef; 252*0b57cec5SDimitry Andric IsImp = isImp; 253*0b57cec5SDimitry Andric IsDeadOrKill = isKill | isDead; 254*0b57cec5SDimitry Andric IsRenamable = false; 255*0b57cec5SDimitry Andric IsUndef = isUndef; 256*0b57cec5SDimitry Andric IsInternalRead = false; 257*0b57cec5SDimitry Andric IsEarlyClobber = false; 258*0b57cec5SDimitry Andric IsDebug = isDebug; 259*0b57cec5SDimitry Andric // Ensure isOnRegUseList() returns false. 260*0b57cec5SDimitry Andric Contents.Reg.Prev = nullptr; 261*0b57cec5SDimitry Andric // Preserve the tie when the operand was already a register. 262*0b57cec5SDimitry Andric if (!WasReg) 263*0b57cec5SDimitry Andric TiedTo = 0; 264*0b57cec5SDimitry Andric 265*0b57cec5SDimitry Andric // If this operand is embedded in a function, add the operand to the 266*0b57cec5SDimitry Andric // register's use/def list. 267*0b57cec5SDimitry Andric if (RegInfo) 268*0b57cec5SDimitry Andric RegInfo->addRegOperandToUseList(this); 269*0b57cec5SDimitry Andric } 270*0b57cec5SDimitry Andric 271*0b57cec5SDimitry Andric /// isIdenticalTo - Return true if this operand is identical to the specified 272*0b57cec5SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload 273*0b57cec5SDimitry Andric /// below. 274*0b57cec5SDimitry Andric bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 275*0b57cec5SDimitry Andric if (getType() != Other.getType() || 276*0b57cec5SDimitry Andric getTargetFlags() != Other.getTargetFlags()) 277*0b57cec5SDimitry Andric return false; 278*0b57cec5SDimitry Andric 279*0b57cec5SDimitry Andric switch (getType()) { 280*0b57cec5SDimitry Andric case MachineOperand::MO_Register: 281*0b57cec5SDimitry Andric return getReg() == Other.getReg() && isDef() == Other.isDef() && 282*0b57cec5SDimitry Andric getSubReg() == Other.getSubReg(); 283*0b57cec5SDimitry Andric case MachineOperand::MO_Immediate: 284*0b57cec5SDimitry Andric return getImm() == Other.getImm(); 285*0b57cec5SDimitry Andric case MachineOperand::MO_CImmediate: 286*0b57cec5SDimitry Andric return getCImm() == Other.getCImm(); 287*0b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate: 288*0b57cec5SDimitry Andric return getFPImm() == Other.getFPImm(); 289*0b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 290*0b57cec5SDimitry Andric return getMBB() == Other.getMBB(); 291*0b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: 292*0b57cec5SDimitry Andric return getIndex() == Other.getIndex(); 293*0b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 294*0b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: 295*0b57cec5SDimitry Andric return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 296*0b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex: 297*0b57cec5SDimitry Andric return getIndex() == Other.getIndex(); 298*0b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress: 299*0b57cec5SDimitry Andric return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 300*0b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: 301*0b57cec5SDimitry Andric return strcmp(getSymbolName(), Other.getSymbolName()) == 0 && 302*0b57cec5SDimitry Andric getOffset() == Other.getOffset(); 303*0b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress: 304*0b57cec5SDimitry Andric return getBlockAddress() == Other.getBlockAddress() && 305*0b57cec5SDimitry Andric getOffset() == Other.getOffset(); 306*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: 307*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: { 308*0b57cec5SDimitry Andric // Shallow compare of the two RegMasks 309*0b57cec5SDimitry Andric const uint32_t *RegMask = getRegMask(); 310*0b57cec5SDimitry Andric const uint32_t *OtherRegMask = Other.getRegMask(); 311*0b57cec5SDimitry Andric if (RegMask == OtherRegMask) 312*0b57cec5SDimitry Andric return true; 313*0b57cec5SDimitry Andric 314*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 315*0b57cec5SDimitry Andric // Calculate the size of the RegMask 316*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 317*0b57cec5SDimitry Andric unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32; 318*0b57cec5SDimitry Andric 319*0b57cec5SDimitry Andric // Deep compare of the two RegMasks 320*0b57cec5SDimitry Andric return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask); 321*0b57cec5SDimitry Andric } 322*0b57cec5SDimitry Andric // We don't know the size of the RegMask, so we can't deep compare the two 323*0b57cec5SDimitry Andric // reg masks. 324*0b57cec5SDimitry Andric return false; 325*0b57cec5SDimitry Andric } 326*0b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol: 327*0b57cec5SDimitry Andric return getMCSymbol() == Other.getMCSymbol(); 328*0b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: 329*0b57cec5SDimitry Andric return getCFIIndex() == Other.getCFIIndex(); 330*0b57cec5SDimitry Andric case MachineOperand::MO_Metadata: 331*0b57cec5SDimitry Andric return getMetadata() == Other.getMetadata(); 332*0b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: 333*0b57cec5SDimitry Andric return getIntrinsicID() == Other.getIntrinsicID(); 334*0b57cec5SDimitry Andric case MachineOperand::MO_Predicate: 335*0b57cec5SDimitry Andric return getPredicate() == Other.getPredicate(); 336*0b57cec5SDimitry Andric } 337*0b57cec5SDimitry Andric llvm_unreachable("Invalid machine operand type"); 338*0b57cec5SDimitry Andric } 339*0b57cec5SDimitry Andric 340*0b57cec5SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above. 341*0b57cec5SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) { 342*0b57cec5SDimitry Andric switch (MO.getType()) { 343*0b57cec5SDimitry Andric case MachineOperand::MO_Register: 344*0b57cec5SDimitry Andric // Register operands don't have target flags. 345*0b57cec5SDimitry Andric return hash_combine(MO.getType(), (unsigned)MO.getReg(), MO.getSubReg(), MO.isDef()); 346*0b57cec5SDimitry Andric case MachineOperand::MO_Immediate: 347*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 348*0b57cec5SDimitry Andric case MachineOperand::MO_CImmediate: 349*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 350*0b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate: 351*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 352*0b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 353*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 354*0b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: 355*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 356*0b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 357*0b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: 358*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 359*0b57cec5SDimitry Andric MO.getOffset()); 360*0b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex: 361*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 362*0b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: 363*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 364*0b57cec5SDimitry Andric StringRef(MO.getSymbolName())); 365*0b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress: 366*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 367*0b57cec5SDimitry Andric MO.getOffset()); 368*0b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress: 369*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(), 370*0b57cec5SDimitry Andric MO.getOffset()); 371*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: 372*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: 373*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); 374*0b57cec5SDimitry Andric case MachineOperand::MO_Metadata: 375*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 376*0b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol: 377*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 378*0b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: 379*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 380*0b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: 381*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); 382*0b57cec5SDimitry Andric case MachineOperand::MO_Predicate: 383*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); 384*0b57cec5SDimitry Andric } 385*0b57cec5SDimitry Andric llvm_unreachable("Invalid machine operand type"); 386*0b57cec5SDimitry Andric } 387*0b57cec5SDimitry Andric 388*0b57cec5SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from 389*0b57cec5SDimitry Andric // it. 390*0b57cec5SDimitry Andric static void tryToGetTargetInfo(const MachineOperand &MO, 391*0b57cec5SDimitry Andric const TargetRegisterInfo *&TRI, 392*0b57cec5SDimitry Andric const TargetIntrinsicInfo *&IntrinsicInfo) { 393*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(MO)) { 394*0b57cec5SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo(); 395*0b57cec5SDimitry Andric IntrinsicInfo = MF->getTarget().getIntrinsicInfo(); 396*0b57cec5SDimitry Andric } 397*0b57cec5SDimitry Andric } 398*0b57cec5SDimitry Andric 399*0b57cec5SDimitry Andric static const char *getTargetIndexName(const MachineFunction &MF, int Index) { 400*0b57cec5SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo(); 401*0b57cec5SDimitry Andric assert(TII && "expected instruction info"); 402*0b57cec5SDimitry Andric auto Indices = TII->getSerializableTargetIndices(); 403*0b57cec5SDimitry Andric auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) { 404*0b57cec5SDimitry Andric return I.first == Index; 405*0b57cec5SDimitry Andric }); 406*0b57cec5SDimitry Andric if (Found != Indices.end()) 407*0b57cec5SDimitry Andric return Found->second; 408*0b57cec5SDimitry Andric return nullptr; 409*0b57cec5SDimitry Andric } 410*0b57cec5SDimitry Andric 411*0b57cec5SDimitry Andric static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) { 412*0b57cec5SDimitry Andric auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 413*0b57cec5SDimitry Andric for (const auto &I : Flags) { 414*0b57cec5SDimitry Andric if (I.first == TF) { 415*0b57cec5SDimitry Andric return I.second; 416*0b57cec5SDimitry Andric } 417*0b57cec5SDimitry Andric } 418*0b57cec5SDimitry Andric return nullptr; 419*0b57cec5SDimitry Andric } 420*0b57cec5SDimitry Andric 421*0b57cec5SDimitry Andric static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 422*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 423*0b57cec5SDimitry Andric if (!TRI) { 424*0b57cec5SDimitry Andric OS << "%dwarfreg." << DwarfReg; 425*0b57cec5SDimitry Andric return; 426*0b57cec5SDimitry Andric } 427*0b57cec5SDimitry Andric 428*0b57cec5SDimitry Andric int Reg = TRI->getLLVMRegNum(DwarfReg, true); 429*0b57cec5SDimitry Andric if (Reg == -1) { 430*0b57cec5SDimitry Andric OS << "<badreg>"; 431*0b57cec5SDimitry Andric return; 432*0b57cec5SDimitry Andric } 433*0b57cec5SDimitry Andric OS << printReg(Reg, TRI); 434*0b57cec5SDimitry Andric } 435*0b57cec5SDimitry Andric 436*0b57cec5SDimitry Andric static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB, 437*0b57cec5SDimitry Andric ModuleSlotTracker &MST) { 438*0b57cec5SDimitry Andric OS << "%ir-block."; 439*0b57cec5SDimitry Andric if (BB.hasName()) { 440*0b57cec5SDimitry Andric printLLVMNameWithoutPrefix(OS, BB.getName()); 441*0b57cec5SDimitry Andric return; 442*0b57cec5SDimitry Andric } 443*0b57cec5SDimitry Andric Optional<int> Slot; 444*0b57cec5SDimitry Andric if (const Function *F = BB.getParent()) { 445*0b57cec5SDimitry Andric if (F == MST.getCurrentFunction()) { 446*0b57cec5SDimitry Andric Slot = MST.getLocalSlot(&BB); 447*0b57cec5SDimitry Andric } else if (const Module *M = F->getParent()) { 448*0b57cec5SDimitry Andric ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false); 449*0b57cec5SDimitry Andric CustomMST.incorporateFunction(*F); 450*0b57cec5SDimitry Andric Slot = CustomMST.getLocalSlot(&BB); 451*0b57cec5SDimitry Andric } 452*0b57cec5SDimitry Andric } 453*0b57cec5SDimitry Andric if (Slot) 454*0b57cec5SDimitry Andric MachineOperand::printIRSlotNumber(OS, *Slot); 455*0b57cec5SDimitry Andric else 456*0b57cec5SDimitry Andric OS << "<unknown>"; 457*0b57cec5SDimitry Andric } 458*0b57cec5SDimitry Andric 459*0b57cec5SDimitry Andric static void printIRValueReference(raw_ostream &OS, const Value &V, 460*0b57cec5SDimitry Andric ModuleSlotTracker &MST) { 461*0b57cec5SDimitry Andric if (isa<GlobalValue>(V)) { 462*0b57cec5SDimitry Andric V.printAsOperand(OS, /*PrintType=*/false, MST); 463*0b57cec5SDimitry Andric return; 464*0b57cec5SDimitry Andric } 465*0b57cec5SDimitry Andric if (isa<Constant>(V)) { 466*0b57cec5SDimitry Andric // Machine memory operands can load/store to/from constant value pointers. 467*0b57cec5SDimitry Andric OS << '`'; 468*0b57cec5SDimitry Andric V.printAsOperand(OS, /*PrintType=*/true, MST); 469*0b57cec5SDimitry Andric OS << '`'; 470*0b57cec5SDimitry Andric return; 471*0b57cec5SDimitry Andric } 472*0b57cec5SDimitry Andric OS << "%ir."; 473*0b57cec5SDimitry Andric if (V.hasName()) { 474*0b57cec5SDimitry Andric printLLVMNameWithoutPrefix(OS, V.getName()); 475*0b57cec5SDimitry Andric return; 476*0b57cec5SDimitry Andric } 477*0b57cec5SDimitry Andric int Slot = MST.getCurrentFunction() ? MST.getLocalSlot(&V) : -1; 478*0b57cec5SDimitry Andric MachineOperand::printIRSlotNumber(OS, Slot); 479*0b57cec5SDimitry Andric } 480*0b57cec5SDimitry Andric 481*0b57cec5SDimitry Andric static void printSyncScope(raw_ostream &OS, const LLVMContext &Context, 482*0b57cec5SDimitry Andric SyncScope::ID SSID, 483*0b57cec5SDimitry Andric SmallVectorImpl<StringRef> &SSNs) { 484*0b57cec5SDimitry Andric switch (SSID) { 485*0b57cec5SDimitry Andric case SyncScope::System: 486*0b57cec5SDimitry Andric break; 487*0b57cec5SDimitry Andric default: 488*0b57cec5SDimitry Andric if (SSNs.empty()) 489*0b57cec5SDimitry Andric Context.getSyncScopeNames(SSNs); 490*0b57cec5SDimitry Andric 491*0b57cec5SDimitry Andric OS << "syncscope(\""; 492*0b57cec5SDimitry Andric printEscapedString(SSNs[SSID], OS); 493*0b57cec5SDimitry Andric OS << "\") "; 494*0b57cec5SDimitry Andric break; 495*0b57cec5SDimitry Andric } 496*0b57cec5SDimitry Andric } 497*0b57cec5SDimitry Andric 498*0b57cec5SDimitry Andric static const char *getTargetMMOFlagName(const TargetInstrInfo &TII, 499*0b57cec5SDimitry Andric unsigned TMMOFlag) { 500*0b57cec5SDimitry Andric auto Flags = TII.getSerializableMachineMemOperandTargetFlags(); 501*0b57cec5SDimitry Andric for (const auto &I : Flags) { 502*0b57cec5SDimitry Andric if (I.first == TMMOFlag) { 503*0b57cec5SDimitry Andric return I.second; 504*0b57cec5SDimitry Andric } 505*0b57cec5SDimitry Andric } 506*0b57cec5SDimitry Andric return nullptr; 507*0b57cec5SDimitry Andric } 508*0b57cec5SDimitry Andric 509*0b57cec5SDimitry Andric static void printFrameIndex(raw_ostream& OS, int FrameIndex, bool IsFixed, 510*0b57cec5SDimitry Andric const MachineFrameInfo *MFI) { 511*0b57cec5SDimitry Andric StringRef Name; 512*0b57cec5SDimitry Andric if (MFI) { 513*0b57cec5SDimitry Andric IsFixed = MFI->isFixedObjectIndex(FrameIndex); 514*0b57cec5SDimitry Andric if (const AllocaInst *Alloca = MFI->getObjectAllocation(FrameIndex)) 515*0b57cec5SDimitry Andric if (Alloca->hasName()) 516*0b57cec5SDimitry Andric Name = Alloca->getName(); 517*0b57cec5SDimitry Andric if (IsFixed) 518*0b57cec5SDimitry Andric FrameIndex -= MFI->getObjectIndexBegin(); 519*0b57cec5SDimitry Andric } 520*0b57cec5SDimitry Andric MachineOperand::printStackObjectReference(OS, FrameIndex, IsFixed, Name); 521*0b57cec5SDimitry Andric } 522*0b57cec5SDimitry Andric 523*0b57cec5SDimitry Andric void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index, 524*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 525*0b57cec5SDimitry Andric OS << "%subreg."; 526*0b57cec5SDimitry Andric if (TRI) 527*0b57cec5SDimitry Andric OS << TRI->getSubRegIndexName(Index); 528*0b57cec5SDimitry Andric else 529*0b57cec5SDimitry Andric OS << Index; 530*0b57cec5SDimitry Andric } 531*0b57cec5SDimitry Andric 532*0b57cec5SDimitry Andric void MachineOperand::printTargetFlags(raw_ostream &OS, 533*0b57cec5SDimitry Andric const MachineOperand &Op) { 534*0b57cec5SDimitry Andric if (!Op.getTargetFlags()) 535*0b57cec5SDimitry Andric return; 536*0b57cec5SDimitry Andric const MachineFunction *MF = getMFIfAvailable(Op); 537*0b57cec5SDimitry Andric if (!MF) 538*0b57cec5SDimitry Andric return; 539*0b57cec5SDimitry Andric 540*0b57cec5SDimitry Andric const auto *TII = MF->getSubtarget().getInstrInfo(); 541*0b57cec5SDimitry Andric assert(TII && "expected instruction info"); 542*0b57cec5SDimitry Andric auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); 543*0b57cec5SDimitry Andric OS << "target-flags("; 544*0b57cec5SDimitry Andric const bool HasDirectFlags = Flags.first; 545*0b57cec5SDimitry Andric const bool HasBitmaskFlags = Flags.second; 546*0b57cec5SDimitry Andric if (!HasDirectFlags && !HasBitmaskFlags) { 547*0b57cec5SDimitry Andric OS << "<unknown>) "; 548*0b57cec5SDimitry Andric return; 549*0b57cec5SDimitry Andric } 550*0b57cec5SDimitry Andric if (HasDirectFlags) { 551*0b57cec5SDimitry Andric if (const auto *Name = getTargetFlagName(TII, Flags.first)) 552*0b57cec5SDimitry Andric OS << Name; 553*0b57cec5SDimitry Andric else 554*0b57cec5SDimitry Andric OS << "<unknown target flag>"; 555*0b57cec5SDimitry Andric } 556*0b57cec5SDimitry Andric if (!HasBitmaskFlags) { 557*0b57cec5SDimitry Andric OS << ") "; 558*0b57cec5SDimitry Andric return; 559*0b57cec5SDimitry Andric } 560*0b57cec5SDimitry Andric bool IsCommaNeeded = HasDirectFlags; 561*0b57cec5SDimitry Andric unsigned BitMask = Flags.second; 562*0b57cec5SDimitry Andric auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags(); 563*0b57cec5SDimitry Andric for (const auto &Mask : BitMasks) { 564*0b57cec5SDimitry Andric // Check if the flag's bitmask has the bits of the current mask set. 565*0b57cec5SDimitry Andric if ((BitMask & Mask.first) == Mask.first) { 566*0b57cec5SDimitry Andric if (IsCommaNeeded) 567*0b57cec5SDimitry Andric OS << ", "; 568*0b57cec5SDimitry Andric IsCommaNeeded = true; 569*0b57cec5SDimitry Andric OS << Mask.second; 570*0b57cec5SDimitry Andric // Clear the bits which were serialized from the flag's bitmask. 571*0b57cec5SDimitry Andric BitMask &= ~(Mask.first); 572*0b57cec5SDimitry Andric } 573*0b57cec5SDimitry Andric } 574*0b57cec5SDimitry Andric if (BitMask) { 575*0b57cec5SDimitry Andric // When the resulting flag's bitmask isn't zero, we know that we didn't 576*0b57cec5SDimitry Andric // serialize all of the bit flags. 577*0b57cec5SDimitry Andric if (IsCommaNeeded) 578*0b57cec5SDimitry Andric OS << ", "; 579*0b57cec5SDimitry Andric OS << "<unknown bitmask target flag>"; 580*0b57cec5SDimitry Andric } 581*0b57cec5SDimitry Andric OS << ") "; 582*0b57cec5SDimitry Andric } 583*0b57cec5SDimitry Andric 584*0b57cec5SDimitry Andric void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) { 585*0b57cec5SDimitry Andric OS << "<mcsymbol " << Sym << ">"; 586*0b57cec5SDimitry Andric } 587*0b57cec5SDimitry Andric 588*0b57cec5SDimitry Andric void MachineOperand::printStackObjectReference(raw_ostream &OS, 589*0b57cec5SDimitry Andric unsigned FrameIndex, 590*0b57cec5SDimitry Andric bool IsFixed, StringRef Name) { 591*0b57cec5SDimitry Andric if (IsFixed) { 592*0b57cec5SDimitry Andric OS << "%fixed-stack." << FrameIndex; 593*0b57cec5SDimitry Andric return; 594*0b57cec5SDimitry Andric } 595*0b57cec5SDimitry Andric 596*0b57cec5SDimitry Andric OS << "%stack." << FrameIndex; 597*0b57cec5SDimitry Andric if (!Name.empty()) 598*0b57cec5SDimitry Andric OS << '.' << Name; 599*0b57cec5SDimitry Andric } 600*0b57cec5SDimitry Andric 601*0b57cec5SDimitry Andric void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) { 602*0b57cec5SDimitry Andric if (Offset == 0) 603*0b57cec5SDimitry Andric return; 604*0b57cec5SDimitry Andric if (Offset < 0) { 605*0b57cec5SDimitry Andric OS << " - " << -Offset; 606*0b57cec5SDimitry Andric return; 607*0b57cec5SDimitry Andric } 608*0b57cec5SDimitry Andric OS << " + " << Offset; 609*0b57cec5SDimitry Andric } 610*0b57cec5SDimitry Andric 611*0b57cec5SDimitry Andric void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) { 612*0b57cec5SDimitry Andric if (Slot == -1) 613*0b57cec5SDimitry Andric OS << "<badref>"; 614*0b57cec5SDimitry Andric else 615*0b57cec5SDimitry Andric OS << Slot; 616*0b57cec5SDimitry Andric } 617*0b57cec5SDimitry Andric 618*0b57cec5SDimitry Andric static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI, 619*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 620*0b57cec5SDimitry Andric switch (CFI.getOperation()) { 621*0b57cec5SDimitry Andric case MCCFIInstruction::OpSameValue: 622*0b57cec5SDimitry Andric OS << "same_value "; 623*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 624*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 625*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 626*0b57cec5SDimitry Andric break; 627*0b57cec5SDimitry Andric case MCCFIInstruction::OpRememberState: 628*0b57cec5SDimitry Andric OS << "remember_state "; 629*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 630*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 631*0b57cec5SDimitry Andric break; 632*0b57cec5SDimitry Andric case MCCFIInstruction::OpRestoreState: 633*0b57cec5SDimitry Andric OS << "restore_state "; 634*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 635*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 636*0b57cec5SDimitry Andric break; 637*0b57cec5SDimitry Andric case MCCFIInstruction::OpOffset: 638*0b57cec5SDimitry Andric OS << "offset "; 639*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 640*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 641*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 642*0b57cec5SDimitry Andric OS << ", " << CFI.getOffset(); 643*0b57cec5SDimitry Andric break; 644*0b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfaRegister: 645*0b57cec5SDimitry Andric OS << "def_cfa_register "; 646*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 647*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 648*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 649*0b57cec5SDimitry Andric break; 650*0b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfaOffset: 651*0b57cec5SDimitry Andric OS << "def_cfa_offset "; 652*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 653*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 654*0b57cec5SDimitry Andric OS << CFI.getOffset(); 655*0b57cec5SDimitry Andric break; 656*0b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfa: 657*0b57cec5SDimitry Andric OS << "def_cfa "; 658*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 659*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 660*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 661*0b57cec5SDimitry Andric OS << ", " << CFI.getOffset(); 662*0b57cec5SDimitry Andric break; 663*0b57cec5SDimitry Andric case MCCFIInstruction::OpRelOffset: 664*0b57cec5SDimitry Andric OS << "rel_offset "; 665*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 666*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 667*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 668*0b57cec5SDimitry Andric OS << ", " << CFI.getOffset(); 669*0b57cec5SDimitry Andric break; 670*0b57cec5SDimitry Andric case MCCFIInstruction::OpAdjustCfaOffset: 671*0b57cec5SDimitry Andric OS << "adjust_cfa_offset "; 672*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 673*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 674*0b57cec5SDimitry Andric OS << CFI.getOffset(); 675*0b57cec5SDimitry Andric break; 676*0b57cec5SDimitry Andric case MCCFIInstruction::OpRestore: 677*0b57cec5SDimitry Andric OS << "restore "; 678*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 679*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 680*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 681*0b57cec5SDimitry Andric break; 682*0b57cec5SDimitry Andric case MCCFIInstruction::OpEscape: { 683*0b57cec5SDimitry Andric OS << "escape "; 684*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 685*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 686*0b57cec5SDimitry Andric if (!CFI.getValues().empty()) { 687*0b57cec5SDimitry Andric size_t e = CFI.getValues().size() - 1; 688*0b57cec5SDimitry Andric for (size_t i = 0; i < e; ++i) 689*0b57cec5SDimitry Andric OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", "; 690*0b57cec5SDimitry Andric OS << format("0x%02x", uint8_t(CFI.getValues()[e])) << ", "; 691*0b57cec5SDimitry Andric } 692*0b57cec5SDimitry Andric break; 693*0b57cec5SDimitry Andric } 694*0b57cec5SDimitry Andric case MCCFIInstruction::OpUndefined: 695*0b57cec5SDimitry Andric OS << "undefined "; 696*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 697*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 698*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 699*0b57cec5SDimitry Andric break; 700*0b57cec5SDimitry Andric case MCCFIInstruction::OpRegister: 701*0b57cec5SDimitry Andric OS << "register "; 702*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 703*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 704*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 705*0b57cec5SDimitry Andric OS << ", "; 706*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister2(), OS, TRI); 707*0b57cec5SDimitry Andric break; 708*0b57cec5SDimitry Andric case MCCFIInstruction::OpWindowSave: 709*0b57cec5SDimitry Andric OS << "window_save "; 710*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 711*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 712*0b57cec5SDimitry Andric break; 713*0b57cec5SDimitry Andric case MCCFIInstruction::OpNegateRAState: 714*0b57cec5SDimitry Andric OS << "negate_ra_sign_state "; 715*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 716*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 717*0b57cec5SDimitry Andric break; 718*0b57cec5SDimitry Andric default: 719*0b57cec5SDimitry Andric // TODO: Print the other CFI Operations. 720*0b57cec5SDimitry Andric OS << "<unserializable cfi directive>"; 721*0b57cec5SDimitry Andric break; 722*0b57cec5SDimitry Andric } 723*0b57cec5SDimitry Andric } 724*0b57cec5SDimitry Andric 725*0b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, 726*0b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 727*0b57cec5SDimitry Andric print(OS, LLT{}, TRI, IntrinsicInfo); 728*0b57cec5SDimitry Andric } 729*0b57cec5SDimitry Andric 730*0b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, LLT TypeToPrint, 731*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI, 732*0b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 733*0b57cec5SDimitry Andric tryToGetTargetInfo(*this, TRI, IntrinsicInfo); 734*0b57cec5SDimitry Andric ModuleSlotTracker DummyMST(nullptr); 735*0b57cec5SDimitry Andric print(OS, DummyMST, TypeToPrint, /*PrintDef=*/false, /*IsStandalone=*/true, 736*0b57cec5SDimitry Andric /*ShouldPrintRegisterTies=*/true, 737*0b57cec5SDimitry Andric /*TiedOperandIdx=*/0, TRI, IntrinsicInfo); 738*0b57cec5SDimitry Andric } 739*0b57cec5SDimitry Andric 740*0b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 741*0b57cec5SDimitry Andric LLT TypeToPrint, bool PrintDef, bool IsStandalone, 742*0b57cec5SDimitry Andric bool ShouldPrintRegisterTies, 743*0b57cec5SDimitry Andric unsigned TiedOperandIdx, 744*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI, 745*0b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 746*0b57cec5SDimitry Andric printTargetFlags(OS, *this); 747*0b57cec5SDimitry Andric switch (getType()) { 748*0b57cec5SDimitry Andric case MachineOperand::MO_Register: { 749*0b57cec5SDimitry Andric unsigned Reg = getReg(); 750*0b57cec5SDimitry Andric if (isImplicit()) 751*0b57cec5SDimitry Andric OS << (isDef() ? "implicit-def " : "implicit "); 752*0b57cec5SDimitry Andric else if (PrintDef && isDef()) 753*0b57cec5SDimitry Andric // Print the 'def' flag only when the operand is defined after '='. 754*0b57cec5SDimitry Andric OS << "def "; 755*0b57cec5SDimitry Andric if (isInternalRead()) 756*0b57cec5SDimitry Andric OS << "internal "; 757*0b57cec5SDimitry Andric if (isDead()) 758*0b57cec5SDimitry Andric OS << "dead "; 759*0b57cec5SDimitry Andric if (isKill()) 760*0b57cec5SDimitry Andric OS << "killed "; 761*0b57cec5SDimitry Andric if (isUndef()) 762*0b57cec5SDimitry Andric OS << "undef "; 763*0b57cec5SDimitry Andric if (isEarlyClobber()) 764*0b57cec5SDimitry Andric OS << "early-clobber "; 765*0b57cec5SDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(getReg()) && isRenamable()) 766*0b57cec5SDimitry Andric OS << "renamable "; 767*0b57cec5SDimitry Andric // isDebug() is exactly true for register operands of a DBG_VALUE. So we 768*0b57cec5SDimitry Andric // simply infer it when parsing and do not need to print it. 769*0b57cec5SDimitry Andric 770*0b57cec5SDimitry Andric const MachineRegisterInfo *MRI = nullptr; 771*0b57cec5SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(Reg)) { 772*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 773*0b57cec5SDimitry Andric MRI = &MF->getRegInfo(); 774*0b57cec5SDimitry Andric } 775*0b57cec5SDimitry Andric } 776*0b57cec5SDimitry Andric 777*0b57cec5SDimitry Andric OS << printReg(Reg, TRI, 0, MRI); 778*0b57cec5SDimitry Andric // Print the sub register. 779*0b57cec5SDimitry Andric if (unsigned SubReg = getSubReg()) { 780*0b57cec5SDimitry Andric if (TRI) 781*0b57cec5SDimitry Andric OS << '.' << TRI->getSubRegIndexName(SubReg); 782*0b57cec5SDimitry Andric else 783*0b57cec5SDimitry Andric OS << ".subreg" << SubReg; 784*0b57cec5SDimitry Andric } 785*0b57cec5SDimitry Andric // Print the register class / bank. 786*0b57cec5SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(Reg)) { 787*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 788*0b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF->getRegInfo(); 789*0b57cec5SDimitry Andric if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) { 790*0b57cec5SDimitry Andric OS << ':'; 791*0b57cec5SDimitry Andric OS << printRegClassOrBank(Reg, MRI, TRI); 792*0b57cec5SDimitry Andric } 793*0b57cec5SDimitry Andric } 794*0b57cec5SDimitry Andric } 795*0b57cec5SDimitry Andric // Print ties. 796*0b57cec5SDimitry Andric if (ShouldPrintRegisterTies && isTied() && !isDef()) 797*0b57cec5SDimitry Andric OS << "(tied-def " << TiedOperandIdx << ")"; 798*0b57cec5SDimitry Andric // Print types. 799*0b57cec5SDimitry Andric if (TypeToPrint.isValid()) 800*0b57cec5SDimitry Andric OS << '(' << TypeToPrint << ')'; 801*0b57cec5SDimitry Andric break; 802*0b57cec5SDimitry Andric } 803*0b57cec5SDimitry Andric case MachineOperand::MO_Immediate: 804*0b57cec5SDimitry Andric OS << getImm(); 805*0b57cec5SDimitry Andric break; 806*0b57cec5SDimitry Andric case MachineOperand::MO_CImmediate: 807*0b57cec5SDimitry Andric getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); 808*0b57cec5SDimitry Andric break; 809*0b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate: 810*0b57cec5SDimitry Andric getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); 811*0b57cec5SDimitry Andric break; 812*0b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 813*0b57cec5SDimitry Andric OS << printMBBReference(*getMBB()); 814*0b57cec5SDimitry Andric break; 815*0b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: { 816*0b57cec5SDimitry Andric int FrameIndex = getIndex(); 817*0b57cec5SDimitry Andric bool IsFixed = false; 818*0b57cec5SDimitry Andric const MachineFrameInfo *MFI = nullptr; 819*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) 820*0b57cec5SDimitry Andric MFI = &MF->getFrameInfo(); 821*0b57cec5SDimitry Andric printFrameIndex(OS, FrameIndex, IsFixed, MFI); 822*0b57cec5SDimitry Andric break; 823*0b57cec5SDimitry Andric } 824*0b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 825*0b57cec5SDimitry Andric OS << "%const." << getIndex(); 826*0b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 827*0b57cec5SDimitry Andric break; 828*0b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: { 829*0b57cec5SDimitry Andric OS << "target-index("; 830*0b57cec5SDimitry Andric const char *Name = "<unknown>"; 831*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) 832*0b57cec5SDimitry Andric if (const auto *TargetIndexName = getTargetIndexName(*MF, getIndex())) 833*0b57cec5SDimitry Andric Name = TargetIndexName; 834*0b57cec5SDimitry Andric OS << Name << ')'; 835*0b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 836*0b57cec5SDimitry Andric break; 837*0b57cec5SDimitry Andric } 838*0b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex: 839*0b57cec5SDimitry Andric OS << printJumpTableEntryReference(getIndex()); 840*0b57cec5SDimitry Andric break; 841*0b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress: 842*0b57cec5SDimitry Andric getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 843*0b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 844*0b57cec5SDimitry Andric break; 845*0b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: { 846*0b57cec5SDimitry Andric StringRef Name = getSymbolName(); 847*0b57cec5SDimitry Andric OS << '&'; 848*0b57cec5SDimitry Andric if (Name.empty()) { 849*0b57cec5SDimitry Andric OS << "\"\""; 850*0b57cec5SDimitry Andric } else { 851*0b57cec5SDimitry Andric printLLVMNameWithoutPrefix(OS, Name); 852*0b57cec5SDimitry Andric } 853*0b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 854*0b57cec5SDimitry Andric break; 855*0b57cec5SDimitry Andric } 856*0b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress: { 857*0b57cec5SDimitry Andric OS << "blockaddress("; 858*0b57cec5SDimitry Andric getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 859*0b57cec5SDimitry Andric MST); 860*0b57cec5SDimitry Andric OS << ", "; 861*0b57cec5SDimitry Andric printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST); 862*0b57cec5SDimitry Andric OS << ')'; 863*0b57cec5SDimitry Andric MachineOperand::printOperandOffset(OS, getOffset()); 864*0b57cec5SDimitry Andric break; 865*0b57cec5SDimitry Andric } 866*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: { 867*0b57cec5SDimitry Andric OS << "<regmask"; 868*0b57cec5SDimitry Andric if (TRI) { 869*0b57cec5SDimitry Andric unsigned NumRegsInMask = 0; 870*0b57cec5SDimitry Andric unsigned NumRegsEmitted = 0; 871*0b57cec5SDimitry Andric for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { 872*0b57cec5SDimitry Andric unsigned MaskWord = i / 32; 873*0b57cec5SDimitry Andric unsigned MaskBit = i % 32; 874*0b57cec5SDimitry Andric if (getRegMask()[MaskWord] & (1 << MaskBit)) { 875*0b57cec5SDimitry Andric if (PrintRegMaskNumRegs < 0 || 876*0b57cec5SDimitry Andric NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) { 877*0b57cec5SDimitry Andric OS << " " << printReg(i, TRI); 878*0b57cec5SDimitry Andric NumRegsEmitted++; 879*0b57cec5SDimitry Andric } 880*0b57cec5SDimitry Andric NumRegsInMask++; 881*0b57cec5SDimitry Andric } 882*0b57cec5SDimitry Andric } 883*0b57cec5SDimitry Andric if (NumRegsEmitted != NumRegsInMask) 884*0b57cec5SDimitry Andric OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; 885*0b57cec5SDimitry Andric } else { 886*0b57cec5SDimitry Andric OS << " ..."; 887*0b57cec5SDimitry Andric } 888*0b57cec5SDimitry Andric OS << ">"; 889*0b57cec5SDimitry Andric break; 890*0b57cec5SDimitry Andric } 891*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: { 892*0b57cec5SDimitry Andric const uint32_t *RegMask = getRegLiveOut(); 893*0b57cec5SDimitry Andric OS << "liveout("; 894*0b57cec5SDimitry Andric if (!TRI) { 895*0b57cec5SDimitry Andric OS << "<unknown>"; 896*0b57cec5SDimitry Andric } else { 897*0b57cec5SDimitry Andric bool IsCommaNeeded = false; 898*0b57cec5SDimitry Andric for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { 899*0b57cec5SDimitry Andric if (RegMask[Reg / 32] & (1U << (Reg % 32))) { 900*0b57cec5SDimitry Andric if (IsCommaNeeded) 901*0b57cec5SDimitry Andric OS << ", "; 902*0b57cec5SDimitry Andric OS << printReg(Reg, TRI); 903*0b57cec5SDimitry Andric IsCommaNeeded = true; 904*0b57cec5SDimitry Andric } 905*0b57cec5SDimitry Andric } 906*0b57cec5SDimitry Andric } 907*0b57cec5SDimitry Andric OS << ")"; 908*0b57cec5SDimitry Andric break; 909*0b57cec5SDimitry Andric } 910*0b57cec5SDimitry Andric case MachineOperand::MO_Metadata: 911*0b57cec5SDimitry Andric getMetadata()->printAsOperand(OS, MST); 912*0b57cec5SDimitry Andric break; 913*0b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol: 914*0b57cec5SDimitry Andric printSymbol(OS, *getMCSymbol()); 915*0b57cec5SDimitry Andric break; 916*0b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: { 917*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) 918*0b57cec5SDimitry Andric printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI); 919*0b57cec5SDimitry Andric else 920*0b57cec5SDimitry Andric OS << "<cfi directive>"; 921*0b57cec5SDimitry Andric break; 922*0b57cec5SDimitry Andric } 923*0b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: { 924*0b57cec5SDimitry Andric Intrinsic::ID ID = getIntrinsicID(); 925*0b57cec5SDimitry Andric if (ID < Intrinsic::num_intrinsics) 926*0b57cec5SDimitry Andric OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; 927*0b57cec5SDimitry Andric else if (IntrinsicInfo) 928*0b57cec5SDimitry Andric OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')'; 929*0b57cec5SDimitry Andric else 930*0b57cec5SDimitry Andric OS << "intrinsic(" << ID << ')'; 931*0b57cec5SDimitry Andric break; 932*0b57cec5SDimitry Andric } 933*0b57cec5SDimitry Andric case MachineOperand::MO_Predicate: { 934*0b57cec5SDimitry Andric auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); 935*0b57cec5SDimitry Andric OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" 936*0b57cec5SDimitry Andric << CmpInst::getPredicateName(Pred) << ')'; 937*0b57cec5SDimitry Andric break; 938*0b57cec5SDimitry Andric } 939*0b57cec5SDimitry Andric } 940*0b57cec5SDimitry Andric } 941*0b57cec5SDimitry Andric 942*0b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 943*0b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; } 944*0b57cec5SDimitry Andric #endif 945*0b57cec5SDimitry Andric 946*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 947*0b57cec5SDimitry Andric // MachineMemOperand Implementation 948*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 949*0b57cec5SDimitry Andric 950*0b57cec5SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer 951*0b57cec5SDimitry Andric /// points into. 952*0b57cec5SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; } 953*0b57cec5SDimitry Andric 954*0b57cec5SDimitry Andric /// isDereferenceable - Return true if V is always dereferenceable for 955*0b57cec5SDimitry Andric /// Offset + Size byte. 956*0b57cec5SDimitry Andric bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C, 957*0b57cec5SDimitry Andric const DataLayout &DL) const { 958*0b57cec5SDimitry Andric if (!V.is<const Value *>()) 959*0b57cec5SDimitry Andric return false; 960*0b57cec5SDimitry Andric 961*0b57cec5SDimitry Andric const Value *BasePtr = V.get<const Value *>(); 962*0b57cec5SDimitry Andric if (BasePtr == nullptr) 963*0b57cec5SDimitry Andric return false; 964*0b57cec5SDimitry Andric 965*0b57cec5SDimitry Andric return isDereferenceableAndAlignedPointer( 966*0b57cec5SDimitry Andric BasePtr, 1, APInt(DL.getPointerSizeInBits(), Offset + Size), DL); 967*0b57cec5SDimitry Andric } 968*0b57cec5SDimitry Andric 969*0b57cec5SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the 970*0b57cec5SDimitry Andric /// constant pool. 971*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { 972*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getConstantPool()); 973*0b57cec5SDimitry Andric } 974*0b57cec5SDimitry Andric 975*0b57cec5SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the 976*0b57cec5SDimitry Andric /// the specified FrameIndex. 977*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, 978*0b57cec5SDimitry Andric int FI, int64_t Offset) { 979*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); 980*0b57cec5SDimitry Andric } 981*0b57cec5SDimitry Andric 982*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { 983*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getJumpTable()); 984*0b57cec5SDimitry Andric } 985*0b57cec5SDimitry Andric 986*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { 987*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getGOT()); 988*0b57cec5SDimitry Andric } 989*0b57cec5SDimitry Andric 990*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, 991*0b57cec5SDimitry Andric int64_t Offset, uint8_t ID) { 992*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID); 993*0b57cec5SDimitry Andric } 994*0b57cec5SDimitry Andric 995*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) { 996*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace()); 997*0b57cec5SDimitry Andric } 998*0b57cec5SDimitry Andric 999*0b57cec5SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f, 1000*0b57cec5SDimitry Andric uint64_t s, uint64_t a, 1001*0b57cec5SDimitry Andric const AAMDNodes &AAInfo, 1002*0b57cec5SDimitry Andric const MDNode *Ranges, SyncScope::ID SSID, 1003*0b57cec5SDimitry Andric AtomicOrdering Ordering, 1004*0b57cec5SDimitry Andric AtomicOrdering FailureOrdering) 1005*0b57cec5SDimitry Andric : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1), 1006*0b57cec5SDimitry Andric AAInfo(AAInfo), Ranges(Ranges) { 1007*0b57cec5SDimitry Andric assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() || 1008*0b57cec5SDimitry Andric isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) && 1009*0b57cec5SDimitry Andric "invalid pointer value"); 1010*0b57cec5SDimitry Andric assert(getBaseAlignment() == a && a != 0 && "Alignment is not a power of 2!"); 1011*0b57cec5SDimitry Andric assert((isLoad() || isStore()) && "Not a load/store!"); 1012*0b57cec5SDimitry Andric 1013*0b57cec5SDimitry Andric AtomicInfo.SSID = static_cast<unsigned>(SSID); 1014*0b57cec5SDimitry Andric assert(getSyncScopeID() == SSID && "Value truncated"); 1015*0b57cec5SDimitry Andric AtomicInfo.Ordering = static_cast<unsigned>(Ordering); 1016*0b57cec5SDimitry Andric assert(getOrdering() == Ordering && "Value truncated"); 1017*0b57cec5SDimitry Andric AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering); 1018*0b57cec5SDimitry Andric assert(getFailureOrdering() == FailureOrdering && "Value truncated"); 1019*0b57cec5SDimitry Andric } 1020*0b57cec5SDimitry Andric 1021*0b57cec5SDimitry Andric /// Profile - Gather unique data for the object. 1022*0b57cec5SDimitry Andric /// 1023*0b57cec5SDimitry Andric void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 1024*0b57cec5SDimitry Andric ID.AddInteger(getOffset()); 1025*0b57cec5SDimitry Andric ID.AddInteger(Size); 1026*0b57cec5SDimitry Andric ID.AddPointer(getOpaqueValue()); 1027*0b57cec5SDimitry Andric ID.AddInteger(getFlags()); 1028*0b57cec5SDimitry Andric ID.AddInteger(getBaseAlignment()); 1029*0b57cec5SDimitry Andric } 1030*0b57cec5SDimitry Andric 1031*0b57cec5SDimitry Andric void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 1032*0b57cec5SDimitry Andric // The Value and Offset may differ due to CSE. But the flags and size 1033*0b57cec5SDimitry Andric // should be the same. 1034*0b57cec5SDimitry Andric assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 1035*0b57cec5SDimitry Andric assert(MMO->getSize() == getSize() && "Size mismatch!"); 1036*0b57cec5SDimitry Andric 1037*0b57cec5SDimitry Andric if (MMO->getBaseAlignment() >= getBaseAlignment()) { 1038*0b57cec5SDimitry Andric // Update the alignment value. 1039*0b57cec5SDimitry Andric BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1; 1040*0b57cec5SDimitry Andric // Also update the base and offset, because the new alignment may 1041*0b57cec5SDimitry Andric // not be applicable with the old ones. 1042*0b57cec5SDimitry Andric PtrInfo = MMO->PtrInfo; 1043*0b57cec5SDimitry Andric } 1044*0b57cec5SDimitry Andric } 1045*0b57cec5SDimitry Andric 1046*0b57cec5SDimitry Andric /// getAlignment - Return the minimum known alignment in bytes of the 1047*0b57cec5SDimitry Andric /// actual memory reference. 1048*0b57cec5SDimitry Andric uint64_t MachineMemOperand::getAlignment() const { 1049*0b57cec5SDimitry Andric return MinAlign(getBaseAlignment(), getOffset()); 1050*0b57cec5SDimitry Andric } 1051*0b57cec5SDimitry Andric 1052*0b57cec5SDimitry Andric void MachineMemOperand::print(raw_ostream &OS) const { 1053*0b57cec5SDimitry Andric ModuleSlotTracker DummyMST(nullptr); 1054*0b57cec5SDimitry Andric print(OS, DummyMST); 1055*0b57cec5SDimitry Andric } 1056*0b57cec5SDimitry Andric 1057*0b57cec5SDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const { 1058*0b57cec5SDimitry Andric SmallVector<StringRef, 0> SSNs; 1059*0b57cec5SDimitry Andric LLVMContext Ctx; 1060*0b57cec5SDimitry Andric print(OS, MST, SSNs, Ctx, nullptr, nullptr); 1061*0b57cec5SDimitry Andric } 1062*0b57cec5SDimitry Andric 1063*0b57cec5SDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 1064*0b57cec5SDimitry Andric SmallVectorImpl<StringRef> &SSNs, 1065*0b57cec5SDimitry Andric const LLVMContext &Context, 1066*0b57cec5SDimitry Andric const MachineFrameInfo *MFI, 1067*0b57cec5SDimitry Andric const TargetInstrInfo *TII) const { 1068*0b57cec5SDimitry Andric OS << '('; 1069*0b57cec5SDimitry Andric if (isVolatile()) 1070*0b57cec5SDimitry Andric OS << "volatile "; 1071*0b57cec5SDimitry Andric if (isNonTemporal()) 1072*0b57cec5SDimitry Andric OS << "non-temporal "; 1073*0b57cec5SDimitry Andric if (isDereferenceable()) 1074*0b57cec5SDimitry Andric OS << "dereferenceable "; 1075*0b57cec5SDimitry Andric if (isInvariant()) 1076*0b57cec5SDimitry Andric OS << "invariant "; 1077*0b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag1) 1078*0b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag1) 1079*0b57cec5SDimitry Andric << "\" "; 1080*0b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag2) 1081*0b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag2) 1082*0b57cec5SDimitry Andric << "\" "; 1083*0b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag3) 1084*0b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag3) 1085*0b57cec5SDimitry Andric << "\" "; 1086*0b57cec5SDimitry Andric 1087*0b57cec5SDimitry Andric assert((isLoad() || isStore()) && 1088*0b57cec5SDimitry Andric "machine memory operand must be a load or store (or both)"); 1089*0b57cec5SDimitry Andric if (isLoad()) 1090*0b57cec5SDimitry Andric OS << "load "; 1091*0b57cec5SDimitry Andric if (isStore()) 1092*0b57cec5SDimitry Andric OS << "store "; 1093*0b57cec5SDimitry Andric 1094*0b57cec5SDimitry Andric printSyncScope(OS, Context, getSyncScopeID(), SSNs); 1095*0b57cec5SDimitry Andric 1096*0b57cec5SDimitry Andric if (getOrdering() != AtomicOrdering::NotAtomic) 1097*0b57cec5SDimitry Andric OS << toIRString(getOrdering()) << ' '; 1098*0b57cec5SDimitry Andric if (getFailureOrdering() != AtomicOrdering::NotAtomic) 1099*0b57cec5SDimitry Andric OS << toIRString(getFailureOrdering()) << ' '; 1100*0b57cec5SDimitry Andric 1101*0b57cec5SDimitry Andric if (getSize() == MemoryLocation::UnknownSize) 1102*0b57cec5SDimitry Andric OS << "unknown-size"; 1103*0b57cec5SDimitry Andric else 1104*0b57cec5SDimitry Andric OS << getSize(); 1105*0b57cec5SDimitry Andric 1106*0b57cec5SDimitry Andric if (const Value *Val = getValue()) { 1107*0b57cec5SDimitry Andric OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into "); 1108*0b57cec5SDimitry Andric printIRValueReference(OS, *Val, MST); 1109*0b57cec5SDimitry Andric } else if (const PseudoSourceValue *PVal = getPseudoValue()) { 1110*0b57cec5SDimitry Andric OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into "); 1111*0b57cec5SDimitry Andric assert(PVal && "Expected a pseudo source value"); 1112*0b57cec5SDimitry Andric switch (PVal->kind()) { 1113*0b57cec5SDimitry Andric case PseudoSourceValue::Stack: 1114*0b57cec5SDimitry Andric OS << "stack"; 1115*0b57cec5SDimitry Andric break; 1116*0b57cec5SDimitry Andric case PseudoSourceValue::GOT: 1117*0b57cec5SDimitry Andric OS << "got"; 1118*0b57cec5SDimitry Andric break; 1119*0b57cec5SDimitry Andric case PseudoSourceValue::JumpTable: 1120*0b57cec5SDimitry Andric OS << "jump-table"; 1121*0b57cec5SDimitry Andric break; 1122*0b57cec5SDimitry Andric case PseudoSourceValue::ConstantPool: 1123*0b57cec5SDimitry Andric OS << "constant-pool"; 1124*0b57cec5SDimitry Andric break; 1125*0b57cec5SDimitry Andric case PseudoSourceValue::FixedStack: { 1126*0b57cec5SDimitry Andric int FrameIndex = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex(); 1127*0b57cec5SDimitry Andric bool IsFixed = true; 1128*0b57cec5SDimitry Andric printFrameIndex(OS, FrameIndex, IsFixed, MFI); 1129*0b57cec5SDimitry Andric break; 1130*0b57cec5SDimitry Andric } 1131*0b57cec5SDimitry Andric case PseudoSourceValue::GlobalValueCallEntry: 1132*0b57cec5SDimitry Andric OS << "call-entry "; 1133*0b57cec5SDimitry Andric cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand( 1134*0b57cec5SDimitry Andric OS, /*PrintType=*/false, MST); 1135*0b57cec5SDimitry Andric break; 1136*0b57cec5SDimitry Andric case PseudoSourceValue::ExternalSymbolCallEntry: 1137*0b57cec5SDimitry Andric OS << "call-entry &"; 1138*0b57cec5SDimitry Andric printLLVMNameWithoutPrefix( 1139*0b57cec5SDimitry Andric OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol()); 1140*0b57cec5SDimitry Andric break; 1141*0b57cec5SDimitry Andric default: 1142*0b57cec5SDimitry Andric // FIXME: This is not necessarily the correct MIR serialization format for 1143*0b57cec5SDimitry Andric // a custom pseudo source value, but at least it allows 1144*0b57cec5SDimitry Andric // -print-machineinstrs to work on a target with custom pseudo source 1145*0b57cec5SDimitry Andric // values. 1146*0b57cec5SDimitry Andric OS << "custom "; 1147*0b57cec5SDimitry Andric PVal->printCustom(OS); 1148*0b57cec5SDimitry Andric break; 1149*0b57cec5SDimitry Andric } 1150*0b57cec5SDimitry Andric } 1151*0b57cec5SDimitry Andric MachineOperand::printOperandOffset(OS, getOffset()); 1152*0b57cec5SDimitry Andric if (getBaseAlignment() != getSize()) 1153*0b57cec5SDimitry Andric OS << ", align " << getBaseAlignment(); 1154*0b57cec5SDimitry Andric auto AAInfo = getAAInfo(); 1155*0b57cec5SDimitry Andric if (AAInfo.TBAA) { 1156*0b57cec5SDimitry Andric OS << ", !tbaa "; 1157*0b57cec5SDimitry Andric AAInfo.TBAA->printAsOperand(OS, MST); 1158*0b57cec5SDimitry Andric } 1159*0b57cec5SDimitry Andric if (AAInfo.Scope) { 1160*0b57cec5SDimitry Andric OS << ", !alias.scope "; 1161*0b57cec5SDimitry Andric AAInfo.Scope->printAsOperand(OS, MST); 1162*0b57cec5SDimitry Andric } 1163*0b57cec5SDimitry Andric if (AAInfo.NoAlias) { 1164*0b57cec5SDimitry Andric OS << ", !noalias "; 1165*0b57cec5SDimitry Andric AAInfo.NoAlias->printAsOperand(OS, MST); 1166*0b57cec5SDimitry Andric } 1167*0b57cec5SDimitry Andric if (getRanges()) { 1168*0b57cec5SDimitry Andric OS << ", !range "; 1169*0b57cec5SDimitry Andric getRanges()->printAsOperand(OS, MST); 1170*0b57cec5SDimitry Andric } 1171*0b57cec5SDimitry Andric // FIXME: Implement addrspace printing/parsing in MIR. 1172*0b57cec5SDimitry Andric // For now, print this even though parsing it is not available in MIR. 1173*0b57cec5SDimitry Andric if (unsigned AS = getAddrSpace()) 1174*0b57cec5SDimitry Andric OS << ", addrspace " << AS; 1175*0b57cec5SDimitry Andric 1176*0b57cec5SDimitry Andric OS << ')'; 1177*0b57cec5SDimitry Andric } 1178