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" 17aa739695SFrancis Visoiu Mistrih #include "llvm/CodeGen/MachineRegisterInfo.h" 18aa739695SFrancis Visoiu Mistrih #include "llvm/CodeGen/TargetRegisterInfo.h" 19aa739695SFrancis Visoiu Mistrih #include "llvm/IR/Constants.h" 20aa739695SFrancis Visoiu Mistrih #include "llvm/IR/ModuleSlotTracker.h" 21a8a83d15SFrancis Visoiu Mistrih #include "llvm/Target/TargetIntrinsicInfo.h" 22a8a83d15SFrancis Visoiu Mistrih #include "llvm/Target/TargetMachine.h" 23aa739695SFrancis Visoiu Mistrih 24aa739695SFrancis Visoiu Mistrih using namespace llvm; 25aa739695SFrancis Visoiu Mistrih 26aa739695SFrancis Visoiu Mistrih static cl::opt<int> 27aa739695SFrancis Visoiu Mistrih PrintRegMaskNumRegs("print-regmask-num-regs", 28aa739695SFrancis Visoiu Mistrih cl::desc("Number of registers to limit to when " 29aa739695SFrancis Visoiu Mistrih "printing regmask operands in IR dumps. " 30aa739695SFrancis Visoiu Mistrih "unlimited = -1"), 31aa739695SFrancis Visoiu Mistrih cl::init(32), cl::Hidden); 32aa739695SFrancis Visoiu Mistrih 3395a05915SFrancis Visoiu Mistrih static const MachineFunction *getMFIfAvailable(const MachineOperand &MO) { 3495a05915SFrancis Visoiu Mistrih if (const MachineInstr *MI = MO.getParent()) 3595a05915SFrancis Visoiu Mistrih if (const MachineBasicBlock *MBB = MI->getParent()) 3695a05915SFrancis Visoiu Mistrih if (const MachineFunction *MF = MBB->getParent()) 3795a05915SFrancis Visoiu Mistrih return MF; 3895a05915SFrancis Visoiu Mistrih return nullptr; 3995a05915SFrancis Visoiu Mistrih } 4095a05915SFrancis Visoiu Mistrih static MachineFunction *getMFIfAvailable(MachineOperand &MO) { 4195a05915SFrancis Visoiu Mistrih return const_cast<MachineFunction *>( 4295a05915SFrancis Visoiu Mistrih getMFIfAvailable(const_cast<const MachineOperand &>(MO))); 4395a05915SFrancis Visoiu Mistrih } 4495a05915SFrancis Visoiu Mistrih 45aa739695SFrancis Visoiu Mistrih void MachineOperand::setReg(unsigned Reg) { 46aa739695SFrancis Visoiu Mistrih if (getReg() == Reg) 47aa739695SFrancis Visoiu Mistrih return; // No change. 48aa739695SFrancis Visoiu Mistrih 49aa739695SFrancis Visoiu Mistrih // Otherwise, we have to change the register. If this operand is embedded 50aa739695SFrancis Visoiu Mistrih // into a machine function, we need to update the old and new register's 51aa739695SFrancis Visoiu Mistrih // use/def lists. 5295a05915SFrancis Visoiu Mistrih if (MachineFunction *MF = getMFIfAvailable(*this)) { 53aa739695SFrancis Visoiu Mistrih MachineRegisterInfo &MRI = MF->getRegInfo(); 54aa739695SFrancis Visoiu Mistrih MRI.removeRegOperandFromUseList(this); 55aa739695SFrancis Visoiu Mistrih SmallContents.RegNo = Reg; 56aa739695SFrancis Visoiu Mistrih MRI.addRegOperandToUseList(this); 57aa739695SFrancis Visoiu Mistrih return; 58aa739695SFrancis Visoiu Mistrih } 59aa739695SFrancis Visoiu Mistrih 60aa739695SFrancis Visoiu Mistrih // Otherwise, just change the register, no problem. :) 61aa739695SFrancis Visoiu Mistrih SmallContents.RegNo = Reg; 62aa739695SFrancis Visoiu Mistrih } 63aa739695SFrancis Visoiu Mistrih 64aa739695SFrancis Visoiu Mistrih void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, 65aa739695SFrancis Visoiu Mistrih const TargetRegisterInfo &TRI) { 66aa739695SFrancis Visoiu Mistrih assert(TargetRegisterInfo::isVirtualRegister(Reg)); 67aa739695SFrancis Visoiu Mistrih if (SubIdx && getSubReg()) 68aa739695SFrancis Visoiu Mistrih SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); 69aa739695SFrancis Visoiu Mistrih setReg(Reg); 70aa739695SFrancis Visoiu Mistrih if (SubIdx) 71aa739695SFrancis Visoiu Mistrih setSubReg(SubIdx); 72aa739695SFrancis Visoiu Mistrih } 73aa739695SFrancis Visoiu Mistrih 74aa739695SFrancis Visoiu Mistrih void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { 75aa739695SFrancis Visoiu Mistrih assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 76aa739695SFrancis Visoiu Mistrih if (getSubReg()) { 77aa739695SFrancis Visoiu Mistrih Reg = TRI.getSubReg(Reg, getSubReg()); 78aa739695SFrancis Visoiu Mistrih // Note that getSubReg() may return 0 if the sub-register doesn't exist. 79aa739695SFrancis Visoiu Mistrih // That won't happen in legal code. 80aa739695SFrancis Visoiu Mistrih setSubReg(0); 81aa739695SFrancis Visoiu Mistrih if (isDef()) 82aa739695SFrancis Visoiu Mistrih setIsUndef(false); 83aa739695SFrancis Visoiu Mistrih } 84aa739695SFrancis Visoiu Mistrih setReg(Reg); 85aa739695SFrancis Visoiu Mistrih } 86aa739695SFrancis Visoiu Mistrih 87aa739695SFrancis Visoiu Mistrih /// Change a def to a use, or a use to a def. 88aa739695SFrancis Visoiu Mistrih void MachineOperand::setIsDef(bool Val) { 89aa739695SFrancis Visoiu Mistrih assert(isReg() && "Wrong MachineOperand accessor"); 90aa739695SFrancis Visoiu Mistrih assert((!Val || !isDebug()) && "Marking a debug operation as def"); 91aa739695SFrancis Visoiu Mistrih if (IsDef == Val) 92aa739695SFrancis Visoiu Mistrih return; 93aa739695SFrancis Visoiu Mistrih // MRI may keep uses and defs in different list positions. 9495a05915SFrancis Visoiu Mistrih if (MachineFunction *MF = getMFIfAvailable(*this)) { 95aa739695SFrancis Visoiu Mistrih MachineRegisterInfo &MRI = MF->getRegInfo(); 96aa739695SFrancis Visoiu Mistrih MRI.removeRegOperandFromUseList(this); 97aa739695SFrancis Visoiu Mistrih IsDef = Val; 98aa739695SFrancis Visoiu Mistrih MRI.addRegOperandToUseList(this); 99aa739695SFrancis Visoiu Mistrih return; 100aa739695SFrancis Visoiu Mistrih } 101aa739695SFrancis Visoiu Mistrih IsDef = Val; 102aa739695SFrancis Visoiu Mistrih } 103aa739695SFrancis Visoiu Mistrih 104aa739695SFrancis Visoiu Mistrih // If this operand is currently a register operand, and if this is in a 105aa739695SFrancis Visoiu Mistrih // function, deregister the operand from the register's use/def list. 106aa739695SFrancis Visoiu Mistrih void MachineOperand::removeRegFromUses() { 107aa739695SFrancis Visoiu Mistrih if (!isReg() || !isOnRegUseList()) 108aa739695SFrancis Visoiu Mistrih return; 109aa739695SFrancis Visoiu Mistrih 11095a05915SFrancis Visoiu Mistrih if (MachineFunction *MF = getMFIfAvailable(*this)) 111aa739695SFrancis Visoiu Mistrih MF->getRegInfo().removeRegOperandFromUseList(this); 112aa739695SFrancis Visoiu Mistrih } 113aa739695SFrancis Visoiu Mistrih 114aa739695SFrancis Visoiu Mistrih /// ChangeToImmediate - Replace this operand with a new immediate operand of 115aa739695SFrancis Visoiu Mistrih /// the specified value. If an operand is known to be an immediate already, 116aa739695SFrancis Visoiu Mistrih /// the setImm method should be used. 117aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToImmediate(int64_t ImmVal) { 118aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 119aa739695SFrancis Visoiu Mistrih 120aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 121aa739695SFrancis Visoiu Mistrih 122aa739695SFrancis Visoiu Mistrih OpKind = MO_Immediate; 123aa739695SFrancis Visoiu Mistrih Contents.ImmVal = ImmVal; 124aa739695SFrancis Visoiu Mistrih } 125aa739695SFrancis Visoiu Mistrih 126aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) { 127aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 128aa739695SFrancis Visoiu Mistrih 129aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 130aa739695SFrancis Visoiu Mistrih 131aa739695SFrancis Visoiu Mistrih OpKind = MO_FPImmediate; 132aa739695SFrancis Visoiu Mistrih Contents.CFP = FPImm; 133aa739695SFrancis Visoiu Mistrih } 134aa739695SFrancis Visoiu Mistrih 135aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToES(const char *SymName, 136aa739695SFrancis Visoiu Mistrih unsigned char TargetFlags) { 137aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && 138aa739695SFrancis Visoiu Mistrih "Cannot change a tied operand into an external symbol"); 139aa739695SFrancis Visoiu Mistrih 140aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 141aa739695SFrancis Visoiu Mistrih 142aa739695SFrancis Visoiu Mistrih OpKind = MO_ExternalSymbol; 143aa739695SFrancis Visoiu Mistrih Contents.OffsetedInfo.Val.SymbolName = SymName; 144aa739695SFrancis Visoiu Mistrih setOffset(0); // Offset is always 0. 145aa739695SFrancis Visoiu Mistrih setTargetFlags(TargetFlags); 146aa739695SFrancis Visoiu Mistrih } 147aa739695SFrancis Visoiu Mistrih 148aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) { 149aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && 150aa739695SFrancis Visoiu Mistrih "Cannot change a tied operand into an MCSymbol"); 151aa739695SFrancis Visoiu Mistrih 152aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 153aa739695SFrancis Visoiu Mistrih 154aa739695SFrancis Visoiu Mistrih OpKind = MO_MCSymbol; 155aa739695SFrancis Visoiu Mistrih Contents.Sym = Sym; 156aa739695SFrancis Visoiu Mistrih } 157aa739695SFrancis Visoiu Mistrih 158aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToFrameIndex(int Idx) { 159aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && 160aa739695SFrancis Visoiu Mistrih "Cannot change a tied operand into a FrameIndex"); 161aa739695SFrancis Visoiu Mistrih 162aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 163aa739695SFrancis Visoiu Mistrih 164aa739695SFrancis Visoiu Mistrih OpKind = MO_FrameIndex; 165aa739695SFrancis Visoiu Mistrih setIndex(Idx); 166aa739695SFrancis Visoiu Mistrih } 167aa739695SFrancis Visoiu Mistrih 168aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToTargetIndex(unsigned Idx, int64_t Offset, 169aa739695SFrancis Visoiu Mistrih unsigned char TargetFlags) { 170aa739695SFrancis Visoiu Mistrih assert((!isReg() || !isTied()) && 171aa739695SFrancis Visoiu Mistrih "Cannot change a tied operand into a FrameIndex"); 172aa739695SFrancis Visoiu Mistrih 173aa739695SFrancis Visoiu Mistrih removeRegFromUses(); 174aa739695SFrancis Visoiu Mistrih 175aa739695SFrancis Visoiu Mistrih OpKind = MO_TargetIndex; 176aa739695SFrancis Visoiu Mistrih setIndex(Idx); 177aa739695SFrancis Visoiu Mistrih setOffset(Offset); 178aa739695SFrancis Visoiu Mistrih setTargetFlags(TargetFlags); 179aa739695SFrancis Visoiu Mistrih } 180aa739695SFrancis Visoiu Mistrih 181aa739695SFrancis Visoiu Mistrih /// ChangeToRegister - Replace this operand with a new register operand of 182aa739695SFrancis Visoiu Mistrih /// the specified value. If an operand is known to be an register already, 183aa739695SFrancis Visoiu Mistrih /// the setReg method should be used. 184aa739695SFrancis Visoiu Mistrih void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, 185aa739695SFrancis Visoiu Mistrih bool isKill, bool isDead, bool isUndef, 186aa739695SFrancis Visoiu Mistrih bool isDebug) { 187aa739695SFrancis Visoiu Mistrih MachineRegisterInfo *RegInfo = nullptr; 18895a05915SFrancis Visoiu Mistrih if (MachineFunction *MF = getMFIfAvailable(*this)) 189aa739695SFrancis Visoiu Mistrih RegInfo = &MF->getRegInfo(); 190aa739695SFrancis Visoiu Mistrih // If this operand is already a register operand, remove it from the 191aa739695SFrancis Visoiu Mistrih // register's use/def lists. 192aa739695SFrancis Visoiu Mistrih bool WasReg = isReg(); 193aa739695SFrancis Visoiu Mistrih if (RegInfo && WasReg) 194aa739695SFrancis Visoiu Mistrih RegInfo->removeRegOperandFromUseList(this); 195aa739695SFrancis Visoiu Mistrih 196aa739695SFrancis Visoiu Mistrih // Change this to a register and set the reg#. 197aa739695SFrancis Visoiu Mistrih OpKind = MO_Register; 198aa739695SFrancis Visoiu Mistrih SmallContents.RegNo = Reg; 199aa739695SFrancis Visoiu Mistrih SubReg_TargetFlags = 0; 200aa739695SFrancis Visoiu Mistrih IsDef = isDef; 201aa739695SFrancis Visoiu Mistrih IsImp = isImp; 202aa739695SFrancis Visoiu Mistrih IsKill = isKill; 203aa739695SFrancis Visoiu Mistrih IsDead = isDead; 204aa739695SFrancis Visoiu Mistrih IsUndef = isUndef; 205aa739695SFrancis Visoiu Mistrih IsInternalRead = false; 206aa739695SFrancis Visoiu Mistrih IsEarlyClobber = false; 207aa739695SFrancis Visoiu Mistrih IsDebug = isDebug; 208aa739695SFrancis Visoiu Mistrih // Ensure isOnRegUseList() returns false. 209aa739695SFrancis Visoiu Mistrih Contents.Reg.Prev = nullptr; 210aa739695SFrancis Visoiu Mistrih // Preserve the tie when the operand was already a register. 211aa739695SFrancis Visoiu Mistrih if (!WasReg) 212aa739695SFrancis Visoiu Mistrih TiedTo = 0; 213aa739695SFrancis Visoiu Mistrih 214aa739695SFrancis Visoiu Mistrih // If this operand is embedded in a function, add the operand to the 215aa739695SFrancis Visoiu Mistrih // register's use/def list. 216aa739695SFrancis Visoiu Mistrih if (RegInfo) 217aa739695SFrancis Visoiu Mistrih RegInfo->addRegOperandToUseList(this); 218aa739695SFrancis Visoiu Mistrih } 219aa739695SFrancis Visoiu Mistrih 220aa739695SFrancis Visoiu Mistrih /// isIdenticalTo - Return true if this operand is identical to the specified 221aa739695SFrancis Visoiu Mistrih /// operand. Note that this should stay in sync with the hash_value overload 222aa739695SFrancis Visoiu Mistrih /// below. 223aa739695SFrancis Visoiu Mistrih bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 224aa739695SFrancis Visoiu Mistrih if (getType() != Other.getType() || 225aa739695SFrancis Visoiu Mistrih getTargetFlags() != Other.getTargetFlags()) 226aa739695SFrancis Visoiu Mistrih return false; 227aa739695SFrancis Visoiu Mistrih 228aa739695SFrancis Visoiu Mistrih switch (getType()) { 229aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Register: 230aa739695SFrancis Visoiu Mistrih return getReg() == Other.getReg() && isDef() == Other.isDef() && 231aa739695SFrancis Visoiu Mistrih getSubReg() == Other.getSubReg(); 232aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Immediate: 233aa739695SFrancis Visoiu Mistrih return getImm() == Other.getImm(); 234aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CImmediate: 235aa739695SFrancis Visoiu Mistrih return getCImm() == Other.getCImm(); 236aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FPImmediate: 237aa739695SFrancis Visoiu Mistrih return getFPImm() == Other.getFPImm(); 238aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MachineBasicBlock: 239aa739695SFrancis Visoiu Mistrih return getMBB() == Other.getMBB(); 240aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FrameIndex: 241aa739695SFrancis Visoiu Mistrih return getIndex() == Other.getIndex(); 242aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ConstantPoolIndex: 243aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_TargetIndex: 244aa739695SFrancis Visoiu Mistrih return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 245aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_JumpTableIndex: 246aa739695SFrancis Visoiu Mistrih return getIndex() == Other.getIndex(); 247aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_GlobalAddress: 248aa739695SFrancis Visoiu Mistrih return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 249aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ExternalSymbol: 250aa739695SFrancis Visoiu Mistrih return strcmp(getSymbolName(), Other.getSymbolName()) == 0 && 251aa739695SFrancis Visoiu Mistrih getOffset() == Other.getOffset(); 252aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_BlockAddress: 253aa739695SFrancis Visoiu Mistrih return getBlockAddress() == Other.getBlockAddress() && 254aa739695SFrancis Visoiu Mistrih getOffset() == Other.getOffset(); 255aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterMask: 256aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterLiveOut: { 257aa739695SFrancis Visoiu Mistrih // Shallow compare of the two RegMasks 258aa739695SFrancis Visoiu Mistrih const uint32_t *RegMask = getRegMask(); 259aa739695SFrancis Visoiu Mistrih const uint32_t *OtherRegMask = Other.getRegMask(); 260aa739695SFrancis Visoiu Mistrih if (RegMask == OtherRegMask) 261aa739695SFrancis Visoiu Mistrih return true; 262aa739695SFrancis Visoiu Mistrih 26395a05915SFrancis Visoiu Mistrih if (const MachineFunction *MF = getMFIfAvailable(*this)) { 264aa739695SFrancis Visoiu Mistrih // Calculate the size of the RegMask 265aa739695SFrancis Visoiu Mistrih const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 266aa739695SFrancis Visoiu Mistrih unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32; 267aa739695SFrancis Visoiu Mistrih 268aa739695SFrancis Visoiu Mistrih // Deep compare of the two RegMasks 269aa739695SFrancis Visoiu Mistrih return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask); 270aa739695SFrancis Visoiu Mistrih } 27195a05915SFrancis Visoiu Mistrih // We don't know the size of the RegMask, so we can't deep compare the two 27295a05915SFrancis Visoiu Mistrih // reg masks. 27395a05915SFrancis Visoiu Mistrih return false; 27495a05915SFrancis Visoiu Mistrih } 275aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MCSymbol: 276aa739695SFrancis Visoiu Mistrih return getMCSymbol() == Other.getMCSymbol(); 277aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CFIIndex: 278aa739695SFrancis Visoiu Mistrih return getCFIIndex() == Other.getCFIIndex(); 279aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Metadata: 280aa739695SFrancis Visoiu Mistrih return getMetadata() == Other.getMetadata(); 281aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_IntrinsicID: 282aa739695SFrancis Visoiu Mistrih return getIntrinsicID() == Other.getIntrinsicID(); 283aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Predicate: 284aa739695SFrancis Visoiu Mistrih return getPredicate() == Other.getPredicate(); 285aa739695SFrancis Visoiu Mistrih } 286aa739695SFrancis Visoiu Mistrih llvm_unreachable("Invalid machine operand type"); 287aa739695SFrancis Visoiu Mistrih } 288aa739695SFrancis Visoiu Mistrih 289aa739695SFrancis Visoiu Mistrih // Note: this must stay exactly in sync with isIdenticalTo above. 290aa739695SFrancis Visoiu Mistrih hash_code llvm::hash_value(const MachineOperand &MO) { 291aa739695SFrancis Visoiu Mistrih switch (MO.getType()) { 292aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Register: 293aa739695SFrancis Visoiu Mistrih // Register operands don't have target flags. 294aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef()); 295aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Immediate: 296aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 297aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CImmediate: 298aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 299aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FPImmediate: 300aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 301aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MachineBasicBlock: 302aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 303aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FrameIndex: 304aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 305aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ConstantPoolIndex: 306aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_TargetIndex: 307aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 308aa739695SFrancis Visoiu Mistrih MO.getOffset()); 309aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_JumpTableIndex: 310aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 311aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ExternalSymbol: 312aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 313aa739695SFrancis Visoiu Mistrih MO.getSymbolName()); 314aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_GlobalAddress: 315aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 316aa739695SFrancis Visoiu Mistrih MO.getOffset()); 317aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_BlockAddress: 318aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getBlockAddress(), 319aa739695SFrancis Visoiu Mistrih MO.getOffset()); 320aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterMask: 321aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterLiveOut: 322aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); 323aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Metadata: 324aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 325aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MCSymbol: 326aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 327aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CFIIndex: 328aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 329aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_IntrinsicID: 330aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); 331aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Predicate: 332aa739695SFrancis Visoiu Mistrih return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); 333aa739695SFrancis Visoiu Mistrih } 334aa739695SFrancis Visoiu Mistrih llvm_unreachable("Invalid machine operand type"); 335aa739695SFrancis Visoiu Mistrih } 336aa739695SFrancis Visoiu Mistrih 337a8a83d15SFrancis Visoiu Mistrih // Try to crawl up to the machine function and get TRI and IntrinsicInfo from 338a8a83d15SFrancis Visoiu Mistrih // it. 339a8a83d15SFrancis Visoiu Mistrih static void tryToGetTargetInfo(const MachineOperand &MO, 340a8a83d15SFrancis Visoiu Mistrih const TargetRegisterInfo *&TRI, 341a8a83d15SFrancis Visoiu Mistrih const TargetIntrinsicInfo *&IntrinsicInfo) { 342*567611efSFrancis Visoiu Mistrih if (const MachineFunction *MF = getMFIfAvailable(MO)) { 343a8a83d15SFrancis Visoiu Mistrih TRI = MF->getSubtarget().getRegisterInfo(); 344a8a83d15SFrancis Visoiu Mistrih IntrinsicInfo = MF->getTarget().getIntrinsicInfo(); 345a8a83d15SFrancis Visoiu Mistrih } 346a8a83d15SFrancis Visoiu Mistrih } 347a8a83d15SFrancis Visoiu Mistrih 348aa739695SFrancis Visoiu Mistrih void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, 349aa739695SFrancis Visoiu Mistrih const TargetIntrinsicInfo *IntrinsicInfo) const { 350a8a83d15SFrancis Visoiu Mistrih tryToGetTargetInfo(*this, TRI, IntrinsicInfo); 351aa739695SFrancis Visoiu Mistrih ModuleSlotTracker DummyMST(nullptr); 352a8a83d15SFrancis Visoiu Mistrih print(OS, DummyMST, LLT{}, /*PrintDef=*/false, 353a8a83d15SFrancis Visoiu Mistrih /*ShouldPrintRegisterTies=*/true, 354a8a83d15SFrancis Visoiu Mistrih /*TiedOperandIdx=*/0, TRI, IntrinsicInfo); 355aa739695SFrancis Visoiu Mistrih } 356aa739695SFrancis Visoiu Mistrih 357aa739695SFrancis Visoiu Mistrih void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 358a8a83d15SFrancis Visoiu Mistrih LLT TypeToPrint, bool PrintDef, 359a8a83d15SFrancis Visoiu Mistrih bool ShouldPrintRegisterTies, 360a8a83d15SFrancis Visoiu Mistrih unsigned TiedOperandIdx, 361aa739695SFrancis Visoiu Mistrih const TargetRegisterInfo *TRI, 362aa739695SFrancis Visoiu Mistrih const TargetIntrinsicInfo *IntrinsicInfo) const { 363aa739695SFrancis Visoiu Mistrih switch (getType()) { 364a8a83d15SFrancis Visoiu Mistrih case MachineOperand::MO_Register: { 365a8a83d15SFrancis Visoiu Mistrih unsigned Reg = getReg(); 366aa739695SFrancis Visoiu Mistrih if (isImplicit()) 367a8a83d15SFrancis Visoiu Mistrih OS << (isDef() ? "implicit-def " : "implicit "); 368a8a83d15SFrancis Visoiu Mistrih else if (PrintDef && isDef()) 369a8a83d15SFrancis Visoiu Mistrih // Print the 'def' flag only when the operand is defined after '='. 370aa739695SFrancis Visoiu Mistrih OS << "def "; 371a8a83d15SFrancis Visoiu Mistrih if (isInternalRead()) 372aa739695SFrancis Visoiu Mistrih OS << "internal "; 373a8a83d15SFrancis Visoiu Mistrih if (isDead()) 374a8a83d15SFrancis Visoiu Mistrih OS << "dead "; 375a8a83d15SFrancis Visoiu Mistrih if (isKill()) 376a8a83d15SFrancis Visoiu Mistrih OS << "killed "; 377a8a83d15SFrancis Visoiu Mistrih if (isUndef()) 378a8a83d15SFrancis Visoiu Mistrih OS << "undef "; 379a8a83d15SFrancis Visoiu Mistrih if (isEarlyClobber()) 380a8a83d15SFrancis Visoiu Mistrih OS << "early-clobber "; 381a8a83d15SFrancis Visoiu Mistrih if (isDebug()) 382a8a83d15SFrancis Visoiu Mistrih OS << "debug-use "; 383a8a83d15SFrancis Visoiu Mistrih OS << printReg(Reg, TRI); 384a8a83d15SFrancis Visoiu Mistrih // Print the sub register. 385a8a83d15SFrancis Visoiu Mistrih if (unsigned SubReg = getSubReg()) { 386a8a83d15SFrancis Visoiu Mistrih if (TRI) 387a8a83d15SFrancis Visoiu Mistrih OS << '.' << TRI->getSubRegIndexName(SubReg); 388a8a83d15SFrancis Visoiu Mistrih else 389a8a83d15SFrancis Visoiu Mistrih OS << ".subreg" << SubReg; 390aa739695SFrancis Visoiu Mistrih } 391a8a83d15SFrancis Visoiu Mistrih // Print the register class / bank. 392a8a83d15SFrancis Visoiu Mistrih if (TargetRegisterInfo::isVirtualRegister(Reg)) { 393*567611efSFrancis Visoiu Mistrih if (const MachineFunction *MF = getMFIfAvailable(*this)) { 394a8a83d15SFrancis Visoiu Mistrih const MachineRegisterInfo &MRI = MF->getRegInfo(); 395a8a83d15SFrancis Visoiu Mistrih if (!PrintDef || MRI.def_empty(Reg)) { 396a8a83d15SFrancis Visoiu Mistrih OS << ':'; 397a8a83d15SFrancis Visoiu Mistrih OS << printRegClassOrBank(Reg, MRI, TRI); 398aa739695SFrancis Visoiu Mistrih } 399aa739695SFrancis Visoiu Mistrih } 400a8a83d15SFrancis Visoiu Mistrih } 401a8a83d15SFrancis Visoiu Mistrih // Print ties. 402a8a83d15SFrancis Visoiu Mistrih if (ShouldPrintRegisterTies && isTied() && !isDef()) 403a8a83d15SFrancis Visoiu Mistrih OS << "(tied-def " << TiedOperandIdx << ")"; 404a8a83d15SFrancis Visoiu Mistrih // Print types. 405a8a83d15SFrancis Visoiu Mistrih if (TypeToPrint.isValid()) 406a8a83d15SFrancis Visoiu Mistrih OS << '(' << TypeToPrint << ')'; 407aa739695SFrancis Visoiu Mistrih break; 408a8a83d15SFrancis Visoiu Mistrih } 409aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Immediate: 410aa739695SFrancis Visoiu Mistrih OS << getImm(); 411aa739695SFrancis Visoiu Mistrih break; 412aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CImmediate: 413aa739695SFrancis Visoiu Mistrih getCImm()->getValue().print(OS, false); 414aa739695SFrancis Visoiu Mistrih break; 415aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FPImmediate: 416aa739695SFrancis Visoiu Mistrih if (getFPImm()->getType()->isFloatTy()) { 417aa739695SFrancis Visoiu Mistrih OS << getFPImm()->getValueAPF().convertToFloat(); 418aa739695SFrancis Visoiu Mistrih } else if (getFPImm()->getType()->isHalfTy()) { 419aa739695SFrancis Visoiu Mistrih APFloat APF = getFPImm()->getValueAPF(); 420aa739695SFrancis Visoiu Mistrih bool Unused; 421aa739695SFrancis Visoiu Mistrih APF.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &Unused); 422aa739695SFrancis Visoiu Mistrih OS << "half " << APF.convertToFloat(); 423aa739695SFrancis Visoiu Mistrih } else if (getFPImm()->getType()->isFP128Ty()) { 424aa739695SFrancis Visoiu Mistrih APFloat APF = getFPImm()->getValueAPF(); 425aa739695SFrancis Visoiu Mistrih SmallString<16> Str; 426aa739695SFrancis Visoiu Mistrih getFPImm()->getValueAPF().toString(Str); 427aa739695SFrancis Visoiu Mistrih OS << "quad " << Str; 428aa739695SFrancis Visoiu Mistrih } else if (getFPImm()->getType()->isX86_FP80Ty()) { 429aa739695SFrancis Visoiu Mistrih APFloat APF = getFPImm()->getValueAPF(); 430aa739695SFrancis Visoiu Mistrih OS << "x86_fp80 0xK"; 431aa739695SFrancis Visoiu Mistrih APInt API = APF.bitcastToAPInt(); 432aa739695SFrancis Visoiu Mistrih OS << format_hex_no_prefix(API.getHiBits(16).getZExtValue(), 4, 433aa739695SFrancis Visoiu Mistrih /*Upper=*/true); 434aa739695SFrancis Visoiu Mistrih OS << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16, 435aa739695SFrancis Visoiu Mistrih /*Upper=*/true); 436aa739695SFrancis Visoiu Mistrih } else { 437aa739695SFrancis Visoiu Mistrih OS << getFPImm()->getValueAPF().convertToDouble(); 438aa739695SFrancis Visoiu Mistrih } 439aa739695SFrancis Visoiu Mistrih break; 440aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MachineBasicBlock: 44125528d6dSFrancis Visoiu Mistrih OS << printMBBReference(*getMBB()); 442aa739695SFrancis Visoiu Mistrih break; 443aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_FrameIndex: 444aa739695SFrancis Visoiu Mistrih OS << "<fi#" << getIndex() << '>'; 445aa739695SFrancis Visoiu Mistrih break; 446aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ConstantPoolIndex: 447aa739695SFrancis Visoiu Mistrih OS << "<cp#" << getIndex(); 448aa739695SFrancis Visoiu Mistrih if (getOffset()) 449aa739695SFrancis Visoiu Mistrih OS << "+" << getOffset(); 450aa739695SFrancis Visoiu Mistrih OS << '>'; 451aa739695SFrancis Visoiu Mistrih break; 452aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_TargetIndex: 453aa739695SFrancis Visoiu Mistrih OS << "<ti#" << getIndex(); 454aa739695SFrancis Visoiu Mistrih if (getOffset()) 455aa739695SFrancis Visoiu Mistrih OS << "+" << getOffset(); 456aa739695SFrancis Visoiu Mistrih OS << '>'; 457aa739695SFrancis Visoiu Mistrih break; 458aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_JumpTableIndex: 459aa739695SFrancis Visoiu Mistrih OS << "<jt#" << getIndex() << '>'; 460aa739695SFrancis Visoiu Mistrih break; 461aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_GlobalAddress: 462aa739695SFrancis Visoiu Mistrih OS << "<ga:"; 463aa739695SFrancis Visoiu Mistrih getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 464aa739695SFrancis Visoiu Mistrih if (getOffset()) 465aa739695SFrancis Visoiu Mistrih OS << "+" << getOffset(); 466aa739695SFrancis Visoiu Mistrih OS << '>'; 467aa739695SFrancis Visoiu Mistrih break; 468aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_ExternalSymbol: 469aa739695SFrancis Visoiu Mistrih OS << "<es:" << getSymbolName(); 470aa739695SFrancis Visoiu Mistrih if (getOffset()) 471aa739695SFrancis Visoiu Mistrih OS << "+" << getOffset(); 472aa739695SFrancis Visoiu Mistrih OS << '>'; 473aa739695SFrancis Visoiu Mistrih break; 474aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_BlockAddress: 475aa739695SFrancis Visoiu Mistrih OS << '<'; 476aa739695SFrancis Visoiu Mistrih getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST); 477aa739695SFrancis Visoiu Mistrih if (getOffset()) 478aa739695SFrancis Visoiu Mistrih OS << "+" << getOffset(); 479aa739695SFrancis Visoiu Mistrih OS << '>'; 480aa739695SFrancis Visoiu Mistrih break; 481aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterMask: { 482a8a83d15SFrancis Visoiu Mistrih OS << "<regmask"; 483a8a83d15SFrancis Visoiu Mistrih if (TRI) { 484aa739695SFrancis Visoiu Mistrih unsigned NumRegsInMask = 0; 485aa739695SFrancis Visoiu Mistrih unsigned NumRegsEmitted = 0; 486aa739695SFrancis Visoiu Mistrih for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { 487aa739695SFrancis Visoiu Mistrih unsigned MaskWord = i / 32; 488aa739695SFrancis Visoiu Mistrih unsigned MaskBit = i % 32; 489aa739695SFrancis Visoiu Mistrih if (getRegMask()[MaskWord] & (1 << MaskBit)) { 490aa739695SFrancis Visoiu Mistrih if (PrintRegMaskNumRegs < 0 || 491aa739695SFrancis Visoiu Mistrih NumRegsEmitted <= static_cast<unsigned>(PrintRegMaskNumRegs)) { 492aa739695SFrancis Visoiu Mistrih OS << " " << printReg(i, TRI); 493aa739695SFrancis Visoiu Mistrih NumRegsEmitted++; 494aa739695SFrancis Visoiu Mistrih } 495aa739695SFrancis Visoiu Mistrih NumRegsInMask++; 496aa739695SFrancis Visoiu Mistrih } 497aa739695SFrancis Visoiu Mistrih } 498aa739695SFrancis Visoiu Mistrih if (NumRegsEmitted != NumRegsInMask) 499aa739695SFrancis Visoiu Mistrih OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; 500a8a83d15SFrancis Visoiu Mistrih } else { 501a8a83d15SFrancis Visoiu Mistrih OS << " ..."; 502a8a83d15SFrancis Visoiu Mistrih } 503aa739695SFrancis Visoiu Mistrih OS << ">"; 504aa739695SFrancis Visoiu Mistrih break; 505aa739695SFrancis Visoiu Mistrih } 506aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_RegisterLiveOut: 507aa739695SFrancis Visoiu Mistrih OS << "<regliveout>"; 508aa739695SFrancis Visoiu Mistrih break; 509aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Metadata: 510aa739695SFrancis Visoiu Mistrih OS << '<'; 511aa739695SFrancis Visoiu Mistrih getMetadata()->printAsOperand(OS, MST); 512aa739695SFrancis Visoiu Mistrih OS << '>'; 513aa739695SFrancis Visoiu Mistrih break; 514aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_MCSymbol: 515aa739695SFrancis Visoiu Mistrih OS << "<MCSym=" << *getMCSymbol() << '>'; 516aa739695SFrancis Visoiu Mistrih break; 517aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_CFIIndex: 518aa739695SFrancis Visoiu Mistrih OS << "<call frame instruction>"; 519aa739695SFrancis Visoiu Mistrih break; 520aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_IntrinsicID: { 521aa739695SFrancis Visoiu Mistrih Intrinsic::ID ID = getIntrinsicID(); 522aa739695SFrancis Visoiu Mistrih if (ID < Intrinsic::num_intrinsics) 523aa739695SFrancis Visoiu Mistrih OS << "<intrinsic:@" << Intrinsic::getName(ID, None) << '>'; 524aa739695SFrancis Visoiu Mistrih else if (IntrinsicInfo) 525aa739695SFrancis Visoiu Mistrih OS << "<intrinsic:@" << IntrinsicInfo->getName(ID) << '>'; 526aa739695SFrancis Visoiu Mistrih else 527aa739695SFrancis Visoiu Mistrih OS << "<intrinsic:" << ID << '>'; 528aa739695SFrancis Visoiu Mistrih break; 529aa739695SFrancis Visoiu Mistrih } 530aa739695SFrancis Visoiu Mistrih case MachineOperand::MO_Predicate: { 531aa739695SFrancis Visoiu Mistrih auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); 532aa739695SFrancis Visoiu Mistrih OS << '<' << (CmpInst::isIntPredicate(Pred) ? "intpred" : "floatpred") 533aa739695SFrancis Visoiu Mistrih << CmpInst::getPredicateName(Pred) << '>'; 534aa739695SFrancis Visoiu Mistrih break; 535aa739695SFrancis Visoiu Mistrih } 536aa739695SFrancis Visoiu Mistrih } 537aa739695SFrancis Visoiu Mistrih if (unsigned TF = getTargetFlags()) 538aa739695SFrancis Visoiu Mistrih OS << "[TF=" << TF << ']'; 539aa739695SFrancis Visoiu Mistrih } 540aa739695SFrancis Visoiu Mistrih 541aa739695SFrancis Visoiu Mistrih #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 542aa739695SFrancis Visoiu Mistrih LLVM_DUMP_METHOD void MachineOperand::dump() const { dbgs() << *this << '\n'; } 543aa739695SFrancis Visoiu Mistrih #endif 544aa739695SFrancis Visoiu Mistrih 545aa739695SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===// 546aa739695SFrancis Visoiu Mistrih // MachineMemOperand Implementation 547aa739695SFrancis Visoiu Mistrih //===----------------------------------------------------------------------===// 548aa739695SFrancis Visoiu Mistrih 549aa739695SFrancis Visoiu Mistrih /// getAddrSpace - Return the LLVM IR address space number that this pointer 550aa739695SFrancis Visoiu Mistrih /// points into. 55149477040SYaxun Liu unsigned MachinePointerInfo::getAddrSpace() const { return AddrSpace; } 552aa739695SFrancis Visoiu Mistrih 553aa739695SFrancis Visoiu Mistrih /// isDereferenceable - Return true if V is always dereferenceable for 554aa739695SFrancis Visoiu Mistrih /// Offset + Size byte. 555aa739695SFrancis Visoiu Mistrih bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C, 556aa739695SFrancis Visoiu Mistrih const DataLayout &DL) const { 557aa739695SFrancis Visoiu Mistrih if (!V.is<const Value *>()) 558aa739695SFrancis Visoiu Mistrih return false; 559aa739695SFrancis Visoiu Mistrih 560aa739695SFrancis Visoiu Mistrih const Value *BasePtr = V.get<const Value *>(); 561aa739695SFrancis Visoiu Mistrih if (BasePtr == nullptr) 562aa739695SFrancis Visoiu Mistrih return false; 563aa739695SFrancis Visoiu Mistrih 564aa739695SFrancis Visoiu Mistrih return isDereferenceableAndAlignedPointer( 565aa739695SFrancis Visoiu Mistrih BasePtr, 1, APInt(DL.getPointerSizeInBits(), Offset + Size), DL); 566aa739695SFrancis Visoiu Mistrih } 567aa739695SFrancis Visoiu Mistrih 568aa739695SFrancis Visoiu Mistrih /// getConstantPool - Return a MachinePointerInfo record that refers to the 569aa739695SFrancis Visoiu Mistrih /// constant pool. 570aa739695SFrancis Visoiu Mistrih MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { 571aa739695SFrancis Visoiu Mistrih return MachinePointerInfo(MF.getPSVManager().getConstantPool()); 572aa739695SFrancis Visoiu Mistrih } 573aa739695SFrancis Visoiu Mistrih 574aa739695SFrancis Visoiu Mistrih /// getFixedStack - Return a MachinePointerInfo record that refers to the 575aa739695SFrancis Visoiu Mistrih /// the specified FrameIndex. 576aa739695SFrancis Visoiu Mistrih MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, 577aa739695SFrancis Visoiu Mistrih int FI, int64_t Offset) { 578aa739695SFrancis Visoiu Mistrih return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); 579aa739695SFrancis Visoiu Mistrih } 580aa739695SFrancis Visoiu Mistrih 581aa739695SFrancis Visoiu Mistrih MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { 582aa739695SFrancis Visoiu Mistrih return MachinePointerInfo(MF.getPSVManager().getJumpTable()); 583aa739695SFrancis Visoiu Mistrih } 584aa739695SFrancis Visoiu Mistrih 585aa739695SFrancis Visoiu Mistrih MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { 586aa739695SFrancis Visoiu Mistrih return MachinePointerInfo(MF.getPSVManager().getGOT()); 587aa739695SFrancis Visoiu Mistrih } 588aa739695SFrancis Visoiu Mistrih 589aa739695SFrancis Visoiu Mistrih MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, 590aa739695SFrancis Visoiu Mistrih int64_t Offset, uint8_t ID) { 591aa739695SFrancis Visoiu Mistrih return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID); 592aa739695SFrancis Visoiu Mistrih } 593aa739695SFrancis Visoiu Mistrih 59449477040SYaxun Liu MachinePointerInfo MachinePointerInfo::getUnknownStack(MachineFunction &MF) { 59549477040SYaxun Liu return MachinePointerInfo(MF.getDataLayout().getAllocaAddrSpace()); 59649477040SYaxun Liu } 59749477040SYaxun Liu 598aa739695SFrancis Visoiu Mistrih MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f, 599aa739695SFrancis Visoiu Mistrih uint64_t s, unsigned int a, 600aa739695SFrancis Visoiu Mistrih const AAMDNodes &AAInfo, 601aa739695SFrancis Visoiu Mistrih const MDNode *Ranges, SyncScope::ID SSID, 602aa739695SFrancis Visoiu Mistrih AtomicOrdering Ordering, 603aa739695SFrancis Visoiu Mistrih AtomicOrdering FailureOrdering) 604aa739695SFrancis Visoiu Mistrih : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1), 605aa739695SFrancis Visoiu Mistrih AAInfo(AAInfo), Ranges(Ranges) { 606aa739695SFrancis Visoiu Mistrih assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue *>() || 607aa739695SFrancis Visoiu Mistrih isa<PointerType>(PtrInfo.V.get<const Value *>()->getType())) && 608aa739695SFrancis Visoiu Mistrih "invalid pointer value"); 609aa739695SFrancis Visoiu Mistrih assert(getBaseAlignment() == a && "Alignment is not a power of 2!"); 610aa739695SFrancis Visoiu Mistrih assert((isLoad() || isStore()) && "Not a load/store!"); 611aa739695SFrancis Visoiu Mistrih 612aa739695SFrancis Visoiu Mistrih AtomicInfo.SSID = static_cast<unsigned>(SSID); 613aa739695SFrancis Visoiu Mistrih assert(getSyncScopeID() == SSID && "Value truncated"); 614aa739695SFrancis Visoiu Mistrih AtomicInfo.Ordering = static_cast<unsigned>(Ordering); 615aa739695SFrancis Visoiu Mistrih assert(getOrdering() == Ordering && "Value truncated"); 616aa739695SFrancis Visoiu Mistrih AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering); 617aa739695SFrancis Visoiu Mistrih assert(getFailureOrdering() == FailureOrdering && "Value truncated"); 618aa739695SFrancis Visoiu Mistrih } 619aa739695SFrancis Visoiu Mistrih 620aa739695SFrancis Visoiu Mistrih /// Profile - Gather unique data for the object. 621aa739695SFrancis Visoiu Mistrih /// 622aa739695SFrancis Visoiu Mistrih void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 623aa739695SFrancis Visoiu Mistrih ID.AddInteger(getOffset()); 624aa739695SFrancis Visoiu Mistrih ID.AddInteger(Size); 625aa739695SFrancis Visoiu Mistrih ID.AddPointer(getOpaqueValue()); 626aa739695SFrancis Visoiu Mistrih ID.AddInteger(getFlags()); 627aa739695SFrancis Visoiu Mistrih ID.AddInteger(getBaseAlignment()); 628aa739695SFrancis Visoiu Mistrih } 629aa739695SFrancis Visoiu Mistrih 630aa739695SFrancis Visoiu Mistrih void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 631aa739695SFrancis Visoiu Mistrih // The Value and Offset may differ due to CSE. But the flags and size 632aa739695SFrancis Visoiu Mistrih // should be the same. 633aa739695SFrancis Visoiu Mistrih assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 634aa739695SFrancis Visoiu Mistrih assert(MMO->getSize() == getSize() && "Size mismatch!"); 635aa739695SFrancis Visoiu Mistrih 636aa739695SFrancis Visoiu Mistrih if (MMO->getBaseAlignment() >= getBaseAlignment()) { 637aa739695SFrancis Visoiu Mistrih // Update the alignment value. 638aa739695SFrancis Visoiu Mistrih BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1; 639aa739695SFrancis Visoiu Mistrih // Also update the base and offset, because the new alignment may 640aa739695SFrancis Visoiu Mistrih // not be applicable with the old ones. 641aa739695SFrancis Visoiu Mistrih PtrInfo = MMO->PtrInfo; 642aa739695SFrancis Visoiu Mistrih } 643aa739695SFrancis Visoiu Mistrih } 644aa739695SFrancis Visoiu Mistrih 645aa739695SFrancis Visoiu Mistrih /// getAlignment - Return the minimum known alignment in bytes of the 646aa739695SFrancis Visoiu Mistrih /// actual memory reference. 647aa739695SFrancis Visoiu Mistrih uint64_t MachineMemOperand::getAlignment() const { 648aa739695SFrancis Visoiu Mistrih return MinAlign(getBaseAlignment(), getOffset()); 649aa739695SFrancis Visoiu Mistrih } 650aa739695SFrancis Visoiu Mistrih 651aa739695SFrancis Visoiu Mistrih void MachineMemOperand::print(raw_ostream &OS) const { 652aa739695SFrancis Visoiu Mistrih ModuleSlotTracker DummyMST(nullptr); 653aa739695SFrancis Visoiu Mistrih print(OS, DummyMST); 654aa739695SFrancis Visoiu Mistrih } 655aa739695SFrancis Visoiu Mistrih void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const { 656aa739695SFrancis Visoiu Mistrih assert((isLoad() || isStore()) && "SV has to be a load, store or both."); 657aa739695SFrancis Visoiu Mistrih 658aa739695SFrancis Visoiu Mistrih if (isVolatile()) 659aa739695SFrancis Visoiu Mistrih OS << "Volatile "; 660aa739695SFrancis Visoiu Mistrih 661aa739695SFrancis Visoiu Mistrih if (isLoad()) 662aa739695SFrancis Visoiu Mistrih OS << "LD"; 663aa739695SFrancis Visoiu Mistrih if (isStore()) 664aa739695SFrancis Visoiu Mistrih OS << "ST"; 665aa739695SFrancis Visoiu Mistrih OS << getSize(); 666aa739695SFrancis Visoiu Mistrih 667aa739695SFrancis Visoiu Mistrih // Print the address information. 668aa739695SFrancis Visoiu Mistrih OS << "["; 669aa739695SFrancis Visoiu Mistrih if (const Value *V = getValue()) 670aa739695SFrancis Visoiu Mistrih V->printAsOperand(OS, /*PrintType=*/false, MST); 671aa739695SFrancis Visoiu Mistrih else if (const PseudoSourceValue *PSV = getPseudoValue()) 672aa739695SFrancis Visoiu Mistrih PSV->printCustom(OS); 673aa739695SFrancis Visoiu Mistrih else 674aa739695SFrancis Visoiu Mistrih OS << "<unknown>"; 675aa739695SFrancis Visoiu Mistrih 676aa739695SFrancis Visoiu Mistrih unsigned AS = getAddrSpace(); 677aa739695SFrancis Visoiu Mistrih if (AS != 0) 678aa739695SFrancis Visoiu Mistrih OS << "(addrspace=" << AS << ')'; 679aa739695SFrancis Visoiu Mistrih 680aa739695SFrancis Visoiu Mistrih // If the alignment of the memory reference itself differs from the alignment 681aa739695SFrancis Visoiu Mistrih // of the base pointer, print the base alignment explicitly, next to the base 682aa739695SFrancis Visoiu Mistrih // pointer. 683aa739695SFrancis Visoiu Mistrih if (getBaseAlignment() != getAlignment()) 684aa739695SFrancis Visoiu Mistrih OS << "(align=" << getBaseAlignment() << ")"; 685aa739695SFrancis Visoiu Mistrih 686aa739695SFrancis Visoiu Mistrih if (getOffset() != 0) 687aa739695SFrancis Visoiu Mistrih OS << "+" << getOffset(); 688aa739695SFrancis Visoiu Mistrih OS << "]"; 689aa739695SFrancis Visoiu Mistrih 690aa739695SFrancis Visoiu Mistrih // Print the alignment of the reference. 691aa739695SFrancis Visoiu Mistrih if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize()) 692aa739695SFrancis Visoiu Mistrih OS << "(align=" << getAlignment() << ")"; 693aa739695SFrancis Visoiu Mistrih 694aa739695SFrancis Visoiu Mistrih // Print TBAA info. 695aa739695SFrancis Visoiu Mistrih if (const MDNode *TBAAInfo = getAAInfo().TBAA) { 696aa739695SFrancis Visoiu Mistrih OS << "(tbaa="; 697aa739695SFrancis Visoiu Mistrih if (TBAAInfo->getNumOperands() > 0) 698aa739695SFrancis Visoiu Mistrih TBAAInfo->getOperand(0)->printAsOperand(OS, MST); 699aa739695SFrancis Visoiu Mistrih else 700aa739695SFrancis Visoiu Mistrih OS << "<unknown>"; 701aa739695SFrancis Visoiu Mistrih OS << ")"; 702aa739695SFrancis Visoiu Mistrih } 703aa739695SFrancis Visoiu Mistrih 704aa739695SFrancis Visoiu Mistrih // Print AA scope info. 705aa739695SFrancis Visoiu Mistrih if (const MDNode *ScopeInfo = getAAInfo().Scope) { 706aa739695SFrancis Visoiu Mistrih OS << "(alias.scope="; 707aa739695SFrancis Visoiu Mistrih if (ScopeInfo->getNumOperands() > 0) 708aa739695SFrancis Visoiu Mistrih for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { 709aa739695SFrancis Visoiu Mistrih ScopeInfo->getOperand(i)->printAsOperand(OS, MST); 710aa739695SFrancis Visoiu Mistrih if (i != ie - 1) 711aa739695SFrancis Visoiu Mistrih OS << ","; 712aa739695SFrancis Visoiu Mistrih } 713aa739695SFrancis Visoiu Mistrih else 714aa739695SFrancis Visoiu Mistrih OS << "<unknown>"; 715aa739695SFrancis Visoiu Mistrih OS << ")"; 716aa739695SFrancis Visoiu Mistrih } 717aa739695SFrancis Visoiu Mistrih 718aa739695SFrancis Visoiu Mistrih // Print AA noalias scope info. 719aa739695SFrancis Visoiu Mistrih if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) { 720aa739695SFrancis Visoiu Mistrih OS << "(noalias="; 721aa739695SFrancis Visoiu Mistrih if (NoAliasInfo->getNumOperands() > 0) 722aa739695SFrancis Visoiu Mistrih for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { 723aa739695SFrancis Visoiu Mistrih NoAliasInfo->getOperand(i)->printAsOperand(OS, MST); 724aa739695SFrancis Visoiu Mistrih if (i != ie - 1) 725aa739695SFrancis Visoiu Mistrih OS << ","; 726aa739695SFrancis Visoiu Mistrih } 727aa739695SFrancis Visoiu Mistrih else 728aa739695SFrancis Visoiu Mistrih OS << "<unknown>"; 729aa739695SFrancis Visoiu Mistrih OS << ")"; 730aa739695SFrancis Visoiu Mistrih } 731aa739695SFrancis Visoiu Mistrih 732aa739695SFrancis Visoiu Mistrih if (const MDNode *Ranges = getRanges()) { 733aa739695SFrancis Visoiu Mistrih unsigned NumRanges = Ranges->getNumOperands(); 734aa739695SFrancis Visoiu Mistrih if (NumRanges != 0) { 735aa739695SFrancis Visoiu Mistrih OS << "(ranges="; 736aa739695SFrancis Visoiu Mistrih 737aa739695SFrancis Visoiu Mistrih for (unsigned I = 0; I != NumRanges; ++I) { 738aa739695SFrancis Visoiu Mistrih Ranges->getOperand(I)->printAsOperand(OS, MST); 739aa739695SFrancis Visoiu Mistrih if (I != NumRanges - 1) 740aa739695SFrancis Visoiu Mistrih OS << ','; 741aa739695SFrancis Visoiu Mistrih } 742aa739695SFrancis Visoiu Mistrih 743aa739695SFrancis Visoiu Mistrih OS << ')'; 744aa739695SFrancis Visoiu Mistrih } 745aa739695SFrancis Visoiu Mistrih } 746aa739695SFrancis Visoiu Mistrih 747aa739695SFrancis Visoiu Mistrih if (isNonTemporal()) 748aa739695SFrancis Visoiu Mistrih OS << "(nontemporal)"; 749aa739695SFrancis Visoiu Mistrih if (isDereferenceable()) 750aa739695SFrancis Visoiu Mistrih OS << "(dereferenceable)"; 751aa739695SFrancis Visoiu Mistrih if (isInvariant()) 752aa739695SFrancis Visoiu Mistrih OS << "(invariant)"; 753aa739695SFrancis Visoiu Mistrih if (getFlags() & MOTargetFlag1) 754aa739695SFrancis Visoiu Mistrih OS << "(flag1)"; 755aa739695SFrancis Visoiu Mistrih if (getFlags() & MOTargetFlag2) 756aa739695SFrancis Visoiu Mistrih OS << "(flag2)"; 757aa739695SFrancis Visoiu Mistrih if (getFlags() & MOTargetFlag3) 758aa739695SFrancis Visoiu Mistrih OS << "(flag3)"; 759aa739695SFrancis Visoiu Mistrih } 760