1aa739695SFrancis Visoiu Mistrih //===- lib/CodeGen/MachineOperand.cpp -------------------------------------===// 2aa739695SFrancis Visoiu Mistrih // 3aa739695SFrancis Visoiu Mistrih // The LLVM Compiler Infrastructure 4aa739695SFrancis Visoiu Mistrih // 5aa739695SFrancis Visoiu Mistrih // This file is distributed under the University of Illinois Open Source 6aa739695SFrancis Visoiu Mistrih // License. See LICENSE.TXT for details. 7aa739695SFrancis Visoiu Mistrih // 8aa739695SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===// 9aa739695SFrancis Visoiu Mistrih // 103aa8eaa9SFrancis Visoiu Mistrih /// \file Methods common to all machine operands. 11aa739695SFrancis Visoiu Mistrih // 12aa739695SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===// 13aa739695SFrancis Visoiu Mistrih 14aa739695SFrancis Visoiu Mistrih #include "llvm/CodeGen/MachineOperand.h" 15aa739695SFrancis Visoiu Mistrih #include "llvm/Analysis/Loads.h" 16aa739695SFrancis Visoiu Mistrih #include "llvm/CodeGen/MIRPrinter.h" 170b5bdceaSFrancis Visoiu Mistrih #include "llvm/CodeGen/MachineFrameInfo.h" 18b41dbbe3SFrancis Visoiu Mistrih #include "llvm/CodeGen/MachineJumpTableInfo.h" 19aa739695SFrancis Visoiu Mistrih #include "llvm/CodeGen/MachineRegisterInfo.h" 20b3a0d513SFrancis Visoiu Mistrih #include "llvm/CodeGen/TargetInstrInfo.h" 21aa739695SFrancis Visoiu Mistrih #include "llvm/CodeGen/TargetRegisterInfo.h" 22aa739695SFrancis Visoiu Mistrih #include "llvm/IR/Constants.h" 23e76c5fcdSFrancis Visoiu Mistrih #include "llvm/IR/IRPrintingPasses.h" 24aa739695SFrancis Visoiu Mistrih #include "llvm/IR/ModuleSlotTracker.h" 25a8a83d15SFrancis Visoiu Mistrih #include "llvm/Target/TargetIntrinsicInfo.h" 26a8a83d15SFrancis Visoiu Mistrih #include "llvm/Target/TargetMachine.h" 27aa739695SFrancis Visoiu Mistrih 28aa739695SFrancis Visoiu Mistrih using namespace llvm; 29aa739695SFrancis Visoiu Mistrih 30aa739695SFrancis Visoiu Mistrih static cl::opt<int> 31aa739695SFrancis Visoiu Mistrih PrintRegMaskNumRegs("print-regmask-num-regs", 32aa739695SFrancis Visoiu Mistrih cl::desc("Number of registers to limit to when " 33aa739695SFrancis Visoiu Mistrih "printing regmask operands in IR dumps. " 34aa739695SFrancis Visoiu Mistrih "unlimited = -1"), 35aa739695SFrancis Visoiu Mistrih cl::init(32), cl::Hidden); 36aa739695SFrancis Visoiu Mistrih 3795a05915SFrancis Visoiu Mistrih static const MachineFunction *getMFIfAvailable(const MachineOperand &MO) { 3895a05915SFrancis Visoiu Mistrih if (const MachineInstr *MI = MO.getParent()) 3995a05915SFrancis Visoiu Mistrih if (const MachineBasicBlock *MBB = MI->getParent()) 4095a05915SFrancis Visoiu Mistrih if (const MachineFunction *MF = MBB->getParent()) 4195a05915SFrancis Visoiu Mistrih return MF; 4295a05915SFrancis Visoiu Mistrih return nullptr; 4395a05915SFrancis Visoiu Mistrih } 4495a05915SFrancis Visoiu Mistrih static MachineFunction *getMFIfAvailable(MachineOperand &MO) { 4595a05915SFrancis Visoiu Mistrih return const_cast<MachineFunction *>( 4695a05915SFrancis Visoiu Mistrih getMFIfAvailable(const_cast<const MachineOperand &>(MO))); 4795a05915SFrancis Visoiu Mistrih } 4895a05915SFrancis Visoiu Mistrih 49aa739695SFrancis Visoiu Mistrih void MachineOperand::setReg(unsigned Reg) { 50aa739695SFrancis Visoiu Mistrih if (getReg() == Reg) 51aa739695SFrancis Visoiu Mistrih return; // No change. 52aa739695SFrancis Visoiu Mistrih 53aa739695SFrancis Visoiu Mistrih // Otherwise, we have to change the register. If this operand is embedded 54aa739695SFrancis Visoiu Mistrih // into a machine function, we need to update the old and new register's 55aa739695SFrancis Visoiu Mistrih // use/def lists. 5695a05915SFrancis Visoiu Mistrih if (MachineFunction *MF = getMFIfAvailable(*this)) { 57aa739695SFrancis Visoiu Mistrih MachineRegisterInfo &MRI = MF->getRegInfo(); 58aa739695SFrancis Visoiu Mistrih MRI.removeRegOperandFromUseList(this); 59aa739695SFrancis Visoiu Mistrih SmallContents.RegNo = Reg; 60aa739695SFrancis Visoiu Mistrih MRI.addRegOperandToUseList(this); 61aa739695SFrancis Visoiu Mistrih return; 62aa739695SFrancis Visoiu Mistrih } 63aa739695SFrancis Visoiu Mistrih 64aa739695SFrancis Visoiu Mistrih // Otherwise, just change the register, no problem. :) 65aa739695SFrancis Visoiu Mistrih SmallContents.RegNo = Reg; 66aa739695SFrancis Visoiu Mistrih } 67aa739695SFrancis Visoiu Mistrih 68aa739695SFrancis Visoiu Mistrih void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, 69aa739695SFrancis Visoiu Mistrih const TargetRegisterInfo &TRI) { 70aa739695SFrancis Visoiu Mistrih assert(TargetRegisterInfo::isVirtualRegister(Reg)); 71aa739695SFrancis Visoiu Mistrih if (SubIdx && getSubReg()) 72aa739695SFrancis Visoiu Mistrih SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); 73aa739695SFrancis Visoiu Mistrih setReg(Reg); 74aa739695SFrancis Visoiu Mistrih if (SubIdx) 75aa739695SFrancis Visoiu Mistrih setSubReg(SubIdx); 76aa739695SFrancis Visoiu Mistrih } 77aa739695SFrancis Visoiu Mistrih 78aa739695SFrancis Visoiu Mistrih void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { 79aa739695SFrancis Visoiu Mistrih assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 80aa739695SFrancis Visoiu Mistrih if (getSubReg()) { 81aa739695SFrancis Visoiu Mistrih Reg = TRI.getSubReg(Reg, getSubReg()); 82aa739695SFrancis Visoiu Mistrih // Note that getSubReg() may return 0 if the sub-register doesn't exist. 83aa739695SFrancis Visoiu Mistrih // That won't happen in legal code. 84aa739695SFrancis Visoiu Mistrih setSubReg(0); 85aa739695SFrancis Visoiu Mistrih if (isDef()) 86aa739695SFrancis Visoiu Mistrih setIsUndef(false); 87aa739695SFrancis Visoiu Mistrih } 88aa739695SFrancis Visoiu Mistrih setReg(Reg); 89aa739695SFrancis Visoiu Mistrih } 90aa739695SFrancis Visoiu Mistrih 91aa739695SFrancis Visoiu Mistrih /// Change a def to a use, or a use to a def. 92aa739695SFrancis Visoiu Mistrih void MachineOperand::setIsDef(bool Val) { 93aa739695SFrancis Visoiu Mistrih assert(isReg() && "Wrong MachineOperand accessor"); 94aa739695SFrancis Visoiu Mistrih assert((!Val || !isDebug()) && "Marking a debug operation as def"); 95aa739695SFrancis Visoiu Mistrih if (IsDef == Val) 96aa739695SFrancis Visoiu Mistrih return; 9760c43102SGeoff Berry assert(!IsDeadOrKill && "Changing def/use with dead/kill set not supported"); 98aa739695SFrancis Visoiu Mistrih // MRI may keep uses and defs in different list positions. 9995a05915SFrancis Visoiu Mistrih if (MachineFunction *MF = getMFIfAvailable(*this)) { 100aa739695SFrancis Visoiu Mistrih MachineRegisterInfo &MRI = MF->getRegInfo(); 101aa739695SFrancis Visoiu Mistrih MRI.removeRegOperandFromUseList(this); 102aa739695SFrancis Visoiu Mistrih IsDef = Val; 103aa739695SFrancis Visoiu Mistrih MRI.addRegOperandToUseList(this); 104aa739695SFrancis Visoiu Mistrih return; 105aa739695SFrancis Visoiu Mistrih } 106aa739695SFrancis Visoiu Mistrih IsDef = Val; 107aa739695SFrancis Visoiu Mistrih } 108aa739695SFrancis Visoiu Mistrih 10960c43102SGeoff Berry bool MachineOperand::isRenamable() const { 11060c43102SGeoff Berry assert(isReg() && "Wrong MachineOperand accessor"); 11160c43102SGeoff Berry assert(TargetRegisterInfo::isPhysicalRegister(getReg()) && 11260c43102SGeoff Berry "isRenamable should only be checked on physical registers"); 11360c43102SGeoff Berry return IsRenamable; 11460c43102SGeoff Berry } 11560c43102SGeoff Berry 11660c43102SGeoff Berry void MachineOperand::setIsRenamable(bool Val) { 11760c43102SGeoff Berry assert(isReg() && "Wrong MachineOperand accessor"); 11860c43102SGeoff Berry assert(TargetRegisterInfo::isPhysicalRegister(getReg()) && 11960c43102SGeoff Berry "setIsRenamable should only be called on physical registers"); 12060c43102SGeoff Berry if (const MachineInstr *MI = getParent()) 12160c43102SGeoff Berry if ((isDef() && MI->hasExtraDefRegAllocReq()) || 12260c43102SGeoff Berry (isUse() && MI->hasExtraSrcRegAllocReq())) 12360c43102SGeoff Berry assert(!Val && "isRenamable should be false for " 12460c43102SGeoff Berry "hasExtraDefRegAllocReq/hasExtraSrcRegAllocReq opcodes"); 12560c43102SGeoff Berry IsRenamable = Val; 12660c43102SGeoff Berry } 12760c43102SGeoff Berry 12860c43102SGeoff Berry void MachineOperand::setIsRenamableIfNoExtraRegAllocReq() { 12960c43102SGeoff Berry if (const MachineInstr *MI = getParent()) 13060c43102SGeoff Berry if ((isDef() && MI->hasExtraDefRegAllocReq()) || 13160c43102SGeoff Berry (isUse() && MI->hasExtraSrcRegAllocReq())) 13260c43102SGeoff Berry return; 13360c43102SGeoff Berry 13460c43102SGeoff Berry setIsRenamable(true); 13560c43102SGeoff Berry } 13660c43102SGeoff Berry 137aa739695SFrancis Visoiu Mistrih // If this operand is currently a register operand, and if this is in a 138aa739695SFrancis Visoiu Mistrih // function, deregister the operand from the register's use/def list. 139aa739695SFrancis Visoiu Mistrih void MachineOperand::removeRegFromUses() { 140aa739695SFrancis Visoiu Mistrih if (!isReg() || !isOnRegUseList()) 141aa739695SFrancis Visoiu Mistrih return; 142aa739695SFrancis Visoiu Mistrih 14395a05915SFrancis Visoiu Mistrih if (MachineFunction *MF = getMFIfAvailable(*this)) 144aa739695SFrancis Visoiu Mistrih MF->getRegInfo().removeRegOperandFromUseList(this); 145aa739695SFrancis Visoiu Mistrih } 146aa739695SFrancis Visoiu Mistrih 147aa739695SFrancis Visoiu Mistrih /// ChangeToImmediate - Replace this operand with a new immediate operand of 148aa739695SFrancis Visoiu Mistrih /// the specified value. If an operand is known to be an immediate already, 149aa739695SFrancis Visoiu Mistrih /// the setImm method should be used. 150aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToImmediate(int64_t ImmVal) { 151aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 152aa739695SFrancis Visoiu Mistrih 153aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 154aa739695SFrancis Visoiu Mistrih 155aa739695SFrancis Visoiu Mistrih OpKind = MO_Immediate; 156aa739695SFrancis Visoiu Mistrih Contents.ImmVal = ImmVal; 157aa739695SFrancis Visoiu Mistrih } 158aa739695SFrancis Visoiu Mistrih 159aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) { 160aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 161aa739695SFrancis Visoiu Mistrih 162aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 163aa739695SFrancis Visoiu Mistrih 164aa739695SFrancis Visoiu Mistrih OpKind = MO_FPImmediate; 165aa739695SFrancis Visoiu Mistrih Contents.CFP = FPImm; 166aa739695SFrancis Visoiu Mistrih } 167aa739695SFrancis Visoiu Mistrih 168aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToES(const char *SymName, 169aa739695SFrancis Visoiu Mistrih unsigned char TargetFlags) { 170aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && 171aa739695SFrancis Visoiu Mistrih "Cannot change a tied operand into an external symbol"); 172aa739695SFrancis Visoiu Mistrih 173aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 174aa739695SFrancis Visoiu Mistrih 175aa739695SFrancis Visoiu Mistrih OpKind = MO_ExternalSymbol; 176aa739695SFrancis Visoiu Mistrih Contents.OffsetedInfo.Val.SymbolName = SymName; 177aa739695SFrancis Visoiu Mistrih setOffset(0); // Offset is always 0. 178aa739695SFrancis Visoiu Mistrih setTargetFlags(TargetFlags); 179aa739695SFrancis Visoiu Mistrih } 180aa739695SFrancis Visoiu Mistrih 181aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) { 182aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && 183aa739695SFrancis Visoiu Mistrih "Cannot change a tied operand into an MCSymbol"); 184aa739695SFrancis Visoiu Mistrih 185aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 186aa739695SFrancis Visoiu Mistrih 187aa739695SFrancis Visoiu Mistrih OpKind = MO_MCSymbol; 188aa739695SFrancis Visoiu Mistrih Contents.Sym = Sym; 189aa739695SFrancis Visoiu Mistrih } 190aa739695SFrancis Visoiu Mistrih 191aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToFrameIndex(int Idx) { 192aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && 193aa739695SFrancis Visoiu Mistrih "Cannot change a tied operand into a FrameIndex"); 194aa739695SFrancis Visoiu Mistrih 195aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 196aa739695SFrancis Visoiu Mistrih 197aa739695SFrancis Visoiu Mistrih OpKind = MO_FrameIndex; 198aa739695SFrancis Visoiu Mistrih setIndex(Idx); 199aa739695SFrancis Visoiu Mistrih } 200aa739695SFrancis Visoiu Mistrih 201aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset, 202aa739695SFrancis Visoiu Mistrih unsigned char TargetFlags) { 203aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && 204aa739695SFrancis Visoiu Mistrih "Cannot change a tied operand into a FrameIndex"); 205aa739695SFrancis Visoiu Mistrih 206aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 207aa739695SFrancis Visoiu Mistrih 208aa739695SFrancis Visoiu Mistrih OpKind = MO_TargetIndex; 209aa739695SFrancis Visoiu Mistrih setIndex(Idx); 210aa739695SFrancis Visoiu Mistrih setOffset(Offset); 211aa739695SFrancis Visoiu Mistrih setTargetFlags(TargetFlags); 212aa739695SFrancis Visoiu Mistrih } 213aa739695SFrancis Visoiu Mistrih 214aa739695SFrancis Visoiu Mistrih /// ChangeToRegister - Replace this operand with a new register operand of 215aa739695SFrancis Visoiu Mistrih /// the specified value. If an operand is known to be an register already, 216aa739695SFrancis Visoiu Mistrih /// the setReg method should be used. 217aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, 218aa739695SFrancis Visoiu Mistrih bool isKill, bool isDead, bool isUndef, 219aa739695SFrancis Visoiu Mistrih bool isDebug) { 220aa739695SFrancis Visoiu Mistrih MachineRegisterInfo *RegInfo = nullptr; 22195a05915SFrancis Visoiu Mistrih if (MachineFunction *MF = getMFIfAvailable(*this)) 222aa739695SFrancis Visoiu Mistrih RegInfo = &MF->getRegInfo(); 223aa739695SFrancis Visoiu Mistrih // If this operand is already a register operand, remove it from the 224aa739695SFrancis Visoiu Mistrih // register's use/def lists. 225aa739695SFrancis Visoiu Mistrih bool WasReg = isReg(); 226aa739695SFrancis Visoiu Mistrih if (RegInfo && WasReg) 227aa739695SFrancis Visoiu Mistrih RegInfo->removeRegOperandFromUseList(this); 228aa739695SFrancis Visoiu Mistrih 229aa739695SFrancis Visoiu Mistrih // Change this to a register and set the reg#. 23060c43102SGeoff Berry assert(!(isDead && !isDef) && "Dead flag on non-def"); 23160c43102SGeoff Berry assert(!(isKill && isDef) && "Kill flag on def"); 232aa739695SFrancis Visoiu Mistrih OpKind = MO_Register; 233aa739695SFrancis Visoiu Mistrih SmallContents.RegNo = Reg; 234aa739695SFrancis Visoiu Mistrih SubReg_TargetFlags = 0; 235aa739695SFrancis Visoiu Mistrih IsDef = isDef; 236aa739695SFrancis Visoiu Mistrih IsImp = isImp; 23760c43102SGeoff Berry IsDeadOrKill = isKill | isDead; 23860c43102SGeoff Berry IsRenamable = false; 239aa739695SFrancis Visoiu Mistrih IsUndef = isUndef; 240aa739695SFrancis Visoiu Mistrih IsInternalRead = false; 241aa739695SFrancis Visoiu Mistrih IsEarlyClobber = false; 242aa739695SFrancis Visoiu Mistrih IsDebug = isDebug; 243aa739695SFrancis Visoiu Mistrih // Ensure isOnRegUseList() returns false. 244aa739695SFrancis Visoiu Mistrih Contents.Reg.Prev = nullptr; 245aa739695SFrancis Visoiu Mistrih // Preserve the tie when the operand was already a register. 246aa739695SFrancis Visoiu Mistrih if (!WasReg) 247aa739695SFrancis Visoiu Mistrih TiedTo = 0; 248aa739695SFrancis Visoiu Mistrih 249aa739695SFrancis Visoiu Mistrih // If this operand is embedded in a function, add the operand to the 250aa739695SFrancis Visoiu Mistrih // register's use/def list. 251aa739695SFrancis Visoiu Mistrih if (RegInfo) 252aa739695SFrancis Visoiu Mistrih RegInfo->addRegOperandToUseList(this); 253aa739695SFrancis Visoiu Mistrih } 254aa739695SFrancis Visoiu Mistrih 255aa739695SFrancis Visoiu Mistrih /// isIdenticalTo - Return true if this operand is identical to the specified 256aa739695SFrancis Visoiu Mistrih /// operand. Note that this should stay in sync with the hash_value overload 257aa739695SFrancis Visoiu Mistrih /// below. 258aa739695SFrancis Visoiu Mistrih bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 259aa739695SFrancis Visoiu Mistrih if (getType() != Other.getType() || 260aa739695SFrancis Visoiu Mistrih getTargetFlags() != Other.getTargetFlags()) 261aa739695SFrancis Visoiu Mistrih return false; 262aa739695SFrancis Visoiu Mistrih 263aa739695SFrancis Visoiu Mistrih switch (getType()) { 264aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Register: 265aa739695SFrancis Visoiu Mistrih return getReg() == Other.getReg() && isDef() == Other.isDef() && 266aa739695SFrancis Visoiu Mistrih getSubReg() == Other.getSubReg(); 267aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Immediate: 268aa739695SFrancis Visoiu Mistrih return getImm() == Other.getImm(); 269aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CImmediate: 270aa739695SFrancis Visoiu Mistrih return getCImm() == Other.getCImm(); 271aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FPImmediate: 272aa739695SFrancis Visoiu Mistrih return getFPImm() == Other.getFPImm(); 273aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MachineBasicBlock: 274aa739695SFrancis Visoiu Mistrih return getMBB() == Other.getMBB(); 275aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FrameIndex: 276aa739695SFrancis Visoiu Mistrih return getIndex() == Other.getIndex(); 277aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ConstantPoolIndex: 278aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_TargetIndex: 279aa739695SFrancis Visoiu Mistrih return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 280aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_JumpTableIndex: 281aa739695SFrancis Visoiu Mistrih return getIndex() == Other.getIndex(); 282aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_GlobalAddress: 283aa739695SFrancis Visoiu Mistrih return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 284aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ExternalSymbol: 285aa739695SFrancis Visoiu Mistrih return strcmp(getSymbolName(), Other.getSymbolName()) == 0 && 286aa739695SFrancis Visoiu Mistrih getOffset() == Other.getOffset(); 287aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_BlockAddress: 288aa739695SFrancis Visoiu Mistrih return getBlockAddress() == Other.getBlockAddress() && 289aa739695SFrancis Visoiu Mistrih getOffset() == Other.getOffset(); 290aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterMask: 291aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterLiveOut: { 292aa739695SFrancis Visoiu Mistrih // Shallow compare of the two RegMasks 293aa739695SFrancis Visoiu Mistrih const uint32_t *RegMask = getRegMask(); 294aa739695SFrancis Visoiu Mistrih const uint32_t *OtherRegMask = Other.getRegMask(); 295aa739695SFrancis Visoiu Mistrih if (RegMask == OtherRegMask) 296aa739695SFrancis Visoiu Mistrih return true; 297aa739695SFrancis Visoiu Mistrih 29895a05915SFrancis Visoiu Mistrih if (const MachineFunction *MF = getMFIfAvailable(*this)) { 299aa739695SFrancis Visoiu Mistrih // Calculate the size of the RegMask 300aa739695SFrancis Visoiu Mistrih const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 301aa739695SFrancis Visoiu Mistrih unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32; 302aa739695SFrancis Visoiu Mistrih 303aa739695SFrancis Visoiu Mistrih // Deep compare of the two RegMasks 304aa739695SFrancis Visoiu Mistrih return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask); 305aa739695SFrancis Visoiu Mistrih } 30695a05915SFrancis Visoiu Mistrih // We don't know the size of the RegMask, so we can't deep compare the two 30795a05915SFrancis Visoiu Mistrih // reg masks. 30895a05915SFrancis Visoiu Mistrih return false; 30995a05915SFrancis Visoiu Mistrih } 310aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MCSymbol: 311aa739695SFrancis Visoiu Mistrih return getMCSymbol() == Other.getMCSymbol(); 312aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CFIIndex: 313aa739695SFrancis Visoiu Mistrih return getCFIIndex() == Other.getCFIIndex(); 314aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Metadata: 315aa739695SFrancis Visoiu Mistrih return getMetadata() == Other.getMetadata(); 316aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_IntrinsicID: 317aa739695SFrancis Visoiu Mistrih return getIntrinsicID() == Other.getIntrinsicID(); 318aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Predicate: 319aa739695SFrancis Visoiu Mistrih return getPredicate() == Other.getPredicate(); 320aa739695SFrancis Visoiu Mistrih } 321aa739695SFrancis Visoiu Mistrih llvm_unreachable("Invalid machine operand type"); 322aa739695SFrancis Visoiu Mistrih } 323aa739695SFrancis Visoiu Mistrih 324aa739695SFrancis Visoiu Mistrih // Note: this must stay exactly in sync with isIdenticalTo above. 325aa739695SFrancis Visoiu Mistrih hash_code llvm::hash_value(const MachineOperand &MO) { 326aa739695SFrancis Visoiu Mistrih switch (MO.getType()) { 327aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Register: 328aa739695SFrancis Visoiu Mistrih // Register operands don't have target flags. 329aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef()); 330aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Immediate: 331aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 332aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CImmediate: 333aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 334aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FPImmediate: 335aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 336aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MachineBasicBlock: 337aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 338aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FrameIndex: 339aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 340aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ConstantPoolIndex: 341aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_TargetIndex: 342aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 343aa739695SFrancis Visoiu Mistrih MO.getOffset()); 344aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_JumpTableIndex: 345aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 346aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ExternalSymbol: 347aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 348aa739695SFrancis Visoiu Mistrih MO.getSymbolName()); 349aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_GlobalAddress: 350aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 351aa739695SFrancis Visoiu Mistrih MO.getOffset()); 352aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_BlockAddress: 353aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(), 354aa739695SFrancis Visoiu Mistrih MO.getOffset()); 355aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterMask: 356aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterLiveOut: 357aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); 358aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Metadata: 359aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 360aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MCSymbol: 361aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 362aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CFIIndex: 363aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 364aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_IntrinsicID: 365aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); 366aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Predicate: 367aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); 368aa739695SFrancis Visoiu Mistrih } 369aa739695SFrancis Visoiu Mistrih llvm_unreachable("Invalid machine operand type"); 370aa739695SFrancis Visoiu Mistrih } 371aa739695SFrancis Visoiu Mistrih 372a8a83d15SFrancis Visoiu Mistrih // Try to crawl up to the machine function and get TRI and IntrinsicInfo from 373a8a83d15SFrancis Visoiu Mistrih // it. 374a8a83d15SFrancis Visoiu Mistrih static void tryToGetTargetInfo(const MachineOperand &MO, 375a8a83d15SFrancis Visoiu Mistrih const TargetRegisterInfo *&TRI, 376a8a83d15SFrancis Visoiu Mistrih const TargetIntrinsicInfo *&IntrinsicInfo) { 377567611efSFrancis Visoiu Mistrih if (const MachineFunction *MF = getMFIfAvailable(MO)) { 378a8a83d15SFrancis Visoiu Mistrih TRI = MF->getSubtarget().getRegisterInfo(); 379a8a83d15SFrancis Visoiu Mistrih IntrinsicInfo = MF->getTarget().getIntrinsicInfo(); 380a8a83d15SFrancis Visoiu Mistrih } 381a8a83d15SFrancis Visoiu Mistrih } 382a8a83d15SFrancis Visoiu Mistrih 383b3a0d513SFrancis Visoiu Mistrih static const char *getTargetIndexName(const MachineFunction &MF, int Index) { 384b3a0d513SFrancis Visoiu Mistrih const auto *TII = MF.getSubtarget().getInstrInfo(); 385b3a0d513SFrancis Visoiu Mistrih assert(TII && "expected instruction info"); 386b3a0d513SFrancis Visoiu Mistrih auto Indices = TII->getSerializableTargetIndices(); 387b3a0d513SFrancis Visoiu Mistrih auto Found = find_if(Indices, [&](const std::pair<int, const char *> &I) { 388b3a0d513SFrancis Visoiu Mistrih return I.first == Index; 389b3a0d513SFrancis Visoiu Mistrih }); 390b3a0d513SFrancis Visoiu Mistrih if (Found != Indices.end()) 391b3a0d513SFrancis Visoiu Mistrih return Found->second; 392b3a0d513SFrancis Visoiu Mistrih return nullptr; 393b3a0d513SFrancis Visoiu Mistrih } 394b3a0d513SFrancis Visoiu Mistrih 3955df3bbf3SFrancis Visoiu Mistrih static const char *getTargetFlagName(const TargetInstrInfo *TII, unsigned TF) { 3965df3bbf3SFrancis Visoiu Mistrih auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 3975df3bbf3SFrancis Visoiu Mistrih for (const auto &I : Flags) { 3985df3bbf3SFrancis Visoiu Mistrih if (I.first == TF) { 3995df3bbf3SFrancis Visoiu Mistrih return I.second; 4005df3bbf3SFrancis Visoiu Mistrih } 4015df3bbf3SFrancis Visoiu Mistrih } 4025df3bbf3SFrancis Visoiu Mistrih return nullptr; 4035df3bbf3SFrancis Visoiu Mistrih } 4045df3bbf3SFrancis Visoiu Mistrih 405874ae6faSFrancis Visoiu Mistrih static void printCFIRegister(unsigned DwarfReg, raw_ostream &OS, 406874ae6faSFrancis Visoiu Mistrih const TargetRegisterInfo *TRI) { 407874ae6faSFrancis Visoiu Mistrih if (!TRI) { 408874ae6faSFrancis Visoiu Mistrih OS << "%dwarfreg." << DwarfReg; 409874ae6faSFrancis Visoiu Mistrih return; 410874ae6faSFrancis Visoiu Mistrih } 411874ae6faSFrancis Visoiu Mistrih 412874ae6faSFrancis Visoiu Mistrih int Reg = TRI->getLLVMRegNum(DwarfReg, true); 413874ae6faSFrancis Visoiu Mistrih if (Reg == -1) { 414874ae6faSFrancis Visoiu Mistrih OS << "<badreg>"; 415874ae6faSFrancis Visoiu Mistrih return; 416874ae6faSFrancis Visoiu Mistrih } 417874ae6faSFrancis Visoiu Mistrih OS << printReg(Reg, TRI); 418874ae6faSFrancis Visoiu Mistrih } 419874ae6faSFrancis Visoiu Mistrih 420f81727d1SFrancis Visoiu Mistrih static void printIRBlockReference(raw_ostream &OS, const BasicBlock &BB, 421f81727d1SFrancis Visoiu Mistrih ModuleSlotTracker &MST) { 422f81727d1SFrancis Visoiu Mistrih OS << "%ir-block."; 423f81727d1SFrancis Visoiu Mistrih if (BB.hasName()) { 424f81727d1SFrancis Visoiu Mistrih printLLVMNameWithoutPrefix(OS, BB.getName()); 425f81727d1SFrancis Visoiu Mistrih return; 426f81727d1SFrancis Visoiu Mistrih } 427f81727d1SFrancis Visoiu Mistrih Optional<int> Slot; 428f81727d1SFrancis Visoiu Mistrih if (const Function *F = BB.getParent()) { 429f81727d1SFrancis Visoiu Mistrih if (F == MST.getCurrentFunction()) { 430f81727d1SFrancis Visoiu Mistrih Slot = MST.getLocalSlot(&BB); 431f81727d1SFrancis Visoiu Mistrih } else if (const Module *M = F->getParent()) { 432f81727d1SFrancis Visoiu Mistrih ModuleSlotTracker CustomMST(M, /*ShouldInitializeAllMetadata=*/false); 433f81727d1SFrancis Visoiu Mistrih CustomMST.incorporateFunction(*F); 434f81727d1SFrancis Visoiu Mistrih Slot = CustomMST.getLocalSlot(&BB); 435f81727d1SFrancis Visoiu Mistrih } 436f81727d1SFrancis Visoiu Mistrih } 437f81727d1SFrancis Visoiu Mistrih if (Slot) 438f81727d1SFrancis Visoiu Mistrih MachineOperand::printIRSlotNumber(OS, *Slot); 439f81727d1SFrancis Visoiu Mistrih else 440f81727d1SFrancis Visoiu Mistrih OS << "<unknown>"; 441f81727d1SFrancis Visoiu Mistrih } 442f81727d1SFrancis Visoiu Mistrih 443ecd0b833SFrancis Visoiu Mistrih void MachineOperand::printSubRegIdx(raw_ostream &OS, uint64_t Index, 444440f69c9SFrancis Visoiu Mistrih const TargetRegisterInfo *TRI) { 445440f69c9SFrancis Visoiu Mistrih OS << "%subreg."; 446440f69c9SFrancis Visoiu Mistrih if (TRI) 447440f69c9SFrancis Visoiu Mistrih OS << TRI->getSubRegIndexName(Index); 448440f69c9SFrancis Visoiu Mistrih else 449440f69c9SFrancis Visoiu Mistrih OS << Index; 450440f69c9SFrancis Visoiu Mistrih } 451440f69c9SFrancis Visoiu Mistrih 4525df3bbf3SFrancis Visoiu Mistrih void MachineOperand::printTargetFlags(raw_ostream &OS, 4535df3bbf3SFrancis Visoiu Mistrih const MachineOperand &Op) { 4545df3bbf3SFrancis Visoiu Mistrih if (!Op.getTargetFlags()) 4555df3bbf3SFrancis Visoiu Mistrih return; 4565df3bbf3SFrancis Visoiu Mistrih const MachineFunction *MF = getMFIfAvailable(Op); 4575df3bbf3SFrancis Visoiu Mistrih if (!MF) 4585df3bbf3SFrancis Visoiu Mistrih return; 4595df3bbf3SFrancis Visoiu Mistrih 4605df3bbf3SFrancis Visoiu Mistrih const auto *TII = MF->getSubtarget().getInstrInfo(); 4615df3bbf3SFrancis Visoiu Mistrih assert(TII && "expected instruction info"); 4625df3bbf3SFrancis Visoiu Mistrih auto Flags = TII->decomposeMachineOperandsTargetFlags(Op.getTargetFlags()); 4635df3bbf3SFrancis Visoiu Mistrih OS << "target-flags("; 4645df3bbf3SFrancis Visoiu Mistrih const bool HasDirectFlags = Flags.first; 4655df3bbf3SFrancis Visoiu Mistrih const bool HasBitmaskFlags = Flags.second; 4665df3bbf3SFrancis Visoiu Mistrih if (!HasDirectFlags && !HasBitmaskFlags) { 4675df3bbf3SFrancis Visoiu Mistrih OS << "<unknown>) "; 4685df3bbf3SFrancis Visoiu Mistrih return; 4695df3bbf3SFrancis Visoiu Mistrih } 4705df3bbf3SFrancis Visoiu Mistrih if (HasDirectFlags) { 4715df3bbf3SFrancis Visoiu Mistrih if (const auto *Name = getTargetFlagName(TII, Flags.first)) 4725df3bbf3SFrancis Visoiu Mistrih OS << Name; 4735df3bbf3SFrancis Visoiu Mistrih else 4745df3bbf3SFrancis Visoiu Mistrih OS << "<unknown target flag>"; 4755df3bbf3SFrancis Visoiu Mistrih } 4765df3bbf3SFrancis Visoiu Mistrih if (!HasBitmaskFlags) { 4775df3bbf3SFrancis Visoiu Mistrih OS << ") "; 4785df3bbf3SFrancis Visoiu Mistrih return; 4795df3bbf3SFrancis Visoiu Mistrih } 4805df3bbf3SFrancis Visoiu Mistrih bool IsCommaNeeded = HasDirectFlags; 4815df3bbf3SFrancis Visoiu Mistrih unsigned BitMask = Flags.second; 4825df3bbf3SFrancis Visoiu Mistrih auto BitMasks = TII->getSerializableBitmaskMachineOperandTargetFlags(); 4835df3bbf3SFrancis Visoiu Mistrih for (const auto &Mask : BitMasks) { 4845df3bbf3SFrancis Visoiu Mistrih // Check if the flag's bitmask has the bits of the current mask set. 4855df3bbf3SFrancis Visoiu Mistrih if ((BitMask & Mask.first) == Mask.first) { 4865df3bbf3SFrancis Visoiu Mistrih if (IsCommaNeeded) 4875df3bbf3SFrancis Visoiu Mistrih OS << ", "; 4885df3bbf3SFrancis Visoiu Mistrih IsCommaNeeded = true; 4895df3bbf3SFrancis Visoiu Mistrih OS << Mask.second; 4905df3bbf3SFrancis Visoiu Mistrih // Clear the bits which were serialized from the flag's bitmask. 4915df3bbf3SFrancis Visoiu Mistrih BitMask &= ~(Mask.first); 4925df3bbf3SFrancis Visoiu Mistrih } 4935df3bbf3SFrancis Visoiu Mistrih } 4945df3bbf3SFrancis Visoiu Mistrih if (BitMask) { 4955df3bbf3SFrancis Visoiu Mistrih // When the resulting flag's bitmask isn't zero, we know that we didn't 4965df3bbf3SFrancis Visoiu Mistrih // serialize all of the bit flags. 4975df3bbf3SFrancis Visoiu Mistrih if (IsCommaNeeded) 4985df3bbf3SFrancis Visoiu Mistrih OS << ", "; 4995df3bbf3SFrancis Visoiu Mistrih OS << "<unknown bitmask target flag>"; 5005df3bbf3SFrancis Visoiu Mistrih } 5015df3bbf3SFrancis Visoiu Mistrih OS << ") "; 5025df3bbf3SFrancis Visoiu Mistrih } 5035df3bbf3SFrancis Visoiu Mistrih 5045de20e03SFrancis Visoiu Mistrih void MachineOperand::printSymbol(raw_ostream &OS, MCSymbol &Sym) { 5055de20e03SFrancis Visoiu Mistrih OS << "<mcsymbol " << Sym << ">"; 5065de20e03SFrancis Visoiu Mistrih } 5075de20e03SFrancis Visoiu Mistrih 5080b5bdceaSFrancis Visoiu Mistrih void MachineOperand::printStackObjectReference(raw_ostream &OS, 5090b5bdceaSFrancis Visoiu Mistrih unsigned FrameIndex, 5100b5bdceaSFrancis Visoiu Mistrih bool IsFixed, StringRef Name) { 5110b5bdceaSFrancis Visoiu Mistrih if (IsFixed) { 5120b5bdceaSFrancis Visoiu Mistrih OS << "%fixed-stack." << FrameIndex; 5130b5bdceaSFrancis Visoiu Mistrih return; 5140b5bdceaSFrancis Visoiu Mistrih } 5150b5bdceaSFrancis Visoiu Mistrih 5160b5bdceaSFrancis Visoiu Mistrih OS << "%stack." << FrameIndex; 5170b5bdceaSFrancis Visoiu Mistrih if (!Name.empty()) 5180b5bdceaSFrancis Visoiu Mistrih OS << '.' << Name; 5190b5bdceaSFrancis Visoiu Mistrih } 5200b5bdceaSFrancis Visoiu Mistrih 52181226602SFrancis Visoiu Mistrih void MachineOperand::printOperandOffset(raw_ostream &OS, int64_t Offset) { 52281226602SFrancis Visoiu Mistrih if (Offset == 0) 52381226602SFrancis Visoiu Mistrih return; 52481226602SFrancis Visoiu Mistrih if (Offset < 0) { 52581226602SFrancis Visoiu Mistrih OS << " - " << -Offset; 52681226602SFrancis Visoiu Mistrih return; 52781226602SFrancis Visoiu Mistrih } 52881226602SFrancis Visoiu Mistrih OS << " + " << Offset; 52981226602SFrancis Visoiu Mistrih } 53081226602SFrancis Visoiu Mistrih 531f81727d1SFrancis Visoiu Mistrih void MachineOperand::printIRSlotNumber(raw_ostream &OS, int Slot) { 532f81727d1SFrancis Visoiu Mistrih if (Slot == -1) 533f81727d1SFrancis Visoiu Mistrih OS << "<badref>"; 534f81727d1SFrancis Visoiu Mistrih else 535f81727d1SFrancis Visoiu Mistrih OS << Slot; 536f81727d1SFrancis Visoiu Mistrih } 537f81727d1SFrancis Visoiu Mistrih 538874ae6faSFrancis Visoiu Mistrih static void printCFI(raw_ostream &OS, const MCCFIInstruction &CFI, 539874ae6faSFrancis Visoiu Mistrih const TargetRegisterInfo *TRI) { 540874ae6faSFrancis Visoiu Mistrih switch (CFI.getOperation()) { 541874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpSameValue: 542874ae6faSFrancis Visoiu Mistrih OS << "same_value "; 543874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 544874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 545874ae6faSFrancis Visoiu Mistrih printCFIRegister(CFI.getRegister(), OS, TRI); 546874ae6faSFrancis Visoiu Mistrih break; 547874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpRememberState: 548874ae6faSFrancis Visoiu Mistrih OS << "remember_state "; 549874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 550874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 551874ae6faSFrancis Visoiu Mistrih break; 552874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpRestoreState: 553874ae6faSFrancis Visoiu Mistrih OS << "restore_state "; 554874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 555874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 556874ae6faSFrancis Visoiu Mistrih break; 557874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpOffset: 558874ae6faSFrancis Visoiu Mistrih OS << "offset "; 559874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 560874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 561874ae6faSFrancis Visoiu Mistrih printCFIRegister(CFI.getRegister(), OS, TRI); 562874ae6faSFrancis Visoiu Mistrih OS << ", " << CFI.getOffset(); 563874ae6faSFrancis Visoiu Mistrih break; 564874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpDefCfaRegister: 565874ae6faSFrancis Visoiu Mistrih OS << "def_cfa_register "; 566874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 567874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 568874ae6faSFrancis Visoiu Mistrih printCFIRegister(CFI.getRegister(), OS, TRI); 569874ae6faSFrancis Visoiu Mistrih break; 570874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpDefCfaOffset: 571874ae6faSFrancis Visoiu Mistrih OS << "def_cfa_offset "; 572874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 573874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 574874ae6faSFrancis Visoiu Mistrih OS << CFI.getOffset(); 575874ae6faSFrancis Visoiu Mistrih break; 576874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpDefCfa: 577874ae6faSFrancis Visoiu Mistrih OS << "def_cfa "; 578874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 579874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 580874ae6faSFrancis Visoiu Mistrih printCFIRegister(CFI.getRegister(), OS, TRI); 581874ae6faSFrancis Visoiu Mistrih OS << ", " << CFI.getOffset(); 582874ae6faSFrancis Visoiu Mistrih break; 583874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpRelOffset: 584874ae6faSFrancis Visoiu Mistrih OS << "rel_offset "; 585874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 586874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 587874ae6faSFrancis Visoiu Mistrih printCFIRegister(CFI.getRegister(), OS, TRI); 588874ae6faSFrancis Visoiu Mistrih OS << ", " << CFI.getOffset(); 589874ae6faSFrancis Visoiu Mistrih break; 590874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpAdjustCfaOffset: 591874ae6faSFrancis Visoiu Mistrih OS << "adjust_cfa_offset "; 592874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 593874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 594874ae6faSFrancis Visoiu Mistrih OS << CFI.getOffset(); 595874ae6faSFrancis Visoiu Mistrih break; 596874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpRestore: 597874ae6faSFrancis Visoiu Mistrih OS << "restore "; 598874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 599874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 600874ae6faSFrancis Visoiu Mistrih printCFIRegister(CFI.getRegister(), OS, TRI); 601874ae6faSFrancis Visoiu Mistrih break; 602874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpEscape: { 603874ae6faSFrancis Visoiu Mistrih OS << "escape "; 604874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 605874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 606874ae6faSFrancis Visoiu Mistrih if (!CFI.getValues().empty()) { 607874ae6faSFrancis Visoiu Mistrih size_t e = CFI.getValues().size() - 1; 608874ae6faSFrancis Visoiu Mistrih for (size_t i = 0; i < e; ++i) 609874ae6faSFrancis Visoiu Mistrih OS << format("0x%02x", uint8_t(CFI.getValues()[i])) << ", "; 610874ae6faSFrancis Visoiu Mistrih OS << format("0x%02x", uint8_t(CFI.getValues()[e])) << ", "; 611874ae6faSFrancis Visoiu Mistrih } 612874ae6faSFrancis Visoiu Mistrih break; 613874ae6faSFrancis Visoiu Mistrih } 614874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpUndefined: 615874ae6faSFrancis Visoiu Mistrih OS << "undefined "; 616874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 617874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 618874ae6faSFrancis Visoiu Mistrih printCFIRegister(CFI.getRegister(), OS, TRI); 619874ae6faSFrancis Visoiu Mistrih break; 620874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpRegister: 621874ae6faSFrancis Visoiu Mistrih OS << "register "; 622874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 623874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 624874ae6faSFrancis Visoiu Mistrih printCFIRegister(CFI.getRegister(), OS, TRI); 625874ae6faSFrancis Visoiu Mistrih OS << ", "; 626874ae6faSFrancis Visoiu Mistrih printCFIRegister(CFI.getRegister2(), OS, TRI); 627874ae6faSFrancis Visoiu Mistrih break; 628874ae6faSFrancis Visoiu Mistrih case MCCFIInstruction::OpWindowSave: 629874ae6faSFrancis Visoiu Mistrih OS << "window_save "; 630874ae6faSFrancis Visoiu Mistrih if (MCSymbol *Label = CFI.getLabel()) 631874ae6faSFrancis Visoiu Mistrih MachineOperand::printSymbol(OS, *Label); 632874ae6faSFrancis Visoiu Mistrih break; 633874ae6faSFrancis Visoiu Mistrih default: 634874ae6faSFrancis Visoiu Mistrih // TODO: Print the other CFI Operations. 635874ae6faSFrancis Visoiu Mistrih OS << "<unserializable cfi directive>"; 636874ae6faSFrancis Visoiu Mistrih break; 637874ae6faSFrancis Visoiu Mistrih } 638874ae6faSFrancis Visoiu Mistrih } 639874ae6faSFrancis Visoiu Mistrih 640aa739695SFrancis Visoiu Mistrih void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, 641aa739695SFrancis Visoiu Mistrih const TargetIntrinsicInfo *IntrinsicInfo) const { 642a8a83d15SFrancis Visoiu Mistrih tryToGetTargetInfo(*this, TRI, IntrinsicInfo); 643aa739695SFrancis Visoiu Mistrih ModuleSlotTracker DummyMST(nullptr); 644*eb3f76fcSFrancis Visoiu Mistrih print(OS, DummyMST, LLT{}, /*PrintDef=*/false, /*IsStandalone=*/true, 645a8a83d15SFrancis Visoiu Mistrih /*ShouldPrintRegisterTies=*/true, 646a8a83d15SFrancis Visoiu Mistrih /*TiedOperandIdx=*/0, TRI, IntrinsicInfo); 647aa739695SFrancis Visoiu Mistrih } 648aa739695SFrancis Visoiu Mistrih 649aa739695SFrancis Visoiu Mistrih void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 650*eb3f76fcSFrancis Visoiu Mistrih LLT TypeToPrint, bool PrintDef, bool IsStandalone, 651a8a83d15SFrancis Visoiu Mistrih bool ShouldPrintRegisterTies, 652a8a83d15SFrancis Visoiu Mistrih unsigned TiedOperandIdx, 653aa739695SFrancis Visoiu Mistrih const TargetRegisterInfo *TRI, 654aa739695SFrancis Visoiu Mistrih const TargetIntrinsicInfo *IntrinsicInfo) const { 6555df3bbf3SFrancis Visoiu Mistrih printTargetFlags(OS, *this); 656aa739695SFrancis Visoiu Mistrih switch (getType()) { 657a8a83d15SFrancis Visoiu Mistrih case MachineOperand::MO_Register: { 658a8a83d15SFrancis Visoiu Mistrih unsigned Reg = getReg(); 659aa739695SFrancis Visoiu Mistrih if (isImplicit()) 660a8a83d15SFrancis Visoiu Mistrih OS << (isDef() ? "implicit-def " : "implicit "); 661a8a83d15SFrancis Visoiu Mistrih else if (PrintDef && isDef()) 662a8a83d15SFrancis Visoiu Mistrih // Print the 'def' flag only when the operand is defined after '='. 663aa739695SFrancis Visoiu Mistrih OS << "def "; 664a8a83d15SFrancis Visoiu Mistrih if (isInternalRead()) 665aa739695SFrancis Visoiu Mistrih OS << "internal "; 666a8a83d15SFrancis Visoiu Mistrih if (isDead()) 667a8a83d15SFrancis Visoiu Mistrih OS << "dead "; 668a8a83d15SFrancis Visoiu Mistrih if (isKill()) 669a8a83d15SFrancis Visoiu Mistrih OS << "killed "; 670a8a83d15SFrancis Visoiu Mistrih if (isUndef()) 671a8a83d15SFrancis Visoiu Mistrih OS << "undef "; 672a8a83d15SFrancis Visoiu Mistrih if (isEarlyClobber()) 673a8a83d15SFrancis Visoiu Mistrih OS << "early-clobber "; 674a8a83d15SFrancis Visoiu Mistrih if (isDebug()) 675a8a83d15SFrancis Visoiu Mistrih OS << "debug-use "; 67660c43102SGeoff Berry if (TargetRegisterInfo::isPhysicalRegister(getReg()) && isRenamable()) 67760c43102SGeoff Berry OS << "renamable "; 678a8a83d15SFrancis Visoiu Mistrih OS << printReg(Reg, TRI); 679a8a83d15SFrancis Visoiu Mistrih // Print the sub register. 680a8a83d15SFrancis Visoiu Mistrih if (unsigned SubReg = getSubReg()) { 681a8a83d15SFrancis Visoiu Mistrih if (TRI) 682a8a83d15SFrancis Visoiu Mistrih OS << '.' << TRI->getSubRegIndexName(SubReg); 683a8a83d15SFrancis Visoiu Mistrih else 684a8a83d15SFrancis Visoiu Mistrih OS << ".subreg" << SubReg; 685aa739695SFrancis Visoiu Mistrih } 686a8a83d15SFrancis Visoiu Mistrih // Print the register class / bank. 687a8a83d15SFrancis Visoiu Mistrih if (TargetRegisterInfo::isVirtualRegister(Reg)) { 688567611efSFrancis Visoiu Mistrih if (const MachineFunction *MF = getMFIfAvailable(*this)) { 689a8a83d15SFrancis Visoiu Mistrih const MachineRegisterInfo &MRI = MF->getRegInfo(); 690*eb3f76fcSFrancis Visoiu Mistrih if (IsStandalone || !PrintDef || MRI.def_empty(Reg)) { 691a8a83d15SFrancis Visoiu Mistrih OS << ':'; 692a8a83d15SFrancis Visoiu Mistrih OS << printRegClassOrBank(Reg, MRI, TRI); 693aa739695SFrancis Visoiu Mistrih } 694aa739695SFrancis Visoiu Mistrih } 695a8a83d15SFrancis Visoiu Mistrih } 696a8a83d15SFrancis Visoiu Mistrih // Print ties. 697a8a83d15SFrancis Visoiu Mistrih if (ShouldPrintRegisterTies && isTied() && !isDef()) 698a8a83d15SFrancis Visoiu Mistrih OS << "(tied-def " << TiedOperandIdx << ")"; 699a8a83d15SFrancis Visoiu Mistrih // Print types. 700a8a83d15SFrancis Visoiu Mistrih if (TypeToPrint.isValid()) 701a8a83d15SFrancis Visoiu Mistrih OS << '(' << TypeToPrint << ')'; 702aa739695SFrancis Visoiu Mistrih break; 703a8a83d15SFrancis Visoiu Mistrih } 704aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Immediate: 705aa739695SFrancis Visoiu Mistrih OS << getImm(); 706aa739695SFrancis Visoiu Mistrih break; 707aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CImmediate: 7086c4ca713SFrancis Visoiu Mistrih getCImm()->printAsOperand(OS, /*PrintType=*/true, MST); 709aa739695SFrancis Visoiu Mistrih break; 710aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FPImmediate: 7113b265c8fSFrancis Visoiu Mistrih getFPImm()->printAsOperand(OS, /*PrintType=*/true, MST); 712aa739695SFrancis Visoiu Mistrih break; 713aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MachineBasicBlock: 71425528d6dSFrancis Visoiu Mistrih OS << printMBBReference(*getMBB()); 715aa739695SFrancis Visoiu Mistrih break; 7160b5bdceaSFrancis Visoiu Mistrih case MachineOperand::MO_FrameIndex: { 7170b5bdceaSFrancis Visoiu Mistrih int FrameIndex = getIndex(); 7180b5bdceaSFrancis Visoiu Mistrih bool IsFixed = false; 7190b5bdceaSFrancis Visoiu Mistrih StringRef Name; 7200b5bdceaSFrancis Visoiu Mistrih if (const MachineFunction *MF = getMFIfAvailable(*this)) { 7210b5bdceaSFrancis Visoiu Mistrih const MachineFrameInfo &MFI = MF->getFrameInfo(); 7220b5bdceaSFrancis Visoiu Mistrih IsFixed = MFI.isFixedObjectIndex(FrameIndex); 7230b5bdceaSFrancis Visoiu Mistrih if (const AllocaInst *Alloca = MFI.getObjectAllocation(FrameIndex)) 7240b5bdceaSFrancis Visoiu Mistrih if (Alloca->hasName()) 7250b5bdceaSFrancis Visoiu Mistrih Name = Alloca->getName(); 7260b5bdceaSFrancis Visoiu Mistrih if (IsFixed) 7270b5bdceaSFrancis Visoiu Mistrih FrameIndex -= MFI.getObjectIndexBegin(); 7280b5bdceaSFrancis Visoiu Mistrih } 7290b5bdceaSFrancis Visoiu Mistrih printStackObjectReference(OS, FrameIndex, IsFixed, Name); 730aa739695SFrancis Visoiu Mistrih break; 7310b5bdceaSFrancis Visoiu Mistrih } 732aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ConstantPoolIndex: 73326ae8a65SFrancis Visoiu Mistrih OS << "%const." << getIndex(); 73481226602SFrancis Visoiu Mistrih printOperandOffset(OS, getOffset()); 735aa739695SFrancis Visoiu Mistrih break; 736b3a0d513SFrancis Visoiu Mistrih case MachineOperand::MO_TargetIndex: { 737b3a0d513SFrancis Visoiu Mistrih OS << "target-index("; 738b3a0d513SFrancis Visoiu Mistrih const char *Name = "<unknown>"; 739b3a0d513SFrancis Visoiu Mistrih if (const MachineFunction *MF = getMFIfAvailable(*this)) 740b3a0d513SFrancis Visoiu Mistrih if (const auto *TargetIndexName = getTargetIndexName(*MF, getIndex())) 741b3a0d513SFrancis Visoiu Mistrih Name = TargetIndexName; 742b3a0d513SFrancis Visoiu Mistrih OS << Name << ')'; 74381226602SFrancis Visoiu Mistrih printOperandOffset(OS, getOffset()); 744aa739695SFrancis Visoiu Mistrih break; 745b3a0d513SFrancis Visoiu Mistrih } 746aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_JumpTableIndex: 747b41dbbe3SFrancis Visoiu Mistrih OS << printJumpTableEntryReference(getIndex()); 748aa739695SFrancis Visoiu Mistrih break; 749aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_GlobalAddress: 750aa739695SFrancis Visoiu Mistrih getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 75181226602SFrancis Visoiu Mistrih printOperandOffset(OS, getOffset()); 752aa739695SFrancis Visoiu Mistrih break; 753e76c5fcdSFrancis Visoiu Mistrih case MachineOperand::MO_ExternalSymbol: { 754e76c5fcdSFrancis Visoiu Mistrih StringRef Name = getSymbolName(); 755fe6c9cbbSPuyan Lotfi OS << '&'; 756e76c5fcdSFrancis Visoiu Mistrih if (Name.empty()) { 757e76c5fcdSFrancis Visoiu Mistrih OS << "\"\""; 758e76c5fcdSFrancis Visoiu Mistrih } else { 759e76c5fcdSFrancis Visoiu Mistrih printLLVMNameWithoutPrefix(OS, Name); 760e76c5fcdSFrancis Visoiu Mistrih } 76181226602SFrancis Visoiu Mistrih printOperandOffset(OS, getOffset()); 762aa739695SFrancis Visoiu Mistrih break; 763e76c5fcdSFrancis Visoiu Mistrih } 764f81727d1SFrancis Visoiu Mistrih case MachineOperand::MO_BlockAddress: { 765f81727d1SFrancis Visoiu Mistrih OS << "blockaddress("; 766f81727d1SFrancis Visoiu Mistrih getBlockAddress()->getFunction()->printAsOperand(OS, /*PrintType=*/false, 767f81727d1SFrancis Visoiu Mistrih MST); 768f81727d1SFrancis Visoiu Mistrih OS << ", "; 769f81727d1SFrancis Visoiu Mistrih printIRBlockReference(OS, *getBlockAddress()->getBasicBlock(), MST); 770f81727d1SFrancis Visoiu Mistrih OS << ')'; 771f81727d1SFrancis Visoiu Mistrih MachineOperand::printOperandOffset(OS, getOffset()); 772aa739695SFrancis Visoiu Mistrih break; 773f81727d1SFrancis Visoiu Mistrih } 774aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterMask: { 775a8a83d15SFrancis Visoiu Mistrih OS << "<regmask"; 776a8a83d15SFrancis Visoiu Mistrih if (TRI) { 777aa739695SFrancis Visoiu Mistrih unsigned NumRegsInMask = 0; 778aa739695SFrancis Visoiu Mistrih unsigned NumRegsEmitted = 0; 779aa739695SFrancis Visoiu Mistrih for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { 780aa739695SFrancis Visoiu Mistrih unsigned MaskWord = i / 32; 781aa739695SFrancis Visoiu Mistrih unsigned MaskBit = i % 32; 782aa739695SFrancis Visoiu Mistrih if (getRegMask()[MaskWord] & (1 << MaskBit)) { 783aa739695SFrancis Visoiu Mistrih if (PrintRegMaskNumRegs < 0 || 784aa739695SFrancis Visoiu Mistrih NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) { 785aa739695SFrancis Visoiu Mistrih OS << " " << printReg(i, TRI); 786aa739695SFrancis Visoiu Mistrih NumRegsEmitted++; 787aa739695SFrancis Visoiu Mistrih } 788aa739695SFrancis Visoiu Mistrih NumRegsInMask++; 789aa739695SFrancis Visoiu Mistrih } 790aa739695SFrancis Visoiu Mistrih } 791aa739695SFrancis Visoiu Mistrih if (NumRegsEmitted != NumRegsInMask) 792aa739695SFrancis Visoiu Mistrih OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; 793a8a83d15SFrancis Visoiu Mistrih } else { 794a8a83d15SFrancis Visoiu Mistrih OS << " ..."; 795a8a83d15SFrancis Visoiu Mistrih } 796aa739695SFrancis Visoiu Mistrih OS << ">"; 797aa739695SFrancis Visoiu Mistrih break; 798aa739695SFrancis Visoiu Mistrih } 799bdaf8bfaSFrancis Visoiu Mistrih case MachineOperand::MO_RegisterLiveOut: { 800bdaf8bfaSFrancis Visoiu Mistrih const uint32_t *RegMask = getRegLiveOut(); 801bdaf8bfaSFrancis Visoiu Mistrih OS << "liveout("; 802bdaf8bfaSFrancis Visoiu Mistrih if (!TRI) { 803bdaf8bfaSFrancis Visoiu Mistrih OS << "<unknown>"; 804bdaf8bfaSFrancis Visoiu Mistrih } else { 805bdaf8bfaSFrancis Visoiu Mistrih bool IsCommaNeeded = false; 806bdaf8bfaSFrancis Visoiu Mistrih for (unsigned Reg = 0, E = TRI->getNumRegs(); Reg < E; ++Reg) { 807bdaf8bfaSFrancis Visoiu Mistrih if (RegMask[Reg / 32] & (1U << (Reg % 32))) { 808bdaf8bfaSFrancis Visoiu Mistrih if (IsCommaNeeded) 809bdaf8bfaSFrancis Visoiu Mistrih OS << ", "; 810bdaf8bfaSFrancis Visoiu Mistrih OS << printReg(Reg, TRI); 811bdaf8bfaSFrancis Visoiu Mistrih IsCommaNeeded = true; 812bdaf8bfaSFrancis Visoiu Mistrih } 813bdaf8bfaSFrancis Visoiu Mistrih } 814bdaf8bfaSFrancis Visoiu Mistrih } 815bdaf8bfaSFrancis Visoiu Mistrih OS << ")"; 816aa739695SFrancis Visoiu Mistrih break; 817bdaf8bfaSFrancis Visoiu Mistrih } 818aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Metadata: 819aa739695SFrancis Visoiu Mistrih getMetadata()->printAsOperand(OS, MST); 820aa739695SFrancis Visoiu Mistrih break; 821aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MCSymbol: 8225de20e03SFrancis Visoiu Mistrih printSymbol(OS, *getMCSymbol()); 823aa739695SFrancis Visoiu Mistrih break; 824874ae6faSFrancis Visoiu Mistrih case MachineOperand::MO_CFIIndex: { 825874ae6faSFrancis Visoiu Mistrih if (const MachineFunction *MF = getMFIfAvailable(*this)) 826874ae6faSFrancis Visoiu Mistrih printCFI(OS, MF->getFrameInstructions()[getCFIIndex()], TRI); 827874ae6faSFrancis Visoiu Mistrih else 828874ae6faSFrancis Visoiu Mistrih OS << "<cfi directive>"; 829aa739695SFrancis Visoiu Mistrih break; 830874ae6faSFrancis Visoiu Mistrih } 831aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_IntrinsicID: { 832aa739695SFrancis Visoiu Mistrih Intrinsic::ID ID = getIntrinsicID(); 833aa739695SFrancis Visoiu Mistrih if (ID < Intrinsic::num_intrinsics) 834bbd610aeSFrancis Visoiu Mistrih OS << "intrinsic(@" << Intrinsic::getName(ID, None) << ')'; 835aa739695SFrancis Visoiu Mistrih else if (IntrinsicInfo) 836bbd610aeSFrancis Visoiu Mistrih OS << "intrinsic(@" << IntrinsicInfo->getName(ID) << ')'; 837aa739695SFrancis Visoiu Mistrih else 838bbd610aeSFrancis Visoiu Mistrih OS << "intrinsic(" << ID << ')'; 839aa739695SFrancis Visoiu Mistrih break; 840aa739695SFrancis Visoiu Mistrih } 841aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Predicate: { 842aa739695SFrancis Visoiu Mistrih auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); 843cb2683d4SFrancis Visoiu Mistrih OS << (CmpInst::isIntPredicate(Pred) ? "int" : "float") << "pred(" 844cb2683d4SFrancis Visoiu Mistrih << CmpInst::getPredicateName(Pred) << ')'; 845aa739695SFrancis Visoiu Mistrih break; 846aa739695SFrancis Visoiu Mistrih } 847aa739695SFrancis Visoiu Mistrih } 848aa739695SFrancis Visoiu Mistrih } 849aa739695SFrancis Visoiu Mistrih 850aa739695SFrancis Visoiu Mistrih #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 851aa739695SFrancis Visoiu Mistrih LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; } 852aa739695SFrancis Visoiu Mistrih #endif 853aa739695SFrancis Visoiu Mistrih 854aa739695SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===// 855aa739695SFrancis Visoiu Mistrih // MachineMemOperand Implementation 856aa739695SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===// 857aa739695SFrancis Visoiu Mistrih 858aa739695SFrancis Visoiu Mistrih /// getAddrSpace - Return the LLVM IR address space number that this pointer 859aa739695SFrancis Visoiu Mistrih /// points into. 86049477040SYaxun Liu unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; } 861aa739695SFrancis Visoiu Mistrih 862aa739695SFrancis Visoiu Mistrih /// isDereferenceable - Return true if V is always dereferenceable for 863aa739695SFrancis Visoiu Mistrih /// Offset + Size byte. 864aa739695SFrancis Visoiu Mistrih bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C, 865aa739695SFrancis Visoiu Mistrih const DataLayout &DL) const { 866aa739695SFrancis Visoiu Mistrih if (!V.is<const Value *>()) 867aa739695SFrancis Visoiu Mistrih return false; 868aa739695SFrancis Visoiu Mistrih 869aa739695SFrancis Visoiu Mistrih const Value *BasePtr = V.get<const Value *>(); 870aa739695SFrancis Visoiu Mistrih if (BasePtr == nullptr) 871aa739695SFrancis Visoiu Mistrih return false; 872aa739695SFrancis Visoiu Mistrih 873aa739695SFrancis Visoiu Mistrih return isDereferenceableAndAlignedPointer( 874aa739695SFrancis Visoiu Mistrih BasePtr, 1, APInt(DL.getPointerSizeInBits(), Offset + Size), DL); 875aa739695SFrancis Visoiu Mistrih } 876aa739695SFrancis Visoiu Mistrih 877aa739695SFrancis Visoiu Mistrih /// getConstantPool - Return a MachinePointerInfo record that refers to the 878aa739695SFrancis Visoiu Mistrih /// constant pool. 879aa739695SFrancis Visoiu Mistrih MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { 880aa739695SFrancis Visoiu Mistrih return MachinePointerInfo(MF.getPSVManager().getConstantPool()); 881aa739695SFrancis Visoiu Mistrih } 882aa739695SFrancis Visoiu Mistrih 883aa739695SFrancis Visoiu Mistrih /// getFixedStack - Return a MachinePointerInfo record that refers to the 884aa739695SFrancis Visoiu Mistrih /// the specified FrameIndex. 885aa739695SFrancis Visoiu Mistrih MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, 886aa739695SFrancis Visoiu Mistrih int FI, int64_t Offset) { 887aa739695SFrancis Visoiu Mistrih return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); 888aa739695SFrancis Visoiu Mistrih } 889aa739695SFrancis Visoiu Mistrih 890aa739695SFrancis Visoiu Mistrih MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { 891aa739695SFrancis Visoiu Mistrih return MachinePointerInfo(MF.getPSVManager().getJumpTable()); 892aa739695SFrancis Visoiu Mistrih } 893aa739695SFrancis Visoiu Mistrih 894aa739695SFrancis Visoiu Mistrih MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { 895aa739695SFrancis Visoiu Mistrih return MachinePointerInfo(MF.getPSVManager().getGOT()); 896aa739695SFrancis Visoiu Mistrih } 897aa739695SFrancis Visoiu Mistrih 898aa739695SFrancis Visoiu Mistrih MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, 899aa739695SFrancis Visoiu Mistrih int64_t Offset, uint8_t ID) { 900aa739695SFrancis Visoiu Mistrih return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID); 901aa739695SFrancis Visoiu Mistrih } 902aa739695SFrancis Visoiu Mistrih 90349477040SYaxun Liu MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) { 90449477040SYaxun Liu return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace()); 90549477040SYaxun Liu } 90649477040SYaxun Liu 907aa739695SFrancis Visoiu Mistrih MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f, 908aa739695SFrancis Visoiu Mistrih uint64_t s, unsigned int a, 909aa739695SFrancis Visoiu Mistrih const AAMDNodes &AAInfo, 910aa739695SFrancis Visoiu Mistrih const MDNode *Ranges, SyncScope::ID SSID, 911aa739695SFrancis Visoiu Mistrih AtomicOrdering Ordering, 912aa739695SFrancis Visoiu Mistrih AtomicOrdering FailureOrdering) 913aa739695SFrancis Visoiu Mistrih : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1), 914aa739695SFrancis Visoiu Mistrih AAInfo(AAInfo), Ranges(Ranges) { 915aa739695SFrancis Visoiu Mistrih assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() || 916aa739695SFrancis Visoiu Mistrih isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) && 917aa739695SFrancis Visoiu Mistrih "invalid pointer value"); 918aa739695SFrancis Visoiu Mistrih assert(getBaseAlignment() == a && "Alignment is not a power of 2!"); 919aa739695SFrancis Visoiu Mistrih assert((isLoad() || isStore()) && "Not a load/store!"); 920aa739695SFrancis Visoiu Mistrih 921aa739695SFrancis Visoiu Mistrih AtomicInfo.SSID = static_cast<unsigned>(SSID); 922aa739695SFrancis Visoiu Mistrih assert(getSyncScopeID() == SSID && "Value truncated"); 923aa739695SFrancis Visoiu Mistrih AtomicInfo.Ordering = static_cast<unsigned>(Ordering); 924aa739695SFrancis Visoiu Mistrih assert(getOrdering() == Ordering && "Value truncated"); 925aa739695SFrancis Visoiu Mistrih AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering); 926aa739695SFrancis Visoiu Mistrih assert(getFailureOrdering() == FailureOrdering && "Value truncated"); 927aa739695SFrancis Visoiu Mistrih } 928aa739695SFrancis Visoiu Mistrih 929aa739695SFrancis Visoiu Mistrih /// Profile - Gather unique data for the object. 930aa739695SFrancis Visoiu Mistrih /// 931aa739695SFrancis Visoiu Mistrih void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 932aa739695SFrancis Visoiu Mistrih ID.AddInteger(getOffset()); 933aa739695SFrancis Visoiu Mistrih ID.AddInteger(Size); 934aa739695SFrancis Visoiu Mistrih ID.AddPointer(getOpaqueValue()); 935aa739695SFrancis Visoiu Mistrih ID.AddInteger(getFlags()); 936aa739695SFrancis Visoiu Mistrih ID.AddInteger(getBaseAlignment()); 937aa739695SFrancis Visoiu Mistrih } 938aa739695SFrancis Visoiu Mistrih 939aa739695SFrancis Visoiu Mistrih void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 940aa739695SFrancis Visoiu Mistrih // The Value and Offset may differ due to CSE. But the flags and size 941aa739695SFrancis Visoiu Mistrih // should be the same. 942aa739695SFrancis Visoiu Mistrih assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 943aa739695SFrancis Visoiu Mistrih assert(MMO->getSize() == getSize() && "Size mismatch!"); 944aa739695SFrancis Visoiu Mistrih 945aa739695SFrancis Visoiu Mistrih if (MMO->getBaseAlignment() >= getBaseAlignment()) { 946aa739695SFrancis Visoiu Mistrih // Update the alignment value. 947aa739695SFrancis Visoiu Mistrih BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1; 948aa739695SFrancis Visoiu Mistrih // Also update the base and offset, because the new alignment may 949aa739695SFrancis Visoiu Mistrih // not be applicable with the old ones. 950aa739695SFrancis Visoiu Mistrih PtrInfo = MMO->PtrInfo; 951aa739695SFrancis Visoiu Mistrih } 952aa739695SFrancis Visoiu Mistrih } 953aa739695SFrancis Visoiu Mistrih 954aa739695SFrancis Visoiu Mistrih /// getAlignment - Return the minimum known alignment in bytes of the 955aa739695SFrancis Visoiu Mistrih /// actual memory reference. 956aa739695SFrancis Visoiu Mistrih uint64_t MachineMemOperand::getAlignment() const { 957aa739695SFrancis Visoiu Mistrih return MinAlign(getBaseAlignment(), getOffset()); 958aa739695SFrancis Visoiu Mistrih } 959aa739695SFrancis Visoiu Mistrih 960aa739695SFrancis Visoiu Mistrih void MachineMemOperand::print(raw_ostream &OS) const { 961aa739695SFrancis Visoiu Mistrih ModuleSlotTracker DummyMST(nullptr); 962aa739695SFrancis Visoiu Mistrih print(OS, DummyMST); 963aa739695SFrancis Visoiu Mistrih } 964aa739695SFrancis Visoiu Mistrih void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const { 965aa739695SFrancis Visoiu Mistrih assert((isLoad() || isStore()) && "SV has to be a load, store or both."); 966aa739695SFrancis Visoiu Mistrih 967aa739695SFrancis Visoiu Mistrih if (isVolatile()) 968aa739695SFrancis Visoiu Mistrih OS << "Volatile "; 969aa739695SFrancis Visoiu Mistrih 970aa739695SFrancis Visoiu Mistrih if (isLoad()) 971aa739695SFrancis Visoiu Mistrih OS << "LD"; 972aa739695SFrancis Visoiu Mistrih if (isStore()) 973aa739695SFrancis Visoiu Mistrih OS << "ST"; 974aa739695SFrancis Visoiu Mistrih OS << getSize(); 975aa739695SFrancis Visoiu Mistrih 976aa739695SFrancis Visoiu Mistrih // Print the address information. 977aa739695SFrancis Visoiu Mistrih OS << "["; 978aa739695SFrancis Visoiu Mistrih if (const Value *V = getValue()) 979aa739695SFrancis Visoiu Mistrih V->printAsOperand(OS, /*PrintType=*/false, MST); 980aa739695SFrancis Visoiu Mistrih else if (const PseudoSourceValue *PSV = getPseudoValue()) 981aa739695SFrancis Visoiu Mistrih PSV->printCustom(OS); 982aa739695SFrancis Visoiu Mistrih else 983aa739695SFrancis Visoiu Mistrih OS << "<unknown>"; 984aa739695SFrancis Visoiu Mistrih 985aa739695SFrancis Visoiu Mistrih unsigned AS = getAddrSpace(); 986aa739695SFrancis Visoiu Mistrih if (AS != 0) 987aa739695SFrancis Visoiu Mistrih OS << "(addrspace=" << AS << ')'; 988aa739695SFrancis Visoiu Mistrih 989aa739695SFrancis Visoiu Mistrih // If the alignment of the memory reference itself differs from the alignment 990aa739695SFrancis Visoiu Mistrih // of the base pointer, print the base alignment explicitly, next to the base 991aa739695SFrancis Visoiu Mistrih // pointer. 992aa739695SFrancis Visoiu Mistrih if (getBaseAlignment() != getAlignment()) 993aa739695SFrancis Visoiu Mistrih OS << "(align=" << getBaseAlignment() << ")"; 994aa739695SFrancis Visoiu Mistrih 995aa739695SFrancis Visoiu Mistrih if (getOffset() != 0) 996aa739695SFrancis Visoiu Mistrih OS << "+" << getOffset(); 997aa739695SFrancis Visoiu Mistrih OS << "]"; 998aa739695SFrancis Visoiu Mistrih 999aa739695SFrancis Visoiu Mistrih // Print the alignment of the reference. 1000aa739695SFrancis Visoiu Mistrih if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize()) 1001aa739695SFrancis Visoiu Mistrih OS << "(align=" << getAlignment() << ")"; 1002aa739695SFrancis Visoiu Mistrih 1003aa739695SFrancis Visoiu Mistrih // Print TBAA info. 1004aa739695SFrancis Visoiu Mistrih if (const MDNode *TBAAInfo = getAAInfo().TBAA) { 1005aa739695SFrancis Visoiu Mistrih OS << "(tbaa="; 1006aa739695SFrancis Visoiu Mistrih if (TBAAInfo->getNumOperands() > 0) 1007aa739695SFrancis Visoiu Mistrih TBAAInfo->getOperand(0)->printAsOperand(OS, MST); 1008aa739695SFrancis Visoiu Mistrih else 1009aa739695SFrancis Visoiu Mistrih OS << "<unknown>"; 1010aa739695SFrancis Visoiu Mistrih OS << ")"; 1011aa739695SFrancis Visoiu Mistrih } 1012aa739695SFrancis Visoiu Mistrih 1013aa739695SFrancis Visoiu Mistrih // Print AA scope info. 1014aa739695SFrancis Visoiu Mistrih if (const MDNode *ScopeInfo = getAAInfo().Scope) { 1015aa739695SFrancis Visoiu Mistrih OS << "(alias.scope="; 1016aa739695SFrancis Visoiu Mistrih if (ScopeInfo->getNumOperands() > 0) 1017aa739695SFrancis Visoiu Mistrih for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { 1018aa739695SFrancis Visoiu Mistrih ScopeInfo->getOperand(i)->printAsOperand(OS, MST); 1019aa739695SFrancis Visoiu Mistrih if (i != ie - 1) 1020aa739695SFrancis Visoiu Mistrih OS << ","; 1021aa739695SFrancis Visoiu Mistrih } 1022aa739695SFrancis Visoiu Mistrih else 1023aa739695SFrancis Visoiu Mistrih OS << "<unknown>"; 1024aa739695SFrancis Visoiu Mistrih OS << ")"; 1025aa739695SFrancis Visoiu Mistrih } 1026aa739695SFrancis Visoiu Mistrih 1027aa739695SFrancis Visoiu Mistrih // Print AA noalias scope info. 1028aa739695SFrancis Visoiu Mistrih if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) { 1029aa739695SFrancis Visoiu Mistrih OS << "(noalias="; 1030aa739695SFrancis Visoiu Mistrih if (NoAliasInfo->getNumOperands() > 0) 1031aa739695SFrancis Visoiu Mistrih for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { 1032aa739695SFrancis Visoiu Mistrih NoAliasInfo->getOperand(i)->printAsOperand(OS, MST); 1033aa739695SFrancis Visoiu Mistrih if (i != ie - 1) 1034aa739695SFrancis Visoiu Mistrih OS << ","; 1035aa739695SFrancis Visoiu Mistrih } 1036aa739695SFrancis Visoiu Mistrih else 1037aa739695SFrancis Visoiu Mistrih OS << "<unknown>"; 1038aa739695SFrancis Visoiu Mistrih OS << ")"; 1039aa739695SFrancis Visoiu Mistrih } 1040aa739695SFrancis Visoiu Mistrih 1041aa739695SFrancis Visoiu Mistrih if (const MDNode *Ranges = getRanges()) { 1042aa739695SFrancis Visoiu Mistrih unsigned NumRanges = Ranges->getNumOperands(); 1043aa739695SFrancis Visoiu Mistrih if (NumRanges != 0) { 1044aa739695SFrancis Visoiu Mistrih OS << "(ranges="; 1045aa739695SFrancis Visoiu Mistrih 1046aa739695SFrancis Visoiu Mistrih for (unsigned I = 0; I != NumRanges; ++I) { 1047aa739695SFrancis Visoiu Mistrih Ranges->getOperand(I)->printAsOperand(OS, MST); 1048aa739695SFrancis Visoiu Mistrih if (I != NumRanges - 1) 1049aa739695SFrancis Visoiu Mistrih OS << ','; 1050aa739695SFrancis Visoiu Mistrih } 1051aa739695SFrancis Visoiu Mistrih 1052aa739695SFrancis Visoiu Mistrih OS << ')'; 1053aa739695SFrancis Visoiu Mistrih } 1054aa739695SFrancis Visoiu Mistrih } 1055aa739695SFrancis Visoiu Mistrih 1056aa739695SFrancis Visoiu Mistrih if (isNonTemporal()) 1057aa739695SFrancis Visoiu Mistrih OS << "(nontemporal)"; 1058aa739695SFrancis Visoiu Mistrih if (isDereferenceable()) 1059aa739695SFrancis Visoiu Mistrih OS << "(dereferenceable)"; 1060aa739695SFrancis Visoiu Mistrih if (isInvariant()) 1061aa739695SFrancis Visoiu Mistrih OS << "(invariant)"; 1062aa739695SFrancis Visoiu Mistrih if (getFlags() & MOTargetFlag1) 1063aa739695SFrancis Visoiu Mistrih OS << "(flag1)"; 1064aa739695SFrancis Visoiu Mistrih if (getFlags() & MOTargetFlag2) 1065aa739695SFrancis Visoiu Mistrih OS << "(flag2)"; 1066aa739695SFrancis Visoiu Mistrih if (getFlags() & MOTargetFlag3) 1067aa739695SFrancis Visoiu Mistrih OS << "(flag3)"; 1068aa739695SFrancis Visoiu Mistrih } 1069