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) { 88e8d8bef9SDimitry Andric assert(Register::isPhysicalRegister(Reg)); 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. 156e8d8bef9SDimitry Andric void MachineOperand::ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags) { 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; 163e8d8bef9SDimitry Andric setTargetFlags(TargetFlags); 164*0b57cec5SDimitry Andric } 165*0b57cec5SDimitry Andric 166e8d8bef9SDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm, 167e8d8bef9SDimitry Andric unsigned TargetFlags) { 168*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric removeRegFromUses(); 171*0b57cec5SDimitry Andric 172*0b57cec5SDimitry Andric OpKind = MO_FPImmediate; 173*0b57cec5SDimitry Andric Contents.CFP = FPImm; 174e8d8bef9SDimitry Andric setTargetFlags(TargetFlags); 175*0b57cec5SDimitry Andric } 176*0b57cec5SDimitry Andric 177*0b57cec5SDimitry Andric void MachineOperand::ChangeToES(const char *SymName, 1788bcb0991SDimitry Andric unsigned TargetFlags) { 179*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 180*0b57cec5SDimitry Andric "Cannot change a tied operand into an external symbol"); 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andric removeRegFromUses(); 183*0b57cec5SDimitry Andric 184*0b57cec5SDimitry Andric OpKind = MO_ExternalSymbol; 185*0b57cec5SDimitry Andric Contents.OffsetedInfo.Val.SymbolName = SymName; 186*0b57cec5SDimitry Andric setOffset(0); // Offset is always 0. 187*0b57cec5SDimitry Andric setTargetFlags(TargetFlags); 188*0b57cec5SDimitry Andric } 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric void MachineOperand::ChangeToGA(const GlobalValue *GV, int64_t Offset, 1918bcb0991SDimitry Andric unsigned TargetFlags) { 192*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 193*0b57cec5SDimitry Andric "Cannot change a tied operand into a global address"); 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric removeRegFromUses(); 196*0b57cec5SDimitry Andric 197*0b57cec5SDimitry Andric OpKind = MO_GlobalAddress; 198*0b57cec5SDimitry Andric Contents.OffsetedInfo.Val.GV = GV; 199*0b57cec5SDimitry Andric setOffset(Offset); 200*0b57cec5SDimitry Andric setTargetFlags(TargetFlags); 201*0b57cec5SDimitry Andric } 202*0b57cec5SDimitry Andric 203e8d8bef9SDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags) { 204*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 205*0b57cec5SDimitry Andric "Cannot change a tied operand into an MCSymbol"); 206*0b57cec5SDimitry Andric 207*0b57cec5SDimitry Andric removeRegFromUses(); 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric OpKind = MO_MCSymbol; 210*0b57cec5SDimitry Andric Contents.Sym = Sym; 211e8d8bef9SDimitry Andric setTargetFlags(TargetFlags); 212*0b57cec5SDimitry Andric } 213*0b57cec5SDimitry Andric 214e8d8bef9SDimitry Andric void MachineOperand::ChangeToFrameIndex(int Idx, unsigned TargetFlags) { 215*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 216*0b57cec5SDimitry Andric "Cannot change a tied operand into a FrameIndex"); 217*0b57cec5SDimitry Andric 218*0b57cec5SDimitry Andric removeRegFromUses(); 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric OpKind = MO_FrameIndex; 221*0b57cec5SDimitry Andric setIndex(Idx); 222e8d8bef9SDimitry Andric setTargetFlags(TargetFlags); 223*0b57cec5SDimitry Andric } 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset, 2268bcb0991SDimitry Andric unsigned TargetFlags) { 227*0b57cec5SDimitry Andric assert((!isReg() || !isTied()) && 228*0b57cec5SDimitry Andric "Cannot change a tied operand into a FrameIndex"); 229*0b57cec5SDimitry Andric 230*0b57cec5SDimitry Andric removeRegFromUses(); 231*0b57cec5SDimitry Andric 232*0b57cec5SDimitry Andric OpKind = MO_TargetIndex; 233*0b57cec5SDimitry Andric setIndex(Idx); 234*0b57cec5SDimitry Andric setOffset(Offset); 235*0b57cec5SDimitry Andric setTargetFlags(TargetFlags); 236*0b57cec5SDimitry Andric } 237*0b57cec5SDimitry Andric 238*0b57cec5SDimitry Andric /// ChangeToRegister - Replace this operand with a new register operand of 239*0b57cec5SDimitry Andric /// the specified value. If an operand is known to be an register already, 240*0b57cec5SDimitry Andric /// the setReg method should be used. 2418bcb0991SDimitry Andric void MachineOperand::ChangeToRegister(Register Reg, bool isDef, bool isImp, 242*0b57cec5SDimitry Andric bool isKill, bool isDead, bool isUndef, 243*0b57cec5SDimitry Andric bool isDebug) { 244*0b57cec5SDimitry Andric MachineRegisterInfo *RegInfo = nullptr; 245*0b57cec5SDimitry Andric if (MachineFunction *MF = getMFIfAvailable(*this)) 246*0b57cec5SDimitry Andric RegInfo = &MF->getRegInfo(); 247*0b57cec5SDimitry Andric // If this operand is already a register operand, remove it from the 248*0b57cec5SDimitry Andric // register's use/def lists. 249*0b57cec5SDimitry Andric bool WasReg = isReg(); 250*0b57cec5SDimitry Andric if (RegInfo && WasReg) 251*0b57cec5SDimitry Andric RegInfo->removeRegOperandFromUseList(this); 252*0b57cec5SDimitry Andric 253*0b57cec5SDimitry Andric // Change this to a register and set the reg#. 254*0b57cec5SDimitry Andric assert(!(isDead && !isDef) && "Dead flag on non-def"); 255*0b57cec5SDimitry Andric assert(!(isKill && isDef) && "Kill flag on def"); 256*0b57cec5SDimitry Andric OpKind = MO_Register; 257*0b57cec5SDimitry Andric SmallContents.RegNo = Reg; 258*0b57cec5SDimitry Andric SubReg_TargetFlags = 0; 259*0b57cec5SDimitry Andric IsDef = isDef; 260*0b57cec5SDimitry Andric IsImp = isImp; 261*0b57cec5SDimitry Andric IsDeadOrKill = isKill | isDead; 262*0b57cec5SDimitry Andric IsRenamable = false; 263*0b57cec5SDimitry Andric IsUndef = isUndef; 264*0b57cec5SDimitry Andric IsInternalRead = false; 265*0b57cec5SDimitry Andric IsEarlyClobber = false; 266*0b57cec5SDimitry Andric IsDebug = isDebug; 267*0b57cec5SDimitry Andric // Ensure isOnRegUseList() returns false. 268*0b57cec5SDimitry Andric Contents.Reg.Prev = nullptr; 269*0b57cec5SDimitry Andric // Preserve the tie when the operand was already a register. 270*0b57cec5SDimitry Andric if (!WasReg) 271*0b57cec5SDimitry Andric TiedTo = 0; 272*0b57cec5SDimitry Andric 273*0b57cec5SDimitry Andric // If this operand is embedded in a function, add the operand to the 274*0b57cec5SDimitry Andric // register's use/def list. 275*0b57cec5SDimitry Andric if (RegInfo) 276*0b57cec5SDimitry Andric RegInfo->addRegOperandToUseList(this); 277*0b57cec5SDimitry Andric } 278*0b57cec5SDimitry Andric 279*0b57cec5SDimitry Andric /// isIdenticalTo - Return true if this operand is identical to the specified 280*0b57cec5SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload 281*0b57cec5SDimitry Andric /// below. 282*0b57cec5SDimitry Andric bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 283*0b57cec5SDimitry Andric if (getType() != Other.getType() || 284*0b57cec5SDimitry Andric getTargetFlags() != Other.getTargetFlags()) 285*0b57cec5SDimitry Andric return false; 286*0b57cec5SDimitry Andric 287*0b57cec5SDimitry Andric switch (getType()) { 288*0b57cec5SDimitry Andric case MachineOperand::MO_Register: 289*0b57cec5SDimitry Andric return getReg() == Other.getReg() && isDef() == Other.isDef() && 290*0b57cec5SDimitry Andric getSubReg() == Other.getSubReg(); 291*0b57cec5SDimitry Andric case MachineOperand::MO_Immediate: 292*0b57cec5SDimitry Andric return getImm() == Other.getImm(); 293*0b57cec5SDimitry Andric case MachineOperand::MO_CImmediate: 294*0b57cec5SDimitry Andric return getCImm() == Other.getCImm(); 295*0b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate: 296*0b57cec5SDimitry Andric return getFPImm() == Other.getFPImm(); 297*0b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 298*0b57cec5SDimitry Andric return getMBB() == Other.getMBB(); 299*0b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: 300*0b57cec5SDimitry Andric return getIndex() == Other.getIndex(); 301*0b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 302*0b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: 303*0b57cec5SDimitry Andric return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 304*0b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex: 305*0b57cec5SDimitry Andric return getIndex() == Other.getIndex(); 306*0b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress: 307*0b57cec5SDimitry Andric return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 308*0b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: 309*0b57cec5SDimitry Andric return strcmp(getSymbolName(), Other.getSymbolName()) == 0 && 310*0b57cec5SDimitry Andric getOffset() == Other.getOffset(); 311*0b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress: 312*0b57cec5SDimitry Andric return getBlockAddress() == Other.getBlockAddress() && 313*0b57cec5SDimitry Andric getOffset() == Other.getOffset(); 314*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: 315*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: { 316*0b57cec5SDimitry Andric // Shallow compare of the two RegMasks 317*0b57cec5SDimitry Andric const uint32_t *RegMask = getRegMask(); 318*0b57cec5SDimitry Andric const uint32_t *OtherRegMask = Other.getRegMask(); 319*0b57cec5SDimitry Andric if (RegMask == OtherRegMask) 320*0b57cec5SDimitry Andric return true; 321*0b57cec5SDimitry Andric 322*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 323*0b57cec5SDimitry Andric // Calculate the size of the RegMask 324*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 325*0b57cec5SDimitry Andric unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32; 326*0b57cec5SDimitry Andric 327*0b57cec5SDimitry Andric // Deep compare of the two RegMasks 328*0b57cec5SDimitry Andric return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask); 329*0b57cec5SDimitry Andric } 330*0b57cec5SDimitry Andric // We don't know the size of the RegMask, so we can't deep compare the two 331*0b57cec5SDimitry Andric // reg masks. 332*0b57cec5SDimitry Andric return false; 333*0b57cec5SDimitry Andric } 334*0b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol: 335*0b57cec5SDimitry Andric return getMCSymbol() == Other.getMCSymbol(); 336*0b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: 337*0b57cec5SDimitry Andric return getCFIIndex() == Other.getCFIIndex(); 338*0b57cec5SDimitry Andric case MachineOperand::MO_Metadata: 339*0b57cec5SDimitry Andric return getMetadata() == Other.getMetadata(); 340*0b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: 341*0b57cec5SDimitry Andric return getIntrinsicID() == Other.getIntrinsicID(); 342*0b57cec5SDimitry Andric case MachineOperand::MO_Predicate: 343*0b57cec5SDimitry Andric return getPredicate() == Other.getPredicate(); 3448bcb0991SDimitry Andric case MachineOperand::MO_ShuffleMask: 3458bcb0991SDimitry Andric return getShuffleMask() == Other.getShuffleMask(); 346*0b57cec5SDimitry Andric } 347*0b57cec5SDimitry Andric llvm_unreachable("Invalid machine operand type"); 348*0b57cec5SDimitry Andric } 349*0b57cec5SDimitry Andric 350*0b57cec5SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above. 351*0b57cec5SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) { 352*0b57cec5SDimitry Andric switch (MO.getType()) { 353*0b57cec5SDimitry Andric case MachineOperand::MO_Register: 354*0b57cec5SDimitry Andric // Register operands don't have target flags. 355*0b57cec5SDimitry Andric return hash_combine(MO.getType(), (unsigned)MO.getReg(), MO.getSubReg(), MO.isDef()); 356*0b57cec5SDimitry Andric case MachineOperand::MO_Immediate: 357*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 358*0b57cec5SDimitry Andric case MachineOperand::MO_CImmediate: 359*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 360*0b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate: 361*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 362*0b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 363*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 364*0b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: 365*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 366*0b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 367*0b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: 368*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 369*0b57cec5SDimitry Andric MO.getOffset()); 370*0b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex: 371*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 372*0b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: 373*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 374*0b57cec5SDimitry Andric StringRef(MO.getSymbolName())); 375*0b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress: 376*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 377*0b57cec5SDimitry Andric MO.getOffset()); 378*0b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress: 379*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(), 380*0b57cec5SDimitry Andric MO.getOffset()); 381*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: 382*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: 383*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); 384*0b57cec5SDimitry Andric case MachineOperand::MO_Metadata: 385*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 386*0b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol: 387*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 388*0b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: 389*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 390*0b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: 391*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); 392*0b57cec5SDimitry Andric case MachineOperand::MO_Predicate: 393*0b57cec5SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); 3948bcb0991SDimitry Andric case MachineOperand::MO_ShuffleMask: 3958bcb0991SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getShuffleMask()); 396*0b57cec5SDimitry Andric } 397*0b57cec5SDimitry Andric llvm_unreachable("Invalid machine operand type"); 398*0b57cec5SDimitry Andric } 399*0b57cec5SDimitry Andric 400*0b57cec5SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from 401*0b57cec5SDimitry Andric // it. 402*0b57cec5SDimitry Andric static void tryToGetTargetInfo(const MachineOperand &MO, 403*0b57cec5SDimitry Andric const TargetRegisterInfo *&TRI, 404*0b57cec5SDimitry Andric const TargetIntrinsicInfo *&IntrinsicInfo) { 405*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(MO)) { 406*0b57cec5SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo(); 407*0b57cec5SDimitry Andric IntrinsicInfo = MF->getTarget().getIntrinsicInfo(); 408*0b57cec5SDimitry Andric } 409*0b57cec5SDimitry Andric } 410*0b57cec5SDimitry Andric 411*0b57cec5SDimitry Andric static const char *getTargetIndexName(const MachineFunction &MF, int Index) { 412*0b57cec5SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo(); 413*0b57cec5SDimitry Andric assert(TII && "expected instruction info"); 414*0b57cec5SDimitry Andric auto Indices = TII->getSerializableTargetIndices(); 415*0b57cec5SDimitry Andric auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) { 416*0b57cec5SDimitry Andric return I.first == Index; 417*0b57cec5SDimitry Andric }); 418*0b57cec5SDimitry Andric if (Found != Indices.end()) 419*0b57cec5SDimitry Andric return Found->second; 420*0b57cec5SDimitry Andric return nullptr; 421*0b57cec5SDimitry Andric } 422*0b57cec5SDimitry Andric 423e8d8bef9SDimitry Andric const char *MachineOperand::getTargetIndexName() const { 424e8d8bef9SDimitry Andric const MachineFunction *MF = getMFIfAvailable(*this); 425e8d8bef9SDimitry Andric return MF ? ::getTargetIndexName(*MF, this->getIndex()) : nullptr; 426e8d8bef9SDimitry Andric } 427e8d8bef9SDimitry Andric 428*0b57cec5SDimitry Andric static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) { 429*0b57cec5SDimitry Andric auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 430*0b57cec5SDimitry Andric for (const auto &I : Flags) { 431*0b57cec5SDimitry Andric if (I.first == TF) { 432*0b57cec5SDimitry Andric return I.second; 433*0b57cec5SDimitry Andric } 434*0b57cec5SDimitry Andric } 435*0b57cec5SDimitry Andric return nullptr; 436*0b57cec5SDimitry Andric } 437*0b57cec5SDimitry Andric 438*0b57cec5SDimitry Andric static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 439*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 440*0b57cec5SDimitry Andric if (!TRI) { 441*0b57cec5SDimitry Andric OS << "%dwarfreg." << DwarfReg; 442*0b57cec5SDimitry Andric return; 443*0b57cec5SDimitry Andric } 444*0b57cec5SDimitry Andric 4458bcb0991SDimitry Andric if (Optional<unsigned> Reg = TRI->getLLVMRegNum(DwarfReg, true)) 4468bcb0991SDimitry Andric OS << printReg(*Reg, TRI); 4478bcb0991SDimitry Andric else 448*0b57cec5SDimitry Andric OS << "<badreg>"; 449*0b57cec5SDimitry Andric } 450*0b57cec5SDimitry Andric 451*0b57cec5SDimitry Andric static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB, 452*0b57cec5SDimitry Andric ModuleSlotTracker &MST) { 453*0b57cec5SDimitry Andric OS << "%ir-block."; 454*0b57cec5SDimitry Andric if (BB.hasName()) { 455*0b57cec5SDimitry Andric printLLVMNameWithoutPrefix(OS, BB.getName()); 456*0b57cec5SDimitry Andric return; 457*0b57cec5SDimitry Andric } 458*0b57cec5SDimitry Andric Optional<int> Slot; 459*0b57cec5SDimitry Andric if (const Function *F = BB.getParent()) { 460*0b57cec5SDimitry Andric if (F == MST.getCurrentFunction()) { 461*0b57cec5SDimitry Andric Slot = MST.getLocalSlot(&BB); 462*0b57cec5SDimitry Andric } else if (const Module *M = F->getParent()) { 463*0b57cec5SDimitry Andric ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false); 464*0b57cec5SDimitry Andric CustomMST.incorporateFunction(*F); 465*0b57cec5SDimitry Andric Slot = CustomMST.getLocalSlot(&BB); 466*0b57cec5SDimitry Andric } 467*0b57cec5SDimitry Andric } 468*0b57cec5SDimitry Andric if (Slot) 469*0b57cec5SDimitry Andric MachineOperand::printIRSlotNumber(OS, *Slot); 470*0b57cec5SDimitry Andric else 471*0b57cec5SDimitry Andric OS << "<unknown>"; 472*0b57cec5SDimitry Andric } 473*0b57cec5SDimitry Andric 474*0b57cec5SDimitry Andric static void printSyncScope(raw_ostream &OS, const LLVMContext &Context, 475*0b57cec5SDimitry Andric SyncScope::ID SSID, 476*0b57cec5SDimitry Andric SmallVectorImpl<StringRef> &SSNs) { 477*0b57cec5SDimitry Andric switch (SSID) { 478*0b57cec5SDimitry Andric case SyncScope::System: 479*0b57cec5SDimitry Andric break; 480*0b57cec5SDimitry Andric default: 481*0b57cec5SDimitry Andric if (SSNs.empty()) 482*0b57cec5SDimitry Andric Context.getSyncScopeNames(SSNs); 483*0b57cec5SDimitry Andric 484*0b57cec5SDimitry Andric OS << "syncscope(\""; 485*0b57cec5SDimitry Andric printEscapedString(SSNs[SSID], OS); 486*0b57cec5SDimitry Andric OS << "\") "; 487*0b57cec5SDimitry Andric break; 488*0b57cec5SDimitry Andric } 489*0b57cec5SDimitry Andric } 490*0b57cec5SDimitry Andric 491*0b57cec5SDimitry Andric static const char *getTargetMMOFlagName(const TargetInstrInfo &TII, 492*0b57cec5SDimitry Andric unsigned TMMOFlag) { 493*0b57cec5SDimitry Andric auto Flags = TII.getSerializableMachineMemOperandTargetFlags(); 494*0b57cec5SDimitry Andric for (const auto &I : Flags) { 495*0b57cec5SDimitry Andric if (I.first == TMMOFlag) { 496*0b57cec5SDimitry Andric return I.second; 497*0b57cec5SDimitry Andric } 498*0b57cec5SDimitry Andric } 499*0b57cec5SDimitry Andric return nullptr; 500*0b57cec5SDimitry Andric } 501*0b57cec5SDimitry Andric 502*0b57cec5SDimitry Andric static void printFrameIndex(raw_ostream& OS, int FrameIndex, bool IsFixed, 503*0b57cec5SDimitry Andric const MachineFrameInfo *MFI) { 504*0b57cec5SDimitry Andric StringRef Name; 505*0b57cec5SDimitry Andric if (MFI) { 506*0b57cec5SDimitry Andric IsFixed = MFI->isFixedObjectIndex(FrameIndex); 507*0b57cec5SDimitry Andric if (const AllocaInst *Alloca = MFI->getObjectAllocation(FrameIndex)) 508*0b57cec5SDimitry Andric if (Alloca->hasName()) 509*0b57cec5SDimitry Andric Name = Alloca->getName(); 510*0b57cec5SDimitry Andric if (IsFixed) 511*0b57cec5SDimitry Andric FrameIndex -= MFI->getObjectIndexBegin(); 512*0b57cec5SDimitry Andric } 513*0b57cec5SDimitry Andric MachineOperand::printStackObjectReference(OS, FrameIndex, IsFixed, Name); 514*0b57cec5SDimitry Andric } 515*0b57cec5SDimitry Andric 516*0b57cec5SDimitry Andric void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index, 517*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 518*0b57cec5SDimitry Andric OS << "%subreg."; 519*0b57cec5SDimitry Andric if (TRI) 520*0b57cec5SDimitry Andric OS << TRI->getSubRegIndexName(Index); 521*0b57cec5SDimitry Andric else 522*0b57cec5SDimitry Andric OS << Index; 523*0b57cec5SDimitry Andric } 524*0b57cec5SDimitry Andric 525*0b57cec5SDimitry Andric void MachineOperand::printTargetFlags(raw_ostream &OS, 526*0b57cec5SDimitry Andric const MachineOperand &Op) { 527*0b57cec5SDimitry Andric if (!Op.getTargetFlags()) 528*0b57cec5SDimitry Andric return; 529*0b57cec5SDimitry Andric const MachineFunction *MF = getMFIfAvailable(Op); 530*0b57cec5SDimitry Andric if (!MF) 531*0b57cec5SDimitry Andric return; 532*0b57cec5SDimitry Andric 533*0b57cec5SDimitry Andric const auto *TII = MF->getSubtarget().getInstrInfo(); 534*0b57cec5SDimitry Andric assert(TII && "expected instruction info"); 535*0b57cec5SDimitry Andric auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); 536*0b57cec5SDimitry Andric OS << "target-flags("; 537*0b57cec5SDimitry Andric const bool HasDirectFlags = Flags.first; 538*0b57cec5SDimitry Andric const bool HasBitmaskFlags = Flags.second; 539*0b57cec5SDimitry Andric if (!HasDirectFlags && !HasBitmaskFlags) { 540*0b57cec5SDimitry Andric OS << "<unknown>) "; 541*0b57cec5SDimitry Andric return; 542*0b57cec5SDimitry Andric } 543*0b57cec5SDimitry Andric if (HasDirectFlags) { 544*0b57cec5SDimitry Andric if (const auto *Name = getTargetFlagName(TII, Flags.first)) 545*0b57cec5SDimitry Andric OS << Name; 546*0b57cec5SDimitry Andric else 547*0b57cec5SDimitry Andric OS << "<unknown target flag>"; 548*0b57cec5SDimitry Andric } 549*0b57cec5SDimitry Andric if (!HasBitmaskFlags) { 550*0b57cec5SDimitry Andric OS << ") "; 551*0b57cec5SDimitry Andric return; 552*0b57cec5SDimitry Andric } 553*0b57cec5SDimitry Andric bool IsCommaNeeded = HasDirectFlags; 554*0b57cec5SDimitry Andric unsigned BitMask = Flags.second; 555*0b57cec5SDimitry Andric auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags(); 556*0b57cec5SDimitry Andric for (const auto &Mask : BitMasks) { 557*0b57cec5SDimitry Andric // Check if the flag's bitmask has the bits of the current mask set. 558*0b57cec5SDimitry Andric if ((BitMask & Mask.first) == Mask.first) { 559*0b57cec5SDimitry Andric if (IsCommaNeeded) 560*0b57cec5SDimitry Andric OS << ", "; 561*0b57cec5SDimitry Andric IsCommaNeeded = true; 562*0b57cec5SDimitry Andric OS << Mask.second; 563*0b57cec5SDimitry Andric // Clear the bits which were serialized from the flag's bitmask. 564*0b57cec5SDimitry Andric BitMask &= ~(Mask.first); 565*0b57cec5SDimitry Andric } 566*0b57cec5SDimitry Andric } 567*0b57cec5SDimitry Andric if (BitMask) { 568*0b57cec5SDimitry Andric // When the resulting flag's bitmask isn't zero, we know that we didn't 569*0b57cec5SDimitry Andric // serialize all of the bit flags. 570*0b57cec5SDimitry Andric if (IsCommaNeeded) 571*0b57cec5SDimitry Andric OS << ", "; 572*0b57cec5SDimitry Andric OS << "<unknown bitmask target flag>"; 573*0b57cec5SDimitry Andric } 574*0b57cec5SDimitry Andric OS << ") "; 575*0b57cec5SDimitry Andric } 576*0b57cec5SDimitry Andric 577*0b57cec5SDimitry Andric void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) { 578*0b57cec5SDimitry Andric OS << "<mcsymbol " << Sym << ">"; 579*0b57cec5SDimitry Andric } 580*0b57cec5SDimitry Andric 581*0b57cec5SDimitry Andric void MachineOperand::printStackObjectReference(raw_ostream &OS, 582*0b57cec5SDimitry Andric unsigned FrameIndex, 583*0b57cec5SDimitry Andric bool IsFixed, StringRef Name) { 584*0b57cec5SDimitry Andric if (IsFixed) { 585*0b57cec5SDimitry Andric OS << "%fixed-stack." << FrameIndex; 586*0b57cec5SDimitry Andric return; 587*0b57cec5SDimitry Andric } 588*0b57cec5SDimitry Andric 589*0b57cec5SDimitry Andric OS << "%stack." << FrameIndex; 590*0b57cec5SDimitry Andric if (!Name.empty()) 591*0b57cec5SDimitry Andric OS << '.' << Name; 592*0b57cec5SDimitry Andric } 593*0b57cec5SDimitry Andric 594*0b57cec5SDimitry Andric void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) { 595*0b57cec5SDimitry Andric if (Offset == 0) 596*0b57cec5SDimitry Andric return; 597*0b57cec5SDimitry Andric if (Offset < 0) { 598*0b57cec5SDimitry Andric OS << " - " << -Offset; 599*0b57cec5SDimitry Andric return; 600*0b57cec5SDimitry Andric } 601*0b57cec5SDimitry Andric OS << " + " << Offset; 602*0b57cec5SDimitry Andric } 603*0b57cec5SDimitry Andric 604*0b57cec5SDimitry Andric void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) { 605*0b57cec5SDimitry Andric if (Slot == -1) 606*0b57cec5SDimitry Andric OS << "<badref>"; 607*0b57cec5SDimitry Andric else 608*0b57cec5SDimitry Andric OS << Slot; 609*0b57cec5SDimitry Andric } 610*0b57cec5SDimitry Andric 611*0b57cec5SDimitry Andric static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI, 612*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) { 613*0b57cec5SDimitry Andric switch (CFI.getOperation()) { 614*0b57cec5SDimitry Andric case MCCFIInstruction::OpSameValue: 615*0b57cec5SDimitry Andric OS << "same_value "; 616*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 617*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 618*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 619*0b57cec5SDimitry Andric break; 620*0b57cec5SDimitry Andric case MCCFIInstruction::OpRememberState: 621*0b57cec5SDimitry Andric OS << "remember_state "; 622*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 623*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 624*0b57cec5SDimitry Andric break; 625*0b57cec5SDimitry Andric case MCCFIInstruction::OpRestoreState: 626*0b57cec5SDimitry Andric OS << "restore_state "; 627*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 628*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 629*0b57cec5SDimitry Andric break; 630*0b57cec5SDimitry Andric case MCCFIInstruction::OpOffset: 631*0b57cec5SDimitry Andric OS << "offset "; 632*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 633*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 634*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 635*0b57cec5SDimitry Andric OS << ", " << CFI.getOffset(); 636*0b57cec5SDimitry Andric break; 637*0b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfaRegister: 638*0b57cec5SDimitry Andric OS << "def_cfa_register "; 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 break; 643*0b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfaOffset: 644*0b57cec5SDimitry Andric OS << "def_cfa_offset "; 645*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 646*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 647*0b57cec5SDimitry Andric OS << CFI.getOffset(); 648*0b57cec5SDimitry Andric break; 649*0b57cec5SDimitry Andric case MCCFIInstruction::OpDefCfa: 650*0b57cec5SDimitry Andric OS << "def_cfa "; 651*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 652*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 653*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 654*0b57cec5SDimitry Andric OS << ", " << CFI.getOffset(); 655*0b57cec5SDimitry Andric break; 656*0b57cec5SDimitry Andric case MCCFIInstruction::OpRelOffset: 657*0b57cec5SDimitry Andric OS << "rel_offset "; 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::OpAdjustCfaOffset: 664*0b57cec5SDimitry Andric OS << "adjust_cfa_offset "; 665*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 666*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 667*0b57cec5SDimitry Andric OS << CFI.getOffset(); 668*0b57cec5SDimitry Andric break; 669*0b57cec5SDimitry Andric case MCCFIInstruction::OpRestore: 670*0b57cec5SDimitry Andric OS << "restore "; 671*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 672*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 673*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 674*0b57cec5SDimitry Andric break; 675*0b57cec5SDimitry Andric case MCCFIInstruction::OpEscape: { 676*0b57cec5SDimitry Andric OS << "escape "; 677*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 678*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 679*0b57cec5SDimitry Andric if (!CFI.getValues().empty()) { 680*0b57cec5SDimitry Andric size_t e = CFI.getValues().size() - 1; 681*0b57cec5SDimitry Andric for (size_t i = 0; i < e; ++i) 682*0b57cec5SDimitry Andric OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", "; 6835ffd83dbSDimitry Andric OS << format("0x%02x", uint8_t(CFI.getValues()[e])); 684*0b57cec5SDimitry Andric } 685*0b57cec5SDimitry Andric break; 686*0b57cec5SDimitry Andric } 687*0b57cec5SDimitry Andric case MCCFIInstruction::OpUndefined: 688*0b57cec5SDimitry Andric OS << "undefined "; 689*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 690*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 691*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 692*0b57cec5SDimitry Andric break; 693*0b57cec5SDimitry Andric case MCCFIInstruction::OpRegister: 694*0b57cec5SDimitry Andric OS << "register "; 695*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 696*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 697*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister(), OS, TRI); 698*0b57cec5SDimitry Andric OS << ", "; 699*0b57cec5SDimitry Andric printCFIRegister(CFI.getRegister2(), OS, TRI); 700*0b57cec5SDimitry Andric break; 701*0b57cec5SDimitry Andric case MCCFIInstruction::OpWindowSave: 702*0b57cec5SDimitry Andric OS << "window_save "; 703*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 704*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 705*0b57cec5SDimitry Andric break; 706*0b57cec5SDimitry Andric case MCCFIInstruction::OpNegateRAState: 707*0b57cec5SDimitry Andric OS << "negate_ra_sign_state "; 708*0b57cec5SDimitry Andric if (MCSymbol *Label = CFI.getLabel()) 709*0b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *Label); 710*0b57cec5SDimitry Andric break; 711*0b57cec5SDimitry Andric default: 712*0b57cec5SDimitry Andric // TODO: Print the other CFI Operations. 713*0b57cec5SDimitry Andric OS << "<unserializable cfi directive>"; 714*0b57cec5SDimitry Andric break; 715*0b57cec5SDimitry Andric } 716*0b57cec5SDimitry Andric } 717*0b57cec5SDimitry Andric 718*0b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, 719*0b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 720*0b57cec5SDimitry Andric print(OS, LLT{}, TRI, IntrinsicInfo); 721*0b57cec5SDimitry Andric } 722*0b57cec5SDimitry Andric 723*0b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, LLT TypeToPrint, 724*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI, 725*0b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 726*0b57cec5SDimitry Andric tryToGetTargetInfo(*this, TRI, IntrinsicInfo); 727*0b57cec5SDimitry Andric ModuleSlotTracker DummyMST(nullptr); 728480093f4SDimitry Andric print(OS, DummyMST, TypeToPrint, None, /*PrintDef=*/false, 729480093f4SDimitry Andric /*IsStandalone=*/true, 730*0b57cec5SDimitry Andric /*ShouldPrintRegisterTies=*/true, 731*0b57cec5SDimitry Andric /*TiedOperandIdx=*/0, TRI, IntrinsicInfo); 732*0b57cec5SDimitry Andric } 733*0b57cec5SDimitry Andric 734*0b57cec5SDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 735480093f4SDimitry Andric LLT TypeToPrint, Optional<unsigned> OpIdx, bool PrintDef, 736480093f4SDimitry Andric bool IsStandalone, bool ShouldPrintRegisterTies, 737*0b57cec5SDimitry Andric unsigned TiedOperandIdx, 738*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI, 739*0b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 740*0b57cec5SDimitry Andric printTargetFlags(OS, *this); 741*0b57cec5SDimitry Andric switch (getType()) { 742*0b57cec5SDimitry Andric case MachineOperand::MO_Register: { 7438bcb0991SDimitry Andric Register Reg = getReg(); 744*0b57cec5SDimitry Andric if (isImplicit()) 745*0b57cec5SDimitry Andric OS << (isDef() ? "implicit-def " : "implicit "); 746*0b57cec5SDimitry Andric else if (PrintDef && isDef()) 747*0b57cec5SDimitry Andric // Print the 'def' flag only when the operand is defined after '='. 748*0b57cec5SDimitry Andric OS << "def "; 749*0b57cec5SDimitry Andric if (isInternalRead()) 750*0b57cec5SDimitry Andric OS << "internal "; 751*0b57cec5SDimitry Andric if (isDead()) 752*0b57cec5SDimitry Andric OS << "dead "; 753*0b57cec5SDimitry Andric if (isKill()) 754*0b57cec5SDimitry Andric OS << "killed "; 755*0b57cec5SDimitry Andric if (isUndef()) 756*0b57cec5SDimitry Andric OS << "undef "; 757*0b57cec5SDimitry Andric if (isEarlyClobber()) 758*0b57cec5SDimitry Andric OS << "early-clobber "; 7598bcb0991SDimitry Andric if (Register::isPhysicalRegister(getReg()) && isRenamable()) 760*0b57cec5SDimitry Andric OS << "renamable "; 761*0b57cec5SDimitry Andric // isDebug() is exactly true for register operands of a DBG_VALUE. So we 762*0b57cec5SDimitry Andric // simply infer it when parsing and do not need to print it. 763*0b57cec5SDimitry Andric 764*0b57cec5SDimitry Andric const MachineRegisterInfo *MRI = nullptr; 7658bcb0991SDimitry Andric if (Register::isVirtualRegister(Reg)) { 766*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 767*0b57cec5SDimitry Andric MRI = &MF->getRegInfo(); 768*0b57cec5SDimitry Andric } 769*0b57cec5SDimitry Andric } 770*0b57cec5SDimitry Andric 771*0b57cec5SDimitry Andric OS << printReg(Reg, TRI, 0, MRI); 772*0b57cec5SDimitry Andric // Print the sub register. 773*0b57cec5SDimitry Andric if (unsigned SubReg = getSubReg()) { 774*0b57cec5SDimitry Andric if (TRI) 775*0b57cec5SDimitry Andric OS << '.' << TRI->getSubRegIndexName(SubReg); 776*0b57cec5SDimitry Andric else 777*0b57cec5SDimitry Andric OS << ".subreg" << SubReg; 778*0b57cec5SDimitry Andric } 779*0b57cec5SDimitry Andric // Print the register class / bank. 7808bcb0991SDimitry Andric if (Register::isVirtualRegister(Reg)) { 781*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 782*0b57cec5SDimitry Andric const MachineRegisterInfo &MRI = MF->getRegInfo(); 783*0b57cec5SDimitry Andric if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) { 784*0b57cec5SDimitry Andric OS << ':'; 785*0b57cec5SDimitry Andric OS << printRegClassOrBank(Reg, MRI, TRI); 786*0b57cec5SDimitry Andric } 787*0b57cec5SDimitry Andric } 788*0b57cec5SDimitry Andric } 789*0b57cec5SDimitry Andric // Print ties. 790*0b57cec5SDimitry Andric if (ShouldPrintRegisterTies && isTied() && !isDef()) 791*0b57cec5SDimitry Andric OS << "(tied-def " << TiedOperandIdx << ")"; 792*0b57cec5SDimitry Andric // Print types. 793*0b57cec5SDimitry Andric if (TypeToPrint.isValid()) 794*0b57cec5SDimitry Andric OS << '(' << TypeToPrint << ')'; 795*0b57cec5SDimitry Andric break; 796*0b57cec5SDimitry Andric } 797480093f4SDimitry Andric case MachineOperand::MO_Immediate: { 798480093f4SDimitry Andric const MIRFormatter *Formatter = nullptr; 799480093f4SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 800480093f4SDimitry Andric const auto *TII = MF->getSubtarget().getInstrInfo(); 801480093f4SDimitry Andric assert(TII && "expected instruction info"); 802480093f4SDimitry Andric Formatter = TII->getMIRFormatter(); 803480093f4SDimitry Andric } 804480093f4SDimitry Andric if (Formatter) 805480093f4SDimitry Andric Formatter->printImm(OS, *getParent(), OpIdx, getImm()); 806480093f4SDimitry Andric else 807*0b57cec5SDimitry Andric OS << getImm(); 808*0b57cec5SDimitry Andric break; 809480093f4SDimitry Andric } 810*0b57cec5SDimitry Andric case MachineOperand::MO_CImmediate: 811*0b57cec5SDimitry Andric getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); 812*0b57cec5SDimitry Andric break; 813*0b57cec5SDimitry Andric case MachineOperand::MO_FPImmediate: 814*0b57cec5SDimitry Andric getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); 815*0b57cec5SDimitry Andric break; 816*0b57cec5SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 817*0b57cec5SDimitry Andric OS << printMBBReference(*getMBB()); 818*0b57cec5SDimitry Andric break; 819*0b57cec5SDimitry Andric case MachineOperand::MO_FrameIndex: { 820*0b57cec5SDimitry Andric int FrameIndex = getIndex(); 821*0b57cec5SDimitry Andric bool IsFixed = false; 822*0b57cec5SDimitry Andric const MachineFrameInfo *MFI = nullptr; 823*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) 824*0b57cec5SDimitry Andric MFI = &MF->getFrameInfo(); 825*0b57cec5SDimitry Andric printFrameIndex(OS, FrameIndex, IsFixed, MFI); 826*0b57cec5SDimitry Andric break; 827*0b57cec5SDimitry Andric } 828*0b57cec5SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 829*0b57cec5SDimitry Andric OS << "%const." << getIndex(); 830*0b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 831*0b57cec5SDimitry Andric break; 832*0b57cec5SDimitry Andric case MachineOperand::MO_TargetIndex: { 833*0b57cec5SDimitry Andric OS << "target-index("; 834*0b57cec5SDimitry Andric const char *Name = "<unknown>"; 835*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) 836e8d8bef9SDimitry Andric if (const auto *TargetIndexName = ::getTargetIndexName(*MF, getIndex())) 837*0b57cec5SDimitry Andric Name = TargetIndexName; 838*0b57cec5SDimitry Andric OS << Name << ')'; 839*0b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 840*0b57cec5SDimitry Andric break; 841*0b57cec5SDimitry Andric } 842*0b57cec5SDimitry Andric case MachineOperand::MO_JumpTableIndex: 843*0b57cec5SDimitry Andric OS << printJumpTableEntryReference(getIndex()); 844*0b57cec5SDimitry Andric break; 845*0b57cec5SDimitry Andric case MachineOperand::MO_GlobalAddress: 846*0b57cec5SDimitry Andric getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 847*0b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 848*0b57cec5SDimitry Andric break; 849*0b57cec5SDimitry Andric case MachineOperand::MO_ExternalSymbol: { 850*0b57cec5SDimitry Andric StringRef Name = getSymbolName(); 851*0b57cec5SDimitry Andric OS << '&'; 852*0b57cec5SDimitry Andric if (Name.empty()) { 853*0b57cec5SDimitry Andric OS << "\"\""; 854*0b57cec5SDimitry Andric } else { 855*0b57cec5SDimitry Andric printLLVMNameWithoutPrefix(OS, Name); 856*0b57cec5SDimitry Andric } 857*0b57cec5SDimitry Andric printOperandOffset(OS, getOffset()); 858*0b57cec5SDimitry Andric break; 859*0b57cec5SDimitry Andric } 860*0b57cec5SDimitry Andric case MachineOperand::MO_BlockAddress: { 861*0b57cec5SDimitry Andric OS << "blockaddress("; 862*0b57cec5SDimitry Andric getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 863*0b57cec5SDimitry Andric MST); 864*0b57cec5SDimitry Andric OS << ", "; 865*0b57cec5SDimitry Andric printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST); 866*0b57cec5SDimitry Andric OS << ')'; 867*0b57cec5SDimitry Andric MachineOperand::printOperandOffset(OS, getOffset()); 868*0b57cec5SDimitry Andric break; 869*0b57cec5SDimitry Andric } 870*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterMask: { 871*0b57cec5SDimitry Andric OS << "<regmask"; 872*0b57cec5SDimitry Andric if (TRI) { 873*0b57cec5SDimitry Andric unsigned NumRegsInMask = 0; 874*0b57cec5SDimitry Andric unsigned NumRegsEmitted = 0; 875*0b57cec5SDimitry Andric for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { 876*0b57cec5SDimitry Andric unsigned MaskWord = i / 32; 877*0b57cec5SDimitry Andric unsigned MaskBit = i % 32; 878*0b57cec5SDimitry Andric if (getRegMask()[MaskWord] & (1 << MaskBit)) { 879*0b57cec5SDimitry Andric if (PrintRegMaskNumRegs < 0 || 880*0b57cec5SDimitry Andric NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) { 881*0b57cec5SDimitry Andric OS << " " << printReg(i, TRI); 882*0b57cec5SDimitry Andric NumRegsEmitted++; 883*0b57cec5SDimitry Andric } 884*0b57cec5SDimitry Andric NumRegsInMask++; 885*0b57cec5SDimitry Andric } 886*0b57cec5SDimitry Andric } 887*0b57cec5SDimitry Andric if (NumRegsEmitted != NumRegsInMask) 888*0b57cec5SDimitry Andric OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; 889*0b57cec5SDimitry Andric } else { 890*0b57cec5SDimitry Andric OS << " ..."; 891*0b57cec5SDimitry Andric } 892*0b57cec5SDimitry Andric OS << ">"; 893*0b57cec5SDimitry Andric break; 894*0b57cec5SDimitry Andric } 895*0b57cec5SDimitry Andric case MachineOperand::MO_RegisterLiveOut: { 896*0b57cec5SDimitry Andric const uint32_t *RegMask = getRegLiveOut(); 897*0b57cec5SDimitry Andric OS << "liveout("; 898*0b57cec5SDimitry Andric if (!TRI) { 899*0b57cec5SDimitry Andric OS << "<unknown>"; 900*0b57cec5SDimitry Andric } else { 901*0b57cec5SDimitry Andric bool IsCommaNeeded = false; 902*0b57cec5SDimitry Andric for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { 903*0b57cec5SDimitry Andric if (RegMask[Reg / 32] & (1U << (Reg % 32))) { 904*0b57cec5SDimitry Andric if (IsCommaNeeded) 905*0b57cec5SDimitry Andric OS << ", "; 906*0b57cec5SDimitry Andric OS << printReg(Reg, TRI); 907*0b57cec5SDimitry Andric IsCommaNeeded = true; 908*0b57cec5SDimitry Andric } 909*0b57cec5SDimitry Andric } 910*0b57cec5SDimitry Andric } 911*0b57cec5SDimitry Andric OS << ")"; 912*0b57cec5SDimitry Andric break; 913*0b57cec5SDimitry Andric } 914*0b57cec5SDimitry Andric case MachineOperand::MO_Metadata: 915*0b57cec5SDimitry Andric getMetadata()->printAsOperand(OS, MST); 916*0b57cec5SDimitry Andric break; 917*0b57cec5SDimitry Andric case MachineOperand::MO_MCSymbol: 918*0b57cec5SDimitry Andric printSymbol(OS, *getMCSymbol()); 919*0b57cec5SDimitry Andric break; 920*0b57cec5SDimitry Andric case MachineOperand::MO_CFIIndex: { 921*0b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) 922*0b57cec5SDimitry Andric printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI); 923*0b57cec5SDimitry Andric else 924*0b57cec5SDimitry Andric OS << "<cfi directive>"; 925*0b57cec5SDimitry Andric break; 926*0b57cec5SDimitry Andric } 927*0b57cec5SDimitry Andric case MachineOperand::MO_IntrinsicID: { 928*0b57cec5SDimitry Andric Intrinsic::ID ID = getIntrinsicID(); 929*0b57cec5SDimitry Andric if (ID < Intrinsic::num_intrinsics) 930*0b57cec5SDimitry Andric OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; 931*0b57cec5SDimitry Andric else if (IntrinsicInfo) 932*0b57cec5SDimitry Andric OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')'; 933*0b57cec5SDimitry Andric else 934*0b57cec5SDimitry Andric OS << "intrinsic(" << ID << ')'; 935*0b57cec5SDimitry Andric break; 936*0b57cec5SDimitry Andric } 937*0b57cec5SDimitry Andric case MachineOperand::MO_Predicate: { 938*0b57cec5SDimitry Andric auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); 939*0b57cec5SDimitry Andric OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" 940*0b57cec5SDimitry Andric << CmpInst::getPredicateName(Pred) << ')'; 941*0b57cec5SDimitry Andric break; 942*0b57cec5SDimitry Andric } 9438bcb0991SDimitry Andric case MachineOperand::MO_ShuffleMask: 9448bcb0991SDimitry Andric OS << "shufflemask("; 945480093f4SDimitry Andric ArrayRef<int> Mask = getShuffleMask(); 9468bcb0991SDimitry Andric StringRef Separator; 947480093f4SDimitry Andric for (int Elt : Mask) { 948480093f4SDimitry Andric if (Elt == -1) 949480093f4SDimitry Andric OS << Separator << "undef"; 950480093f4SDimitry Andric else 951480093f4SDimitry Andric OS << Separator << Elt; 9528bcb0991SDimitry Andric Separator = ", "; 9538bcb0991SDimitry Andric } 9548bcb0991SDimitry Andric 9558bcb0991SDimitry Andric OS << ')'; 9568bcb0991SDimitry Andric break; 957*0b57cec5SDimitry Andric } 958*0b57cec5SDimitry Andric } 959*0b57cec5SDimitry Andric 960*0b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 961*0b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; } 962*0b57cec5SDimitry Andric #endif 963*0b57cec5SDimitry Andric 964*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 965*0b57cec5SDimitry Andric // MachineMemOperand Implementation 966*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 967*0b57cec5SDimitry Andric 968*0b57cec5SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer 969*0b57cec5SDimitry Andric /// points into. 970*0b57cec5SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; } 971*0b57cec5SDimitry Andric 972*0b57cec5SDimitry Andric /// isDereferenceable - Return true if V is always dereferenceable for 973*0b57cec5SDimitry Andric /// Offset + Size byte. 974*0b57cec5SDimitry Andric bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C, 975*0b57cec5SDimitry Andric const DataLayout &DL) const { 976*0b57cec5SDimitry Andric if (!V.is<const Value *>()) 977*0b57cec5SDimitry Andric return false; 978*0b57cec5SDimitry Andric 979*0b57cec5SDimitry Andric const Value *BasePtr = V.get<const Value *>(); 980*0b57cec5SDimitry Andric if (BasePtr == nullptr) 981*0b57cec5SDimitry Andric return false; 982*0b57cec5SDimitry Andric 983*0b57cec5SDimitry Andric return isDereferenceableAndAlignedPointer( 9845ffd83dbSDimitry Andric BasePtr, Align(1), APInt(DL.getPointerSizeInBits(), Offset + Size), DL); 985*0b57cec5SDimitry Andric } 986*0b57cec5SDimitry Andric 987*0b57cec5SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the 988*0b57cec5SDimitry Andric /// constant pool. 989*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { 990*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getConstantPool()); 991*0b57cec5SDimitry Andric } 992*0b57cec5SDimitry Andric 993*0b57cec5SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the 994*0b57cec5SDimitry Andric /// the specified FrameIndex. 995*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, 996*0b57cec5SDimitry Andric int FI, int64_t Offset) { 997*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); 998*0b57cec5SDimitry Andric } 999*0b57cec5SDimitry Andric 1000*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { 1001*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getJumpTable()); 1002*0b57cec5SDimitry Andric } 1003*0b57cec5SDimitry Andric 1004*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { 1005*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getGOT()); 1006*0b57cec5SDimitry Andric } 1007*0b57cec5SDimitry Andric 1008*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, 1009*0b57cec5SDimitry Andric int64_t Offset, uint8_t ID) { 1010*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID); 1011*0b57cec5SDimitry Andric } 1012*0b57cec5SDimitry Andric 1013*0b57cec5SDimitry Andric MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) { 1014*0b57cec5SDimitry Andric return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace()); 1015*0b57cec5SDimitry Andric } 1016*0b57cec5SDimitry Andric 1017*0b57cec5SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f, 10185ffd83dbSDimitry Andric uint64_t s, Align a, 1019*0b57cec5SDimitry Andric const AAMDNodes &AAInfo, 1020*0b57cec5SDimitry Andric const MDNode *Ranges, SyncScope::ID SSID, 1021*0b57cec5SDimitry Andric AtomicOrdering Ordering, 1022*0b57cec5SDimitry Andric AtomicOrdering FailureOrdering) 10235ffd83dbSDimitry Andric : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlign(a), AAInfo(AAInfo), 10245ffd83dbSDimitry Andric Ranges(Ranges) { 1025*0b57cec5SDimitry Andric assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() || 1026*0b57cec5SDimitry Andric isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) && 1027*0b57cec5SDimitry Andric "invalid pointer value"); 1028*0b57cec5SDimitry Andric assert((isLoad() || isStore()) && "Not a load/store!"); 1029*0b57cec5SDimitry Andric 1030*0b57cec5SDimitry Andric AtomicInfo.SSID = static_cast<unsigned>(SSID); 1031*0b57cec5SDimitry Andric assert(getSyncScopeID() == SSID && "Value truncated"); 1032*0b57cec5SDimitry Andric AtomicInfo.Ordering = static_cast<unsigned>(Ordering); 1033*0b57cec5SDimitry Andric assert(getOrdering() == Ordering && "Value truncated"); 1034*0b57cec5SDimitry Andric AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering); 1035*0b57cec5SDimitry Andric assert(getFailureOrdering() == FailureOrdering && "Value truncated"); 1036*0b57cec5SDimitry Andric } 1037*0b57cec5SDimitry Andric 1038*0b57cec5SDimitry Andric /// Profile - Gather unique data for the object. 1039*0b57cec5SDimitry Andric /// 1040*0b57cec5SDimitry Andric void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 1041*0b57cec5SDimitry Andric ID.AddInteger(getOffset()); 1042*0b57cec5SDimitry Andric ID.AddInteger(Size); 1043*0b57cec5SDimitry Andric ID.AddPointer(getOpaqueValue()); 1044*0b57cec5SDimitry Andric ID.AddInteger(getFlags()); 10455ffd83dbSDimitry Andric ID.AddInteger(getBaseAlign().value()); 1046*0b57cec5SDimitry Andric } 1047*0b57cec5SDimitry Andric 1048*0b57cec5SDimitry Andric void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 1049*0b57cec5SDimitry Andric // The Value and Offset may differ due to CSE. But the flags and size 1050*0b57cec5SDimitry Andric // should be the same. 1051*0b57cec5SDimitry Andric assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 1052*0b57cec5SDimitry Andric assert(MMO->getSize() == getSize() && "Size mismatch!"); 1053*0b57cec5SDimitry Andric 10545ffd83dbSDimitry Andric if (MMO->getBaseAlign() >= getBaseAlign()) { 1055*0b57cec5SDimitry Andric // Update the alignment value. 10565ffd83dbSDimitry Andric BaseAlign = MMO->getBaseAlign(); 1057*0b57cec5SDimitry Andric // Also update the base and offset, because the new alignment may 1058*0b57cec5SDimitry Andric // not be applicable with the old ones. 1059*0b57cec5SDimitry Andric PtrInfo = MMO->PtrInfo; 1060*0b57cec5SDimitry Andric } 1061*0b57cec5SDimitry Andric } 1062*0b57cec5SDimitry Andric 1063*0b57cec5SDimitry Andric /// getAlignment - Return the minimum known alignment in bytes of the 1064*0b57cec5SDimitry Andric /// actual memory reference. 10655ffd83dbSDimitry Andric uint64_t MachineMemOperand::getAlignment() const { return getAlign().value(); } 10665ffd83dbSDimitry Andric 10675ffd83dbSDimitry Andric /// getAlign - Return the minimum known alignment in bytes of the 10685ffd83dbSDimitry Andric /// actual memory reference. 10695ffd83dbSDimitry Andric Align MachineMemOperand::getAlign() const { 10705ffd83dbSDimitry Andric return commonAlignment(getBaseAlign(), getOffset()); 1071*0b57cec5SDimitry Andric } 1072*0b57cec5SDimitry Andric 1073*0b57cec5SDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 1074*0b57cec5SDimitry Andric SmallVectorImpl<StringRef> &SSNs, 1075*0b57cec5SDimitry Andric const LLVMContext &Context, 1076*0b57cec5SDimitry Andric const MachineFrameInfo *MFI, 1077*0b57cec5SDimitry Andric const TargetInstrInfo *TII) const { 1078*0b57cec5SDimitry Andric OS << '('; 1079*0b57cec5SDimitry Andric if (isVolatile()) 1080*0b57cec5SDimitry Andric OS << "volatile "; 1081*0b57cec5SDimitry Andric if (isNonTemporal()) 1082*0b57cec5SDimitry Andric OS << "non-temporal "; 1083*0b57cec5SDimitry Andric if (isDereferenceable()) 1084*0b57cec5SDimitry Andric OS << "dereferenceable "; 1085*0b57cec5SDimitry Andric if (isInvariant()) 1086*0b57cec5SDimitry Andric OS << "invariant "; 1087*0b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag1) 1088*0b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag1) 1089*0b57cec5SDimitry Andric << "\" "; 1090*0b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag2) 1091*0b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag2) 1092*0b57cec5SDimitry Andric << "\" "; 1093*0b57cec5SDimitry Andric if (getFlags() & MachineMemOperand::MOTargetFlag3) 1094*0b57cec5SDimitry Andric OS << '"' << getTargetMMOFlagName(*TII, MachineMemOperand::MOTargetFlag3) 1095*0b57cec5SDimitry Andric << "\" "; 1096*0b57cec5SDimitry Andric 1097*0b57cec5SDimitry Andric assert((isLoad() || isStore()) && 1098*0b57cec5SDimitry Andric "machine memory operand must be a load or store (or both)"); 1099*0b57cec5SDimitry Andric if (isLoad()) 1100*0b57cec5SDimitry Andric OS << "load "; 1101*0b57cec5SDimitry Andric if (isStore()) 1102*0b57cec5SDimitry Andric OS << "store "; 1103*0b57cec5SDimitry Andric 1104*0b57cec5SDimitry Andric printSyncScope(OS, Context, getSyncScopeID(), SSNs); 1105*0b57cec5SDimitry Andric 1106*0b57cec5SDimitry Andric if (getOrdering() != AtomicOrdering::NotAtomic) 1107*0b57cec5SDimitry Andric OS << toIRString(getOrdering()) << ' '; 1108*0b57cec5SDimitry Andric if (getFailureOrdering() != AtomicOrdering::NotAtomic) 1109*0b57cec5SDimitry Andric OS << toIRString(getFailureOrdering()) << ' '; 1110*0b57cec5SDimitry Andric 1111*0b57cec5SDimitry Andric if (getSize() == MemoryLocation::UnknownSize) 1112*0b57cec5SDimitry Andric OS << "unknown-size"; 1113*0b57cec5SDimitry Andric else 1114*0b57cec5SDimitry Andric OS << getSize(); 1115*0b57cec5SDimitry Andric 1116*0b57cec5SDimitry Andric if (const Value *Val = getValue()) { 1117*0b57cec5SDimitry Andric OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into "); 1118480093f4SDimitry Andric MIRFormatter::printIRValue(OS, *Val, MST); 1119*0b57cec5SDimitry Andric } else if (const PseudoSourceValue *PVal = getPseudoValue()) { 1120*0b57cec5SDimitry Andric OS << ((isLoad() && isStore()) ? " on " : isLoad() ? " from " : " into "); 1121*0b57cec5SDimitry Andric assert(PVal && "Expected a pseudo source value"); 1122*0b57cec5SDimitry Andric switch (PVal->kind()) { 1123*0b57cec5SDimitry Andric case PseudoSourceValue::Stack: 1124*0b57cec5SDimitry Andric OS << "stack"; 1125*0b57cec5SDimitry Andric break; 1126*0b57cec5SDimitry Andric case PseudoSourceValue::GOT: 1127*0b57cec5SDimitry Andric OS << "got"; 1128*0b57cec5SDimitry Andric break; 1129*0b57cec5SDimitry Andric case PseudoSourceValue::JumpTable: 1130*0b57cec5SDimitry Andric OS << "jump-table"; 1131*0b57cec5SDimitry Andric break; 1132*0b57cec5SDimitry Andric case PseudoSourceValue::ConstantPool: 1133*0b57cec5SDimitry Andric OS << "constant-pool"; 1134*0b57cec5SDimitry Andric break; 1135*0b57cec5SDimitry Andric case PseudoSourceValue::FixedStack: { 1136*0b57cec5SDimitry Andric int FrameIndex = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex(); 1137*0b57cec5SDimitry Andric bool IsFixed = true; 1138*0b57cec5SDimitry Andric printFrameIndex(OS, FrameIndex, IsFixed, MFI); 1139*0b57cec5SDimitry Andric break; 1140*0b57cec5SDimitry Andric } 1141*0b57cec5SDimitry Andric case PseudoSourceValue::GlobalValueCallEntry: 1142*0b57cec5SDimitry Andric OS << "call-entry "; 1143*0b57cec5SDimitry Andric cast<GlobalValuePseudoSourceValue>(PVal)->getValue()->printAsOperand( 1144*0b57cec5SDimitry Andric OS, /*PrintType=*/false, MST); 1145*0b57cec5SDimitry Andric break; 1146*0b57cec5SDimitry Andric case PseudoSourceValue::ExternalSymbolCallEntry: 1147*0b57cec5SDimitry Andric OS << "call-entry &"; 1148*0b57cec5SDimitry Andric printLLVMNameWithoutPrefix( 1149*0b57cec5SDimitry Andric OS, cast<ExternalSymbolPseudoSourceValue>(PVal)->getSymbol()); 1150*0b57cec5SDimitry Andric break; 1151480093f4SDimitry Andric default: { 1152480093f4SDimitry Andric const MIRFormatter *Formatter = TII->getMIRFormatter(); 1153*0b57cec5SDimitry Andric // FIXME: This is not necessarily the correct MIR serialization format for 1154*0b57cec5SDimitry Andric // a custom pseudo source value, but at least it allows 1155e8d8bef9SDimitry Andric // MIR printing to work on a target with custom pseudo source 1156*0b57cec5SDimitry Andric // values. 1157480093f4SDimitry Andric OS << "custom \""; 1158480093f4SDimitry Andric Formatter->printCustomPseudoSourceValue(OS, MST, *PVal); 1159480093f4SDimitry Andric OS << '\"'; 1160*0b57cec5SDimitry Andric break; 1161*0b57cec5SDimitry Andric } 1162*0b57cec5SDimitry Andric } 1163480093f4SDimitry Andric } 1164*0b57cec5SDimitry Andric MachineOperand::printOperandOffset(OS, getOffset()); 1165e8d8bef9SDimitry Andric if (getAlign() != getSize()) 1166e8d8bef9SDimitry Andric OS << ", align " << getAlign().value(); 1167e8d8bef9SDimitry Andric if (getAlign() != getBaseAlign()) 1168e8d8bef9SDimitry Andric OS << ", basealign " << getBaseAlign().value(); 1169*0b57cec5SDimitry Andric auto AAInfo = getAAInfo(); 1170*0b57cec5SDimitry Andric if (AAInfo.TBAA) { 1171*0b57cec5SDimitry Andric OS << ", !tbaa "; 1172*0b57cec5SDimitry Andric AAInfo.TBAA->printAsOperand(OS, MST); 1173*0b57cec5SDimitry Andric } 1174*0b57cec5SDimitry Andric if (AAInfo.Scope) { 1175*0b57cec5SDimitry Andric OS << ", !alias.scope "; 1176*0b57cec5SDimitry Andric AAInfo.Scope->printAsOperand(OS, MST); 1177*0b57cec5SDimitry Andric } 1178*0b57cec5SDimitry Andric if (AAInfo.NoAlias) { 1179*0b57cec5SDimitry Andric OS << ", !noalias "; 1180*0b57cec5SDimitry Andric AAInfo.NoAlias->printAsOperand(OS, MST); 1181*0b57cec5SDimitry Andric } 1182*0b57cec5SDimitry Andric if (getRanges()) { 1183*0b57cec5SDimitry Andric OS << ", !range "; 1184*0b57cec5SDimitry Andric getRanges()->printAsOperand(OS, MST); 1185*0b57cec5SDimitry Andric } 1186*0b57cec5SDimitry Andric // FIXME: Implement addrspace printing/parsing in MIR. 1187*0b57cec5SDimitry Andric // For now, print this even though parsing it is not available in MIR. 1188*0b57cec5SDimitry Andric if (unsigned AS = getAddrSpace()) 1189*0b57cec5SDimitry Andric OS << ", addrspace " << AS; 1190*0b57cec5SDimitry Andric 1191*0b57cec5SDimitry Andric OS << ')'; 1192*0b57cec5SDimitry Andric } 1193