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