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