1f9448bf3SDimitry Andric //===- lib/CodeGen/MachineInstr.cpp ---------------------------------------===// 2f22ef01cSRoman Divacky // 3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure 4f22ef01cSRoman Divacky // 5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source 6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details. 7f22ef01cSRoman Divacky // 8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 9f22ef01cSRoman Divacky // 10f22ef01cSRoman Divacky // Methods common to all machine instructions. 11f22ef01cSRoman Divacky // 12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 13f22ef01cSRoman Divacky 14db17bf38SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 15f9448bf3SDimitry Andric #include "llvm/ADT/APFloat.h" 16f9448bf3SDimitry Andric #include "llvm/ADT/ArrayRef.h" 17139f7f9bSDimitry Andric #include "llvm/ADT/FoldingSet.h" 18139f7f9bSDimitry Andric #include "llvm/ADT/Hashing.h" 19f9448bf3SDimitry Andric #include "llvm/ADT/None.h" 20db17bf38SDimitry Andric #include "llvm/ADT/STLExtras.h" 21f9448bf3SDimitry Andric #include "llvm/ADT/SmallString.h" 22f9448bf3SDimitry Andric #include "llvm/ADT/SmallVector.h" 23139f7f9bSDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 24edd7eaddSDimitry Andric #include "llvm/Analysis/Loads.h" 25f9448bf3SDimitry Andric #include "llvm/Analysis/MemoryLocation.h" 26f9448bf3SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 27f9448bf3SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 28f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunction.h" 293ca95b02SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 30f9448bf3SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h" 31f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineMemOperand.h" 3217a519f9SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 33f9448bf3SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 34f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h" 35f22ef01cSRoman Divacky #include "llvm/CodeGen/PseudoSourceValue.h" 36139f7f9bSDimitry Andric #include "llvm/IR/Constants.h" 37f9448bf3SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 38f9448bf3SDimitry Andric #include "llvm/IR/DebugLoc.h" 39f9448bf3SDimitry Andric #include "llvm/IR/DerivedTypes.h" 40139f7f9bSDimitry Andric #include "llvm/IR/Function.h" 41139f7f9bSDimitry Andric #include "llvm/IR/InlineAsm.h" 42f9448bf3SDimitry Andric #include "llvm/IR/InstrTypes.h" 43d88c1a5aSDimitry Andric #include "llvm/IR/Intrinsics.h" 44139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h" 45139f7f9bSDimitry Andric #include "llvm/IR/Metadata.h" 46139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 473dac3a9bSDimitry Andric #include "llvm/IR/ModuleSlotTracker.h" 48139f7f9bSDimitry Andric #include "llvm/IR/Type.h" 49139f7f9bSDimitry Andric #include "llvm/IR/Value.h" 5017a519f9SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 51f9448bf3SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 52db17bf38SDimitry Andric #include "llvm/MC/MCSymbol.h" 53f9448bf3SDimitry Andric #include "llvm/Support/Casting.h" 547d523365SDimitry Andric #include "llvm/Support/CommandLine.h" 55f9448bf3SDimitry Andric #include "llvm/Support/Compiler.h" 56f22ef01cSRoman Divacky #include "llvm/Support/Debug.h" 57f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 58f9448bf3SDimitry Andric #include "llvm/Support/LowLevelTypeImpl.h" 59f22ef01cSRoman Divacky #include "llvm/Support/MathExtras.h" 60f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 61139f7f9bSDimitry Andric #include "llvm/Target/TargetInstrInfo.h" 62d88c1a5aSDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h" 63139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h" 64139f7f9bSDimitry Andric #include "llvm/Target/TargetRegisterInfo.h" 6539d628a0SDimitry Andric #include "llvm/Target/TargetSubtargetInfo.h" 66f9448bf3SDimitry Andric #include <algorithm> 67f9448bf3SDimitry Andric #include <cassert> 68f9448bf3SDimitry Andric #include <cstddef> 69f9448bf3SDimitry Andric #include <cstdint> 70f9448bf3SDimitry Andric #include <cstring> 71f9448bf3SDimitry Andric #include <iterator> 72f9448bf3SDimitry Andric #include <utility> 73f9448bf3SDimitry Andric 74f22ef01cSRoman Divacky using namespace llvm; 75f22ef01cSRoman Divacky 767d523365SDimitry Andric static cl::opt<bool> PrintWholeRegMask( 777d523365SDimitry Andric "print-whole-regmask", 787d523365SDimitry Andric cl::desc("Print the full contents of regmask operands in IR dumps"), 797d523365SDimitry Andric cl::init(true), cl::Hidden); 807d523365SDimitry Andric 81f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 82f22ef01cSRoman Divacky // MachineOperand Implementation 83f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 84f22ef01cSRoman Divacky 85f22ef01cSRoman Divacky void MachineOperand::setReg(unsigned Reg) { 86f22ef01cSRoman Divacky if (getReg() == Reg) return; // No change. 87f22ef01cSRoman Divacky 88f22ef01cSRoman Divacky // Otherwise, we have to change the register. If this operand is embedded 89f22ef01cSRoman Divacky // into a machine function, we need to update the old and new register's 90f22ef01cSRoman Divacky // use/def lists. 91f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 92f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 93f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) { 947ae0e2c9SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 957ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(this); 962754fe60SDimitry Andric SmallContents.RegNo = Reg; 977ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(this); 98f22ef01cSRoman Divacky return; 99f22ef01cSRoman Divacky } 100f22ef01cSRoman Divacky 101f22ef01cSRoman Divacky // Otherwise, just change the register, no problem. :) 1022754fe60SDimitry Andric SmallContents.RegNo = Reg; 103f22ef01cSRoman Divacky } 104f22ef01cSRoman Divacky 105ffd1746dSEd Schouten void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, 106ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 107ffd1746dSEd Schouten assert(TargetRegisterInfo::isVirtualRegister(Reg)); 108ffd1746dSEd Schouten if (SubIdx && getSubReg()) 109ffd1746dSEd Schouten SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); 110ffd1746dSEd Schouten setReg(Reg); 111ffd1746dSEd Schouten if (SubIdx) 112ffd1746dSEd Schouten setSubReg(SubIdx); 113ffd1746dSEd Schouten } 114ffd1746dSEd Schouten 115ffd1746dSEd Schouten void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { 116ffd1746dSEd Schouten assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 117ffd1746dSEd Schouten if (getSubReg()) { 118ffd1746dSEd Schouten Reg = TRI.getSubReg(Reg, getSubReg()); 119bd5abe19SDimitry Andric // Note that getSubReg() may return 0 if the sub-register doesn't exist. 120bd5abe19SDimitry Andric // That won't happen in legal code. 121ffd1746dSEd Schouten setSubReg(0); 122d88c1a5aSDimitry Andric if (isDef()) 123d88c1a5aSDimitry Andric setIsUndef(false); 124ffd1746dSEd Schouten } 125ffd1746dSEd Schouten setReg(Reg); 126ffd1746dSEd Schouten } 127ffd1746dSEd Schouten 1287ae0e2c9SDimitry Andric /// Change a def to a use, or a use to a def. 1297ae0e2c9SDimitry Andric void MachineOperand::setIsDef(bool Val) { 1307ae0e2c9SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 1317ae0e2c9SDimitry Andric assert((!Val || !isDebug()) && "Marking a debug operation as def"); 1327ae0e2c9SDimitry Andric if (IsDef == Val) 1337ae0e2c9SDimitry Andric return; 1347ae0e2c9SDimitry Andric // MRI may keep uses and defs in different list positions. 1357ae0e2c9SDimitry Andric if (MachineInstr *MI = getParent()) 1367ae0e2c9SDimitry Andric if (MachineBasicBlock *MBB = MI->getParent()) 1377ae0e2c9SDimitry Andric if (MachineFunction *MF = MBB->getParent()) { 1387ae0e2c9SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 1397ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(this); 1407ae0e2c9SDimitry Andric IsDef = Val; 1417ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(this); 1427ae0e2c9SDimitry Andric return; 1437ae0e2c9SDimitry Andric } 1447ae0e2c9SDimitry Andric IsDef = Val; 1457ae0e2c9SDimitry Andric } 1467ae0e2c9SDimitry Andric 14739d628a0SDimitry Andric // If this operand is currently a register operand, and if this is in a 14839d628a0SDimitry Andric // function, deregister the operand from the register's use/def list. 14939d628a0SDimitry Andric void MachineOperand::removeRegFromUses() { 15039d628a0SDimitry Andric if (!isReg() || !isOnRegUseList()) 15139d628a0SDimitry Andric return; 15239d628a0SDimitry Andric 15339d628a0SDimitry Andric if (MachineInstr *MI = getParent()) { 15439d628a0SDimitry Andric if (MachineBasicBlock *MBB = MI->getParent()) { 15539d628a0SDimitry Andric if (MachineFunction *MF = MBB->getParent()) 15639d628a0SDimitry Andric MF->getRegInfo().removeRegOperandFromUseList(this); 15739d628a0SDimitry Andric } 15839d628a0SDimitry Andric } 15939d628a0SDimitry Andric } 16039d628a0SDimitry Andric 161f22ef01cSRoman Divacky /// ChangeToImmediate - Replace this operand with a new immediate operand of 162f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an immediate already, 163f22ef01cSRoman Divacky /// the setImm method should be used. 164f22ef01cSRoman Divacky void MachineOperand::ChangeToImmediate(int64_t ImmVal) { 1653861d79fSDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 16639d628a0SDimitry Andric 16739d628a0SDimitry Andric removeRegFromUses(); 168f22ef01cSRoman Divacky 169f22ef01cSRoman Divacky OpKind = MO_Immediate; 170f22ef01cSRoman Divacky Contents.ImmVal = ImmVal; 171f22ef01cSRoman Divacky } 172f22ef01cSRoman Divacky 17339d628a0SDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) { 17439d628a0SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 17539d628a0SDimitry Andric 17639d628a0SDimitry Andric removeRegFromUses(); 17739d628a0SDimitry Andric 17839d628a0SDimitry Andric OpKind = MO_FPImmediate; 17939d628a0SDimitry Andric Contents.CFP = FPImm; 18039d628a0SDimitry Andric } 18139d628a0SDimitry Andric 182ff0cc061SDimitry Andric void MachineOperand::ChangeToES(const char *SymName, unsigned char TargetFlags) { 183ff0cc061SDimitry Andric assert((!isReg() || !isTied()) && 184ff0cc061SDimitry Andric "Cannot change a tied operand into an external symbol"); 185ff0cc061SDimitry Andric 186ff0cc061SDimitry Andric removeRegFromUses(); 187ff0cc061SDimitry Andric 188ff0cc061SDimitry Andric OpKind = MO_ExternalSymbol; 189ff0cc061SDimitry Andric Contents.OffsetedInfo.Val.SymbolName = SymName; 190ff0cc061SDimitry Andric setOffset(0); // Offset is always 0. 191ff0cc061SDimitry Andric setTargetFlags(TargetFlags); 192ff0cc061SDimitry Andric } 193ff0cc061SDimitry Andric 194ff0cc061SDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) { 195ff0cc061SDimitry Andric assert((!isReg() || !isTied()) && 196ff0cc061SDimitry Andric "Cannot change a tied operand into an MCSymbol"); 197ff0cc061SDimitry Andric 198ff0cc061SDimitry Andric removeRegFromUses(); 199ff0cc061SDimitry Andric 200ff0cc061SDimitry Andric OpKind = MO_MCSymbol; 201ff0cc061SDimitry Andric Contents.Sym = Sym; 202ff0cc061SDimitry Andric } 203ff0cc061SDimitry Andric 204d88c1a5aSDimitry Andric void MachineOperand::ChangeToFrameIndex(int Idx) { 205d88c1a5aSDimitry Andric assert((!isReg() || !isTied()) && 206d88c1a5aSDimitry Andric "Cannot change a tied operand into a FrameIndex"); 207d88c1a5aSDimitry Andric 208d88c1a5aSDimitry Andric removeRegFromUses(); 209d88c1a5aSDimitry Andric 210d88c1a5aSDimitry Andric OpKind = MO_FrameIndex; 211d88c1a5aSDimitry Andric setIndex(Idx); 212d88c1a5aSDimitry Andric } 213d88c1a5aSDimitry Andric 214f22ef01cSRoman Divacky /// ChangeToRegister - Replace this operand with a new register operand of 215f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an register already, 216f22ef01cSRoman Divacky /// the setReg method should be used. 217f22ef01cSRoman Divacky void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, 218f22ef01cSRoman Divacky bool isKill, bool isDead, bool isUndef, 219f22ef01cSRoman Divacky bool isDebug) { 22091bc56edSDimitry Andric MachineRegisterInfo *RegInfo = nullptr; 221f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 222f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 223f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) 2247ae0e2c9SDimitry Andric RegInfo = &MF->getRegInfo(); 2257ae0e2c9SDimitry Andric // If this operand is already a register operand, remove it from the 2267ae0e2c9SDimitry Andric // register's use/def lists. 2273861d79fSDimitry Andric bool WasReg = isReg(); 2283861d79fSDimitry Andric if (RegInfo && WasReg) 2297ae0e2c9SDimitry Andric RegInfo->removeRegOperandFromUseList(this); 230f22ef01cSRoman Divacky 2317ae0e2c9SDimitry Andric // Change this to a register and set the reg#. 2327ae0e2c9SDimitry Andric OpKind = MO_Register; 2337ae0e2c9SDimitry Andric SmallContents.RegNo = Reg; 234139f7f9bSDimitry Andric SubReg_TargetFlags = 0; 235f22ef01cSRoman Divacky IsDef = isDef; 236f22ef01cSRoman Divacky IsImp = isImp; 237f22ef01cSRoman Divacky IsKill = isKill; 238f22ef01cSRoman Divacky IsDead = isDead; 239f22ef01cSRoman Divacky IsUndef = isUndef; 240dff0c46cSDimitry Andric IsInternalRead = false; 241f22ef01cSRoman Divacky IsEarlyClobber = false; 242f22ef01cSRoman Divacky IsDebug = isDebug; 2437ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false. 24491bc56edSDimitry Andric Contents.Reg.Prev = nullptr; 2453861d79fSDimitry Andric // Preserve the tie when the operand was already a register. 2463861d79fSDimitry Andric if (!WasReg) 2473861d79fSDimitry Andric TiedTo = 0; 2487ae0e2c9SDimitry Andric 2497ae0e2c9SDimitry Andric // If this operand is embedded in a function, add the operand to the 2507ae0e2c9SDimitry Andric // register's use/def list. 2517ae0e2c9SDimitry Andric if (RegInfo) 2527ae0e2c9SDimitry Andric RegInfo->addRegOperandToUseList(this); 253f22ef01cSRoman Divacky } 254f22ef01cSRoman Divacky 255f22ef01cSRoman Divacky /// isIdenticalTo - Return true if this operand is identical to the specified 2567ae0e2c9SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload 2577ae0e2c9SDimitry Andric /// below. 258f22ef01cSRoman Divacky bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 259f22ef01cSRoman Divacky if (getType() != Other.getType() || 260f22ef01cSRoman Divacky getTargetFlags() != Other.getTargetFlags()) 261f22ef01cSRoman Divacky return false; 262f22ef01cSRoman Divacky 263f22ef01cSRoman Divacky switch (getType()) { 264f22ef01cSRoman Divacky case MachineOperand::MO_Register: 265f22ef01cSRoman Divacky return getReg() == Other.getReg() && isDef() == Other.isDef() && 266f22ef01cSRoman Divacky getSubReg() == Other.getSubReg(); 267f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 268f22ef01cSRoman Divacky return getImm() == Other.getImm(); 26917a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 27017a519f9SDimitry Andric return getCImm() == Other.getCImm(); 271f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 272f22ef01cSRoman Divacky return getFPImm() == Other.getFPImm(); 273f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 274f22ef01cSRoman Divacky return getMBB() == Other.getMBB(); 275f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 276f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 277f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 2787ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 279f22ef01cSRoman Divacky return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 280f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 281f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 282f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 283f22ef01cSRoman Divacky return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 284f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 285f9448bf3SDimitry Andric return strcmp(getSymbolName(), Other.getSymbolName()) == 0 && 286f22ef01cSRoman Divacky getOffset() == Other.getOffset(); 287f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 2883861d79fSDimitry Andric return getBlockAddress() == Other.getBlockAddress() && 2893861d79fSDimitry Andric getOffset() == Other.getOffset(); 29091bc56edSDimitry Andric case MachineOperand::MO_RegisterMask: 2917a7e6055SDimitry Andric case MachineOperand::MO_RegisterLiveOut: { 2927a7e6055SDimitry Andric // Shallow compare of the two RegMasks 2937a7e6055SDimitry Andric const uint32_t *RegMask = getRegMask(); 2947a7e6055SDimitry Andric const uint32_t *OtherRegMask = Other.getRegMask(); 2957a7e6055SDimitry Andric if (RegMask == OtherRegMask) 2967a7e6055SDimitry Andric return true; 2977a7e6055SDimitry Andric 2987a7e6055SDimitry Andric // Calculate the size of the RegMask 2997a7e6055SDimitry Andric const MachineFunction *MF = getParent()->getParent()->getParent(); 3007a7e6055SDimitry Andric const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 3017a7e6055SDimitry Andric unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32; 3027a7e6055SDimitry Andric 3037a7e6055SDimitry Andric // Deep compare of the two RegMasks 3047a7e6055SDimitry Andric return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask); 3057a7e6055SDimitry Andric } 306f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 307f22ef01cSRoman Divacky return getMCSymbol() == Other.getMCSymbol(); 30891bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 30991bc56edSDimitry Andric return getCFIIndex() == Other.getCFIIndex(); 310f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 311f22ef01cSRoman Divacky return getMetadata() == Other.getMetadata(); 312d88c1a5aSDimitry Andric case MachineOperand::MO_IntrinsicID: 313d88c1a5aSDimitry Andric return getIntrinsicID() == Other.getIntrinsicID(); 314d88c1a5aSDimitry Andric case MachineOperand::MO_Predicate: 315d88c1a5aSDimitry Andric return getPredicate() == Other.getPredicate(); 316f22ef01cSRoman Divacky } 317dff0c46cSDimitry Andric llvm_unreachable("Invalid machine operand type"); 318f22ef01cSRoman Divacky } 319f22ef01cSRoman Divacky 3207ae0e2c9SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above. 3217ae0e2c9SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) { 3227ae0e2c9SDimitry Andric switch (MO.getType()) { 3237ae0e2c9SDimitry Andric case MachineOperand::MO_Register: 3243861d79fSDimitry Andric // Register operands don't have target flags. 3253861d79fSDimitry Andric return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef()); 3267ae0e2c9SDimitry Andric case MachineOperand::MO_Immediate: 3277ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 3287ae0e2c9SDimitry Andric case MachineOperand::MO_CImmediate: 3297ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 3307ae0e2c9SDimitry Andric case MachineOperand::MO_FPImmediate: 3317ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 3327ae0e2c9SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 3337ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 3347ae0e2c9SDimitry Andric case MachineOperand::MO_FrameIndex: 3357ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 3367ae0e2c9SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 3377ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 3387ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 3397ae0e2c9SDimitry Andric MO.getOffset()); 3407ae0e2c9SDimitry Andric case MachineOperand::MO_JumpTableIndex: 3417ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 3427ae0e2c9SDimitry Andric case MachineOperand::MO_ExternalSymbol: 3437ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 3447ae0e2c9SDimitry Andric MO.getSymbolName()); 3457ae0e2c9SDimitry Andric case MachineOperand::MO_GlobalAddress: 3467ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 3477ae0e2c9SDimitry Andric MO.getOffset()); 3487ae0e2c9SDimitry Andric case MachineOperand::MO_BlockAddress: 3497ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), 3503861d79fSDimitry Andric MO.getBlockAddress(), MO.getOffset()); 3517ae0e2c9SDimitry Andric case MachineOperand::MO_RegisterMask: 35291bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 3537ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); 3547ae0e2c9SDimitry Andric case MachineOperand::MO_Metadata: 3557ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 3567ae0e2c9SDimitry Andric case MachineOperand::MO_MCSymbol: 3577ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 35891bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 35991bc56edSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 360d88c1a5aSDimitry Andric case MachineOperand::MO_IntrinsicID: 361d88c1a5aSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); 362d88c1a5aSDimitry Andric case MachineOperand::MO_Predicate: 363d88c1a5aSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); 3647ae0e2c9SDimitry Andric } 3657ae0e2c9SDimitry Andric llvm_unreachable("Invalid machine operand type"); 3667ae0e2c9SDimitry Andric } 3677ae0e2c9SDimitry Andric 368d88c1a5aSDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, 369d88c1a5aSDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 3703dac3a9bSDimitry Andric ModuleSlotTracker DummyMST(nullptr); 371d88c1a5aSDimitry Andric print(OS, DummyMST, TRI, IntrinsicInfo); 3723dac3a9bSDimitry Andric } 3733dac3a9bSDimitry Andric 3743dac3a9bSDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 375d88c1a5aSDimitry Andric const TargetRegisterInfo *TRI, 376d88c1a5aSDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 377f22ef01cSRoman Divacky switch (getType()) { 378f22ef01cSRoman Divacky case MachineOperand::MO_Register: 3792754fe60SDimitry Andric OS << PrintReg(getReg(), TRI, getSubReg()); 380f22ef01cSRoman Divacky 381f22ef01cSRoman Divacky if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || 3823861d79fSDimitry Andric isInternalRead() || isEarlyClobber() || isTied()) { 383f22ef01cSRoman Divacky OS << '<'; 384f22ef01cSRoman Divacky bool NeedComma = false; 385f22ef01cSRoman Divacky if (isDef()) { 386f22ef01cSRoman Divacky if (NeedComma) OS << ','; 387f22ef01cSRoman Divacky if (isEarlyClobber()) 388f22ef01cSRoman Divacky OS << "earlyclobber,"; 389f22ef01cSRoman Divacky if (isImplicit()) 390f22ef01cSRoman Divacky OS << "imp-"; 391f22ef01cSRoman Divacky OS << "def"; 392f22ef01cSRoman Divacky NeedComma = true; 3937ae0e2c9SDimitry Andric // <def,read-undef> only makes sense when getSubReg() is set. 3947ae0e2c9SDimitry Andric // Don't clutter the output otherwise. 3957ae0e2c9SDimitry Andric if (isUndef() && getSubReg()) 3967ae0e2c9SDimitry Andric OS << ",read-undef"; 397f22ef01cSRoman Divacky } else if (isImplicit()) { 398f22ef01cSRoman Divacky OS << "imp-use"; 399f22ef01cSRoman Divacky NeedComma = true; 400f22ef01cSRoman Divacky } 401f22ef01cSRoman Divacky 402dff0c46cSDimitry Andric if (isKill()) { 4033861d79fSDimitry Andric if (NeedComma) OS << ','; 404dff0c46cSDimitry Andric OS << "kill"; 405dff0c46cSDimitry Andric NeedComma = true; 406dff0c46cSDimitry Andric } 407dff0c46cSDimitry Andric if (isDead()) { 4083861d79fSDimitry Andric if (NeedComma) OS << ','; 409dff0c46cSDimitry Andric OS << "dead"; 410dff0c46cSDimitry Andric NeedComma = true; 411dff0c46cSDimitry Andric } 4127ae0e2c9SDimitry Andric if (isUndef() && isUse()) { 413dff0c46cSDimitry Andric if (NeedComma) OS << ','; 414f22ef01cSRoman Divacky OS << "undef"; 415dff0c46cSDimitry Andric NeedComma = true; 416dff0c46cSDimitry Andric } 417dff0c46cSDimitry Andric if (isInternalRead()) { 418dff0c46cSDimitry Andric if (NeedComma) OS << ','; 419dff0c46cSDimitry Andric OS << "internal"; 420dff0c46cSDimitry Andric NeedComma = true; 421f22ef01cSRoman Divacky } 4223861d79fSDimitry Andric if (isTied()) { 4233861d79fSDimitry Andric if (NeedComma) OS << ','; 4243861d79fSDimitry Andric OS << "tied"; 4253861d79fSDimitry Andric if (TiedTo != 15) 4263861d79fSDimitry Andric OS << unsigned(TiedTo - 1); 427f22ef01cSRoman Divacky } 428f22ef01cSRoman Divacky OS << '>'; 429f22ef01cSRoman Divacky } 430f22ef01cSRoman Divacky break; 431f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 432f22ef01cSRoman Divacky OS << getImm(); 433f22ef01cSRoman Divacky break; 43417a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 43517a519f9SDimitry Andric getCImm()->getValue().print(OS, false); 43617a519f9SDimitry Andric break; 437f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 4383ca95b02SDimitry Andric if (getFPImm()->getType()->isFloatTy()) { 439f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToFloat(); 4403ca95b02SDimitry Andric } else if (getFPImm()->getType()->isHalfTy()) { 4413ca95b02SDimitry Andric APFloat APF = getFPImm()->getValueAPF(); 4423ca95b02SDimitry Andric bool Unused; 443d88c1a5aSDimitry Andric APF.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &Unused); 4443ca95b02SDimitry Andric OS << "half " << APF.convertToFloat(); 4457a7e6055SDimitry Andric } else if (getFPImm()->getType()->isFP128Ty()) { 4467a7e6055SDimitry Andric APFloat APF = getFPImm()->getValueAPF(); 4477a7e6055SDimitry Andric SmallString<16> Str; 4487a7e6055SDimitry Andric getFPImm()->getValueAPF().toString(Str); 4497a7e6055SDimitry Andric OS << "quad " << Str; 4503ca95b02SDimitry Andric } else { 451f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToDouble(); 4523ca95b02SDimitry Andric } 453f22ef01cSRoman Divacky break; 454f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 455f22ef01cSRoman Divacky OS << "<BB#" << getMBB()->getNumber() << ">"; 456f22ef01cSRoman Divacky break; 457f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 458f22ef01cSRoman Divacky OS << "<fi#" << getIndex() << '>'; 459f22ef01cSRoman Divacky break; 460f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 461f22ef01cSRoman Divacky OS << "<cp#" << getIndex(); 462f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 463f22ef01cSRoman Divacky OS << '>'; 464f22ef01cSRoman Divacky break; 4657ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 4667ae0e2c9SDimitry Andric OS << "<ti#" << getIndex(); 4677ae0e2c9SDimitry Andric if (getOffset()) OS << "+" << getOffset(); 4687ae0e2c9SDimitry Andric OS << '>'; 4697ae0e2c9SDimitry Andric break; 470f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 471f22ef01cSRoman Divacky OS << "<jt#" << getIndex() << '>'; 472f22ef01cSRoman Divacky break; 473f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 474f22ef01cSRoman Divacky OS << "<ga:"; 4753dac3a9bSDimitry Andric getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 476f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 477f22ef01cSRoman Divacky OS << '>'; 478f22ef01cSRoman Divacky break; 479f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 480f22ef01cSRoman Divacky OS << "<es:" << getSymbolName(); 481f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 482f22ef01cSRoman Divacky OS << '>'; 483f22ef01cSRoman Divacky break; 484f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 485f22ef01cSRoman Divacky OS << '<'; 4863dac3a9bSDimitry Andric getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST); 4873861d79fSDimitry Andric if (getOffset()) OS << "+" << getOffset(); 488f22ef01cSRoman Divacky OS << '>'; 489f22ef01cSRoman Divacky break; 4907d523365SDimitry Andric case MachineOperand::MO_RegisterMask: { 4917d523365SDimitry Andric unsigned NumRegsInMask = 0; 4927d523365SDimitry Andric unsigned NumRegsEmitted = 0; 4937d523365SDimitry Andric OS << "<regmask"; 4947d523365SDimitry Andric for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { 4957d523365SDimitry Andric unsigned MaskWord = i / 32; 4967d523365SDimitry Andric unsigned MaskBit = i % 32; 4977d523365SDimitry Andric if (getRegMask()[MaskWord] & (1 << MaskBit)) { 4987d523365SDimitry Andric if (PrintWholeRegMask || NumRegsEmitted <= 10) { 4997d523365SDimitry Andric OS << " " << PrintReg(i, TRI); 5007d523365SDimitry Andric NumRegsEmitted++; 5017d523365SDimitry Andric } 5027d523365SDimitry Andric NumRegsInMask++; 5037d523365SDimitry Andric } 5047d523365SDimitry Andric } 5057d523365SDimitry Andric if (NumRegsEmitted != NumRegsInMask) 5067d523365SDimitry Andric OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; 5077d523365SDimitry Andric OS << ">"; 508dff0c46cSDimitry Andric break; 5097d523365SDimitry Andric } 51091bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 51191bc56edSDimitry Andric OS << "<regliveout>"; 51291bc56edSDimitry Andric break; 513f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 514f22ef01cSRoman Divacky OS << '<'; 5153dac3a9bSDimitry Andric getMetadata()->printAsOperand(OS, MST); 516f22ef01cSRoman Divacky OS << '>'; 517f22ef01cSRoman Divacky break; 518f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 519f22ef01cSRoman Divacky OS << "<MCSym=" << *getMCSymbol() << '>'; 520f22ef01cSRoman Divacky break; 52191bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 52291bc56edSDimitry Andric OS << "<call frame instruction>"; 52391bc56edSDimitry Andric break; 524d88c1a5aSDimitry Andric case MachineOperand::MO_IntrinsicID: { 525d88c1a5aSDimitry Andric Intrinsic::ID ID = getIntrinsicID(); 526d88c1a5aSDimitry Andric if (ID < Intrinsic::num_intrinsics) 527d88c1a5aSDimitry Andric OS << "<intrinsic:@" << Intrinsic::getName(ID, None) << '>'; 528d88c1a5aSDimitry Andric else if (IntrinsicInfo) 529d88c1a5aSDimitry Andric OS << "<intrinsic:@" << IntrinsicInfo->getName(ID) << '>'; 530d88c1a5aSDimitry Andric else 531d88c1a5aSDimitry Andric OS << "<intrinsic:" << ID << '>'; 532d88c1a5aSDimitry Andric break; 533f22ef01cSRoman Divacky } 534d88c1a5aSDimitry Andric case MachineOperand::MO_Predicate: { 535d88c1a5aSDimitry Andric auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); 536d88c1a5aSDimitry Andric OS << '<' << (CmpInst::isIntPredicate(Pred) ? "intpred" : "floatpred") 537d88c1a5aSDimitry Andric << CmpInst::getPredicateName(Pred) << '>'; 5387a7e6055SDimitry Andric break; 539d88c1a5aSDimitry Andric } 540d88c1a5aSDimitry Andric } 541f22ef01cSRoman Divacky if (unsigned TF = getTargetFlags()) 542f22ef01cSRoman Divacky OS << "[TF=" << TF << ']'; 543f22ef01cSRoman Divacky } 544f22ef01cSRoman Divacky 545d88c1a5aSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 546d88c1a5aSDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { 547d88c1a5aSDimitry Andric dbgs() << *this << '\n'; 548d88c1a5aSDimitry Andric } 549d88c1a5aSDimitry Andric #endif 550d88c1a5aSDimitry Andric 551f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 552f22ef01cSRoman Divacky // MachineMemOperand Implementation 553f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 554f22ef01cSRoman Divacky 5552754fe60SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer 5562754fe60SDimitry Andric /// points into. 5572754fe60SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { 55891bc56edSDimitry Andric if (V.isNull() || V.is<const PseudoSourceValue*>()) return 0; 55991bc56edSDimitry Andric return cast<PointerType>(V.get<const Value*>()->getType())->getAddressSpace(); 5602754fe60SDimitry Andric } 5612754fe60SDimitry Andric 562edd7eaddSDimitry Andric /// isDereferenceable - Return true if V is always dereferenceable for 563edd7eaddSDimitry Andric /// Offset + Size byte. 564edd7eaddSDimitry Andric bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C, 565edd7eaddSDimitry Andric const DataLayout &DL) const { 566edd7eaddSDimitry Andric if (!V.is<const Value*>()) 567edd7eaddSDimitry Andric return false; 568edd7eaddSDimitry Andric 569edd7eaddSDimitry Andric const Value *BasePtr = V.get<const Value*>(); 570edd7eaddSDimitry Andric if (BasePtr == nullptr) 571edd7eaddSDimitry Andric return false; 572edd7eaddSDimitry Andric 573edd7eaddSDimitry Andric return isDereferenceableAndAlignedPointer(BasePtr, 1, 574edd7eaddSDimitry Andric APInt(DL.getPointerSize(), 575edd7eaddSDimitry Andric Offset + Size), 576edd7eaddSDimitry Andric DL); 577edd7eaddSDimitry Andric } 578edd7eaddSDimitry Andric 5792754fe60SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the 5802754fe60SDimitry Andric /// constant pool. 5817d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { 5827d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getConstantPool()); 5832754fe60SDimitry Andric } 5842754fe60SDimitry Andric 5852754fe60SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the 5862754fe60SDimitry Andric /// the specified FrameIndex. 5877d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, 5887d523365SDimitry Andric int FI, int64_t Offset) { 5897d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); 5902754fe60SDimitry Andric } 5912754fe60SDimitry Andric 5927d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { 5937d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getJumpTable()); 5942754fe60SDimitry Andric } 5952754fe60SDimitry Andric 5967d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { 5977d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getGOT()); 5982754fe60SDimitry Andric } 5992754fe60SDimitry Andric 6007d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, 6017d523365SDimitry Andric int64_t Offset) { 6027d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getStack(), Offset); 6032754fe60SDimitry Andric } 6042754fe60SDimitry Andric 6053ca95b02SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f, 6062754fe60SDimitry Andric uint64_t s, unsigned int a, 60739d628a0SDimitry Andric const AAMDNodes &AAInfo, 608d88c1a5aSDimitry Andric const MDNode *Ranges, 609d88c1a5aSDimitry Andric SynchronizationScope SynchScope, 610d88c1a5aSDimitry Andric AtomicOrdering Ordering, 611d88c1a5aSDimitry Andric AtomicOrdering FailureOrdering) 6123ca95b02SDimitry Andric : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1), 61339d628a0SDimitry Andric AAInfo(AAInfo), Ranges(Ranges) { 61491bc56edSDimitry Andric assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue*>() || 61591bc56edSDimitry Andric isa<PointerType>(PtrInfo.V.get<const Value*>()->getType())) && 6162754fe60SDimitry Andric "invalid pointer value"); 617f22ef01cSRoman Divacky assert(getBaseAlignment() == a && "Alignment is not a power of 2!"); 618f22ef01cSRoman Divacky assert((isLoad() || isStore()) && "Not a load/store!"); 619d88c1a5aSDimitry Andric 620d88c1a5aSDimitry Andric AtomicInfo.SynchScope = static_cast<unsigned>(SynchScope); 621d88c1a5aSDimitry Andric assert(getSynchScope() == SynchScope && "Value truncated"); 622d88c1a5aSDimitry Andric AtomicInfo.Ordering = static_cast<unsigned>(Ordering); 623d88c1a5aSDimitry Andric assert(getOrdering() == Ordering && "Value truncated"); 624d88c1a5aSDimitry Andric AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering); 625d88c1a5aSDimitry Andric assert(getFailureOrdering() == FailureOrdering && "Value truncated"); 626f22ef01cSRoman Divacky } 627f22ef01cSRoman Divacky 628f22ef01cSRoman Divacky /// Profile - Gather unique data for the object. 629f22ef01cSRoman Divacky /// 630f22ef01cSRoman Divacky void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 6312754fe60SDimitry Andric ID.AddInteger(getOffset()); 632f22ef01cSRoman Divacky ID.AddInteger(Size); 63391bc56edSDimitry Andric ID.AddPointer(getOpaqueValue()); 6343ca95b02SDimitry Andric ID.AddInteger(getFlags()); 6353ca95b02SDimitry Andric ID.AddInteger(getBaseAlignment()); 636f22ef01cSRoman Divacky } 637f22ef01cSRoman Divacky 638f22ef01cSRoman Divacky void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 639f22ef01cSRoman Divacky // The Value and Offset may differ due to CSE. But the flags and size 640f22ef01cSRoman Divacky // should be the same. 641f22ef01cSRoman Divacky assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 642f22ef01cSRoman Divacky assert(MMO->getSize() == getSize() && "Size mismatch!"); 643f22ef01cSRoman Divacky 644f22ef01cSRoman Divacky if (MMO->getBaseAlignment() >= getBaseAlignment()) { 645f22ef01cSRoman Divacky // Update the alignment value. 6463ca95b02SDimitry Andric BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1; 647f22ef01cSRoman Divacky // Also update the base and offset, because the new alignment may 648f22ef01cSRoman Divacky // not be applicable with the old ones. 6492754fe60SDimitry Andric PtrInfo = MMO->PtrInfo; 650f22ef01cSRoman Divacky } 651f22ef01cSRoman Divacky } 652f22ef01cSRoman Divacky 653f22ef01cSRoman Divacky /// getAlignment - Return the minimum known alignment in bytes of the 654f22ef01cSRoman Divacky /// actual memory reference. 655f22ef01cSRoman Divacky uint64_t MachineMemOperand::getAlignment() const { 656f22ef01cSRoman Divacky return MinAlign(getBaseAlignment(), getOffset()); 657f22ef01cSRoman Divacky } 658f22ef01cSRoman Divacky 6593dac3a9bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS) const { 6603dac3a9bSDimitry Andric ModuleSlotTracker DummyMST(nullptr); 6613dac3a9bSDimitry Andric print(OS, DummyMST); 6623dac3a9bSDimitry Andric } 6633dac3a9bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const { 6643dac3a9bSDimitry Andric assert((isLoad() || isStore()) && 665f22ef01cSRoman Divacky "SV has to be a load, store or both."); 666f22ef01cSRoman Divacky 6673dac3a9bSDimitry Andric if (isVolatile()) 668f22ef01cSRoman Divacky OS << "Volatile "; 669f22ef01cSRoman Divacky 6703dac3a9bSDimitry Andric if (isLoad()) 671f22ef01cSRoman Divacky OS << "LD"; 6723dac3a9bSDimitry Andric if (isStore()) 673f22ef01cSRoman Divacky OS << "ST"; 6743dac3a9bSDimitry Andric OS << getSize(); 675f22ef01cSRoman Divacky 676f22ef01cSRoman Divacky // Print the address information. 677f22ef01cSRoman Divacky OS << "["; 6783dac3a9bSDimitry Andric if (const Value *V = getValue()) 6793dac3a9bSDimitry Andric V->printAsOperand(OS, /*PrintType=*/false, MST); 6803dac3a9bSDimitry Andric else if (const PseudoSourceValue *PSV = getPseudoValue()) 68191bc56edSDimitry Andric PSV->printCustom(OS); 682f22ef01cSRoman Divacky else 68391bc56edSDimitry Andric OS << "<unknown>"; 68491bc56edSDimitry Andric 6853dac3a9bSDimitry Andric unsigned AS = getAddrSpace(); 68691bc56edSDimitry Andric if (AS != 0) 68791bc56edSDimitry Andric OS << "(addrspace=" << AS << ')'; 688f22ef01cSRoman Divacky 689f22ef01cSRoman Divacky // If the alignment of the memory reference itself differs from the alignment 690f22ef01cSRoman Divacky // of the base pointer, print the base alignment explicitly, next to the base 691f22ef01cSRoman Divacky // pointer. 6923dac3a9bSDimitry Andric if (getBaseAlignment() != getAlignment()) 6933dac3a9bSDimitry Andric OS << "(align=" << getBaseAlignment() << ")"; 694f22ef01cSRoman Divacky 6953dac3a9bSDimitry Andric if (getOffset() != 0) 6963dac3a9bSDimitry Andric OS << "+" << getOffset(); 697f22ef01cSRoman Divacky OS << "]"; 698f22ef01cSRoman Divacky 699f22ef01cSRoman Divacky // Print the alignment of the reference. 7003dac3a9bSDimitry Andric if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize()) 7013dac3a9bSDimitry Andric OS << "(align=" << getAlignment() << ")"; 702f22ef01cSRoman Divacky 7032754fe60SDimitry Andric // Print TBAA info. 7043dac3a9bSDimitry Andric if (const MDNode *TBAAInfo = getAAInfo().TBAA) { 7052754fe60SDimitry Andric OS << "(tbaa="; 7062754fe60SDimitry Andric if (TBAAInfo->getNumOperands() > 0) 7073dac3a9bSDimitry Andric TBAAInfo->getOperand(0)->printAsOperand(OS, MST); 70839d628a0SDimitry Andric else 70939d628a0SDimitry Andric OS << "<unknown>"; 71039d628a0SDimitry Andric OS << ")"; 71139d628a0SDimitry Andric } 71239d628a0SDimitry Andric 71339d628a0SDimitry Andric // Print AA scope info. 7143dac3a9bSDimitry Andric if (const MDNode *ScopeInfo = getAAInfo().Scope) { 71539d628a0SDimitry Andric OS << "(alias.scope="; 71639d628a0SDimitry Andric if (ScopeInfo->getNumOperands() > 0) 71739d628a0SDimitry Andric for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { 7183dac3a9bSDimitry Andric ScopeInfo->getOperand(i)->printAsOperand(OS, MST); 71939d628a0SDimitry Andric if (i != ie-1) 72039d628a0SDimitry Andric OS << ","; 72139d628a0SDimitry Andric } 72239d628a0SDimitry Andric else 72339d628a0SDimitry Andric OS << "<unknown>"; 72439d628a0SDimitry Andric OS << ")"; 72539d628a0SDimitry Andric } 72639d628a0SDimitry Andric 72739d628a0SDimitry Andric // Print AA noalias scope info. 7283dac3a9bSDimitry Andric if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) { 72939d628a0SDimitry Andric OS << "(noalias="; 73039d628a0SDimitry Andric if (NoAliasInfo->getNumOperands() > 0) 73139d628a0SDimitry Andric for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { 7323dac3a9bSDimitry Andric NoAliasInfo->getOperand(i)->printAsOperand(OS, MST); 73339d628a0SDimitry Andric if (i != ie-1) 73439d628a0SDimitry Andric OS << ","; 73539d628a0SDimitry Andric } 7362754fe60SDimitry Andric else 7372754fe60SDimitry Andric OS << "<unknown>"; 7382754fe60SDimitry Andric OS << ")"; 7392754fe60SDimitry Andric } 7402754fe60SDimitry Andric 7413dac3a9bSDimitry Andric if (isNonTemporal()) 7423b0f4066SDimitry Andric OS << "(nontemporal)"; 743d88c1a5aSDimitry Andric if (isDereferenceable()) 744d88c1a5aSDimitry Andric OS << "(dereferenceable)"; 7453dac3a9bSDimitry Andric if (isInvariant()) 7463dac3a9bSDimitry Andric OS << "(invariant)"; 747f22ef01cSRoman Divacky } 748f22ef01cSRoman Divacky 749f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 750f22ef01cSRoman Divacky // MachineInstr Implementation 751f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 752f22ef01cSRoman Divacky 753139f7f9bSDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { 75417a519f9SDimitry Andric if (MCID->ImplicitDefs) 7557d523365SDimitry Andric for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; 7567d523365SDimitry Andric ++ImpDefs) 757139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true)); 75817a519f9SDimitry Andric if (MCID->ImplicitUses) 7597d523365SDimitry Andric for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses; 7607d523365SDimitry Andric ++ImpUses) 761139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true)); 762f22ef01cSRoman Divacky } 763f22ef01cSRoman Divacky 764f22ef01cSRoman Divacky /// MachineInstr ctor - This constructor creates a MachineInstr and adds the 765f22ef01cSRoman Divacky /// implicit operands. It reserves space for the number of operands specified by 76617a519f9SDimitry Andric /// the MCInstrDesc. 767139f7f9bSDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid, 768ff0cc061SDimitry Andric DebugLoc dl, bool NoImp) 769f9448bf3SDimitry Andric : MCID(&tid), debugLoc(std::move(dl)) { 77039d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 77139d628a0SDimitry Andric 772139f7f9bSDimitry Andric // Reserve space for the expected number of operands. 773139f7f9bSDimitry Andric if (unsigned NumOps = MCID->getNumOperands() + 774139f7f9bSDimitry Andric MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) { 775139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(NumOps); 776139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 777f22ef01cSRoman Divacky } 778f22ef01cSRoman Divacky 779139f7f9bSDimitry Andric if (!NoImp) 780139f7f9bSDimitry Andric addImplicitDefUseOperands(MF); 781f22ef01cSRoman Divacky } 782f22ef01cSRoman Divacky 783f22ef01cSRoman Divacky /// MachineInstr ctor - Copies MachineInstr arg exactly 784f22ef01cSRoman Divacky /// 785f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) 786f9448bf3SDimitry Andric : MCID(&MI.getDesc()), NumMemRefs(MI.NumMemRefs), MemRefs(MI.MemRefs), 787f9448bf3SDimitry Andric debugLoc(MI.getDebugLoc()) { 78839d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 78939d628a0SDimitry Andric 790139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(MI.getNumOperands()); 791139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 792f22ef01cSRoman Divacky 793139f7f9bSDimitry Andric // Copy operands. 794ff0cc061SDimitry Andric for (const MachineOperand &MO : MI.operands()) 795ff0cc061SDimitry Andric addOperand(MF, MO); 796f22ef01cSRoman Divacky 797139f7f9bSDimitry Andric // Copy all the sensible flags. 798139f7f9bSDimitry Andric setFlags(MI.Flags); 799f22ef01cSRoman Divacky } 800f22ef01cSRoman Divacky 801f22ef01cSRoman Divacky /// getRegInfo - If this instruction is embedded into a MachineFunction, 802f22ef01cSRoman Divacky /// return the MachineRegisterInfo object for the current function, otherwise 803f22ef01cSRoman Divacky /// return null. 804f22ef01cSRoman Divacky MachineRegisterInfo *MachineInstr::getRegInfo() { 805f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = getParent()) 806f22ef01cSRoman Divacky return &MBB->getParent()->getRegInfo(); 80791bc56edSDimitry Andric return nullptr; 808f22ef01cSRoman Divacky } 809f22ef01cSRoman Divacky 810f22ef01cSRoman Divacky /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in 811f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 812f22ef01cSRoman Divacky /// operands already be on their use lists. 8137ae0e2c9SDimitry Andric void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) { 814ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 815ff0cc061SDimitry Andric if (MO.isReg()) 816ff0cc061SDimitry Andric MRI.removeRegOperandFromUseList(&MO); 817f22ef01cSRoman Divacky } 818f22ef01cSRoman Divacky 819f22ef01cSRoman Divacky /// AddRegOperandsToUseLists - Add all of the register operands in 820f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 821f22ef01cSRoman Divacky /// operands not be on their use lists yet. 8227ae0e2c9SDimitry Andric void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) { 823ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 824ff0cc061SDimitry Andric if (MO.isReg()) 825ff0cc061SDimitry Andric MRI.addRegOperandToUseList(&MO); 826f22ef01cSRoman Divacky } 827f22ef01cSRoman Divacky 828139f7f9bSDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) { 829139f7f9bSDimitry Andric MachineBasicBlock *MBB = getParent(); 830139f7f9bSDimitry Andric assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs"); 831139f7f9bSDimitry Andric MachineFunction *MF = MBB->getParent(); 832139f7f9bSDimitry Andric assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs"); 833139f7f9bSDimitry Andric addOperand(*MF, Op); 834139f7f9bSDimitry Andric } 835139f7f9bSDimitry Andric 836139f7f9bSDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping 837139f7f9bSDimitry Andric /// ranges. If MRI is non-null also update use-def chains. 838139f7f9bSDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src, 839139f7f9bSDimitry Andric unsigned NumOps, MachineRegisterInfo *MRI) { 840139f7f9bSDimitry Andric if (MRI) 841139f7f9bSDimitry Andric return MRI->moveOperands(Dst, Src, NumOps); 842139f7f9bSDimitry Andric 843ff0cc061SDimitry Andric // MachineOperand is a trivially copyable type so we can just use memmove. 844ff0cc061SDimitry Andric std::memmove(Dst, Src, NumOps * sizeof(MachineOperand)); 845139f7f9bSDimitry Andric } 846139f7f9bSDimitry Andric 847f22ef01cSRoman Divacky /// addOperand - Add the specified operand to the instruction. If it is an 848f22ef01cSRoman Divacky /// implicit operand, it is added to the end of the operand list. If it is 849f22ef01cSRoman Divacky /// an explicit operand it is added at the end of the explicit operand list 850f22ef01cSRoman Divacky /// (before the first implicit operand). 851139f7f9bSDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { 8526122f3e6SDimitry Andric assert(MCID && "Cannot add operands before providing an instr descriptor"); 853f22ef01cSRoman Divacky 854139f7f9bSDimitry Andric // Check if we're adding one of our existing operands. 855139f7f9bSDimitry Andric if (&Op >= Operands && &Op < Operands + NumOperands) { 856139f7f9bSDimitry Andric // This is unusual: MI->addOperand(MI->getOperand(i)). 857139f7f9bSDimitry Andric // If adding Op requires reallocating or moving existing operands around, 858139f7f9bSDimitry Andric // the Op reference could go stale. Support it by copying Op. 859139f7f9bSDimitry Andric MachineOperand CopyOp(Op); 860139f7f9bSDimitry Andric return addOperand(MF, CopyOp); 861139f7f9bSDimitry Andric } 862f22ef01cSRoman Divacky 8636122f3e6SDimitry Andric // Find the insert location for the new operand. Implicit registers go at 864139f7f9bSDimitry Andric // the end, everything else goes before the implicit regs. 865139f7f9bSDimitry Andric // 8666122f3e6SDimitry Andric // FIXME: Allow mixed explicit and implicit operands on inline asm. 8676122f3e6SDimitry Andric // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as 8686122f3e6SDimitry Andric // implicit-defs, but they must not be moved around. See the FIXME in 8696122f3e6SDimitry Andric // InstrEmitter.cpp. 870139f7f9bSDimitry Andric unsigned OpNo = getNumOperands(); 871139f7f9bSDimitry Andric bool isImpReg = Op.isReg() && Op.isImplicit(); 8726122f3e6SDimitry Andric if (!isImpReg && !isInlineAsm()) { 8736122f3e6SDimitry Andric while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) { 8746122f3e6SDimitry Andric --OpNo; 8753861d79fSDimitry Andric assert(!Operands[OpNo].isTied() && "Cannot move tied operands"); 876f22ef01cSRoman Divacky } 877f22ef01cSRoman Divacky } 878f22ef01cSRoman Divacky 879f785676fSDimitry Andric #ifndef NDEBUG 880f785676fSDimitry Andric bool isMetaDataOp = Op.getType() == MachineOperand::MO_Metadata; 8816122f3e6SDimitry Andric // OpNo now points as the desired insertion point. Unless this is a variadic 8826122f3e6SDimitry Andric // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). 8837ae0e2c9SDimitry Andric // RegMask operands go between the explicit and implicit operands. 8847ae0e2c9SDimitry Andric assert((isImpReg || Op.isRegMask() || MCID->isVariadic() || 885f785676fSDimitry Andric OpNo < MCID->getNumOperands() || isMetaDataOp) && 8866122f3e6SDimitry Andric "Trying to add an operand to a machine instr that is already done!"); 887f785676fSDimitry Andric #endif 888f22ef01cSRoman Divacky 889139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 890f22ef01cSRoman Divacky 891139f7f9bSDimitry Andric // Determine if the Operands array needs to be reallocated. 892139f7f9bSDimitry Andric // Save the old capacity and operand array. 893139f7f9bSDimitry Andric OperandCapacity OldCap = CapOperands; 894139f7f9bSDimitry Andric MachineOperand *OldOperands = Operands; 895139f7f9bSDimitry Andric if (!OldOperands || OldCap.getSize() == getNumOperands()) { 896139f7f9bSDimitry Andric CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1); 897139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 898139f7f9bSDimitry Andric // Move the operands before the insertion point. 899139f7f9bSDimitry Andric if (OpNo) 900139f7f9bSDimitry Andric moveOperands(Operands, OldOperands, OpNo, MRI); 901139f7f9bSDimitry Andric } 902f22ef01cSRoman Divacky 903139f7f9bSDimitry Andric // Move the operands following the insertion point. 904139f7f9bSDimitry Andric if (OpNo != NumOperands) 905139f7f9bSDimitry Andric moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo, 906139f7f9bSDimitry Andric MRI); 907139f7f9bSDimitry Andric ++NumOperands; 9086122f3e6SDimitry Andric 909139f7f9bSDimitry Andric // Deallocate the old operand array. 910139f7f9bSDimitry Andric if (OldOperands != Operands && OldOperands) 911139f7f9bSDimitry Andric MF.deallocateOperandArray(OldCap, OldOperands); 912139f7f9bSDimitry Andric 913139f7f9bSDimitry Andric // Copy Op into place. It still needs to be inserted into the MRI use lists. 914139f7f9bSDimitry Andric MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op); 915139f7f9bSDimitry Andric NewMO->ParentMI = this; 916139f7f9bSDimitry Andric 917139f7f9bSDimitry Andric // When adding a register operand, tell MRI about it. 918139f7f9bSDimitry Andric if (NewMO->isReg()) { 9197ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false, regardless of Op's status. 92091bc56edSDimitry Andric NewMO->Contents.Reg.Prev = nullptr; 9213861d79fSDimitry Andric // Ignore existing ties. This is not a property that can be copied. 922139f7f9bSDimitry Andric NewMO->TiedTo = 0; 923139f7f9bSDimitry Andric // Add the new operand to MRI, but only for instructions in an MBB. 924139f7f9bSDimitry Andric if (MRI) 925139f7f9bSDimitry Andric MRI->addRegOperandToUseList(NewMO); 9263861d79fSDimitry Andric // The MCID operand information isn't accurate until we start adding 9273861d79fSDimitry Andric // explicit operands. The implicit operands are added first, then the 9283861d79fSDimitry Andric // explicits are inserted before them. 9293861d79fSDimitry Andric if (!isImpReg) { 9303861d79fSDimitry Andric // Tie uses to defs as indicated in MCInstrDesc. 931139f7f9bSDimitry Andric if (NewMO->isUse()) { 9323861d79fSDimitry Andric int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO); 9333861d79fSDimitry Andric if (DefIdx != -1) 9343861d79fSDimitry Andric tieOperands(DefIdx, OpNo); 9353861d79fSDimitry Andric } 9366122f3e6SDimitry Andric // If the register operand is flagged as early, mark the operand as such. 93717a519f9SDimitry Andric if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) 938139f7f9bSDimitry Andric NewMO->setIsEarlyClobber(true); 939f22ef01cSRoman Divacky } 940f22ef01cSRoman Divacky } 941f22ef01cSRoman Divacky } 942f22ef01cSRoman Divacky 943f22ef01cSRoman Divacky /// RemoveOperand - Erase an operand from an instruction, leaving it with one 944f22ef01cSRoman Divacky /// fewer operand than it started with. 945f22ef01cSRoman Divacky /// 946f22ef01cSRoman Divacky void MachineInstr::RemoveOperand(unsigned OpNo) { 947139f7f9bSDimitry Andric assert(OpNo < getNumOperands() && "Invalid operand number"); 9483861d79fSDimitry Andric untieRegOperand(OpNo); 949f22ef01cSRoman Divacky 9503861d79fSDimitry Andric #ifndef NDEBUG 9513861d79fSDimitry Andric // Moving tied operands would break the ties. 952139f7f9bSDimitry Andric for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i) 9533861d79fSDimitry Andric if (Operands[i].isReg()) 9543861d79fSDimitry Andric assert(!Operands[i].isTied() && "Cannot move tied operands"); 9553861d79fSDimitry Andric #endif 9563861d79fSDimitry Andric 957139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 958139f7f9bSDimitry Andric if (MRI && Operands[OpNo].isReg()) 959139f7f9bSDimitry Andric MRI->removeRegOperandFromUseList(Operands + OpNo); 960f22ef01cSRoman Divacky 961139f7f9bSDimitry Andric // Don't call the MachineOperand destructor. A lot of this code depends on 962139f7f9bSDimitry Andric // MachineOperand having a trivial destructor anyway, and adding a call here 963139f7f9bSDimitry Andric // wouldn't make it 'destructor-correct'. 964139f7f9bSDimitry Andric 965139f7f9bSDimitry Andric if (unsigned N = NumOperands - 1 - OpNo) 966139f7f9bSDimitry Andric moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI); 967139f7f9bSDimitry Andric --NumOperands; 968f22ef01cSRoman Divacky } 969f22ef01cSRoman Divacky 970f22ef01cSRoman Divacky /// addMemOperand - Add a MachineMemOperand to the machine instruction. 971f22ef01cSRoman Divacky /// This function should be used only occasionally. The setMemRefs function 972f22ef01cSRoman Divacky /// is the primary method for setting up a MachineInstr's MemRefs list. 973f22ef01cSRoman Divacky void MachineInstr::addMemOperand(MachineFunction &MF, 974f22ef01cSRoman Divacky MachineMemOperand *MO) { 975f22ef01cSRoman Divacky mmo_iterator OldMemRefs = MemRefs; 976139f7f9bSDimitry Andric unsigned OldNumMemRefs = NumMemRefs; 977f22ef01cSRoman Divacky 978139f7f9bSDimitry Andric unsigned NewNum = NumMemRefs + 1; 979f22ef01cSRoman Divacky mmo_iterator NewMemRefs = MF.allocateMemRefsArray(NewNum); 980f22ef01cSRoman Divacky 981dff0c46cSDimitry Andric std::copy(OldMemRefs, OldMemRefs + OldNumMemRefs, NewMemRefs); 982f22ef01cSRoman Divacky NewMemRefs[NewNum - 1] = MO; 983139f7f9bSDimitry Andric setMemRefs(NewMemRefs, NewMemRefs + NewNum); 984dff0c46cSDimitry Andric } 985dff0c46cSDimitry Andric 986444ed5c5SDimitry Andric /// Check to see if the MMOs pointed to by the two MemRefs arrays are 987444ed5c5SDimitry Andric /// identical. 988444ed5c5SDimitry Andric static bool hasIdenticalMMOs(const MachineInstr &MI1, const MachineInstr &MI2) { 989444ed5c5SDimitry Andric auto I1 = MI1.memoperands_begin(), E1 = MI1.memoperands_end(); 990444ed5c5SDimitry Andric auto I2 = MI2.memoperands_begin(), E2 = MI2.memoperands_end(); 991444ed5c5SDimitry Andric if ((E1 - I1) != (E2 - I2)) 992444ed5c5SDimitry Andric return false; 993444ed5c5SDimitry Andric for (; I1 != E1; ++I1, ++I2) { 994444ed5c5SDimitry Andric if (**I1 != **I2) 995444ed5c5SDimitry Andric return false; 996444ed5c5SDimitry Andric } 997444ed5c5SDimitry Andric return true; 998444ed5c5SDimitry Andric } 999444ed5c5SDimitry Andric 10004d0b32cdSDimitry Andric std::pair<MachineInstr::mmo_iterator, unsigned> 10014d0b32cdSDimitry Andric MachineInstr::mergeMemRefsWith(const MachineInstr& Other) { 1002444ed5c5SDimitry Andric 1003444ed5c5SDimitry Andric // If either of the incoming memrefs are empty, we must be conservative and 1004444ed5c5SDimitry Andric // treat this as if we've exhausted our space for memrefs and dropped them. 1005444ed5c5SDimitry Andric if (memoperands_empty() || Other.memoperands_empty()) 1006444ed5c5SDimitry Andric return std::make_pair(nullptr, 0); 1007444ed5c5SDimitry Andric 1008444ed5c5SDimitry Andric // If both instructions have identical memrefs, we don't need to merge them. 1009444ed5c5SDimitry Andric // Since many instructions have a single memref, and we tend to merge things 1010444ed5c5SDimitry Andric // like pairs of loads from the same location, this catches a large number of 1011444ed5c5SDimitry Andric // cases in practice. 1012444ed5c5SDimitry Andric if (hasIdenticalMMOs(*this, Other)) 1013444ed5c5SDimitry Andric return std::make_pair(MemRefs, NumMemRefs); 1014444ed5c5SDimitry Andric 10154d0b32cdSDimitry Andric // TODO: consider uniquing elements within the operand lists to reduce 10164d0b32cdSDimitry Andric // space usage and fall back to conservative information less often. 1017444ed5c5SDimitry Andric size_t CombinedNumMemRefs = NumMemRefs + Other.NumMemRefs; 1018444ed5c5SDimitry Andric 1019444ed5c5SDimitry Andric // If we don't have enough room to store this many memrefs, be conservative 1020444ed5c5SDimitry Andric // and drop them. Otherwise, we'd fail asserts when trying to add them to 1021444ed5c5SDimitry Andric // the new instruction. 1022444ed5c5SDimitry Andric if (CombinedNumMemRefs != uint8_t(CombinedNumMemRefs)) 1023444ed5c5SDimitry Andric return std::make_pair(nullptr, 0); 10244d0b32cdSDimitry Andric 10254d0b32cdSDimitry Andric MachineFunction *MF = getParent()->getParent(); 10264d0b32cdSDimitry Andric mmo_iterator MemBegin = MF->allocateMemRefsArray(CombinedNumMemRefs); 10274d0b32cdSDimitry Andric mmo_iterator MemEnd = std::copy(memoperands_begin(), memoperands_end(), 10284d0b32cdSDimitry Andric MemBegin); 10294d0b32cdSDimitry Andric MemEnd = std::copy(Other.memoperands_begin(), Other.memoperands_end(), 10304d0b32cdSDimitry Andric MemEnd); 10314d0b32cdSDimitry Andric assert(MemEnd - MemBegin == (ptrdiff_t)CombinedNumMemRefs && 10324d0b32cdSDimitry Andric "missing memrefs"); 10334d0b32cdSDimitry Andric 10344d0b32cdSDimitry Andric return std::make_pair(MemBegin, CombinedNumMemRefs); 10354d0b32cdSDimitry Andric } 10364d0b32cdSDimitry Andric 1037dff0c46cSDimitry Andric bool MachineInstr::hasPropertyInBundle(unsigned Mask, QueryType Type) const { 1038139f7f9bSDimitry Andric assert(!isBundledWithPred() && "Must be called on bundle header"); 10397d523365SDimitry Andric for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) { 1040dff0c46cSDimitry Andric if (MII->getDesc().getFlags() & Mask) { 1041dff0c46cSDimitry Andric if (Type == AnyInBundle) 1042dff0c46cSDimitry Andric return true; 1043dff0c46cSDimitry Andric } else { 1044139f7f9bSDimitry Andric if (Type == AllInBundle && !MII->isBundle()) 1045dff0c46cSDimitry Andric return false; 1046dff0c46cSDimitry Andric } 1047139f7f9bSDimitry Andric // This was the last instruction in the bundle. 1048139f7f9bSDimitry Andric if (!MII->isBundledWithSucc()) 1049dff0c46cSDimitry Andric return Type == AllInBundle; 1050f22ef01cSRoman Divacky } 1051139f7f9bSDimitry Andric } 1052f22ef01cSRoman Divacky 10533ca95b02SDimitry Andric bool MachineInstr::isIdenticalTo(const MachineInstr &Other, 1054f22ef01cSRoman Divacky MICheckType Check) const { 1055f22ef01cSRoman Divacky // If opcodes or number of operands are not the same then the two 1056f22ef01cSRoman Divacky // instructions are obviously not identical. 10573ca95b02SDimitry Andric if (Other.getOpcode() != getOpcode() || 10583ca95b02SDimitry Andric Other.getNumOperands() != getNumOperands()) 1059f22ef01cSRoman Divacky return false; 1060f22ef01cSRoman Divacky 1061dff0c46cSDimitry Andric if (isBundle()) { 1062d88c1a5aSDimitry Andric // We have passed the test above that both instructions have the same 1063d88c1a5aSDimitry Andric // opcode, so we know that both instructions are bundles here. Let's compare 1064d88c1a5aSDimitry Andric // MIs inside the bundle. 1065d88c1a5aSDimitry Andric assert(Other.isBundle() && "Expected that both instructions are bundles."); 10667d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I1 = getIterator(); 10673ca95b02SDimitry Andric MachineBasicBlock::const_instr_iterator I2 = Other.getIterator(); 1068d88c1a5aSDimitry Andric // Loop until we analysed the last intruction inside at least one of the 1069d88c1a5aSDimitry Andric // bundles. 1070d88c1a5aSDimitry Andric while (I1->isBundledWithSucc() && I2->isBundledWithSucc()) { 1071d88c1a5aSDimitry Andric ++I1; 1072dff0c46cSDimitry Andric ++I2; 1073d88c1a5aSDimitry Andric if (!I1->isIdenticalTo(*I2, Check)) 1074dff0c46cSDimitry Andric return false; 1075dff0c46cSDimitry Andric } 1076d88c1a5aSDimitry Andric // If we've reached the end of just one of the two bundles, but not both, 1077d88c1a5aSDimitry Andric // the instructions are not identical. 1078d88c1a5aSDimitry Andric if (I1->isBundledWithSucc() || I2->isBundledWithSucc()) 1079d88c1a5aSDimitry Andric return false; 1080dff0c46cSDimitry Andric } 1081dff0c46cSDimitry Andric 1082f22ef01cSRoman Divacky // Check operands to make sure they match. 1083f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1084f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 10853ca95b02SDimitry Andric const MachineOperand &OMO = Other.getOperand(i); 1086bd5abe19SDimitry Andric if (!MO.isReg()) { 1087bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1088bd5abe19SDimitry Andric return false; 1089bd5abe19SDimitry Andric continue; 1090bd5abe19SDimitry Andric } 1091bd5abe19SDimitry Andric 1092f22ef01cSRoman Divacky // Clients may or may not want to ignore defs when testing for equality. 1093f22ef01cSRoman Divacky // For example, machine CSE pass only cares about finding common 1094f22ef01cSRoman Divacky // subexpressions, so it's safe to ignore virtual register defs. 1095bd5abe19SDimitry Andric if (MO.isDef()) { 1096f22ef01cSRoman Divacky if (Check == IgnoreDefs) 1097f22ef01cSRoman Divacky continue; 1098bd5abe19SDimitry Andric else if (Check == IgnoreVRegDefs) { 1099f22ef01cSRoman Divacky if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) || 1100f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(OMO.getReg())) 1101f22ef01cSRoman Divacky if (MO.getReg() != OMO.getReg()) 1102f22ef01cSRoman Divacky return false; 1103bd5abe19SDimitry Andric } else { 1104bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1105f22ef01cSRoman Divacky return false; 1106bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isDead() != OMO.isDead()) 1107bd5abe19SDimitry Andric return false; 1108bd5abe19SDimitry Andric } 1109bd5abe19SDimitry Andric } else { 1110bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1111bd5abe19SDimitry Andric return false; 1112bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isKill() != OMO.isKill()) 1113bd5abe19SDimitry Andric return false; 1114bd5abe19SDimitry Andric } 1115f22ef01cSRoman Divacky } 111617a519f9SDimitry Andric // If DebugLoc does not match then two dbg.values are not identical. 111717a519f9SDimitry Andric if (isDebugValue()) 11183ca95b02SDimitry Andric if (getDebugLoc() && Other.getDebugLoc() && 11193ca95b02SDimitry Andric getDebugLoc() != Other.getDebugLoc()) 112017a519f9SDimitry Andric return false; 1121f22ef01cSRoman Divacky return true; 1122f22ef01cSRoman Divacky } 1123f22ef01cSRoman Divacky 1124f22ef01cSRoman Divacky MachineInstr *MachineInstr::removeFromParent() { 1125f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 1126139f7f9bSDimitry Andric return getParent()->remove(this); 1127f22ef01cSRoman Divacky } 1128f22ef01cSRoman Divacky 1129139f7f9bSDimitry Andric MachineInstr *MachineInstr::removeFromBundle() { 1130139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 1131139f7f9bSDimitry Andric return getParent()->remove_instr(this); 1132139f7f9bSDimitry Andric } 1133f22ef01cSRoman Divacky 1134f22ef01cSRoman Divacky void MachineInstr::eraseFromParent() { 1135f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 1136139f7f9bSDimitry Andric getParent()->erase(this); 1137f22ef01cSRoman Divacky } 1138f22ef01cSRoman Divacky 113939d628a0SDimitry Andric void MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval() { 114039d628a0SDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 114139d628a0SDimitry Andric MachineBasicBlock *MBB = getParent(); 114239d628a0SDimitry Andric MachineFunction *MF = MBB->getParent(); 114339d628a0SDimitry Andric assert(MF && "Not embedded in a function!"); 114439d628a0SDimitry Andric 114539d628a0SDimitry Andric MachineInstr *MI = (MachineInstr *)this; 114639d628a0SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 114739d628a0SDimitry Andric 1148ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 114939d628a0SDimitry Andric if (!MO.isReg() || !MO.isDef()) 115039d628a0SDimitry Andric continue; 115139d628a0SDimitry Andric unsigned Reg = MO.getReg(); 115239d628a0SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg)) 115339d628a0SDimitry Andric continue; 115439d628a0SDimitry Andric MRI.markUsesInDebugValueAsUndef(Reg); 115539d628a0SDimitry Andric } 115639d628a0SDimitry Andric MI->eraseFromParent(); 115739d628a0SDimitry Andric } 115839d628a0SDimitry Andric 1159139f7f9bSDimitry Andric void MachineInstr::eraseFromBundle() { 1160139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 1161139f7f9bSDimitry Andric getParent()->erase_instr(this); 1162139f7f9bSDimitry Andric } 1163f22ef01cSRoman Divacky 1164f22ef01cSRoman Divacky /// getNumExplicitOperands - Returns the number of non-implicit operands. 1165f22ef01cSRoman Divacky /// 1166f22ef01cSRoman Divacky unsigned MachineInstr::getNumExplicitOperands() const { 116717a519f9SDimitry Andric unsigned NumOperands = MCID->getNumOperands(); 116817a519f9SDimitry Andric if (!MCID->isVariadic()) 1169f22ef01cSRoman Divacky return NumOperands; 1170f22ef01cSRoman Divacky 1171f22ef01cSRoman Divacky for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) { 1172f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1173f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isImplicit()) 1174f22ef01cSRoman Divacky NumOperands++; 1175f22ef01cSRoman Divacky } 1176f22ef01cSRoman Divacky return NumOperands; 1177f22ef01cSRoman Divacky } 1178f22ef01cSRoman Divacky 1179139f7f9bSDimitry Andric void MachineInstr::bundleWithPred() { 1180139f7f9bSDimitry Andric assert(!isBundledWithPred() && "MI is already bundled with its predecessor"); 1181139f7f9bSDimitry Andric setFlag(BundledPred); 11827d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 1183139f7f9bSDimitry Andric --Pred; 1184139f7f9bSDimitry Andric assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 1185139f7f9bSDimitry Andric Pred->setFlag(BundledSucc); 1186139f7f9bSDimitry Andric } 1187139f7f9bSDimitry Andric 1188139f7f9bSDimitry Andric void MachineInstr::bundleWithSucc() { 1189139f7f9bSDimitry Andric assert(!isBundledWithSucc() && "MI is already bundled with its successor"); 1190139f7f9bSDimitry Andric setFlag(BundledSucc); 11917d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 1192139f7f9bSDimitry Andric ++Succ; 1193139f7f9bSDimitry Andric assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags"); 1194139f7f9bSDimitry Andric Succ->setFlag(BundledPred); 1195139f7f9bSDimitry Andric } 1196139f7f9bSDimitry Andric 1197139f7f9bSDimitry Andric void MachineInstr::unbundleFromPred() { 1198139f7f9bSDimitry Andric assert(isBundledWithPred() && "MI isn't bundled with its predecessor"); 1199139f7f9bSDimitry Andric clearFlag(BundledPred); 12007d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 1201139f7f9bSDimitry Andric --Pred; 1202139f7f9bSDimitry Andric assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 1203139f7f9bSDimitry Andric Pred->clearFlag(BundledSucc); 1204139f7f9bSDimitry Andric } 1205139f7f9bSDimitry Andric 1206139f7f9bSDimitry Andric void MachineInstr::unbundleFromSucc() { 1207139f7f9bSDimitry Andric assert(isBundledWithSucc() && "MI isn't bundled with its successor"); 1208139f7f9bSDimitry Andric clearFlag(BundledSucc); 12097d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 1210139f7f9bSDimitry Andric ++Succ; 1211139f7f9bSDimitry Andric assert(Succ->isBundledWithPred() && "Inconsistent bundle flags"); 1212139f7f9bSDimitry Andric Succ->clearFlag(BundledPred); 1213dff0c46cSDimitry Andric } 1214dff0c46cSDimitry Andric 12152754fe60SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const { 12162754fe60SDimitry Andric if (isInlineAsm()) { 12172754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 12182754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 12192754fe60SDimitry Andric return true; 12202754fe60SDimitry Andric } 12212754fe60SDimitry Andric return false; 12222754fe60SDimitry Andric } 1223f22ef01cSRoman Divacky 12243861d79fSDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const { 12253861d79fSDimitry Andric assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!"); 12263861d79fSDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 12273861d79fSDimitry Andric return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0); 12283861d79fSDimitry Andric } 12293861d79fSDimitry Andric 12306122f3e6SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx, 12316122f3e6SDimitry Andric unsigned *GroupNo) const { 12326122f3e6SDimitry Andric assert(isInlineAsm() && "Expected an inline asm instruction"); 12336122f3e6SDimitry Andric assert(OpIdx < getNumOperands() && "OpIdx out of range"); 12346122f3e6SDimitry Andric 12356122f3e6SDimitry Andric // Ignore queries about the initial operands. 12366122f3e6SDimitry Andric if (OpIdx < InlineAsm::MIOp_FirstOperand) 12376122f3e6SDimitry Andric return -1; 12386122f3e6SDimitry Andric 12396122f3e6SDimitry Andric unsigned Group = 0; 12406122f3e6SDimitry Andric unsigned NumOps; 12416122f3e6SDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 12426122f3e6SDimitry Andric i += NumOps) { 12436122f3e6SDimitry Andric const MachineOperand &FlagMO = getOperand(i); 12446122f3e6SDimitry Andric // If we reach the implicit register operands, stop looking. 12456122f3e6SDimitry Andric if (!FlagMO.isImm()) 12466122f3e6SDimitry Andric return -1; 12476122f3e6SDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 12486122f3e6SDimitry Andric if (i + NumOps > OpIdx) { 12496122f3e6SDimitry Andric if (GroupNo) 12506122f3e6SDimitry Andric *GroupNo = Group; 12516122f3e6SDimitry Andric return i; 12526122f3e6SDimitry Andric } 12536122f3e6SDimitry Andric ++Group; 12546122f3e6SDimitry Andric } 12556122f3e6SDimitry Andric return -1; 12566122f3e6SDimitry Andric } 12576122f3e6SDimitry Andric 12583ca95b02SDimitry Andric const DILocalVariable *MachineInstr::getDebugVariable() const { 12593ca95b02SDimitry Andric assert(isDebugValue() && "not a DBG_VALUE"); 12603ca95b02SDimitry Andric return cast<DILocalVariable>(getOperand(2).getMetadata()); 12613ca95b02SDimitry Andric } 12623ca95b02SDimitry Andric 12633ca95b02SDimitry Andric const DIExpression *MachineInstr::getDebugExpression() const { 12643ca95b02SDimitry Andric assert(isDebugValue() && "not a DBG_VALUE"); 12653ca95b02SDimitry Andric return cast<DIExpression>(getOperand(3).getMetadata()); 12663ca95b02SDimitry Andric } 12673ca95b02SDimitry Andric 12686122f3e6SDimitry Andric const TargetRegisterClass* 12696122f3e6SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx, 12706122f3e6SDimitry Andric const TargetInstrInfo *TII, 12716122f3e6SDimitry Andric const TargetRegisterInfo *TRI) const { 12727ae0e2c9SDimitry Andric assert(getParent() && "Can't have an MBB reference here!"); 12737ae0e2c9SDimitry Andric assert(getParent()->getParent() && "Can't have an MF reference here!"); 12747ae0e2c9SDimitry Andric const MachineFunction &MF = *getParent()->getParent(); 12757ae0e2c9SDimitry Andric 12766122f3e6SDimitry Andric // Most opcodes have fixed constraints in their MCInstrDesc. 12776122f3e6SDimitry Andric if (!isInlineAsm()) 12787ae0e2c9SDimitry Andric return TII->getRegClass(getDesc(), OpIdx, TRI, MF); 12796122f3e6SDimitry Andric 12806122f3e6SDimitry Andric if (!getOperand(OpIdx).isReg()) 128191bc56edSDimitry Andric return nullptr; 12826122f3e6SDimitry Andric 12836122f3e6SDimitry Andric // For tied uses on inline asm, get the constraint from the def. 12846122f3e6SDimitry Andric unsigned DefIdx; 12856122f3e6SDimitry Andric if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx)) 12866122f3e6SDimitry Andric OpIdx = DefIdx; 12876122f3e6SDimitry Andric 12886122f3e6SDimitry Andric // Inline asm stores register class constraints in the flag word. 12896122f3e6SDimitry Andric int FlagIdx = findInlineAsmFlagIdx(OpIdx); 12906122f3e6SDimitry Andric if (FlagIdx < 0) 129191bc56edSDimitry Andric return nullptr; 12926122f3e6SDimitry Andric 12936122f3e6SDimitry Andric unsigned Flag = getOperand(FlagIdx).getImm(); 12946122f3e6SDimitry Andric unsigned RCID; 12953ca95b02SDimitry Andric if ((InlineAsm::getKind(Flag) == InlineAsm::Kind_RegUse || 12963ca95b02SDimitry Andric InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDef || 12973ca95b02SDimitry Andric InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDefEarlyClobber) && 12983ca95b02SDimitry Andric InlineAsm::hasRegClassConstraint(Flag, RCID)) 12996122f3e6SDimitry Andric return TRI->getRegClass(RCID); 13006122f3e6SDimitry Andric 13016122f3e6SDimitry Andric // Assume that all registers in a memory operand are pointers. 13026122f3e6SDimitry Andric if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem) 13037ae0e2c9SDimitry Andric return TRI->getPointerRegClass(MF); 13046122f3e6SDimitry Andric 130591bc56edSDimitry Andric return nullptr; 130691bc56edSDimitry Andric } 130791bc56edSDimitry Andric 130891bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( 130991bc56edSDimitry Andric unsigned Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, 131091bc56edSDimitry Andric const TargetRegisterInfo *TRI, bool ExploreBundle) const { 131191bc56edSDimitry Andric // Check every operands inside the bundle if we have 131291bc56edSDimitry Andric // been asked to. 131391bc56edSDimitry Andric if (ExploreBundle) 13143ca95b02SDimitry Andric for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC; 131591bc56edSDimitry Andric ++OpndIt) 131691bc56edSDimitry Andric CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl( 131791bc56edSDimitry Andric OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); 131891bc56edSDimitry Andric else 131991bc56edSDimitry Andric // Otherwise, just check the current operands. 132097bc6c73SDimitry Andric for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) 132197bc6c73SDimitry Andric CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); 132291bc56edSDimitry Andric return CurRC; 132391bc56edSDimitry Andric } 132491bc56edSDimitry Andric 132591bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl( 132691bc56edSDimitry Andric unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC, 132791bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 132891bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 132991bc56edSDimitry Andric // Check if Reg is constrained by some of its use/def from MI. 133091bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 133191bc56edSDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 133291bc56edSDimitry Andric return CurRC; 133391bc56edSDimitry Andric // If yes, accumulate the constraints through the operand. 133491bc56edSDimitry Andric return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI); 133591bc56edSDimitry Andric } 133691bc56edSDimitry Andric 133791bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( 133891bc56edSDimitry Andric unsigned OpIdx, const TargetRegisterClass *CurRC, 133991bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 134091bc56edSDimitry Andric const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI); 134191bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 134291bc56edSDimitry Andric assert(MO.isReg() && 134391bc56edSDimitry Andric "Cannot get register constraints for non-register operand"); 134491bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 134591bc56edSDimitry Andric if (unsigned SubIdx = MO.getSubReg()) { 134691bc56edSDimitry Andric if (OpRC) 134791bc56edSDimitry Andric CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx); 134891bc56edSDimitry Andric else 134991bc56edSDimitry Andric CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx); 135091bc56edSDimitry Andric } else if (OpRC) 135191bc56edSDimitry Andric CurRC = TRI->getCommonSubClass(CurRC, OpRC); 135291bc56edSDimitry Andric return CurRC; 13536122f3e6SDimitry Andric } 13546122f3e6SDimitry Andric 1355139f7f9bSDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the 1356139f7f9bSDimitry Andric /// header instruction. 1357dff0c46cSDimitry Andric unsigned MachineInstr::getBundleSize() const { 13587d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I = getIterator(); 1359dff0c46cSDimitry Andric unsigned Size = 0; 13603ca95b02SDimitry Andric while (I->isBundledWithSucc()) { 13613ca95b02SDimitry Andric ++Size; 13623ca95b02SDimitry Andric ++I; 13633ca95b02SDimitry Andric } 1364dff0c46cSDimitry Andric return Size; 1365dff0c46cSDimitry Andric } 1366dff0c46cSDimitry Andric 13673ca95b02SDimitry Andric /// Returns true if the MachineInstr has an implicit-use operand of exactly 13683ca95b02SDimitry Andric /// the given register (not considering sub/super-registers). 13693ca95b02SDimitry Andric bool MachineInstr::hasRegisterImplicitUseOperand(unsigned Reg) const { 13703ca95b02SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 13713ca95b02SDimitry Andric const MachineOperand &MO = getOperand(i); 13723ca95b02SDimitry Andric if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == Reg) 13733ca95b02SDimitry Andric return true; 13743ca95b02SDimitry Andric } 13753ca95b02SDimitry Andric return false; 13763ca95b02SDimitry Andric } 13773ca95b02SDimitry Andric 1378f22ef01cSRoman Divacky /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of 1379f22ef01cSRoman Divacky /// the specific register or -1 if it is not found. It further tightens 1380f22ef01cSRoman Divacky /// the search criteria to a use that kills the register if isKill is true. 1381d88c1a5aSDimitry Andric int MachineInstr::findRegisterUseOperandIdx( 1382d88c1a5aSDimitry Andric unsigned Reg, bool isKill, const TargetRegisterInfo *TRI) const { 1383f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1384f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1385f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse()) 1386f22ef01cSRoman Divacky continue; 1387f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1388f22ef01cSRoman Divacky if (!MOReg) 1389f22ef01cSRoman Divacky continue; 1390d88c1a5aSDimitry Andric if (MOReg == Reg || (TRI && TargetRegisterInfo::isPhysicalRegister(MOReg) && 1391f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg) && 1392f22ef01cSRoman Divacky TRI->isSubRegister(MOReg, Reg))) 1393f22ef01cSRoman Divacky if (!isKill || MO.isKill()) 1394f22ef01cSRoman Divacky return i; 1395f22ef01cSRoman Divacky } 1396f22ef01cSRoman Divacky return -1; 1397f22ef01cSRoman Divacky } 1398f22ef01cSRoman Divacky 1399f22ef01cSRoman Divacky /// readsWritesVirtualRegister - Return a pair of bools (reads, writes) 1400f22ef01cSRoman Divacky /// indicating if this instruction reads or writes Reg. This also considers 1401f22ef01cSRoman Divacky /// partial defines. 1402f22ef01cSRoman Divacky std::pair<bool,bool> 1403f22ef01cSRoman Divacky MachineInstr::readsWritesVirtualRegister(unsigned Reg, 1404f22ef01cSRoman Divacky SmallVectorImpl<unsigned> *Ops) const { 1405f22ef01cSRoman Divacky bool PartDef = false; // Partial redefine. 1406f22ef01cSRoman Divacky bool FullDef = false; // Full define. 1407f22ef01cSRoman Divacky bool Use = false; 1408f22ef01cSRoman Divacky 1409f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1410f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1411f22ef01cSRoman Divacky if (!MO.isReg() || MO.getReg() != Reg) 1412f22ef01cSRoman Divacky continue; 1413f22ef01cSRoman Divacky if (Ops) 1414f22ef01cSRoman Divacky Ops->push_back(i); 1415f22ef01cSRoman Divacky if (MO.isUse()) 1416f22ef01cSRoman Divacky Use |= !MO.isUndef(); 14176122f3e6SDimitry Andric else if (MO.getSubReg() && !MO.isUndef()) 14186122f3e6SDimitry Andric // A partial <def,undef> doesn't count as reading the register. 1419f22ef01cSRoman Divacky PartDef = true; 1420f22ef01cSRoman Divacky else 1421f22ef01cSRoman Divacky FullDef = true; 1422f22ef01cSRoman Divacky } 1423f22ef01cSRoman Divacky // A partial redefine uses Reg unless there is also a full define. 1424f22ef01cSRoman Divacky return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef); 1425f22ef01cSRoman Divacky } 1426f22ef01cSRoman Divacky 1427f22ef01cSRoman Divacky /// findRegisterDefOperandIdx() - Returns the operand index that is a def of 1428f22ef01cSRoman Divacky /// the specified register or -1 if it is not found. If isDead is true, defs 1429f22ef01cSRoman Divacky /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it 1430f22ef01cSRoman Divacky /// also checks if there is a def of a super-register. 1431f22ef01cSRoman Divacky int 1432f22ef01cSRoman Divacky MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap, 1433f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 1434f22ef01cSRoman Divacky bool isPhys = TargetRegisterInfo::isPhysicalRegister(Reg); 1435f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1436f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1437dff0c46cSDimitry Andric // Accept regmask operands when Overlap is set. 1438dff0c46cSDimitry Andric // Ignore them when looking for a specific def operand (Overlap == false). 1439dff0c46cSDimitry Andric if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg)) 1440dff0c46cSDimitry Andric return i; 1441f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 1442f22ef01cSRoman Divacky continue; 1443f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1444f22ef01cSRoman Divacky bool Found = (MOReg == Reg); 1445f22ef01cSRoman Divacky if (!Found && TRI && isPhys && 1446f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg)) { 1447f22ef01cSRoman Divacky if (Overlap) 1448f22ef01cSRoman Divacky Found = TRI->regsOverlap(MOReg, Reg); 1449f22ef01cSRoman Divacky else 1450f22ef01cSRoman Divacky Found = TRI->isSubRegister(MOReg, Reg); 1451f22ef01cSRoman Divacky } 1452f22ef01cSRoman Divacky if (Found && (!isDead || MO.isDead())) 1453f22ef01cSRoman Divacky return i; 1454f22ef01cSRoman Divacky } 1455f22ef01cSRoman Divacky return -1; 1456f22ef01cSRoman Divacky } 1457f22ef01cSRoman Divacky 1458f22ef01cSRoman Divacky /// findFirstPredOperandIdx() - Find the index of the first operand in the 1459f22ef01cSRoman Divacky /// operand list that is used to represent the predicate. It returns -1 if 1460f22ef01cSRoman Divacky /// none is found. 1461f22ef01cSRoman Divacky int MachineInstr::findFirstPredOperandIdx() const { 14626122f3e6SDimitry Andric // Don't call MCID.findFirstPredOperandIdx() because this variant 14636122f3e6SDimitry Andric // is sometimes called on an instruction that's not yet complete, and 14646122f3e6SDimitry Andric // so the number of operands is less than the MCID indicates. In 14656122f3e6SDimitry Andric // particular, the PTX target does this. 146617a519f9SDimitry Andric const MCInstrDesc &MCID = getDesc(); 146717a519f9SDimitry Andric if (MCID.isPredicable()) { 1468f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 146917a519f9SDimitry Andric if (MCID.OpInfo[i].isPredicate()) 1470f22ef01cSRoman Divacky return i; 1471f22ef01cSRoman Divacky } 1472f22ef01cSRoman Divacky 1473f22ef01cSRoman Divacky return -1; 1474f22ef01cSRoman Divacky } 1475f22ef01cSRoman Divacky 14763861d79fSDimitry Andric // MachineOperand::TiedTo is 4 bits wide. 14773861d79fSDimitry Andric const unsigned TiedMax = 15; 14786122f3e6SDimitry Andric 14793861d79fSDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other. 14803861d79fSDimitry Andric /// 14813861d79fSDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo 14823861d79fSDimitry Andric /// field. TiedTo can have these values: 14833861d79fSDimitry Andric /// 14843861d79fSDimitry Andric /// 0: Operand is not tied to anything. 14853861d79fSDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1). 14863861d79fSDimitry Andric /// TiedMax: Tied to an operand >= TiedMax-1. 14873861d79fSDimitry Andric /// 14883861d79fSDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal 14893861d79fSDimitry Andric /// instruction. INLINEASM instructions allow more tied defs. 14903861d79fSDimitry Andric /// 14913861d79fSDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) { 14923861d79fSDimitry Andric MachineOperand &DefMO = getOperand(DefIdx); 14933861d79fSDimitry Andric MachineOperand &UseMO = getOperand(UseIdx); 14943861d79fSDimitry Andric assert(DefMO.isDef() && "DefIdx must be a def operand"); 14953861d79fSDimitry Andric assert(UseMO.isUse() && "UseIdx must be a use operand"); 14963861d79fSDimitry Andric assert(!DefMO.isTied() && "Def is already tied to another use"); 14973861d79fSDimitry Andric assert(!UseMO.isTied() && "Use is already tied to another def"); 14986122f3e6SDimitry Andric 14993861d79fSDimitry Andric if (DefIdx < TiedMax) 15003861d79fSDimitry Andric UseMO.TiedTo = DefIdx + 1; 15013861d79fSDimitry Andric else { 15023861d79fSDimitry Andric // Inline asm can use the group descriptors to find tied operands, but on 15033861d79fSDimitry Andric // normal instruction, the tied def must be within the first TiedMax 15043861d79fSDimitry Andric // operands. 15053861d79fSDimitry Andric assert(isInlineAsm() && "DefIdx out of range"); 15063861d79fSDimitry Andric UseMO.TiedTo = TiedMax; 15073861d79fSDimitry Andric } 15083861d79fSDimitry Andric 15093861d79fSDimitry Andric // UseIdx can be out of range, we'll search for it in findTiedOperandIdx(). 15103861d79fSDimitry Andric DefMO.TiedTo = std::min(UseIdx + 1, TiedMax); 15113861d79fSDimitry Andric } 15123861d79fSDimitry Andric 15133861d79fSDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to. 15143861d79fSDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand 15153861d79fSDimitry Andric /// which must exist. 15163861d79fSDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const { 15173861d79fSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 15183861d79fSDimitry Andric assert(MO.isTied() && "Operand isn't tied"); 15193861d79fSDimitry Andric 15203861d79fSDimitry Andric // Normally TiedTo is in range. 15213861d79fSDimitry Andric if (MO.TiedTo < TiedMax) 15223861d79fSDimitry Andric return MO.TiedTo - 1; 15233861d79fSDimitry Andric 15243861d79fSDimitry Andric // Uses on normal instructions can be out of range. 15253861d79fSDimitry Andric if (!isInlineAsm()) { 15263861d79fSDimitry Andric // Normal tied defs must be in the 0..TiedMax-1 range. 15273861d79fSDimitry Andric if (MO.isUse()) 15283861d79fSDimitry Andric return TiedMax - 1; 15293861d79fSDimitry Andric // MO is a def. Search for the tied use. 15303861d79fSDimitry Andric for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) { 15313861d79fSDimitry Andric const MachineOperand &UseMO = getOperand(i); 15323861d79fSDimitry Andric if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1) 15333861d79fSDimitry Andric return i; 15343861d79fSDimitry Andric } 15353861d79fSDimitry Andric llvm_unreachable("Can't find tied use"); 15363861d79fSDimitry Andric } 15373861d79fSDimitry Andric 15383861d79fSDimitry Andric // Now deal with inline asm by parsing the operand group descriptor flags. 15393861d79fSDimitry Andric // Find the beginning of each operand group. 15403861d79fSDimitry Andric SmallVector<unsigned, 8> GroupIdx; 15413861d79fSDimitry Andric unsigned OpIdxGroup = ~0u; 15423861d79fSDimitry Andric unsigned NumOps; 15433861d79fSDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 15443861d79fSDimitry Andric i += NumOps) { 15453861d79fSDimitry Andric const MachineOperand &FlagMO = getOperand(i); 15463861d79fSDimitry Andric assert(FlagMO.isImm() && "Invalid tied operand on inline asm"); 15473861d79fSDimitry Andric unsigned CurGroup = GroupIdx.size(); 15483861d79fSDimitry Andric GroupIdx.push_back(i); 15493861d79fSDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 15503861d79fSDimitry Andric // OpIdx belongs to this operand group. 15513861d79fSDimitry Andric if (OpIdx > i && OpIdx < i + NumOps) 15523861d79fSDimitry Andric OpIdxGroup = CurGroup; 15533861d79fSDimitry Andric unsigned TiedGroup; 15543861d79fSDimitry Andric if (!InlineAsm::isUseOperandTiedToDef(FlagMO.getImm(), TiedGroup)) 1555f22ef01cSRoman Divacky continue; 15563861d79fSDimitry Andric // Operands in this group are tied to operands in TiedGroup which must be 15573861d79fSDimitry Andric // earlier. Find the number of operands between the two groups. 15583861d79fSDimitry Andric unsigned Delta = i - GroupIdx[TiedGroup]; 1559f22ef01cSRoman Divacky 15603861d79fSDimitry Andric // OpIdx is a use tied to TiedGroup. 15613861d79fSDimitry Andric if (OpIdxGroup == CurGroup) 15623861d79fSDimitry Andric return OpIdx - Delta; 1563f22ef01cSRoman Divacky 15643861d79fSDimitry Andric // OpIdx is a def tied to this use group. 15653861d79fSDimitry Andric if (OpIdxGroup == TiedGroup) 15663861d79fSDimitry Andric return OpIdx + Delta; 1567f22ef01cSRoman Divacky } 15683861d79fSDimitry Andric llvm_unreachable("Invalid tied operand on inline asm"); 1569f22ef01cSRoman Divacky } 1570f22ef01cSRoman Divacky 1571f22ef01cSRoman Divacky /// clearKillInfo - Clears kill flags on all operands. 1572f22ef01cSRoman Divacky /// 1573f22ef01cSRoman Divacky void MachineInstr::clearKillInfo() { 1574ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1575f22ef01cSRoman Divacky if (MO.isReg() && MO.isUse()) 1576f22ef01cSRoman Divacky MO.setIsKill(false); 1577f22ef01cSRoman Divacky } 1578f22ef01cSRoman Divacky } 1579f22ef01cSRoman Divacky 1580ffd1746dSEd Schouten void MachineInstr::substituteRegister(unsigned FromReg, 1581ffd1746dSEd Schouten unsigned ToReg, 1582ffd1746dSEd Schouten unsigned SubIdx, 1583ffd1746dSEd Schouten const TargetRegisterInfo &RegInfo) { 1584ffd1746dSEd Schouten if (TargetRegisterInfo::isPhysicalRegister(ToReg)) { 1585ffd1746dSEd Schouten if (SubIdx) 1586ffd1746dSEd Schouten ToReg = RegInfo.getSubReg(ToReg, SubIdx); 1587ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1588ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1589ffd1746dSEd Schouten continue; 1590ffd1746dSEd Schouten MO.substPhysReg(ToReg, RegInfo); 1591ffd1746dSEd Schouten } 1592ffd1746dSEd Schouten } else { 1593ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1594ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1595ffd1746dSEd Schouten continue; 1596ffd1746dSEd Schouten MO.substVirtReg(ToReg, SubIdx, RegInfo); 1597ffd1746dSEd Schouten } 1598ffd1746dSEd Schouten } 1599ffd1746dSEd Schouten } 1600ffd1746dSEd Schouten 1601f22ef01cSRoman Divacky /// isSafeToMove - Return true if it is safe to move this instruction. If 1602f22ef01cSRoman Divacky /// SawStore is set to true, it means that there is a store (or call) between 1603f22ef01cSRoman Divacky /// the instruction's location and its intended destination. 1604ff0cc061SDimitry Andric bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const { 1605f22ef01cSRoman Divacky // Ignore stuff that we obviously can't move. 16063861d79fSDimitry Andric // 16073861d79fSDimitry Andric // Treat volatile loads as stores. This is not strictly necessary for 16083861d79fSDimitry Andric // volatiles, but it is required for atomic loads. It is not allowed to move 16093861d79fSDimitry Andric // a load across an atomic load with Ordering > Monotonic. 16103861d79fSDimitry Andric if (mayStore() || isCall() || 16113861d79fSDimitry Andric (mayLoad() && hasOrderedMemoryRef())) { 1612f22ef01cSRoman Divacky SawStore = true; 1613f22ef01cSRoman Divacky return false; 1614f22ef01cSRoman Divacky } 16152754fe60SDimitry Andric 161691bc56edSDimitry Andric if (isPosition() || isDebugValue() || isTerminator() || 161791bc56edSDimitry Andric hasUnmodeledSideEffects()) 1618f22ef01cSRoman Divacky return false; 1619f22ef01cSRoman Divacky 1620f22ef01cSRoman Divacky // See if this instruction does a load. If so, we have to guarantee that the 1621f22ef01cSRoman Divacky // loaded value doesn't change between the load and the its intended 1622f22ef01cSRoman Divacky // destination. The check for isInvariantLoad gives the targe the chance to 1623f22ef01cSRoman Divacky // classify the load as always returning a constant, e.g. a constant pool 1624f22ef01cSRoman Divacky // load. 1625d88c1a5aSDimitry Andric if (mayLoad() && !isDereferenceableInvariantLoad(AA)) 1626f22ef01cSRoman Divacky // Otherwise, this is a real load. If there is a store between the load and 16273861d79fSDimitry Andric // end of block, we can't move it. 16283861d79fSDimitry Andric return !SawStore; 1629f22ef01cSRoman Divacky 1630f22ef01cSRoman Divacky return true; 1631f22ef01cSRoman Divacky } 1632f22ef01cSRoman Divacky 16337a7e6055SDimitry Andric bool MachineInstr::mayAlias(AliasAnalysis *AA, MachineInstr &Other, 16347a7e6055SDimitry Andric bool UseTBAA) { 16357a7e6055SDimitry Andric const MachineFunction *MF = getParent()->getParent(); 16367a7e6055SDimitry Andric const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 16377a7e6055SDimitry Andric 16387a7e6055SDimitry Andric // If neither instruction stores to memory, they can't alias in any 16397a7e6055SDimitry Andric // meaningful way, even if they read from the same address. 16407a7e6055SDimitry Andric if (!mayStore() && !Other.mayStore()) 16417a7e6055SDimitry Andric return false; 16427a7e6055SDimitry Andric 16437a7e6055SDimitry Andric // Let the target decide if memory accesses cannot possibly overlap. 16447a7e6055SDimitry Andric if (TII->areMemAccessesTriviallyDisjoint(*this, Other, AA)) 16457a7e6055SDimitry Andric return false; 16467a7e6055SDimitry Andric 16477a7e6055SDimitry Andric if (!AA) 16487a7e6055SDimitry Andric return true; 16497a7e6055SDimitry Andric 16507a7e6055SDimitry Andric // FIXME: Need to handle multiple memory operands to support all targets. 16517a7e6055SDimitry Andric if (!hasOneMemOperand() || !Other.hasOneMemOperand()) 16527a7e6055SDimitry Andric return true; 16537a7e6055SDimitry Andric 16547a7e6055SDimitry Andric MachineMemOperand *MMOa = *memoperands_begin(); 16557a7e6055SDimitry Andric MachineMemOperand *MMOb = *Other.memoperands_begin(); 16567a7e6055SDimitry Andric 16577a7e6055SDimitry Andric if (!MMOa->getValue() || !MMOb->getValue()) 16587a7e6055SDimitry Andric return true; 16597a7e6055SDimitry Andric 16607a7e6055SDimitry Andric // The following interface to AA is fashioned after DAGCombiner::isAlias 16617a7e6055SDimitry Andric // and operates with MachineMemOperand offset with some important 16627a7e6055SDimitry Andric // assumptions: 16637a7e6055SDimitry Andric // - LLVM fundamentally assumes flat address spaces. 16647a7e6055SDimitry Andric // - MachineOperand offset can *only* result from legalization and 16657a7e6055SDimitry Andric // cannot affect queries other than the trivial case of overlap 16667a7e6055SDimitry Andric // checking. 16677a7e6055SDimitry Andric // - These offsets never wrap and never step outside 16687a7e6055SDimitry Andric // of allocated objects. 16697a7e6055SDimitry Andric // - There should never be any negative offsets here. 16707a7e6055SDimitry Andric // 16717a7e6055SDimitry Andric // FIXME: Modify API to hide this math from "user" 16727a7e6055SDimitry Andric // FIXME: Even before we go to AA we can reason locally about some 16737a7e6055SDimitry Andric // memory objects. It can save compile time, and possibly catch some 16747a7e6055SDimitry Andric // corner cases not currently covered. 16757a7e6055SDimitry Andric 16767a7e6055SDimitry Andric assert((MMOa->getOffset() >= 0) && "Negative MachineMemOperand offset"); 16777a7e6055SDimitry Andric assert((MMOb->getOffset() >= 0) && "Negative MachineMemOperand offset"); 16787a7e6055SDimitry Andric 16797a7e6055SDimitry Andric int64_t MinOffset = std::min(MMOa->getOffset(), MMOb->getOffset()); 16807a7e6055SDimitry Andric int64_t Overlapa = MMOa->getSize() + MMOa->getOffset() - MinOffset; 16817a7e6055SDimitry Andric int64_t Overlapb = MMOb->getSize() + MMOb->getOffset() - MinOffset; 16827a7e6055SDimitry Andric 16837a7e6055SDimitry Andric AliasResult AAResult = 16847a7e6055SDimitry Andric AA->alias(MemoryLocation(MMOa->getValue(), Overlapa, 16857a7e6055SDimitry Andric UseTBAA ? MMOa->getAAInfo() : AAMDNodes()), 16867a7e6055SDimitry Andric MemoryLocation(MMOb->getValue(), Overlapb, 16877a7e6055SDimitry Andric UseTBAA ? MMOb->getAAInfo() : AAMDNodes())); 16887a7e6055SDimitry Andric 16897a7e6055SDimitry Andric return (AAResult != NoAlias); 16907a7e6055SDimitry Andric } 16917a7e6055SDimitry Andric 16923861d79fSDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered 16933861d79fSDimitry Andric /// or volatile memory reference, or if the information describing the memory 16943861d79fSDimitry Andric /// reference is not available. Return false if it is known to have no ordered 16953861d79fSDimitry Andric /// memory references. 16963861d79fSDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const { 1697f22ef01cSRoman Divacky // An instruction known never to access memory won't have a volatile access. 1698dff0c46cSDimitry Andric if (!mayStore() && 1699dff0c46cSDimitry Andric !mayLoad() && 1700dff0c46cSDimitry Andric !isCall() && 17012754fe60SDimitry Andric !hasUnmodeledSideEffects()) 1702f22ef01cSRoman Divacky return false; 1703f22ef01cSRoman Divacky 1704f22ef01cSRoman Divacky // Otherwise, if the instruction has no memory reference information, 1705f22ef01cSRoman Divacky // conservatively assume it wasn't preserved. 1706f22ef01cSRoman Divacky if (memoperands_empty()) 1707f22ef01cSRoman Divacky return true; 1708f22ef01cSRoman Divacky 17093ca95b02SDimitry Andric // Check if any of our memory operands are ordered. 1710f9448bf3SDimitry Andric return llvm::any_of(memoperands(), [](const MachineMemOperand *MMO) { 17113ca95b02SDimitry Andric return !MMO->isUnordered(); 17123ca95b02SDimitry Andric }); 1713f22ef01cSRoman Divacky } 1714f22ef01cSRoman Divacky 1715d88c1a5aSDimitry Andric /// isDereferenceableInvariantLoad - Return true if this instruction will never 1716d88c1a5aSDimitry Andric /// trap and is loading from a location whose value is invariant across a run of 1717d88c1a5aSDimitry Andric /// this function. 1718d88c1a5aSDimitry Andric bool MachineInstr::isDereferenceableInvariantLoad(AliasAnalysis *AA) const { 1719f22ef01cSRoman Divacky // If the instruction doesn't load at all, it isn't an invariant load. 1720dff0c46cSDimitry Andric if (!mayLoad()) 1721f22ef01cSRoman Divacky return false; 1722f22ef01cSRoman Divacky 1723f22ef01cSRoman Divacky // If the instruction has lost its memoperands, conservatively assume that 1724f22ef01cSRoman Divacky // it may not be an invariant load. 1725f22ef01cSRoman Divacky if (memoperands_empty()) 1726f22ef01cSRoman Divacky return false; 1727f22ef01cSRoman Divacky 1728d88c1a5aSDimitry Andric const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo(); 1729f22ef01cSRoman Divacky 17303ca95b02SDimitry Andric for (MachineMemOperand *MMO : memoperands()) { 17313ca95b02SDimitry Andric if (MMO->isVolatile()) return false; 17323ca95b02SDimitry Andric if (MMO->isStore()) return false; 1733d88c1a5aSDimitry Andric if (MMO->isInvariant() && MMO->isDereferenceable()) 1734d88c1a5aSDimitry Andric continue; 173591bc56edSDimitry Andric 1736f22ef01cSRoman Divacky // A load from a constant PseudoSourceValue is invariant. 17373ca95b02SDimitry Andric if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) 1738d88c1a5aSDimitry Andric if (PSV->isConstant(&MFI)) 1739f22ef01cSRoman Divacky continue; 174091bc56edSDimitry Andric 17413ca95b02SDimitry Andric if (const Value *V = MMO->getValue()) { 1742f22ef01cSRoman Divacky // If we have an AliasAnalysis, ask it whether the memory is constant. 17438f0fd8f6SDimitry Andric if (AA && 17448f0fd8f6SDimitry Andric AA->pointsToConstantMemory( 17453ca95b02SDimitry Andric MemoryLocation(V, MMO->getSize(), MMO->getAAInfo()))) 1746f22ef01cSRoman Divacky continue; 1747f22ef01cSRoman Divacky } 1748f22ef01cSRoman Divacky 1749f22ef01cSRoman Divacky // Otherwise assume conservatively. 1750f22ef01cSRoman Divacky return false; 1751f22ef01cSRoman Divacky } 1752f22ef01cSRoman Divacky 1753f22ef01cSRoman Divacky // Everything checks out. 1754f22ef01cSRoman Divacky return true; 1755f22ef01cSRoman Divacky } 1756f22ef01cSRoman Divacky 1757f22ef01cSRoman Divacky /// isConstantValuePHI - If the specified instruction is a PHI that always 1758f22ef01cSRoman Divacky /// merges together the same virtual register, return the register, otherwise 1759f22ef01cSRoman Divacky /// return 0. 1760f22ef01cSRoman Divacky unsigned MachineInstr::isConstantValuePHI() const { 1761f22ef01cSRoman Divacky if (!isPHI()) 1762f22ef01cSRoman Divacky return 0; 1763f22ef01cSRoman Divacky assert(getNumOperands() >= 3 && 1764f22ef01cSRoman Divacky "It's illegal to have a PHI without source operands"); 1765f22ef01cSRoman Divacky 1766f22ef01cSRoman Divacky unsigned Reg = getOperand(1).getReg(); 1767f22ef01cSRoman Divacky for (unsigned i = 3, e = getNumOperands(); i < e; i += 2) 1768f22ef01cSRoman Divacky if (getOperand(i).getReg() != Reg) 1769f22ef01cSRoman Divacky return 0; 1770f22ef01cSRoman Divacky return Reg; 1771f22ef01cSRoman Divacky } 1772f22ef01cSRoman Divacky 17732754fe60SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const { 1774dff0c46cSDimitry Andric if (hasProperty(MCID::UnmodeledSideEffects)) 17752754fe60SDimitry Andric return true; 17762754fe60SDimitry Andric if (isInlineAsm()) { 17772754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 17782754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 17792754fe60SDimitry Andric return true; 17802754fe60SDimitry Andric } 17812754fe60SDimitry Andric 17822754fe60SDimitry Andric return false; 17832754fe60SDimitry Andric } 17842754fe60SDimitry Andric 17857d523365SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const { 17867d523365SDimitry Andric return mayStore() || isCall() || hasUnmodeledSideEffects(); 17877d523365SDimitry Andric } 17887d523365SDimitry Andric 1789f22ef01cSRoman Divacky /// allDefsAreDead - Return true if all the defs of this instruction are dead. 1790f22ef01cSRoman Divacky /// 1791f22ef01cSRoman Divacky bool MachineInstr::allDefsAreDead() const { 1792ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 1793f22ef01cSRoman Divacky if (!MO.isReg() || MO.isUse()) 1794f22ef01cSRoman Divacky continue; 1795f22ef01cSRoman Divacky if (!MO.isDead()) 1796f22ef01cSRoman Divacky return false; 1797f22ef01cSRoman Divacky } 1798f22ef01cSRoman Divacky return true; 1799f22ef01cSRoman Divacky } 1800f22ef01cSRoman Divacky 18012754fe60SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified 18022754fe60SDimitry Andric /// instruction to this instruction. 1803139f7f9bSDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF, 18043ca95b02SDimitry Andric const MachineInstr &MI) { 18053ca95b02SDimitry Andric for (unsigned i = MI.getDesc().getNumOperands(), e = MI.getNumOperands(); 18062754fe60SDimitry Andric i != e; ++i) { 18073ca95b02SDimitry Andric const MachineOperand &MO = MI.getOperand(i); 180891bc56edSDimitry Andric if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask()) 1809139f7f9bSDimitry Andric addOperand(MF, MO); 18102754fe60SDimitry Andric } 18112754fe60SDimitry Andric } 18122754fe60SDimitry Andric 18133861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 18147a7e6055SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dump() const { 1815d88c1a5aSDimitry Andric dbgs() << " "; 18167a7e6055SDimitry Andric print(dbgs()); 1817f22ef01cSRoman Divacky } 18187a7e6055SDimitry Andric #endif 1819f22ef01cSRoman Divacky 18207a7e6055SDimitry Andric void MachineInstr::print(raw_ostream &OS, bool SkipOpers, bool SkipDebugLoc, 1821d88c1a5aSDimitry Andric const TargetInstrInfo *TII) const { 18223dac3a9bSDimitry Andric const Module *M = nullptr; 18233dac3a9bSDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 18243dac3a9bSDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 18253dac3a9bSDimitry Andric M = MF->getFunction()->getParent(); 18263dac3a9bSDimitry Andric 18273dac3a9bSDimitry Andric ModuleSlotTracker MST(M); 18287a7e6055SDimitry Andric print(OS, MST, SkipOpers, SkipDebugLoc, TII); 18293dac3a9bSDimitry Andric } 18303dac3a9bSDimitry Andric 18313dac3a9bSDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, 18327a7e6055SDimitry Andric bool SkipOpers, bool SkipDebugLoc, 18337a7e6055SDimitry Andric const TargetInstrInfo *TII) const { 1834ff0cc061SDimitry Andric // We can be a bit tidier if we know the MachineFunction. 183591bc56edSDimitry Andric const MachineFunction *MF = nullptr; 1836ff0cc061SDimitry Andric const TargetRegisterInfo *TRI = nullptr; 183791bc56edSDimitry Andric const MachineRegisterInfo *MRI = nullptr; 1838d88c1a5aSDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo = nullptr; 1839d88c1a5aSDimitry Andric 1840f22ef01cSRoman Divacky if (const MachineBasicBlock *MBB = getParent()) { 1841f22ef01cSRoman Divacky MF = MBB->getParent(); 1842ff0cc061SDimitry Andric if (MF) { 1843e580952dSDimitry Andric MRI = &MF->getRegInfo(); 1844ff0cc061SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo(); 1845d88c1a5aSDimitry Andric if (!TII) 1846ff0cc061SDimitry Andric TII = MF->getSubtarget().getInstrInfo(); 1847d88c1a5aSDimitry Andric IntrinsicInfo = MF->getTarget().getIntrinsicInfo(); 1848ff0cc061SDimitry Andric } 1849f22ef01cSRoman Divacky } 1850f22ef01cSRoman Divacky 1851e580952dSDimitry Andric // Save a list of virtual registers. 1852e580952dSDimitry Andric SmallVector<unsigned, 8> VirtRegs; 1853e580952dSDimitry Andric 1854f22ef01cSRoman Divacky // Print explicitly defined operands on the left of an assignment syntax. 1855f22ef01cSRoman Divacky unsigned StartOp = 0, e = getNumOperands(); 1856f22ef01cSRoman Divacky for (; StartOp < e && getOperand(StartOp).isReg() && 1857f22ef01cSRoman Divacky getOperand(StartOp).isDef() && 1858f22ef01cSRoman Divacky !getOperand(StartOp).isImplicit(); 1859f22ef01cSRoman Divacky ++StartOp) { 1860f22ef01cSRoman Divacky if (StartOp != 0) OS << ", "; 1861d88c1a5aSDimitry Andric getOperand(StartOp).print(OS, MST, TRI, IntrinsicInfo); 1862e580952dSDimitry Andric unsigned Reg = getOperand(StartOp).getReg(); 18633ca95b02SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(Reg)) { 1864e580952dSDimitry Andric VirtRegs.push_back(Reg); 1865d88c1a5aSDimitry Andric LLT Ty = MRI ? MRI->getType(Reg) : LLT{}; 1866d88c1a5aSDimitry Andric if (Ty.isValid()) 1867d88c1a5aSDimitry Andric OS << '(' << Ty << ')'; 18683ca95b02SDimitry Andric } 1869f22ef01cSRoman Divacky } 1870f22ef01cSRoman Divacky 1871f22ef01cSRoman Divacky if (StartOp != 0) 1872f22ef01cSRoman Divacky OS << " = "; 1873f22ef01cSRoman Divacky 1874f22ef01cSRoman Divacky // Print the opcode name. 1875ff0cc061SDimitry Andric if (TII) 1876ff0cc061SDimitry Andric OS << TII->getName(getOpcode()); 1877dff0c46cSDimitry Andric else 1878dff0c46cSDimitry Andric OS << "UNKNOWN"; 1879f22ef01cSRoman Divacky 1880139f7f9bSDimitry Andric if (SkipOpers) 1881139f7f9bSDimitry Andric return; 1882139f7f9bSDimitry Andric 1883f22ef01cSRoman Divacky // Print the rest of the operands. 1884f22ef01cSRoman Divacky bool FirstOp = true; 188517a519f9SDimitry Andric unsigned AsmDescOp = ~0u; 188617a519f9SDimitry Andric unsigned AsmOpCount = 0; 18872754fe60SDimitry Andric 18886122f3e6SDimitry Andric if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { 18892754fe60SDimitry Andric // Print asm string. 18902754fe60SDimitry Andric OS << " "; 18913dac3a9bSDimitry Andric getOperand(InlineAsm::MIOp_AsmString).print(OS, MST, TRI); 18922754fe60SDimitry Andric 1893139f7f9bSDimitry Andric // Print HasSideEffects, MayLoad, MayStore, IsAlignStack 18942754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 18952754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 18962754fe60SDimitry Andric OS << " [sideeffect]"; 1897139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayLoad) 1898139f7f9bSDimitry Andric OS << " [mayload]"; 1899139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayStore) 1900139f7f9bSDimitry Andric OS << " [maystore]"; 19013ca95b02SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsConvergent) 19023ca95b02SDimitry Andric OS << " [isconvergent]"; 19032754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 19042754fe60SDimitry Andric OS << " [alignstack]"; 19053861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_ATT) 19063861d79fSDimitry Andric OS << " [attdialect]"; 19073861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_Intel) 19083861d79fSDimitry Andric OS << " [inteldialect]"; 19092754fe60SDimitry Andric 191017a519f9SDimitry Andric StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand; 19112754fe60SDimitry Andric FirstOp = false; 19122754fe60SDimitry Andric } 19132754fe60SDimitry Andric 1914f22ef01cSRoman Divacky for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 1915f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1916f22ef01cSRoman Divacky 19172754fe60SDimitry Andric if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) 1918e580952dSDimitry Andric VirtRegs.push_back(MO.getReg()); 1919e580952dSDimitry Andric 1920f22ef01cSRoman Divacky if (FirstOp) FirstOp = false; else OS << ","; 1921f22ef01cSRoman Divacky OS << " "; 1922f22ef01cSRoman Divacky if (i < getDesc().NumOperands) { 192317a519f9SDimitry Andric const MCOperandInfo &MCOI = getDesc().OpInfo[i]; 192417a519f9SDimitry Andric if (MCOI.isPredicate()) 1925f22ef01cSRoman Divacky OS << "pred:"; 192617a519f9SDimitry Andric if (MCOI.isOptionalDef()) 1927f22ef01cSRoman Divacky OS << "opt:"; 1928f22ef01cSRoman Divacky } 1929f22ef01cSRoman Divacky if (isDebugValue() && MO.isMetadata()) { 1930f22ef01cSRoman Divacky // Pretty print DBG_VALUE instructions. 1931ff0cc061SDimitry Andric auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata()); 1932ff0cc061SDimitry Andric if (DIV && !DIV->getName().empty()) 1933ff0cc061SDimitry Andric OS << "!\"" << DIV->getName() << '\"'; 1934f22ef01cSRoman Divacky else 19353dac3a9bSDimitry Andric MO.print(OS, MST, TRI); 1936f1a29dd3SDimitry Andric } else if (TRI && (isInsertSubreg() || isRegSequence() || 1937f1a29dd3SDimitry Andric (isSubregToReg() && i == 3)) && MO.isImm()) { 1938ff0cc061SDimitry Andric OS << TRI->getSubRegIndexName(MO.getImm()); 193917a519f9SDimitry Andric } else if (i == AsmDescOp && MO.isImm()) { 194017a519f9SDimitry Andric // Pretty print the inline asm operand descriptor. 194117a519f9SDimitry Andric OS << '$' << AsmOpCount++; 194217a519f9SDimitry Andric unsigned Flag = MO.getImm(); 194317a519f9SDimitry Andric switch (InlineAsm::getKind(Flag)) { 19446122f3e6SDimitry Andric case InlineAsm::Kind_RegUse: OS << ":[reguse"; break; 19456122f3e6SDimitry Andric case InlineAsm::Kind_RegDef: OS << ":[regdef"; break; 19466122f3e6SDimitry Andric case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec"; break; 19476122f3e6SDimitry Andric case InlineAsm::Kind_Clobber: OS << ":[clobber"; break; 19486122f3e6SDimitry Andric case InlineAsm::Kind_Imm: OS << ":[imm"; break; 19496122f3e6SDimitry Andric case InlineAsm::Kind_Mem: OS << ":[mem"; break; 19506122f3e6SDimitry Andric default: OS << ":[??" << InlineAsm::getKind(Flag); break; 19516122f3e6SDimitry Andric } 19526122f3e6SDimitry Andric 19536122f3e6SDimitry Andric unsigned RCID = 0; 19543ca95b02SDimitry Andric if (!InlineAsm::isImmKind(Flag) && !InlineAsm::isMemKind(Flag) && 19553ca95b02SDimitry Andric InlineAsm::hasRegClassConstraint(Flag, RCID)) { 1956ff0cc061SDimitry Andric if (TRI) { 1957ff0cc061SDimitry Andric OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID)); 195839d628a0SDimitry Andric } else 19596122f3e6SDimitry Andric OS << ":RC" << RCID; 196017a519f9SDimitry Andric } 196117a519f9SDimitry Andric 19623ca95b02SDimitry Andric if (InlineAsm::isMemKind(Flag)) { 19633ca95b02SDimitry Andric unsigned MCID = InlineAsm::getMemoryConstraintID(Flag); 19643ca95b02SDimitry Andric switch (MCID) { 19653ca95b02SDimitry Andric case InlineAsm::Constraint_es: OS << ":es"; break; 19663ca95b02SDimitry Andric case InlineAsm::Constraint_i: OS << ":i"; break; 19673ca95b02SDimitry Andric case InlineAsm::Constraint_m: OS << ":m"; break; 19683ca95b02SDimitry Andric case InlineAsm::Constraint_o: OS << ":o"; break; 19693ca95b02SDimitry Andric case InlineAsm::Constraint_v: OS << ":v"; break; 19703ca95b02SDimitry Andric case InlineAsm::Constraint_Q: OS << ":Q"; break; 19713ca95b02SDimitry Andric case InlineAsm::Constraint_R: OS << ":R"; break; 19723ca95b02SDimitry Andric case InlineAsm::Constraint_S: OS << ":S"; break; 19733ca95b02SDimitry Andric case InlineAsm::Constraint_T: OS << ":T"; break; 19743ca95b02SDimitry Andric case InlineAsm::Constraint_Um: OS << ":Um"; break; 19753ca95b02SDimitry Andric case InlineAsm::Constraint_Un: OS << ":Un"; break; 19763ca95b02SDimitry Andric case InlineAsm::Constraint_Uq: OS << ":Uq"; break; 19773ca95b02SDimitry Andric case InlineAsm::Constraint_Us: OS << ":Us"; break; 19783ca95b02SDimitry Andric case InlineAsm::Constraint_Ut: OS << ":Ut"; break; 19793ca95b02SDimitry Andric case InlineAsm::Constraint_Uv: OS << ":Uv"; break; 19803ca95b02SDimitry Andric case InlineAsm::Constraint_Uy: OS << ":Uy"; break; 19813ca95b02SDimitry Andric case InlineAsm::Constraint_X: OS << ":X"; break; 19823ca95b02SDimitry Andric case InlineAsm::Constraint_Z: OS << ":Z"; break; 19833ca95b02SDimitry Andric case InlineAsm::Constraint_ZC: OS << ":ZC"; break; 19843ca95b02SDimitry Andric case InlineAsm::Constraint_Zy: OS << ":Zy"; break; 19853ca95b02SDimitry Andric default: OS << ":?"; break; 19863ca95b02SDimitry Andric } 19873ca95b02SDimitry Andric } 19883ca95b02SDimitry Andric 198917a519f9SDimitry Andric unsigned TiedTo = 0; 199017a519f9SDimitry Andric if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo)) 19916122f3e6SDimitry Andric OS << " tiedto:$" << TiedTo; 19926122f3e6SDimitry Andric 19936122f3e6SDimitry Andric OS << ']'; 199417a519f9SDimitry Andric 199517a519f9SDimitry Andric // Compute the index of the next operand descriptor. 199617a519f9SDimitry Andric AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); 1997f22ef01cSRoman Divacky } else 19983dac3a9bSDimitry Andric MO.print(OS, MST, TRI); 1999f22ef01cSRoman Divacky } 2000f22ef01cSRoman Divacky 2001f22ef01cSRoman Divacky bool HaveSemi = false; 20027d523365SDimitry Andric const unsigned PrintableFlags = FrameSetup | FrameDestroy; 2003139f7f9bSDimitry Andric if (Flags & PrintableFlags) { 20044d0b32cdSDimitry Andric if (!HaveSemi) { 20054d0b32cdSDimitry Andric OS << ";"; 20064d0b32cdSDimitry Andric HaveSemi = true; 20074d0b32cdSDimitry Andric } 20083b0f4066SDimitry Andric OS << " flags: "; 20093b0f4066SDimitry Andric 20103b0f4066SDimitry Andric if (Flags & FrameSetup) 20113b0f4066SDimitry Andric OS << "FrameSetup"; 20127d523365SDimitry Andric 20137d523365SDimitry Andric if (Flags & FrameDestroy) 20147d523365SDimitry Andric OS << "FrameDestroy"; 20153b0f4066SDimitry Andric } 20163b0f4066SDimitry Andric 2017f22ef01cSRoman Divacky if (!memoperands_empty()) { 20184d0b32cdSDimitry Andric if (!HaveSemi) { 20194d0b32cdSDimitry Andric OS << ";"; 20204d0b32cdSDimitry Andric HaveSemi = true; 20214d0b32cdSDimitry Andric } 2022f22ef01cSRoman Divacky 2023f22ef01cSRoman Divacky OS << " mem:"; 2024f22ef01cSRoman Divacky for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); 2025f22ef01cSRoman Divacky i != e; ++i) { 20263dac3a9bSDimitry Andric (*i)->print(OS, MST); 202791bc56edSDimitry Andric if (std::next(i) != e) 2028f22ef01cSRoman Divacky OS << " "; 2029f22ef01cSRoman Divacky } 2030f22ef01cSRoman Divacky } 2031f22ef01cSRoman Divacky 2032e580952dSDimitry Andric // Print the regclass of any virtual registers encountered. 2033e580952dSDimitry Andric if (MRI && !VirtRegs.empty()) { 20344d0b32cdSDimitry Andric if (!HaveSemi) { 20354d0b32cdSDimitry Andric OS << ";"; 20364d0b32cdSDimitry Andric HaveSemi = true; 20374d0b32cdSDimitry Andric } 2038e580952dSDimitry Andric for (unsigned i = 0; i != VirtRegs.size(); ++i) { 20393ca95b02SDimitry Andric const RegClassOrRegBank &RC = MRI->getRegClassOrRegBank(VirtRegs[i]); 20403ca95b02SDimitry Andric if (!RC) 20413ca95b02SDimitry Andric continue; 20423ca95b02SDimitry Andric // Generic virtual registers do not have register classes. 20433ca95b02SDimitry Andric if (RC.is<const RegisterBank *>()) 20443ca95b02SDimitry Andric OS << " " << RC.get<const RegisterBank *>()->getName(); 20453ca95b02SDimitry Andric else 20463ca95b02SDimitry Andric OS << " " 20473ca95b02SDimitry Andric << TRI->getRegClassName(RC.get<const TargetRegisterClass *>()); 20483ca95b02SDimitry Andric OS << ':' << PrintReg(VirtRegs[i]); 2049e580952dSDimitry Andric for (unsigned j = i+1; j != VirtRegs.size();) { 20503ca95b02SDimitry Andric if (MRI->getRegClassOrRegBank(VirtRegs[j]) != RC) { 2051e580952dSDimitry Andric ++j; 2052e580952dSDimitry Andric continue; 2053e580952dSDimitry Andric } 2054e580952dSDimitry Andric if (VirtRegs[i] != VirtRegs[j]) 20552754fe60SDimitry Andric OS << "," << PrintReg(VirtRegs[j]); 2056e580952dSDimitry Andric VirtRegs.erase(VirtRegs.begin()+j); 2057e580952dSDimitry Andric } 2058e580952dSDimitry Andric } 2059e580952dSDimitry Andric } 2060e580952dSDimitry Andric 20613b0f4066SDimitry Andric // Print debug location information. 2062ff0cc061SDimitry Andric if (isDebugValue() && getOperand(e - 2).isMetadata()) { 20634d0b32cdSDimitry Andric if (!HaveSemi) 20644d0b32cdSDimitry Andric OS << ";"; 2065ff0cc061SDimitry Andric auto *DV = cast<DILocalVariable>(getOperand(e - 2).getMetadata()); 2066ff0cc061SDimitry Andric OS << " line no:" << DV->getLine(); 2067ff0cc061SDimitry Andric if (auto *InlinedAt = debugLoc->getInlinedAt()) { 2068ff0cc061SDimitry Andric DebugLoc InlinedAtDL(InlinedAt); 2069ff0cc061SDimitry Andric if (InlinedAtDL && MF) { 20706122f3e6SDimitry Andric OS << " inlined @[ "; 2071ff0cc061SDimitry Andric InlinedAtDL.print(OS); 20726122f3e6SDimitry Andric OS << " ]"; 20736122f3e6SDimitry Andric } 20746122f3e6SDimitry Andric } 207539d628a0SDimitry Andric if (isIndirectDebugValue()) 207639d628a0SDimitry Andric OS << " indirect"; 20777a7e6055SDimitry Andric } else if (SkipDebugLoc) { 20787a7e6055SDimitry Andric return; 2079ff0cc061SDimitry Andric } else if (debugLoc && MF) { 20804d0b32cdSDimitry Andric if (!HaveSemi) 20814d0b32cdSDimitry Andric OS << ";"; 2082f22ef01cSRoman Divacky OS << " dbg:"; 2083ff0cc061SDimitry Andric debugLoc.print(OS); 2084f22ef01cSRoman Divacky } 2085f22ef01cSRoman Divacky 20863b0f4066SDimitry Andric OS << '\n'; 2087f22ef01cSRoman Divacky } 2088f22ef01cSRoman Divacky 2089f22ef01cSRoman Divacky bool MachineInstr::addRegisterKilled(unsigned IncomingReg, 2090f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 2091f22ef01cSRoman Divacky bool AddIfNotFound) { 2092f22ef01cSRoman Divacky bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); 20937ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 20947ae0e2c9SDimitry Andric MCRegAliasIterator(IncomingReg, RegInfo, false).isValid(); 2095f22ef01cSRoman Divacky bool Found = false; 2096f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 2097f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 2098f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 2099f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse() || MO.isUndef()) 2100f22ef01cSRoman Divacky continue; 21013ca95b02SDimitry Andric 21023ca95b02SDimitry Andric // DEBUG_VALUE nodes do not contribute to code generation and should 21033ca95b02SDimitry Andric // always be ignored. Failure to do so may result in trying to modify 21043ca95b02SDimitry Andric // KILL flags on DEBUG_VALUE nodes. 21053ca95b02SDimitry Andric if (MO.isDebug()) 21063ca95b02SDimitry Andric continue; 21073ca95b02SDimitry Andric 2108f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 2109f22ef01cSRoman Divacky if (!Reg) 2110f22ef01cSRoman Divacky continue; 2111f22ef01cSRoman Divacky 2112f22ef01cSRoman Divacky if (Reg == IncomingReg) { 2113f22ef01cSRoman Divacky if (!Found) { 2114f22ef01cSRoman Divacky if (MO.isKill()) 2115f22ef01cSRoman Divacky // The register is already marked kill. 2116f22ef01cSRoman Divacky return true; 2117f22ef01cSRoman Divacky if (isPhysReg && isRegTiedToDefOperand(i)) 2118f22ef01cSRoman Divacky // Two-address uses of physregs must not be marked kill. 2119f22ef01cSRoman Divacky return true; 2120f22ef01cSRoman Divacky MO.setIsKill(); 2121f22ef01cSRoman Divacky Found = true; 2122f22ef01cSRoman Divacky } 2123f22ef01cSRoman Divacky } else if (hasAliases && MO.isKill() && 2124f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg)) { 2125f22ef01cSRoman Divacky // A super-register kill already exists. 2126f22ef01cSRoman Divacky if (RegInfo->isSuperRegister(IncomingReg, Reg)) 2127f22ef01cSRoman Divacky return true; 2128f22ef01cSRoman Divacky if (RegInfo->isSubRegister(IncomingReg, Reg)) 2129f22ef01cSRoman Divacky DeadOps.push_back(i); 2130f22ef01cSRoman Divacky } 2131f22ef01cSRoman Divacky } 2132f22ef01cSRoman Divacky 2133f22ef01cSRoman Divacky // Trim unneeded kill operands. 2134f22ef01cSRoman Divacky while (!DeadOps.empty()) { 2135f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 2136f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 2137f22ef01cSRoman Divacky RemoveOperand(OpIdx); 2138f22ef01cSRoman Divacky else 2139f22ef01cSRoman Divacky getOperand(OpIdx).setIsKill(false); 2140f22ef01cSRoman Divacky DeadOps.pop_back(); 2141f22ef01cSRoman Divacky } 2142f22ef01cSRoman Divacky 2143f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is killed. Add a 2144f22ef01cSRoman Divacky // new implicit operand if required. 2145f22ef01cSRoman Divacky if (!Found && AddIfNotFound) { 2146f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(IncomingReg, 2147f22ef01cSRoman Divacky false /*IsDef*/, 2148f22ef01cSRoman Divacky true /*IsImp*/, 2149f22ef01cSRoman Divacky true /*IsKill*/)); 2150f22ef01cSRoman Divacky return true; 2151f22ef01cSRoman Divacky } 2152f22ef01cSRoman Divacky return Found; 2153f22ef01cSRoman Divacky } 2154f22ef01cSRoman Divacky 2155dff0c46cSDimitry Andric void MachineInstr::clearRegisterKills(unsigned Reg, 2156dff0c46cSDimitry Andric const TargetRegisterInfo *RegInfo) { 2157dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) 215891bc56edSDimitry Andric RegInfo = nullptr; 2159ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2160dff0c46cSDimitry Andric if (!MO.isReg() || !MO.isUse() || !MO.isKill()) 2161dff0c46cSDimitry Andric continue; 2162dff0c46cSDimitry Andric unsigned OpReg = MO.getReg(); 21633ca95b02SDimitry Andric if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg) 2164dff0c46cSDimitry Andric MO.setIsKill(false); 2165dff0c46cSDimitry Andric } 2166dff0c46cSDimitry Andric } 2167dff0c46cSDimitry Andric 2168f785676fSDimitry Andric bool MachineInstr::addRegisterDead(unsigned Reg, 2169f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 2170f22ef01cSRoman Divacky bool AddIfNotFound) { 2171f785676fSDimitry Andric bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(Reg); 21727ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 2173f785676fSDimitry Andric MCRegAliasIterator(Reg, RegInfo, false).isValid(); 2174f22ef01cSRoman Divacky bool Found = false; 2175f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 2176f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 2177f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 2178f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 2179f22ef01cSRoman Divacky continue; 2180f785676fSDimitry Andric unsigned MOReg = MO.getReg(); 2181f785676fSDimitry Andric if (!MOReg) 2182f22ef01cSRoman Divacky continue; 2183f22ef01cSRoman Divacky 2184f785676fSDimitry Andric if (MOReg == Reg) { 2185f22ef01cSRoman Divacky MO.setIsDead(); 2186f22ef01cSRoman Divacky Found = true; 2187f22ef01cSRoman Divacky } else if (hasAliases && MO.isDead() && 2188f785676fSDimitry Andric TargetRegisterInfo::isPhysicalRegister(MOReg)) { 2189f22ef01cSRoman Divacky // There exists a super-register that's marked dead. 2190f785676fSDimitry Andric if (RegInfo->isSuperRegister(Reg, MOReg)) 2191f22ef01cSRoman Divacky return true; 2192f785676fSDimitry Andric if (RegInfo->isSubRegister(Reg, MOReg)) 2193f22ef01cSRoman Divacky DeadOps.push_back(i); 2194f22ef01cSRoman Divacky } 2195f22ef01cSRoman Divacky } 2196f22ef01cSRoman Divacky 2197f22ef01cSRoman Divacky // Trim unneeded dead operands. 2198f22ef01cSRoman Divacky while (!DeadOps.empty()) { 2199f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 2200f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 2201f22ef01cSRoman Divacky RemoveOperand(OpIdx); 2202f22ef01cSRoman Divacky else 2203f22ef01cSRoman Divacky getOperand(OpIdx).setIsDead(false); 2204f22ef01cSRoman Divacky DeadOps.pop_back(); 2205f22ef01cSRoman Divacky } 2206f22ef01cSRoman Divacky 2207f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is dead. Add a 2208f22ef01cSRoman Divacky // new implicit operand if required. 2209f22ef01cSRoman Divacky if (Found || !AddIfNotFound) 2210f22ef01cSRoman Divacky return Found; 2211f22ef01cSRoman Divacky 2212f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 2213f22ef01cSRoman Divacky true /*IsDef*/, 2214f22ef01cSRoman Divacky true /*IsImp*/, 2215f22ef01cSRoman Divacky false /*IsKill*/, 2216f22ef01cSRoman Divacky true /*IsDead*/)); 2217f22ef01cSRoman Divacky return true; 2218f22ef01cSRoman Divacky } 2219f22ef01cSRoman Divacky 2220ff0cc061SDimitry Andric void MachineInstr::clearRegisterDeads(unsigned Reg) { 2221ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2222ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg) 2223ff0cc061SDimitry Andric continue; 2224ff0cc061SDimitry Andric MO.setIsDead(false); 2225ff0cc061SDimitry Andric } 2226ff0cc061SDimitry Andric } 2227ff0cc061SDimitry Andric 22287d523365SDimitry Andric void MachineInstr::setRegisterDefReadUndef(unsigned Reg, bool IsUndef) { 2229ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2230ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0) 2231ff0cc061SDimitry Andric continue; 22327d523365SDimitry Andric MO.setIsUndef(IsUndef); 2233ff0cc061SDimitry Andric } 2234ff0cc061SDimitry Andric } 2235ff0cc061SDimitry Andric 2236f785676fSDimitry Andric void MachineInstr::addRegisterDefined(unsigned Reg, 2237f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo) { 2238f785676fSDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 2239f785676fSDimitry Andric MachineOperand *MO = findRegisterDefOperand(Reg, false, RegInfo); 2240f22ef01cSRoman Divacky if (MO) 2241f22ef01cSRoman Divacky return; 2242f22ef01cSRoman Divacky } else { 2243ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 2244f785676fSDimitry Andric if (MO.isReg() && MO.getReg() == Reg && MO.isDef() && 2245f22ef01cSRoman Divacky MO.getSubReg() == 0) 2246f22ef01cSRoman Divacky return; 2247f22ef01cSRoman Divacky } 2248f22ef01cSRoman Divacky } 2249f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 2250f22ef01cSRoman Divacky true /*IsDef*/, 2251f22ef01cSRoman Divacky true /*IsImp*/)); 2252f22ef01cSRoman Divacky } 2253f22ef01cSRoman Divacky 2254dff0c46cSDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs, 2255ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 2256dff0c46cSDimitry Andric bool HasRegMask = false; 2257ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2258dff0c46cSDimitry Andric if (MO.isRegMask()) { 2259dff0c46cSDimitry Andric HasRegMask = true; 2260dff0c46cSDimitry Andric continue; 2261dff0c46cSDimitry Andric } 2262ffd1746dSEd Schouten if (!MO.isReg() || !MO.isDef()) continue; 2263ffd1746dSEd Schouten unsigned Reg = MO.getReg(); 2264dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; 2265ffd1746dSEd Schouten // If there are no uses, including partial uses, the def is dead. 2266f9448bf3SDimitry Andric if (llvm::none_of(UsedRegs, 2267ff0cc061SDimitry Andric [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); })) 2268ff0cc061SDimitry Andric MO.setIsDead(); 2269ffd1746dSEd Schouten } 2270dff0c46cSDimitry Andric 2271dff0c46cSDimitry Andric // This is a call with a register mask operand. 2272dff0c46cSDimitry Andric // Mask clobbers are always dead, so add defs for the non-dead defines. 2273dff0c46cSDimitry Andric if (HasRegMask) 2274dff0c46cSDimitry Andric for (ArrayRef<unsigned>::iterator I = UsedRegs.begin(), E = UsedRegs.end(); 2275dff0c46cSDimitry Andric I != E; ++I) 2276dff0c46cSDimitry Andric addRegisterDefined(*I, &TRI); 2277ffd1746dSEd Schouten } 2278ffd1746dSEd Schouten 2279f22ef01cSRoman Divacky unsigned 2280f22ef01cSRoman Divacky MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { 2281dff0c46cSDimitry Andric // Build up a buffer of hash code components. 2282dff0c46cSDimitry Andric SmallVector<size_t, 8> HashComponents; 2283dff0c46cSDimitry Andric HashComponents.reserve(MI->getNumOperands() + 1); 2284dff0c46cSDimitry Andric HashComponents.push_back(MI->getOpcode()); 2285ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 22867ae0e2c9SDimitry Andric if (MO.isReg() && MO.isDef() && 22877ae0e2c9SDimitry Andric TargetRegisterInfo::isVirtualRegister(MO.getReg())) 2288f22ef01cSRoman Divacky continue; // Skip virtual register defs. 22897ae0e2c9SDimitry Andric 22907ae0e2c9SDimitry Andric HashComponents.push_back(hash_value(MO)); 2291f22ef01cSRoman Divacky } 2292dff0c46cSDimitry Andric return hash_combine_range(HashComponents.begin(), HashComponents.end()); 2293f22ef01cSRoman Divacky } 229417a519f9SDimitry Andric 229517a519f9SDimitry Andric void MachineInstr::emitError(StringRef Msg) const { 229617a519f9SDimitry Andric // Find the source location cookie. 229717a519f9SDimitry Andric unsigned LocCookie = 0; 229891bc56edSDimitry Andric const MDNode *LocMD = nullptr; 229917a519f9SDimitry Andric for (unsigned i = getNumOperands(); i != 0; --i) { 230017a519f9SDimitry Andric if (getOperand(i-1).isMetadata() && 230117a519f9SDimitry Andric (LocMD = getOperand(i-1).getMetadata()) && 230217a519f9SDimitry Andric LocMD->getNumOperands() != 0) { 230339d628a0SDimitry Andric if (const ConstantInt *CI = 230439d628a0SDimitry Andric mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) { 230517a519f9SDimitry Andric LocCookie = CI->getZExtValue(); 230617a519f9SDimitry Andric break; 230717a519f9SDimitry Andric } 230817a519f9SDimitry Andric } 230917a519f9SDimitry Andric } 231017a519f9SDimitry Andric 231117a519f9SDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 231217a519f9SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 231317a519f9SDimitry Andric return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg); 231417a519f9SDimitry Andric report_fatal_error(Msg); 231517a519f9SDimitry Andric } 23163ca95b02SDimitry Andric 23173ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, 23183ca95b02SDimitry Andric const MCInstrDesc &MCID, bool IsIndirect, 23193ca95b02SDimitry Andric unsigned Reg, unsigned Offset, 23203ca95b02SDimitry Andric const MDNode *Variable, const MDNode *Expr) { 23213ca95b02SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 23223ca95b02SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 23233ca95b02SDimitry Andric assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 23243ca95b02SDimitry Andric "Expected inlined-at fields to agree"); 23253ca95b02SDimitry Andric if (IsIndirect) 23263ca95b02SDimitry Andric return BuildMI(MF, DL, MCID) 23273ca95b02SDimitry Andric .addReg(Reg, RegState::Debug) 23283ca95b02SDimitry Andric .addImm(Offset) 23293ca95b02SDimitry Andric .addMetadata(Variable) 23303ca95b02SDimitry Andric .addMetadata(Expr); 23313ca95b02SDimitry Andric else { 23323ca95b02SDimitry Andric assert(Offset == 0 && "A direct address cannot have an offset."); 23333ca95b02SDimitry Andric return BuildMI(MF, DL, MCID) 23343ca95b02SDimitry Andric .addReg(Reg, RegState::Debug) 23353ca95b02SDimitry Andric .addReg(0U, RegState::Debug) 23363ca95b02SDimitry Andric .addMetadata(Variable) 23373ca95b02SDimitry Andric .addMetadata(Expr); 23383ca95b02SDimitry Andric } 23393ca95b02SDimitry Andric } 23403ca95b02SDimitry Andric 23413ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, 23423ca95b02SDimitry Andric MachineBasicBlock::iterator I, 23433ca95b02SDimitry Andric const DebugLoc &DL, const MCInstrDesc &MCID, 23443ca95b02SDimitry Andric bool IsIndirect, unsigned Reg, 23453ca95b02SDimitry Andric unsigned Offset, const MDNode *Variable, 23463ca95b02SDimitry Andric const MDNode *Expr) { 23473ca95b02SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 23483ca95b02SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 23493ca95b02SDimitry Andric MachineFunction &MF = *BB.getParent(); 23503ca95b02SDimitry Andric MachineInstr *MI = 23513ca95b02SDimitry Andric BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr); 23523ca95b02SDimitry Andric BB.insert(I, MI); 23533ca95b02SDimitry Andric return MachineInstrBuilder(MF, MI); 23543ca95b02SDimitry Andric } 23556bc11b14SDimitry Andric 23566bc11b14SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB, 23576bc11b14SDimitry Andric MachineBasicBlock::iterator I, 23586bc11b14SDimitry Andric const MachineInstr &Orig, 23596bc11b14SDimitry Andric int FrameIndex) { 23606bc11b14SDimitry Andric const MDNode *Var = Orig.getDebugVariable(); 2361f37b6182SDimitry Andric const auto *Expr = cast_or_null<DIExpression>(Orig.getDebugExpression()); 23626bc11b14SDimitry Andric bool IsIndirect = Orig.isIndirectDebugValue(); 23636bc11b14SDimitry Andric uint64_t Offset = IsIndirect ? Orig.getOperand(1).getImm() : 0; 23646bc11b14SDimitry Andric DebugLoc DL = Orig.getDebugLoc(); 23656bc11b14SDimitry Andric assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) && 23666bc11b14SDimitry Andric "Expected inlined-at fields to agree"); 23676bc11b14SDimitry Andric // If the DBG_VALUE already was a memory location, add an extra 23686bc11b14SDimitry Andric // DW_OP_deref. Otherwise just turning this from a register into a 23696bc11b14SDimitry Andric // memory/indirect location is sufficient. 2370f37b6182SDimitry Andric if (IsIndirect) 2371f37b6182SDimitry Andric Expr = DIExpression::prepend(Expr, DIExpression::WithDeref); 23726bc11b14SDimitry Andric return BuildMI(BB, I, DL, Orig.getDesc()) 23736bc11b14SDimitry Andric .addFrameIndex(FrameIndex) 23746bc11b14SDimitry Andric .addImm(Offset) 23756bc11b14SDimitry Andric .addMetadata(Var) 23766bc11b14SDimitry Andric .addMetadata(Expr); 23776bc11b14SDimitry Andric } 2378