1f22ef01cSRoman Divacky //===-- 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 14f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineInstr.h" 15139f7f9bSDimitry Andric #include "llvm/ADT/FoldingSet.h" 16139f7f9bSDimitry Andric #include "llvm/ADT/Hashing.h" 17139f7f9bSDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 18f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineConstantPool.h" 19f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunction.h" 203ca95b02SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 21f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineMemOperand.h" 2217a519f9SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 23f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h" 24f22ef01cSRoman Divacky #include "llvm/CodeGen/PseudoSourceValue.h" 25139f7f9bSDimitry Andric #include "llvm/IR/Constants.h" 2691bc56edSDimitry Andric #include "llvm/IR/DebugInfo.h" 27139f7f9bSDimitry Andric #include "llvm/IR/Function.h" 28139f7f9bSDimitry Andric #include "llvm/IR/InlineAsm.h" 29d88c1a5aSDimitry Andric #include "llvm/IR/Intrinsics.h" 30139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h" 31139f7f9bSDimitry Andric #include "llvm/IR/Metadata.h" 32139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 333dac3a9bSDimitry Andric #include "llvm/IR/ModuleSlotTracker.h" 34139f7f9bSDimitry Andric #include "llvm/IR/Type.h" 35139f7f9bSDimitry Andric #include "llvm/IR/Value.h" 3617a519f9SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 37f22ef01cSRoman Divacky #include "llvm/MC/MCSymbol.h" 387d523365SDimitry Andric #include "llvm/Support/CommandLine.h" 39f22ef01cSRoman Divacky #include "llvm/Support/Debug.h" 40f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 41f22ef01cSRoman Divacky #include "llvm/Support/MathExtras.h" 42f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 43139f7f9bSDimitry Andric #include "llvm/Target/TargetInstrInfo.h" 44d88c1a5aSDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h" 45139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h" 46139f7f9bSDimitry Andric #include "llvm/Target/TargetRegisterInfo.h" 4739d628a0SDimitry Andric #include "llvm/Target/TargetSubtargetInfo.h" 48f22ef01cSRoman Divacky using namespace llvm; 49f22ef01cSRoman Divacky 507d523365SDimitry Andric static cl::opt<bool> PrintWholeRegMask( 517d523365SDimitry Andric "print-whole-regmask", 527d523365SDimitry Andric cl::desc("Print the full contents of regmask operands in IR dumps"), 537d523365SDimitry Andric cl::init(true), cl::Hidden); 547d523365SDimitry Andric 55f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 56f22ef01cSRoman Divacky // MachineOperand Implementation 57f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 58f22ef01cSRoman Divacky 59f22ef01cSRoman Divacky void MachineOperand::setReg(unsigned Reg) { 60f22ef01cSRoman Divacky if (getReg() == Reg) return; // No change. 61f22ef01cSRoman Divacky 62f22ef01cSRoman Divacky // Otherwise, we have to change the register. If this operand is embedded 63f22ef01cSRoman Divacky // into a machine function, we need to update the old and new register's 64f22ef01cSRoman Divacky // use/def lists. 65f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 66f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 67f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) { 687ae0e2c9SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 697ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(this); 702754fe60SDimitry Andric SmallContents.RegNo = Reg; 717ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(this); 72f22ef01cSRoman Divacky return; 73f22ef01cSRoman Divacky } 74f22ef01cSRoman Divacky 75f22ef01cSRoman Divacky // Otherwise, just change the register, no problem. :) 762754fe60SDimitry Andric SmallContents.RegNo = Reg; 77f22ef01cSRoman Divacky } 78f22ef01cSRoman Divacky 79ffd1746dSEd Schouten void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, 80ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 81ffd1746dSEd Schouten assert(TargetRegisterInfo::isVirtualRegister(Reg)); 82ffd1746dSEd Schouten if (SubIdx && getSubReg()) 83ffd1746dSEd Schouten SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); 84ffd1746dSEd Schouten setReg(Reg); 85ffd1746dSEd Schouten if (SubIdx) 86ffd1746dSEd Schouten setSubReg(SubIdx); 87ffd1746dSEd Schouten } 88ffd1746dSEd Schouten 89ffd1746dSEd Schouten void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { 90ffd1746dSEd Schouten assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 91ffd1746dSEd Schouten if (getSubReg()) { 92ffd1746dSEd Schouten Reg = TRI.getSubReg(Reg, getSubReg()); 93bd5abe19SDimitry Andric // Note that getSubReg() may return 0 if the sub-register doesn't exist. 94bd5abe19SDimitry Andric // That won't happen in legal code. 95ffd1746dSEd Schouten setSubReg(0); 96d88c1a5aSDimitry Andric if (isDef()) 97d88c1a5aSDimitry Andric setIsUndef(false); 98ffd1746dSEd Schouten } 99ffd1746dSEd Schouten setReg(Reg); 100ffd1746dSEd Schouten } 101ffd1746dSEd Schouten 1027ae0e2c9SDimitry Andric /// Change a def to a use, or a use to a def. 1037ae0e2c9SDimitry Andric void MachineOperand::setIsDef(bool Val) { 1047ae0e2c9SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 1057ae0e2c9SDimitry Andric assert((!Val || !isDebug()) && "Marking a debug operation as def"); 1067ae0e2c9SDimitry Andric if (IsDef == Val) 1077ae0e2c9SDimitry Andric return; 1087ae0e2c9SDimitry Andric // MRI may keep uses and defs in different list positions. 1097ae0e2c9SDimitry Andric if (MachineInstr *MI = getParent()) 1107ae0e2c9SDimitry Andric if (MachineBasicBlock *MBB = MI->getParent()) 1117ae0e2c9SDimitry Andric if (MachineFunction *MF = MBB->getParent()) { 1127ae0e2c9SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 1137ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(this); 1147ae0e2c9SDimitry Andric IsDef = Val; 1157ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(this); 1167ae0e2c9SDimitry Andric return; 1177ae0e2c9SDimitry Andric } 1187ae0e2c9SDimitry Andric IsDef = Val; 1197ae0e2c9SDimitry Andric } 1207ae0e2c9SDimitry Andric 12139d628a0SDimitry Andric // If this operand is currently a register operand, and if this is in a 12239d628a0SDimitry Andric // function, deregister the operand from the register's use/def list. 12339d628a0SDimitry Andric void MachineOperand::removeRegFromUses() { 12439d628a0SDimitry Andric if (!isReg() || !isOnRegUseList()) 12539d628a0SDimitry Andric return; 12639d628a0SDimitry Andric 12739d628a0SDimitry Andric if (MachineInstr *MI = getParent()) { 12839d628a0SDimitry Andric if (MachineBasicBlock *MBB = MI->getParent()) { 12939d628a0SDimitry Andric if (MachineFunction *MF = MBB->getParent()) 13039d628a0SDimitry Andric MF->getRegInfo().removeRegOperandFromUseList(this); 13139d628a0SDimitry Andric } 13239d628a0SDimitry Andric } 13339d628a0SDimitry Andric } 13439d628a0SDimitry Andric 135f22ef01cSRoman Divacky /// ChangeToImmediate - Replace this operand with a new immediate operand of 136f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an immediate already, 137f22ef01cSRoman Divacky /// the setImm method should be used. 138f22ef01cSRoman Divacky void MachineOperand::ChangeToImmediate(int64_t ImmVal) { 1393861d79fSDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 14039d628a0SDimitry Andric 14139d628a0SDimitry Andric removeRegFromUses(); 142f22ef01cSRoman Divacky 143f22ef01cSRoman Divacky OpKind = MO_Immediate; 144f22ef01cSRoman Divacky Contents.ImmVal = ImmVal; 145f22ef01cSRoman Divacky } 146f22ef01cSRoman Divacky 14739d628a0SDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) { 14839d628a0SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 14939d628a0SDimitry Andric 15039d628a0SDimitry Andric removeRegFromUses(); 15139d628a0SDimitry Andric 15239d628a0SDimitry Andric OpKind = MO_FPImmediate; 15339d628a0SDimitry Andric Contents.CFP = FPImm; 15439d628a0SDimitry Andric } 15539d628a0SDimitry Andric 156ff0cc061SDimitry Andric void MachineOperand::ChangeToES(const char *SymName, unsigned char TargetFlags) { 157ff0cc061SDimitry Andric assert((!isReg() || !isTied()) && 158ff0cc061SDimitry Andric "Cannot change a tied operand into an external symbol"); 159ff0cc061SDimitry Andric 160ff0cc061SDimitry Andric removeRegFromUses(); 161ff0cc061SDimitry Andric 162ff0cc061SDimitry Andric OpKind = MO_ExternalSymbol; 163ff0cc061SDimitry Andric Contents.OffsetedInfo.Val.SymbolName = SymName; 164ff0cc061SDimitry Andric setOffset(0); // Offset is always 0. 165ff0cc061SDimitry Andric setTargetFlags(TargetFlags); 166ff0cc061SDimitry Andric } 167ff0cc061SDimitry Andric 168ff0cc061SDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) { 169ff0cc061SDimitry Andric assert((!isReg() || !isTied()) && 170ff0cc061SDimitry Andric "Cannot change a tied operand into an MCSymbol"); 171ff0cc061SDimitry Andric 172ff0cc061SDimitry Andric removeRegFromUses(); 173ff0cc061SDimitry Andric 174ff0cc061SDimitry Andric OpKind = MO_MCSymbol; 175ff0cc061SDimitry Andric Contents.Sym = Sym; 176ff0cc061SDimitry Andric } 177ff0cc061SDimitry Andric 178d88c1a5aSDimitry Andric void MachineOperand::ChangeToFrameIndex(int Idx) { 179d88c1a5aSDimitry Andric assert((!isReg() || !isTied()) && 180d88c1a5aSDimitry Andric "Cannot change a tied operand into a FrameIndex"); 181d88c1a5aSDimitry Andric 182d88c1a5aSDimitry Andric removeRegFromUses(); 183d88c1a5aSDimitry Andric 184d88c1a5aSDimitry Andric OpKind = MO_FrameIndex; 185d88c1a5aSDimitry Andric setIndex(Idx); 186d88c1a5aSDimitry Andric } 187d88c1a5aSDimitry Andric 188f22ef01cSRoman Divacky /// ChangeToRegister - Replace this operand with a new register operand of 189f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an register already, 190f22ef01cSRoman Divacky /// the setReg method should be used. 191f22ef01cSRoman Divacky void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, 192f22ef01cSRoman Divacky bool isKill, bool isDead, bool isUndef, 193f22ef01cSRoman Divacky bool isDebug) { 19491bc56edSDimitry Andric MachineRegisterInfo *RegInfo = nullptr; 195f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 196f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 197f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) 1987ae0e2c9SDimitry Andric RegInfo = &MF->getRegInfo(); 1997ae0e2c9SDimitry Andric // If this operand is already a register operand, remove it from the 2007ae0e2c9SDimitry Andric // register's use/def lists. 2013861d79fSDimitry Andric bool WasReg = isReg(); 2023861d79fSDimitry Andric if (RegInfo && WasReg) 2037ae0e2c9SDimitry Andric RegInfo->removeRegOperandFromUseList(this); 204f22ef01cSRoman Divacky 2057ae0e2c9SDimitry Andric // Change this to a register and set the reg#. 2067ae0e2c9SDimitry Andric OpKind = MO_Register; 2077ae0e2c9SDimitry Andric SmallContents.RegNo = Reg; 208139f7f9bSDimitry Andric SubReg_TargetFlags = 0; 209f22ef01cSRoman Divacky IsDef = isDef; 210f22ef01cSRoman Divacky IsImp = isImp; 211f22ef01cSRoman Divacky IsKill = isKill; 212f22ef01cSRoman Divacky IsDead = isDead; 213f22ef01cSRoman Divacky IsUndef = isUndef; 214dff0c46cSDimitry Andric IsInternalRead = false; 215f22ef01cSRoman Divacky IsEarlyClobber = false; 216f22ef01cSRoman Divacky IsDebug = isDebug; 2177ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false. 21891bc56edSDimitry Andric Contents.Reg.Prev = nullptr; 2193861d79fSDimitry Andric // Preserve the tie when the operand was already a register. 2203861d79fSDimitry Andric if (!WasReg) 2213861d79fSDimitry Andric TiedTo = 0; 2227ae0e2c9SDimitry Andric 2237ae0e2c9SDimitry Andric // If this operand is embedded in a function, add the operand to the 2247ae0e2c9SDimitry Andric // register's use/def list. 2257ae0e2c9SDimitry Andric if (RegInfo) 2267ae0e2c9SDimitry Andric RegInfo->addRegOperandToUseList(this); 227f22ef01cSRoman Divacky } 228f22ef01cSRoman Divacky 229f22ef01cSRoman Divacky /// isIdenticalTo - Return true if this operand is identical to the specified 2307ae0e2c9SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload 2317ae0e2c9SDimitry Andric /// below. 232f22ef01cSRoman Divacky bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 233f22ef01cSRoman Divacky if (getType() != Other.getType() || 234f22ef01cSRoman Divacky getTargetFlags() != Other.getTargetFlags()) 235f22ef01cSRoman Divacky return false; 236f22ef01cSRoman Divacky 237f22ef01cSRoman Divacky switch (getType()) { 238f22ef01cSRoman Divacky case MachineOperand::MO_Register: 239f22ef01cSRoman Divacky return getReg() == Other.getReg() && isDef() == Other.isDef() && 240f22ef01cSRoman Divacky getSubReg() == Other.getSubReg(); 241f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 242f22ef01cSRoman Divacky return getImm() == Other.getImm(); 24317a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 24417a519f9SDimitry Andric return getCImm() == Other.getCImm(); 245f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 246f22ef01cSRoman Divacky return getFPImm() == Other.getFPImm(); 247f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 248f22ef01cSRoman Divacky return getMBB() == Other.getMBB(); 249f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 250f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 251f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 2527ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 253f22ef01cSRoman Divacky return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 254f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 255f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 256f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 257f22ef01cSRoman Divacky return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 258f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 259f22ef01cSRoman Divacky return !strcmp(getSymbolName(), Other.getSymbolName()) && 260f22ef01cSRoman Divacky getOffset() == Other.getOffset(); 261f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 2623861d79fSDimitry Andric return getBlockAddress() == Other.getBlockAddress() && 2633861d79fSDimitry Andric getOffset() == Other.getOffset(); 26491bc56edSDimitry Andric case MachineOperand::MO_RegisterMask: 2657a7e6055SDimitry Andric case MachineOperand::MO_RegisterLiveOut: { 2667a7e6055SDimitry Andric // Shallow compare of the two RegMasks 2677a7e6055SDimitry Andric const uint32_t *RegMask = getRegMask(); 2687a7e6055SDimitry Andric const uint32_t *OtherRegMask = Other.getRegMask(); 2697a7e6055SDimitry Andric if (RegMask == OtherRegMask) 2707a7e6055SDimitry Andric return true; 2717a7e6055SDimitry Andric 2727a7e6055SDimitry Andric // Calculate the size of the RegMask 2737a7e6055SDimitry Andric const MachineFunction *MF = getParent()->getParent()->getParent(); 2747a7e6055SDimitry Andric const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 2757a7e6055SDimitry Andric unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32; 2767a7e6055SDimitry Andric 2777a7e6055SDimitry Andric // Deep compare of the two RegMasks 2787a7e6055SDimitry Andric return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask); 2797a7e6055SDimitry Andric } 280f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 281f22ef01cSRoman Divacky return getMCSymbol() == Other.getMCSymbol(); 28291bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 28391bc56edSDimitry Andric return getCFIIndex() == Other.getCFIIndex(); 284f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 285f22ef01cSRoman Divacky return getMetadata() == Other.getMetadata(); 286d88c1a5aSDimitry Andric case MachineOperand::MO_IntrinsicID: 287d88c1a5aSDimitry Andric return getIntrinsicID() == Other.getIntrinsicID(); 288d88c1a5aSDimitry Andric case MachineOperand::MO_Predicate: 289d88c1a5aSDimitry Andric return getPredicate() == Other.getPredicate(); 290f22ef01cSRoman Divacky } 291dff0c46cSDimitry Andric llvm_unreachable("Invalid machine operand type"); 292f22ef01cSRoman Divacky } 293f22ef01cSRoman Divacky 2947ae0e2c9SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above. 2957ae0e2c9SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) { 2967ae0e2c9SDimitry Andric switch (MO.getType()) { 2977ae0e2c9SDimitry Andric case MachineOperand::MO_Register: 2983861d79fSDimitry Andric // Register operands don't have target flags. 2993861d79fSDimitry Andric return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef()); 3007ae0e2c9SDimitry Andric case MachineOperand::MO_Immediate: 3017ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 3027ae0e2c9SDimitry Andric case MachineOperand::MO_CImmediate: 3037ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 3047ae0e2c9SDimitry Andric case MachineOperand::MO_FPImmediate: 3057ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 3067ae0e2c9SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 3077ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 3087ae0e2c9SDimitry Andric case MachineOperand::MO_FrameIndex: 3097ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 3107ae0e2c9SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 3117ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 3127ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 3137ae0e2c9SDimitry Andric MO.getOffset()); 3147ae0e2c9SDimitry Andric case MachineOperand::MO_JumpTableIndex: 3157ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 3167ae0e2c9SDimitry Andric case MachineOperand::MO_ExternalSymbol: 3177ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 3187ae0e2c9SDimitry Andric MO.getSymbolName()); 3197ae0e2c9SDimitry Andric case MachineOperand::MO_GlobalAddress: 3207ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 3217ae0e2c9SDimitry Andric MO.getOffset()); 3227ae0e2c9SDimitry Andric case MachineOperand::MO_BlockAddress: 3237ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), 3243861d79fSDimitry Andric MO.getBlockAddress(), MO.getOffset()); 3257ae0e2c9SDimitry Andric case MachineOperand::MO_RegisterMask: 32691bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 3277ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); 3287ae0e2c9SDimitry Andric case MachineOperand::MO_Metadata: 3297ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 3307ae0e2c9SDimitry Andric case MachineOperand::MO_MCSymbol: 3317ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 33291bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 33391bc56edSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 334d88c1a5aSDimitry Andric case MachineOperand::MO_IntrinsicID: 335d88c1a5aSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); 336d88c1a5aSDimitry Andric case MachineOperand::MO_Predicate: 337d88c1a5aSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); 3387ae0e2c9SDimitry Andric } 3397ae0e2c9SDimitry Andric llvm_unreachable("Invalid machine operand type"); 3407ae0e2c9SDimitry Andric } 3417ae0e2c9SDimitry Andric 342d88c1a5aSDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, 343d88c1a5aSDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 3443dac3a9bSDimitry Andric ModuleSlotTracker DummyMST(nullptr); 345d88c1a5aSDimitry Andric print(OS, DummyMST, TRI, IntrinsicInfo); 3463dac3a9bSDimitry Andric } 3473dac3a9bSDimitry Andric 3483dac3a9bSDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 349d88c1a5aSDimitry Andric const TargetRegisterInfo *TRI, 350d88c1a5aSDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 351f22ef01cSRoman Divacky switch (getType()) { 352f22ef01cSRoman Divacky case MachineOperand::MO_Register: 3532754fe60SDimitry Andric OS << PrintReg(getReg(), TRI, getSubReg()); 354f22ef01cSRoman Divacky 355f22ef01cSRoman Divacky if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || 3563861d79fSDimitry Andric isInternalRead() || isEarlyClobber() || isTied()) { 357f22ef01cSRoman Divacky OS << '<'; 358f22ef01cSRoman Divacky bool NeedComma = false; 359f22ef01cSRoman Divacky if (isDef()) { 360f22ef01cSRoman Divacky if (NeedComma) OS << ','; 361f22ef01cSRoman Divacky if (isEarlyClobber()) 362f22ef01cSRoman Divacky OS << "earlyclobber,"; 363f22ef01cSRoman Divacky if (isImplicit()) 364f22ef01cSRoman Divacky OS << "imp-"; 365f22ef01cSRoman Divacky OS << "def"; 366f22ef01cSRoman Divacky NeedComma = true; 3677ae0e2c9SDimitry Andric // <def,read-undef> only makes sense when getSubReg() is set. 3687ae0e2c9SDimitry Andric // Don't clutter the output otherwise. 3697ae0e2c9SDimitry Andric if (isUndef() && getSubReg()) 3707ae0e2c9SDimitry Andric OS << ",read-undef"; 371f22ef01cSRoman Divacky } else if (isImplicit()) { 372f22ef01cSRoman Divacky OS << "imp-use"; 373f22ef01cSRoman Divacky NeedComma = true; 374f22ef01cSRoman Divacky } 375f22ef01cSRoman Divacky 376dff0c46cSDimitry Andric if (isKill()) { 3773861d79fSDimitry Andric if (NeedComma) OS << ','; 378dff0c46cSDimitry Andric OS << "kill"; 379dff0c46cSDimitry Andric NeedComma = true; 380dff0c46cSDimitry Andric } 381dff0c46cSDimitry Andric if (isDead()) { 3823861d79fSDimitry Andric if (NeedComma) OS << ','; 383dff0c46cSDimitry Andric OS << "dead"; 384dff0c46cSDimitry Andric NeedComma = true; 385dff0c46cSDimitry Andric } 3867ae0e2c9SDimitry Andric if (isUndef() && isUse()) { 387dff0c46cSDimitry Andric if (NeedComma) OS << ','; 388f22ef01cSRoman Divacky OS << "undef"; 389dff0c46cSDimitry Andric NeedComma = true; 390dff0c46cSDimitry Andric } 391dff0c46cSDimitry Andric if (isInternalRead()) { 392dff0c46cSDimitry Andric if (NeedComma) OS << ','; 393dff0c46cSDimitry Andric OS << "internal"; 394dff0c46cSDimitry Andric NeedComma = true; 395f22ef01cSRoman Divacky } 3963861d79fSDimitry Andric if (isTied()) { 3973861d79fSDimitry Andric if (NeedComma) OS << ','; 3983861d79fSDimitry Andric OS << "tied"; 3993861d79fSDimitry Andric if (TiedTo != 15) 4003861d79fSDimitry Andric OS << unsigned(TiedTo - 1); 401f22ef01cSRoman Divacky } 402f22ef01cSRoman Divacky OS << '>'; 403f22ef01cSRoman Divacky } 404f22ef01cSRoman Divacky break; 405f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 406f22ef01cSRoman Divacky OS << getImm(); 407f22ef01cSRoman Divacky break; 40817a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 40917a519f9SDimitry Andric getCImm()->getValue().print(OS, false); 41017a519f9SDimitry Andric break; 411f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 4123ca95b02SDimitry Andric if (getFPImm()->getType()->isFloatTy()) { 413f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToFloat(); 4143ca95b02SDimitry Andric } else if (getFPImm()->getType()->isHalfTy()) { 4153ca95b02SDimitry Andric APFloat APF = getFPImm()->getValueAPF(); 4163ca95b02SDimitry Andric bool Unused; 417d88c1a5aSDimitry Andric APF.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &Unused); 4183ca95b02SDimitry Andric OS << "half " << APF.convertToFloat(); 4197a7e6055SDimitry Andric } else if (getFPImm()->getType()->isFP128Ty()) { 4207a7e6055SDimitry Andric APFloat APF = getFPImm()->getValueAPF(); 4217a7e6055SDimitry Andric SmallString<16> Str; 4227a7e6055SDimitry Andric getFPImm()->getValueAPF().toString(Str); 4237a7e6055SDimitry Andric OS << "quad " << Str; 4243ca95b02SDimitry Andric } else { 425f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToDouble(); 4263ca95b02SDimitry Andric } 427f22ef01cSRoman Divacky break; 428f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 429f22ef01cSRoman Divacky OS << "<BB#" << getMBB()->getNumber() << ">"; 430f22ef01cSRoman Divacky break; 431f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 432f22ef01cSRoman Divacky OS << "<fi#" << getIndex() << '>'; 433f22ef01cSRoman Divacky break; 434f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 435f22ef01cSRoman Divacky OS << "<cp#" << getIndex(); 436f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 437f22ef01cSRoman Divacky OS << '>'; 438f22ef01cSRoman Divacky break; 4397ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 4407ae0e2c9SDimitry Andric OS << "<ti#" << getIndex(); 4417ae0e2c9SDimitry Andric if (getOffset()) OS << "+" << getOffset(); 4427ae0e2c9SDimitry Andric OS << '>'; 4437ae0e2c9SDimitry Andric break; 444f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 445f22ef01cSRoman Divacky OS << "<jt#" << getIndex() << '>'; 446f22ef01cSRoman Divacky break; 447f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 448f22ef01cSRoman Divacky OS << "<ga:"; 4493dac3a9bSDimitry Andric getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 450f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 451f22ef01cSRoman Divacky OS << '>'; 452f22ef01cSRoman Divacky break; 453f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 454f22ef01cSRoman Divacky OS << "<es:" << getSymbolName(); 455f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 456f22ef01cSRoman Divacky OS << '>'; 457f22ef01cSRoman Divacky break; 458f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 459f22ef01cSRoman Divacky OS << '<'; 4603dac3a9bSDimitry Andric getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST); 4613861d79fSDimitry Andric if (getOffset()) OS << "+" << getOffset(); 462f22ef01cSRoman Divacky OS << '>'; 463f22ef01cSRoman Divacky break; 4647d523365SDimitry Andric case MachineOperand::MO_RegisterMask: { 4657d523365SDimitry Andric unsigned NumRegsInMask = 0; 4667d523365SDimitry Andric unsigned NumRegsEmitted = 0; 4677d523365SDimitry Andric OS << "<regmask"; 4687d523365SDimitry Andric for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { 4697d523365SDimitry Andric unsigned MaskWord = i / 32; 4707d523365SDimitry Andric unsigned MaskBit = i % 32; 4717d523365SDimitry Andric if (getRegMask()[MaskWord] & (1 << MaskBit)) { 4727d523365SDimitry Andric if (PrintWholeRegMask || NumRegsEmitted <= 10) { 4737d523365SDimitry Andric OS << " " << PrintReg(i, TRI); 4747d523365SDimitry Andric NumRegsEmitted++; 4757d523365SDimitry Andric } 4767d523365SDimitry Andric NumRegsInMask++; 4777d523365SDimitry Andric } 4787d523365SDimitry Andric } 4797d523365SDimitry Andric if (NumRegsEmitted != NumRegsInMask) 4807d523365SDimitry Andric OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; 4817d523365SDimitry Andric OS << ">"; 482dff0c46cSDimitry Andric break; 4837d523365SDimitry Andric } 48491bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 48591bc56edSDimitry Andric OS << "<regliveout>"; 48691bc56edSDimitry Andric break; 487f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 488f22ef01cSRoman Divacky OS << '<'; 4893dac3a9bSDimitry Andric getMetadata()->printAsOperand(OS, MST); 490f22ef01cSRoman Divacky OS << '>'; 491f22ef01cSRoman Divacky break; 492f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 493f22ef01cSRoman Divacky OS << "<MCSym=" << *getMCSymbol() << '>'; 494f22ef01cSRoman Divacky break; 49591bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 49691bc56edSDimitry Andric OS << "<call frame instruction>"; 49791bc56edSDimitry Andric break; 498d88c1a5aSDimitry Andric case MachineOperand::MO_IntrinsicID: { 499d88c1a5aSDimitry Andric Intrinsic::ID ID = getIntrinsicID(); 500d88c1a5aSDimitry Andric if (ID < Intrinsic::num_intrinsics) 501d88c1a5aSDimitry Andric OS << "<intrinsic:@" << Intrinsic::getName(ID, None) << '>'; 502d88c1a5aSDimitry Andric else if (IntrinsicInfo) 503d88c1a5aSDimitry Andric OS << "<intrinsic:@" << IntrinsicInfo->getName(ID) << '>'; 504d88c1a5aSDimitry Andric else 505d88c1a5aSDimitry Andric OS << "<intrinsic:" << ID << '>'; 506d88c1a5aSDimitry Andric break; 507f22ef01cSRoman Divacky } 508d88c1a5aSDimitry Andric case MachineOperand::MO_Predicate: { 509d88c1a5aSDimitry Andric auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); 510d88c1a5aSDimitry Andric OS << '<' << (CmpInst::isIntPredicate(Pred) ? "intpred" : "floatpred") 511d88c1a5aSDimitry Andric << CmpInst::getPredicateName(Pred) << '>'; 5127a7e6055SDimitry Andric break; 513d88c1a5aSDimitry Andric } 514d88c1a5aSDimitry Andric } 515f22ef01cSRoman Divacky if (unsigned TF = getTargetFlags()) 516f22ef01cSRoman Divacky OS << "[TF=" << TF << ']'; 517f22ef01cSRoman Divacky } 518f22ef01cSRoman Divacky 519d88c1a5aSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 520d88c1a5aSDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { 521d88c1a5aSDimitry Andric dbgs() << *this << '\n'; 522d88c1a5aSDimitry Andric } 523d88c1a5aSDimitry Andric #endif 524d88c1a5aSDimitry Andric 525f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 526f22ef01cSRoman Divacky // MachineMemOperand Implementation 527f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 528f22ef01cSRoman Divacky 5292754fe60SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer 5302754fe60SDimitry Andric /// points into. 5312754fe60SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { 53291bc56edSDimitry Andric if (V.isNull() || V.is<const PseudoSourceValue*>()) return 0; 53391bc56edSDimitry Andric return cast<PointerType>(V.get<const Value*>()->getType())->getAddressSpace(); 5342754fe60SDimitry Andric } 5352754fe60SDimitry Andric 5362754fe60SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the 5372754fe60SDimitry Andric /// constant pool. 5387d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { 5397d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getConstantPool()); 5402754fe60SDimitry Andric } 5412754fe60SDimitry Andric 5422754fe60SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the 5432754fe60SDimitry Andric /// the specified FrameIndex. 5447d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, 5457d523365SDimitry Andric int FI, int64_t Offset) { 5467d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); 5472754fe60SDimitry Andric } 5482754fe60SDimitry Andric 5497d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { 5507d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getJumpTable()); 5512754fe60SDimitry Andric } 5522754fe60SDimitry Andric 5537d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { 5547d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getGOT()); 5552754fe60SDimitry Andric } 5562754fe60SDimitry Andric 5577d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, 5587d523365SDimitry Andric int64_t Offset) { 5597d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getStack(), Offset); 5602754fe60SDimitry Andric } 5612754fe60SDimitry Andric 5623ca95b02SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f, 5632754fe60SDimitry Andric uint64_t s, unsigned int a, 56439d628a0SDimitry Andric const AAMDNodes &AAInfo, 565d88c1a5aSDimitry Andric const MDNode *Ranges, 566d88c1a5aSDimitry Andric SynchronizationScope SynchScope, 567d88c1a5aSDimitry Andric AtomicOrdering Ordering, 568d88c1a5aSDimitry Andric AtomicOrdering FailureOrdering) 5693ca95b02SDimitry Andric : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1), 57039d628a0SDimitry Andric AAInfo(AAInfo), Ranges(Ranges) { 57191bc56edSDimitry Andric assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue*>() || 57291bc56edSDimitry Andric isa<PointerType>(PtrInfo.V.get<const Value*>()->getType())) && 5732754fe60SDimitry Andric "invalid pointer value"); 574f22ef01cSRoman Divacky assert(getBaseAlignment() == a && "Alignment is not a power of 2!"); 575f22ef01cSRoman Divacky assert((isLoad() || isStore()) && "Not a load/store!"); 576d88c1a5aSDimitry Andric 577d88c1a5aSDimitry Andric AtomicInfo.SynchScope = static_cast<unsigned>(SynchScope); 578d88c1a5aSDimitry Andric assert(getSynchScope() == SynchScope && "Value truncated"); 579d88c1a5aSDimitry Andric AtomicInfo.Ordering = static_cast<unsigned>(Ordering); 580d88c1a5aSDimitry Andric assert(getOrdering() == Ordering && "Value truncated"); 581d88c1a5aSDimitry Andric AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering); 582d88c1a5aSDimitry Andric assert(getFailureOrdering() == FailureOrdering && "Value truncated"); 583f22ef01cSRoman Divacky } 584f22ef01cSRoman Divacky 585f22ef01cSRoman Divacky /// Profile - Gather unique data for the object. 586f22ef01cSRoman Divacky /// 587f22ef01cSRoman Divacky void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 5882754fe60SDimitry Andric ID.AddInteger(getOffset()); 589f22ef01cSRoman Divacky ID.AddInteger(Size); 59091bc56edSDimitry Andric ID.AddPointer(getOpaqueValue()); 5913ca95b02SDimitry Andric ID.AddInteger(getFlags()); 5923ca95b02SDimitry Andric ID.AddInteger(getBaseAlignment()); 593f22ef01cSRoman Divacky } 594f22ef01cSRoman Divacky 595f22ef01cSRoman Divacky void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 596f22ef01cSRoman Divacky // The Value and Offset may differ due to CSE. But the flags and size 597f22ef01cSRoman Divacky // should be the same. 598f22ef01cSRoman Divacky assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 599f22ef01cSRoman Divacky assert(MMO->getSize() == getSize() && "Size mismatch!"); 600f22ef01cSRoman Divacky 601f22ef01cSRoman Divacky if (MMO->getBaseAlignment() >= getBaseAlignment()) { 602f22ef01cSRoman Divacky // Update the alignment value. 6033ca95b02SDimitry Andric BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1; 604f22ef01cSRoman Divacky // Also update the base and offset, because the new alignment may 605f22ef01cSRoman Divacky // not be applicable with the old ones. 6062754fe60SDimitry Andric PtrInfo = MMO->PtrInfo; 607f22ef01cSRoman Divacky } 608f22ef01cSRoman Divacky } 609f22ef01cSRoman Divacky 610f22ef01cSRoman Divacky /// getAlignment - Return the minimum known alignment in bytes of the 611f22ef01cSRoman Divacky /// actual memory reference. 612f22ef01cSRoman Divacky uint64_t MachineMemOperand::getAlignment() const { 613f22ef01cSRoman Divacky return MinAlign(getBaseAlignment(), getOffset()); 614f22ef01cSRoman Divacky } 615f22ef01cSRoman Divacky 6163dac3a9bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS) const { 6173dac3a9bSDimitry Andric ModuleSlotTracker DummyMST(nullptr); 6183dac3a9bSDimitry Andric print(OS, DummyMST); 6193dac3a9bSDimitry Andric } 6203dac3a9bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const { 6213dac3a9bSDimitry Andric assert((isLoad() || isStore()) && 622f22ef01cSRoman Divacky "SV has to be a load, store or both."); 623f22ef01cSRoman Divacky 6243dac3a9bSDimitry Andric if (isVolatile()) 625f22ef01cSRoman Divacky OS << "Volatile "; 626f22ef01cSRoman Divacky 6273dac3a9bSDimitry Andric if (isLoad()) 628f22ef01cSRoman Divacky OS << "LD"; 6293dac3a9bSDimitry Andric if (isStore()) 630f22ef01cSRoman Divacky OS << "ST"; 6313dac3a9bSDimitry Andric OS << getSize(); 632f22ef01cSRoman Divacky 633f22ef01cSRoman Divacky // Print the address information. 634f22ef01cSRoman Divacky OS << "["; 6353dac3a9bSDimitry Andric if (const Value *V = getValue()) 6363dac3a9bSDimitry Andric V->printAsOperand(OS, /*PrintType=*/false, MST); 6373dac3a9bSDimitry Andric else if (const PseudoSourceValue *PSV = getPseudoValue()) 63891bc56edSDimitry Andric PSV->printCustom(OS); 639f22ef01cSRoman Divacky else 64091bc56edSDimitry Andric OS << "<unknown>"; 64191bc56edSDimitry Andric 6423dac3a9bSDimitry Andric unsigned AS = getAddrSpace(); 64391bc56edSDimitry Andric if (AS != 0) 64491bc56edSDimitry Andric OS << "(addrspace=" << AS << ')'; 645f22ef01cSRoman Divacky 646f22ef01cSRoman Divacky // If the alignment of the memory reference itself differs from the alignment 647f22ef01cSRoman Divacky // of the base pointer, print the base alignment explicitly, next to the base 648f22ef01cSRoman Divacky // pointer. 6493dac3a9bSDimitry Andric if (getBaseAlignment() != getAlignment()) 6503dac3a9bSDimitry Andric OS << "(align=" << getBaseAlignment() << ")"; 651f22ef01cSRoman Divacky 6523dac3a9bSDimitry Andric if (getOffset() != 0) 6533dac3a9bSDimitry Andric OS << "+" << getOffset(); 654f22ef01cSRoman Divacky OS << "]"; 655f22ef01cSRoman Divacky 656f22ef01cSRoman Divacky // Print the alignment of the reference. 6573dac3a9bSDimitry Andric if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize()) 6583dac3a9bSDimitry Andric OS << "(align=" << getAlignment() << ")"; 659f22ef01cSRoman Divacky 6602754fe60SDimitry Andric // Print TBAA info. 6613dac3a9bSDimitry Andric if (const MDNode *TBAAInfo = getAAInfo().TBAA) { 6622754fe60SDimitry Andric OS << "(tbaa="; 6632754fe60SDimitry Andric if (TBAAInfo->getNumOperands() > 0) 6643dac3a9bSDimitry Andric TBAAInfo->getOperand(0)->printAsOperand(OS, MST); 66539d628a0SDimitry Andric else 66639d628a0SDimitry Andric OS << "<unknown>"; 66739d628a0SDimitry Andric OS << ")"; 66839d628a0SDimitry Andric } 66939d628a0SDimitry Andric 67039d628a0SDimitry Andric // Print AA scope info. 6713dac3a9bSDimitry Andric if (const MDNode *ScopeInfo = getAAInfo().Scope) { 67239d628a0SDimitry Andric OS << "(alias.scope="; 67339d628a0SDimitry Andric if (ScopeInfo->getNumOperands() > 0) 67439d628a0SDimitry Andric for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { 6753dac3a9bSDimitry Andric ScopeInfo->getOperand(i)->printAsOperand(OS, MST); 67639d628a0SDimitry Andric if (i != ie-1) 67739d628a0SDimitry Andric OS << ","; 67839d628a0SDimitry Andric } 67939d628a0SDimitry Andric else 68039d628a0SDimitry Andric OS << "<unknown>"; 68139d628a0SDimitry Andric OS << ")"; 68239d628a0SDimitry Andric } 68339d628a0SDimitry Andric 68439d628a0SDimitry Andric // Print AA noalias scope info. 6853dac3a9bSDimitry Andric if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) { 68639d628a0SDimitry Andric OS << "(noalias="; 68739d628a0SDimitry Andric if (NoAliasInfo->getNumOperands() > 0) 68839d628a0SDimitry Andric for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { 6893dac3a9bSDimitry Andric NoAliasInfo->getOperand(i)->printAsOperand(OS, MST); 69039d628a0SDimitry Andric if (i != ie-1) 69139d628a0SDimitry Andric OS << ","; 69239d628a0SDimitry Andric } 6932754fe60SDimitry Andric else 6942754fe60SDimitry Andric OS << "<unknown>"; 6952754fe60SDimitry Andric OS << ")"; 6962754fe60SDimitry Andric } 6972754fe60SDimitry Andric 6983dac3a9bSDimitry Andric if (isNonTemporal()) 6993b0f4066SDimitry Andric OS << "(nontemporal)"; 700d88c1a5aSDimitry Andric if (isDereferenceable()) 701d88c1a5aSDimitry Andric OS << "(dereferenceable)"; 7023dac3a9bSDimitry Andric if (isInvariant()) 7033dac3a9bSDimitry Andric OS << "(invariant)"; 704f22ef01cSRoman Divacky } 705f22ef01cSRoman Divacky 706f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 707f22ef01cSRoman Divacky // MachineInstr Implementation 708f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 709f22ef01cSRoman Divacky 710139f7f9bSDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { 71117a519f9SDimitry Andric if (MCID->ImplicitDefs) 7127d523365SDimitry Andric for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; 7137d523365SDimitry Andric ++ImpDefs) 714139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true)); 71517a519f9SDimitry Andric if (MCID->ImplicitUses) 7167d523365SDimitry Andric for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses; 7177d523365SDimitry Andric ++ImpUses) 718139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true)); 719f22ef01cSRoman Divacky } 720f22ef01cSRoman Divacky 721f22ef01cSRoman Divacky /// MachineInstr ctor - This constructor creates a MachineInstr and adds the 722f22ef01cSRoman Divacky /// implicit operands. It reserves space for the number of operands specified by 72317a519f9SDimitry Andric /// the MCInstrDesc. 724139f7f9bSDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid, 725ff0cc061SDimitry Andric DebugLoc dl, bool NoImp) 726ff0cc061SDimitry Andric : MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), Flags(0), 727ff0cc061SDimitry Andric AsmPrinterFlags(0), NumMemRefs(0), MemRefs(nullptr), 728d88c1a5aSDimitry Andric debugLoc(std::move(dl)) { 72939d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 73039d628a0SDimitry Andric 731139f7f9bSDimitry Andric // Reserve space for the expected number of operands. 732139f7f9bSDimitry Andric if (unsigned NumOps = MCID->getNumOperands() + 733139f7f9bSDimitry Andric MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) { 734139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(NumOps); 735139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 736f22ef01cSRoman Divacky } 737f22ef01cSRoman Divacky 738139f7f9bSDimitry Andric if (!NoImp) 739139f7f9bSDimitry Andric addImplicitDefUseOperands(MF); 740f22ef01cSRoman Divacky } 741f22ef01cSRoman Divacky 742f22ef01cSRoman Divacky /// MachineInstr ctor - Copies MachineInstr arg exactly 743f22ef01cSRoman Divacky /// 744f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) 74591bc56edSDimitry Andric : MCID(&MI.getDesc()), Parent(nullptr), Operands(nullptr), NumOperands(0), 7463ca95b02SDimitry Andric Flags(0), AsmPrinterFlags(0), NumMemRefs(MI.NumMemRefs), 747d88c1a5aSDimitry Andric MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc()) { 74839d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 74939d628a0SDimitry Andric 750139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(MI.getNumOperands()); 751139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 752f22ef01cSRoman Divacky 753139f7f9bSDimitry Andric // Copy operands. 754ff0cc061SDimitry Andric for (const MachineOperand &MO : MI.operands()) 755ff0cc061SDimitry Andric addOperand(MF, MO); 756f22ef01cSRoman Divacky 757139f7f9bSDimitry Andric // Copy all the sensible flags. 758139f7f9bSDimitry Andric setFlags(MI.Flags); 759f22ef01cSRoman Divacky } 760f22ef01cSRoman Divacky 761f22ef01cSRoman Divacky /// getRegInfo - If this instruction is embedded into a MachineFunction, 762f22ef01cSRoman Divacky /// return the MachineRegisterInfo object for the current function, otherwise 763f22ef01cSRoman Divacky /// return null. 764f22ef01cSRoman Divacky MachineRegisterInfo *MachineInstr::getRegInfo() { 765f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = getParent()) 766f22ef01cSRoman Divacky return &MBB->getParent()->getRegInfo(); 76791bc56edSDimitry Andric return nullptr; 768f22ef01cSRoman Divacky } 769f22ef01cSRoman Divacky 770f22ef01cSRoman Divacky /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in 771f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 772f22ef01cSRoman Divacky /// operands already be on their use lists. 7737ae0e2c9SDimitry Andric void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) { 774ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 775ff0cc061SDimitry Andric if (MO.isReg()) 776ff0cc061SDimitry Andric MRI.removeRegOperandFromUseList(&MO); 777f22ef01cSRoman Divacky } 778f22ef01cSRoman Divacky 779f22ef01cSRoman Divacky /// AddRegOperandsToUseLists - Add all of the register operands in 780f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 781f22ef01cSRoman Divacky /// operands not be on their use lists yet. 7827ae0e2c9SDimitry Andric void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) { 783ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 784ff0cc061SDimitry Andric if (MO.isReg()) 785ff0cc061SDimitry Andric MRI.addRegOperandToUseList(&MO); 786f22ef01cSRoman Divacky } 787f22ef01cSRoman Divacky 788139f7f9bSDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) { 789139f7f9bSDimitry Andric MachineBasicBlock *MBB = getParent(); 790139f7f9bSDimitry Andric assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs"); 791139f7f9bSDimitry Andric MachineFunction *MF = MBB->getParent(); 792139f7f9bSDimitry Andric assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs"); 793139f7f9bSDimitry Andric addOperand(*MF, Op); 794139f7f9bSDimitry Andric } 795139f7f9bSDimitry Andric 796139f7f9bSDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping 797139f7f9bSDimitry Andric /// ranges. If MRI is non-null also update use-def chains. 798139f7f9bSDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src, 799139f7f9bSDimitry Andric unsigned NumOps, MachineRegisterInfo *MRI) { 800139f7f9bSDimitry Andric if (MRI) 801139f7f9bSDimitry Andric return MRI->moveOperands(Dst, Src, NumOps); 802139f7f9bSDimitry Andric 803ff0cc061SDimitry Andric // MachineOperand is a trivially copyable type so we can just use memmove. 804ff0cc061SDimitry Andric std::memmove(Dst, Src, NumOps * sizeof(MachineOperand)); 805139f7f9bSDimitry Andric } 806139f7f9bSDimitry Andric 807f22ef01cSRoman Divacky /// addOperand - Add the specified operand to the instruction. If it is an 808f22ef01cSRoman Divacky /// implicit operand, it is added to the end of the operand list. If it is 809f22ef01cSRoman Divacky /// an explicit operand it is added at the end of the explicit operand list 810f22ef01cSRoman Divacky /// (before the first implicit operand). 811139f7f9bSDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { 8126122f3e6SDimitry Andric assert(MCID && "Cannot add operands before providing an instr descriptor"); 813f22ef01cSRoman Divacky 814139f7f9bSDimitry Andric // Check if we're adding one of our existing operands. 815139f7f9bSDimitry Andric if (&Op >= Operands && &Op < Operands + NumOperands) { 816139f7f9bSDimitry Andric // This is unusual: MI->addOperand(MI->getOperand(i)). 817139f7f9bSDimitry Andric // If adding Op requires reallocating or moving existing operands around, 818139f7f9bSDimitry Andric // the Op reference could go stale. Support it by copying Op. 819139f7f9bSDimitry Andric MachineOperand CopyOp(Op); 820139f7f9bSDimitry Andric return addOperand(MF, CopyOp); 821139f7f9bSDimitry Andric } 822f22ef01cSRoman Divacky 8236122f3e6SDimitry Andric // Find the insert location for the new operand. Implicit registers go at 824139f7f9bSDimitry Andric // the end, everything else goes before the implicit regs. 825139f7f9bSDimitry Andric // 8266122f3e6SDimitry Andric // FIXME: Allow mixed explicit and implicit operands on inline asm. 8276122f3e6SDimitry Andric // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as 8286122f3e6SDimitry Andric // implicit-defs, but they must not be moved around. See the FIXME in 8296122f3e6SDimitry Andric // InstrEmitter.cpp. 830139f7f9bSDimitry Andric unsigned OpNo = getNumOperands(); 831139f7f9bSDimitry Andric bool isImpReg = Op.isReg() && Op.isImplicit(); 8326122f3e6SDimitry Andric if (!isImpReg && !isInlineAsm()) { 8336122f3e6SDimitry Andric while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) { 8346122f3e6SDimitry Andric --OpNo; 8353861d79fSDimitry Andric assert(!Operands[OpNo].isTied() && "Cannot move tied operands"); 836f22ef01cSRoman Divacky } 837f22ef01cSRoman Divacky } 838f22ef01cSRoman Divacky 839f785676fSDimitry Andric #ifndef NDEBUG 840f785676fSDimitry Andric bool isMetaDataOp = Op.getType() == MachineOperand::MO_Metadata; 8416122f3e6SDimitry Andric // OpNo now points as the desired insertion point. Unless this is a variadic 8426122f3e6SDimitry Andric // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). 8437ae0e2c9SDimitry Andric // RegMask operands go between the explicit and implicit operands. 8447ae0e2c9SDimitry Andric assert((isImpReg || Op.isRegMask() || MCID->isVariadic() || 845f785676fSDimitry Andric OpNo < MCID->getNumOperands() || isMetaDataOp) && 8466122f3e6SDimitry Andric "Trying to add an operand to a machine instr that is already done!"); 847f785676fSDimitry Andric #endif 848f22ef01cSRoman Divacky 849139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 850f22ef01cSRoman Divacky 851139f7f9bSDimitry Andric // Determine if the Operands array needs to be reallocated. 852139f7f9bSDimitry Andric // Save the old capacity and operand array. 853139f7f9bSDimitry Andric OperandCapacity OldCap = CapOperands; 854139f7f9bSDimitry Andric MachineOperand *OldOperands = Operands; 855139f7f9bSDimitry Andric if (!OldOperands || OldCap.getSize() == getNumOperands()) { 856139f7f9bSDimitry Andric CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1); 857139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 858139f7f9bSDimitry Andric // Move the operands before the insertion point. 859139f7f9bSDimitry Andric if (OpNo) 860139f7f9bSDimitry Andric moveOperands(Operands, OldOperands, OpNo, MRI); 861139f7f9bSDimitry Andric } 862f22ef01cSRoman Divacky 863139f7f9bSDimitry Andric // Move the operands following the insertion point. 864139f7f9bSDimitry Andric if (OpNo != NumOperands) 865139f7f9bSDimitry Andric moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo, 866139f7f9bSDimitry Andric MRI); 867139f7f9bSDimitry Andric ++NumOperands; 8686122f3e6SDimitry Andric 869139f7f9bSDimitry Andric // Deallocate the old operand array. 870139f7f9bSDimitry Andric if (OldOperands != Operands && OldOperands) 871139f7f9bSDimitry Andric MF.deallocateOperandArray(OldCap, OldOperands); 872139f7f9bSDimitry Andric 873139f7f9bSDimitry Andric // Copy Op into place. It still needs to be inserted into the MRI use lists. 874139f7f9bSDimitry Andric MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op); 875139f7f9bSDimitry Andric NewMO->ParentMI = this; 876139f7f9bSDimitry Andric 877139f7f9bSDimitry Andric // When adding a register operand, tell MRI about it. 878139f7f9bSDimitry Andric if (NewMO->isReg()) { 8797ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false, regardless of Op's status. 88091bc56edSDimitry Andric NewMO->Contents.Reg.Prev = nullptr; 8813861d79fSDimitry Andric // Ignore existing ties. This is not a property that can be copied. 882139f7f9bSDimitry Andric NewMO->TiedTo = 0; 883139f7f9bSDimitry Andric // Add the new operand to MRI, but only for instructions in an MBB. 884139f7f9bSDimitry Andric if (MRI) 885139f7f9bSDimitry Andric MRI->addRegOperandToUseList(NewMO); 8863861d79fSDimitry Andric // The MCID operand information isn't accurate until we start adding 8873861d79fSDimitry Andric // explicit operands. The implicit operands are added first, then the 8883861d79fSDimitry Andric // explicits are inserted before them. 8893861d79fSDimitry Andric if (!isImpReg) { 8903861d79fSDimitry Andric // Tie uses to defs as indicated in MCInstrDesc. 891139f7f9bSDimitry Andric if (NewMO->isUse()) { 8923861d79fSDimitry Andric int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO); 8933861d79fSDimitry Andric if (DefIdx != -1) 8943861d79fSDimitry Andric tieOperands(DefIdx, OpNo); 8953861d79fSDimitry Andric } 8966122f3e6SDimitry Andric // If the register operand is flagged as early, mark the operand as such. 89717a519f9SDimitry Andric if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) 898139f7f9bSDimitry Andric NewMO->setIsEarlyClobber(true); 899f22ef01cSRoman Divacky } 900f22ef01cSRoman Divacky } 901f22ef01cSRoman Divacky } 902f22ef01cSRoman Divacky 903f22ef01cSRoman Divacky /// RemoveOperand - Erase an operand from an instruction, leaving it with one 904f22ef01cSRoman Divacky /// fewer operand than it started with. 905f22ef01cSRoman Divacky /// 906f22ef01cSRoman Divacky void MachineInstr::RemoveOperand(unsigned OpNo) { 907139f7f9bSDimitry Andric assert(OpNo < getNumOperands() && "Invalid operand number"); 9083861d79fSDimitry Andric untieRegOperand(OpNo); 909f22ef01cSRoman Divacky 9103861d79fSDimitry Andric #ifndef NDEBUG 9113861d79fSDimitry Andric // Moving tied operands would break the ties. 912139f7f9bSDimitry Andric for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i) 9133861d79fSDimitry Andric if (Operands[i].isReg()) 9143861d79fSDimitry Andric assert(!Operands[i].isTied() && "Cannot move tied operands"); 9153861d79fSDimitry Andric #endif 9163861d79fSDimitry Andric 917139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 918139f7f9bSDimitry Andric if (MRI && Operands[OpNo].isReg()) 919139f7f9bSDimitry Andric MRI->removeRegOperandFromUseList(Operands + OpNo); 920f22ef01cSRoman Divacky 921139f7f9bSDimitry Andric // Don't call the MachineOperand destructor. A lot of this code depends on 922139f7f9bSDimitry Andric // MachineOperand having a trivial destructor anyway, and adding a call here 923139f7f9bSDimitry Andric // wouldn't make it 'destructor-correct'. 924139f7f9bSDimitry Andric 925139f7f9bSDimitry Andric if (unsigned N = NumOperands - 1 - OpNo) 926139f7f9bSDimitry Andric moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI); 927139f7f9bSDimitry Andric --NumOperands; 928f22ef01cSRoman Divacky } 929f22ef01cSRoman Divacky 930f22ef01cSRoman Divacky /// addMemOperand - Add a MachineMemOperand to the machine instruction. 931f22ef01cSRoman Divacky /// This function should be used only occasionally. The setMemRefs function 932f22ef01cSRoman Divacky /// is the primary method for setting up a MachineInstr's MemRefs list. 933f22ef01cSRoman Divacky void MachineInstr::addMemOperand(MachineFunction &MF, 934f22ef01cSRoman Divacky MachineMemOperand *MO) { 935f22ef01cSRoman Divacky mmo_iterator OldMemRefs = MemRefs; 936139f7f9bSDimitry Andric unsigned OldNumMemRefs = NumMemRefs; 937f22ef01cSRoman Divacky 938139f7f9bSDimitry Andric unsigned NewNum = NumMemRefs + 1; 939f22ef01cSRoman Divacky mmo_iterator NewMemRefs = MF.allocateMemRefsArray(NewNum); 940f22ef01cSRoman Divacky 941dff0c46cSDimitry Andric std::copy(OldMemRefs, OldMemRefs + OldNumMemRefs, NewMemRefs); 942f22ef01cSRoman Divacky NewMemRefs[NewNum - 1] = MO; 943139f7f9bSDimitry Andric setMemRefs(NewMemRefs, NewMemRefs + NewNum); 944dff0c46cSDimitry Andric } 945dff0c46cSDimitry Andric 946444ed5c5SDimitry Andric /// Check to see if the MMOs pointed to by the two MemRefs arrays are 947444ed5c5SDimitry Andric /// identical. 948444ed5c5SDimitry Andric static bool hasIdenticalMMOs(const MachineInstr &MI1, const MachineInstr &MI2) { 949444ed5c5SDimitry Andric auto I1 = MI1.memoperands_begin(), E1 = MI1.memoperands_end(); 950444ed5c5SDimitry Andric auto I2 = MI2.memoperands_begin(), E2 = MI2.memoperands_end(); 951444ed5c5SDimitry Andric if ((E1 - I1) != (E2 - I2)) 952444ed5c5SDimitry Andric return false; 953444ed5c5SDimitry Andric for (; I1 != E1; ++I1, ++I2) { 954444ed5c5SDimitry Andric if (**I1 != **I2) 955444ed5c5SDimitry Andric return false; 956444ed5c5SDimitry Andric } 957444ed5c5SDimitry Andric return true; 958444ed5c5SDimitry Andric } 959444ed5c5SDimitry Andric 9604d0b32cdSDimitry Andric std::pair<MachineInstr::mmo_iterator, unsigned> 9614d0b32cdSDimitry Andric MachineInstr::mergeMemRefsWith(const MachineInstr& Other) { 962444ed5c5SDimitry Andric 963444ed5c5SDimitry Andric // If either of the incoming memrefs are empty, we must be conservative and 964444ed5c5SDimitry Andric // treat this as if we've exhausted our space for memrefs and dropped them. 965444ed5c5SDimitry Andric if (memoperands_empty() || Other.memoperands_empty()) 966444ed5c5SDimitry Andric return std::make_pair(nullptr, 0); 967444ed5c5SDimitry Andric 968444ed5c5SDimitry Andric // If both instructions have identical memrefs, we don't need to merge them. 969444ed5c5SDimitry Andric // Since many instructions have a single memref, and we tend to merge things 970444ed5c5SDimitry Andric // like pairs of loads from the same location, this catches a large number of 971444ed5c5SDimitry Andric // cases in practice. 972444ed5c5SDimitry Andric if (hasIdenticalMMOs(*this, Other)) 973444ed5c5SDimitry Andric return std::make_pair(MemRefs, NumMemRefs); 974444ed5c5SDimitry Andric 9754d0b32cdSDimitry Andric // TODO: consider uniquing elements within the operand lists to reduce 9764d0b32cdSDimitry Andric // space usage and fall back to conservative information less often. 977444ed5c5SDimitry Andric size_t CombinedNumMemRefs = NumMemRefs + Other.NumMemRefs; 978444ed5c5SDimitry Andric 979444ed5c5SDimitry Andric // If we don't have enough room to store this many memrefs, be conservative 980444ed5c5SDimitry Andric // and drop them. Otherwise, we'd fail asserts when trying to add them to 981444ed5c5SDimitry Andric // the new instruction. 982444ed5c5SDimitry Andric if (CombinedNumMemRefs != uint8_t(CombinedNumMemRefs)) 983444ed5c5SDimitry Andric return std::make_pair(nullptr, 0); 9844d0b32cdSDimitry Andric 9854d0b32cdSDimitry Andric MachineFunction *MF = getParent()->getParent(); 9864d0b32cdSDimitry Andric mmo_iterator MemBegin = MF->allocateMemRefsArray(CombinedNumMemRefs); 9874d0b32cdSDimitry Andric mmo_iterator MemEnd = std::copy(memoperands_begin(), memoperands_end(), 9884d0b32cdSDimitry Andric MemBegin); 9894d0b32cdSDimitry Andric MemEnd = std::copy(Other.memoperands_begin(), Other.memoperands_end(), 9904d0b32cdSDimitry Andric MemEnd); 9914d0b32cdSDimitry Andric assert(MemEnd - MemBegin == (ptrdiff_t)CombinedNumMemRefs && 9924d0b32cdSDimitry Andric "missing memrefs"); 9934d0b32cdSDimitry Andric 9944d0b32cdSDimitry Andric return std::make_pair(MemBegin, CombinedNumMemRefs); 9954d0b32cdSDimitry Andric } 9964d0b32cdSDimitry Andric 997dff0c46cSDimitry Andric bool MachineInstr::hasPropertyInBundle(unsigned Mask, QueryType Type) const { 998139f7f9bSDimitry Andric assert(!isBundledWithPred() && "Must be called on bundle header"); 9997d523365SDimitry Andric for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) { 1000dff0c46cSDimitry Andric if (MII->getDesc().getFlags() & Mask) { 1001dff0c46cSDimitry Andric if (Type == AnyInBundle) 1002dff0c46cSDimitry Andric return true; 1003dff0c46cSDimitry Andric } else { 1004139f7f9bSDimitry Andric if (Type == AllInBundle && !MII->isBundle()) 1005dff0c46cSDimitry Andric return false; 1006dff0c46cSDimitry Andric } 1007139f7f9bSDimitry Andric // This was the last instruction in the bundle. 1008139f7f9bSDimitry Andric if (!MII->isBundledWithSucc()) 1009dff0c46cSDimitry Andric return Type == AllInBundle; 1010f22ef01cSRoman Divacky } 1011139f7f9bSDimitry Andric } 1012f22ef01cSRoman Divacky 10133ca95b02SDimitry Andric bool MachineInstr::isIdenticalTo(const MachineInstr &Other, 1014f22ef01cSRoman Divacky MICheckType Check) const { 1015f22ef01cSRoman Divacky // If opcodes or number of operands are not the same then the two 1016f22ef01cSRoman Divacky // instructions are obviously not identical. 10173ca95b02SDimitry Andric if (Other.getOpcode() != getOpcode() || 10183ca95b02SDimitry Andric Other.getNumOperands() != getNumOperands()) 1019f22ef01cSRoman Divacky return false; 1020f22ef01cSRoman Divacky 1021dff0c46cSDimitry Andric if (isBundle()) { 1022d88c1a5aSDimitry Andric // We have passed the test above that both instructions have the same 1023d88c1a5aSDimitry Andric // opcode, so we know that both instructions are bundles here. Let's compare 1024d88c1a5aSDimitry Andric // MIs inside the bundle. 1025d88c1a5aSDimitry Andric assert(Other.isBundle() && "Expected that both instructions are bundles."); 10267d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I1 = getIterator(); 10273ca95b02SDimitry Andric MachineBasicBlock::const_instr_iterator I2 = Other.getIterator(); 1028d88c1a5aSDimitry Andric // Loop until we analysed the last intruction inside at least one of the 1029d88c1a5aSDimitry Andric // bundles. 1030d88c1a5aSDimitry Andric while (I1->isBundledWithSucc() && I2->isBundledWithSucc()) { 1031d88c1a5aSDimitry Andric ++I1; 1032dff0c46cSDimitry Andric ++I2; 1033d88c1a5aSDimitry Andric if (!I1->isIdenticalTo(*I2, Check)) 1034dff0c46cSDimitry Andric return false; 1035dff0c46cSDimitry Andric } 1036d88c1a5aSDimitry Andric // If we've reached the end of just one of the two bundles, but not both, 1037d88c1a5aSDimitry Andric // the instructions are not identical. 1038d88c1a5aSDimitry Andric if (I1->isBundledWithSucc() || I2->isBundledWithSucc()) 1039d88c1a5aSDimitry Andric return false; 1040dff0c46cSDimitry Andric } 1041dff0c46cSDimitry Andric 1042f22ef01cSRoman Divacky // Check operands to make sure they match. 1043f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1044f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 10453ca95b02SDimitry Andric const MachineOperand &OMO = Other.getOperand(i); 1046bd5abe19SDimitry Andric if (!MO.isReg()) { 1047bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1048bd5abe19SDimitry Andric return false; 1049bd5abe19SDimitry Andric continue; 1050bd5abe19SDimitry Andric } 1051bd5abe19SDimitry Andric 1052f22ef01cSRoman Divacky // Clients may or may not want to ignore defs when testing for equality. 1053f22ef01cSRoman Divacky // For example, machine CSE pass only cares about finding common 1054f22ef01cSRoman Divacky // subexpressions, so it's safe to ignore virtual register defs. 1055bd5abe19SDimitry Andric if (MO.isDef()) { 1056f22ef01cSRoman Divacky if (Check == IgnoreDefs) 1057f22ef01cSRoman Divacky continue; 1058bd5abe19SDimitry Andric else if (Check == IgnoreVRegDefs) { 1059f22ef01cSRoman Divacky if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) || 1060f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(OMO.getReg())) 1061f22ef01cSRoman Divacky if (MO.getReg() != OMO.getReg()) 1062f22ef01cSRoman Divacky return false; 1063bd5abe19SDimitry Andric } else { 1064bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1065f22ef01cSRoman Divacky return false; 1066bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isDead() != OMO.isDead()) 1067bd5abe19SDimitry Andric return false; 1068bd5abe19SDimitry Andric } 1069bd5abe19SDimitry Andric } else { 1070bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1071bd5abe19SDimitry Andric return false; 1072bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isKill() != OMO.isKill()) 1073bd5abe19SDimitry Andric return false; 1074bd5abe19SDimitry Andric } 1075f22ef01cSRoman Divacky } 107617a519f9SDimitry Andric // If DebugLoc does not match then two dbg.values are not identical. 107717a519f9SDimitry Andric if (isDebugValue()) 10783ca95b02SDimitry Andric if (getDebugLoc() && Other.getDebugLoc() && 10793ca95b02SDimitry Andric getDebugLoc() != Other.getDebugLoc()) 108017a519f9SDimitry Andric return false; 1081f22ef01cSRoman Divacky return true; 1082f22ef01cSRoman Divacky } 1083f22ef01cSRoman Divacky 1084f22ef01cSRoman Divacky MachineInstr *MachineInstr::removeFromParent() { 1085f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 1086139f7f9bSDimitry Andric return getParent()->remove(this); 1087f22ef01cSRoman Divacky } 1088f22ef01cSRoman Divacky 1089139f7f9bSDimitry Andric MachineInstr *MachineInstr::removeFromBundle() { 1090139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 1091139f7f9bSDimitry Andric return getParent()->remove_instr(this); 1092139f7f9bSDimitry Andric } 1093f22ef01cSRoman Divacky 1094f22ef01cSRoman Divacky void MachineInstr::eraseFromParent() { 1095f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 1096139f7f9bSDimitry Andric getParent()->erase(this); 1097f22ef01cSRoman Divacky } 1098f22ef01cSRoman Divacky 109939d628a0SDimitry Andric void MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval() { 110039d628a0SDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 110139d628a0SDimitry Andric MachineBasicBlock *MBB = getParent(); 110239d628a0SDimitry Andric MachineFunction *MF = MBB->getParent(); 110339d628a0SDimitry Andric assert(MF && "Not embedded in a function!"); 110439d628a0SDimitry Andric 110539d628a0SDimitry Andric MachineInstr *MI = (MachineInstr *)this; 110639d628a0SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 110739d628a0SDimitry Andric 1108ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 110939d628a0SDimitry Andric if (!MO.isReg() || !MO.isDef()) 111039d628a0SDimitry Andric continue; 111139d628a0SDimitry Andric unsigned Reg = MO.getReg(); 111239d628a0SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg)) 111339d628a0SDimitry Andric continue; 111439d628a0SDimitry Andric MRI.markUsesInDebugValueAsUndef(Reg); 111539d628a0SDimitry Andric } 111639d628a0SDimitry Andric MI->eraseFromParent(); 111739d628a0SDimitry Andric } 111839d628a0SDimitry Andric 1119139f7f9bSDimitry Andric void MachineInstr::eraseFromBundle() { 1120139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 1121139f7f9bSDimitry Andric getParent()->erase_instr(this); 1122139f7f9bSDimitry Andric } 1123f22ef01cSRoman Divacky 1124f22ef01cSRoman Divacky /// getNumExplicitOperands - Returns the number of non-implicit operands. 1125f22ef01cSRoman Divacky /// 1126f22ef01cSRoman Divacky unsigned MachineInstr::getNumExplicitOperands() const { 112717a519f9SDimitry Andric unsigned NumOperands = MCID->getNumOperands(); 112817a519f9SDimitry Andric if (!MCID->isVariadic()) 1129f22ef01cSRoman Divacky return NumOperands; 1130f22ef01cSRoman Divacky 1131f22ef01cSRoman Divacky for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) { 1132f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1133f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isImplicit()) 1134f22ef01cSRoman Divacky NumOperands++; 1135f22ef01cSRoman Divacky } 1136f22ef01cSRoman Divacky return NumOperands; 1137f22ef01cSRoman Divacky } 1138f22ef01cSRoman Divacky 1139139f7f9bSDimitry Andric void MachineInstr::bundleWithPred() { 1140139f7f9bSDimitry Andric assert(!isBundledWithPred() && "MI is already bundled with its predecessor"); 1141139f7f9bSDimitry Andric setFlag(BundledPred); 11427d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 1143139f7f9bSDimitry Andric --Pred; 1144139f7f9bSDimitry Andric assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 1145139f7f9bSDimitry Andric Pred->setFlag(BundledSucc); 1146139f7f9bSDimitry Andric } 1147139f7f9bSDimitry Andric 1148139f7f9bSDimitry Andric void MachineInstr::bundleWithSucc() { 1149139f7f9bSDimitry Andric assert(!isBundledWithSucc() && "MI is already bundled with its successor"); 1150139f7f9bSDimitry Andric setFlag(BundledSucc); 11517d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 1152139f7f9bSDimitry Andric ++Succ; 1153139f7f9bSDimitry Andric assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags"); 1154139f7f9bSDimitry Andric Succ->setFlag(BundledPred); 1155139f7f9bSDimitry Andric } 1156139f7f9bSDimitry Andric 1157139f7f9bSDimitry Andric void MachineInstr::unbundleFromPred() { 1158139f7f9bSDimitry Andric assert(isBundledWithPred() && "MI isn't bundled with its predecessor"); 1159139f7f9bSDimitry Andric clearFlag(BundledPred); 11607d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 1161139f7f9bSDimitry Andric --Pred; 1162139f7f9bSDimitry Andric assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 1163139f7f9bSDimitry Andric Pred->clearFlag(BundledSucc); 1164139f7f9bSDimitry Andric } 1165139f7f9bSDimitry Andric 1166139f7f9bSDimitry Andric void MachineInstr::unbundleFromSucc() { 1167139f7f9bSDimitry Andric assert(isBundledWithSucc() && "MI isn't bundled with its successor"); 1168139f7f9bSDimitry Andric clearFlag(BundledSucc); 11697d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 1170139f7f9bSDimitry Andric ++Succ; 1171139f7f9bSDimitry Andric assert(Succ->isBundledWithPred() && "Inconsistent bundle flags"); 1172139f7f9bSDimitry Andric Succ->clearFlag(BundledPred); 1173dff0c46cSDimitry Andric } 1174dff0c46cSDimitry Andric 11752754fe60SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const { 11762754fe60SDimitry Andric if (isInlineAsm()) { 11772754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 11782754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 11792754fe60SDimitry Andric return true; 11802754fe60SDimitry Andric } 11812754fe60SDimitry Andric return false; 11822754fe60SDimitry Andric } 1183f22ef01cSRoman Divacky 11843861d79fSDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const { 11853861d79fSDimitry Andric assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!"); 11863861d79fSDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 11873861d79fSDimitry Andric return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0); 11883861d79fSDimitry Andric } 11893861d79fSDimitry Andric 11906122f3e6SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx, 11916122f3e6SDimitry Andric unsigned *GroupNo) const { 11926122f3e6SDimitry Andric assert(isInlineAsm() && "Expected an inline asm instruction"); 11936122f3e6SDimitry Andric assert(OpIdx < getNumOperands() && "OpIdx out of range"); 11946122f3e6SDimitry Andric 11956122f3e6SDimitry Andric // Ignore queries about the initial operands. 11966122f3e6SDimitry Andric if (OpIdx < InlineAsm::MIOp_FirstOperand) 11976122f3e6SDimitry Andric return -1; 11986122f3e6SDimitry Andric 11996122f3e6SDimitry Andric unsigned Group = 0; 12006122f3e6SDimitry Andric unsigned NumOps; 12016122f3e6SDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 12026122f3e6SDimitry Andric i += NumOps) { 12036122f3e6SDimitry Andric const MachineOperand &FlagMO = getOperand(i); 12046122f3e6SDimitry Andric // If we reach the implicit register operands, stop looking. 12056122f3e6SDimitry Andric if (!FlagMO.isImm()) 12066122f3e6SDimitry Andric return -1; 12076122f3e6SDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 12086122f3e6SDimitry Andric if (i + NumOps > OpIdx) { 12096122f3e6SDimitry Andric if (GroupNo) 12106122f3e6SDimitry Andric *GroupNo = Group; 12116122f3e6SDimitry Andric return i; 12126122f3e6SDimitry Andric } 12136122f3e6SDimitry Andric ++Group; 12146122f3e6SDimitry Andric } 12156122f3e6SDimitry Andric return -1; 12166122f3e6SDimitry Andric } 12176122f3e6SDimitry Andric 12183ca95b02SDimitry Andric const DILocalVariable *MachineInstr::getDebugVariable() const { 12193ca95b02SDimitry Andric assert(isDebugValue() && "not a DBG_VALUE"); 12203ca95b02SDimitry Andric return cast<DILocalVariable>(getOperand(2).getMetadata()); 12213ca95b02SDimitry Andric } 12223ca95b02SDimitry Andric 12233ca95b02SDimitry Andric const DIExpression *MachineInstr::getDebugExpression() const { 12243ca95b02SDimitry Andric assert(isDebugValue() && "not a DBG_VALUE"); 12253ca95b02SDimitry Andric return cast<DIExpression>(getOperand(3).getMetadata()); 12263ca95b02SDimitry Andric } 12273ca95b02SDimitry Andric 12286122f3e6SDimitry Andric const TargetRegisterClass* 12296122f3e6SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx, 12306122f3e6SDimitry Andric const TargetInstrInfo *TII, 12316122f3e6SDimitry Andric const TargetRegisterInfo *TRI) const { 12327ae0e2c9SDimitry Andric assert(getParent() && "Can't have an MBB reference here!"); 12337ae0e2c9SDimitry Andric assert(getParent()->getParent() && "Can't have an MF reference here!"); 12347ae0e2c9SDimitry Andric const MachineFunction &MF = *getParent()->getParent(); 12357ae0e2c9SDimitry Andric 12366122f3e6SDimitry Andric // Most opcodes have fixed constraints in their MCInstrDesc. 12376122f3e6SDimitry Andric if (!isInlineAsm()) 12387ae0e2c9SDimitry Andric return TII->getRegClass(getDesc(), OpIdx, TRI, MF); 12396122f3e6SDimitry Andric 12406122f3e6SDimitry Andric if (!getOperand(OpIdx).isReg()) 124191bc56edSDimitry Andric return nullptr; 12426122f3e6SDimitry Andric 12436122f3e6SDimitry Andric // For tied uses on inline asm, get the constraint from the def. 12446122f3e6SDimitry Andric unsigned DefIdx; 12456122f3e6SDimitry Andric if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx)) 12466122f3e6SDimitry Andric OpIdx = DefIdx; 12476122f3e6SDimitry Andric 12486122f3e6SDimitry Andric // Inline asm stores register class constraints in the flag word. 12496122f3e6SDimitry Andric int FlagIdx = findInlineAsmFlagIdx(OpIdx); 12506122f3e6SDimitry Andric if (FlagIdx < 0) 125191bc56edSDimitry Andric return nullptr; 12526122f3e6SDimitry Andric 12536122f3e6SDimitry Andric unsigned Flag = getOperand(FlagIdx).getImm(); 12546122f3e6SDimitry Andric unsigned RCID; 12553ca95b02SDimitry Andric if ((InlineAsm::getKind(Flag) == InlineAsm::Kind_RegUse || 12563ca95b02SDimitry Andric InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDef || 12573ca95b02SDimitry Andric InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDefEarlyClobber) && 12583ca95b02SDimitry Andric InlineAsm::hasRegClassConstraint(Flag, RCID)) 12596122f3e6SDimitry Andric return TRI->getRegClass(RCID); 12606122f3e6SDimitry Andric 12616122f3e6SDimitry Andric // Assume that all registers in a memory operand are pointers. 12626122f3e6SDimitry Andric if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem) 12637ae0e2c9SDimitry Andric return TRI->getPointerRegClass(MF); 12646122f3e6SDimitry Andric 126591bc56edSDimitry Andric return nullptr; 126691bc56edSDimitry Andric } 126791bc56edSDimitry Andric 126891bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( 126991bc56edSDimitry Andric unsigned Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, 127091bc56edSDimitry Andric const TargetRegisterInfo *TRI, bool ExploreBundle) const { 127191bc56edSDimitry Andric // Check every operands inside the bundle if we have 127291bc56edSDimitry Andric // been asked to. 127391bc56edSDimitry Andric if (ExploreBundle) 12743ca95b02SDimitry Andric for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC; 127591bc56edSDimitry Andric ++OpndIt) 127691bc56edSDimitry Andric CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl( 127791bc56edSDimitry Andric OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); 127891bc56edSDimitry Andric else 127991bc56edSDimitry Andric // Otherwise, just check the current operands. 128097bc6c73SDimitry Andric for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) 128197bc6c73SDimitry Andric CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); 128291bc56edSDimitry Andric return CurRC; 128391bc56edSDimitry Andric } 128491bc56edSDimitry Andric 128591bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl( 128691bc56edSDimitry Andric unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC, 128791bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 128891bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 128991bc56edSDimitry Andric // Check if Reg is constrained by some of its use/def from MI. 129091bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 129191bc56edSDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 129291bc56edSDimitry Andric return CurRC; 129391bc56edSDimitry Andric // If yes, accumulate the constraints through the operand. 129491bc56edSDimitry Andric return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI); 129591bc56edSDimitry Andric } 129691bc56edSDimitry Andric 129791bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( 129891bc56edSDimitry Andric unsigned OpIdx, const TargetRegisterClass *CurRC, 129991bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 130091bc56edSDimitry Andric const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI); 130191bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 130291bc56edSDimitry Andric assert(MO.isReg() && 130391bc56edSDimitry Andric "Cannot get register constraints for non-register operand"); 130491bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 130591bc56edSDimitry Andric if (unsigned SubIdx = MO.getSubReg()) { 130691bc56edSDimitry Andric if (OpRC) 130791bc56edSDimitry Andric CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx); 130891bc56edSDimitry Andric else 130991bc56edSDimitry Andric CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx); 131091bc56edSDimitry Andric } else if (OpRC) 131191bc56edSDimitry Andric CurRC = TRI->getCommonSubClass(CurRC, OpRC); 131291bc56edSDimitry Andric return CurRC; 13136122f3e6SDimitry Andric } 13146122f3e6SDimitry Andric 1315139f7f9bSDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the 1316139f7f9bSDimitry Andric /// header instruction. 1317dff0c46cSDimitry Andric unsigned MachineInstr::getBundleSize() const { 13187d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I = getIterator(); 1319dff0c46cSDimitry Andric unsigned Size = 0; 13203ca95b02SDimitry Andric while (I->isBundledWithSucc()) { 13213ca95b02SDimitry Andric ++Size; 13223ca95b02SDimitry Andric ++I; 13233ca95b02SDimitry Andric } 1324dff0c46cSDimitry Andric return Size; 1325dff0c46cSDimitry Andric } 1326dff0c46cSDimitry Andric 13273ca95b02SDimitry Andric /// Returns true if the MachineInstr has an implicit-use operand of exactly 13283ca95b02SDimitry Andric /// the given register (not considering sub/super-registers). 13293ca95b02SDimitry Andric bool MachineInstr::hasRegisterImplicitUseOperand(unsigned Reg) const { 13303ca95b02SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 13313ca95b02SDimitry Andric const MachineOperand &MO = getOperand(i); 13323ca95b02SDimitry Andric if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == Reg) 13333ca95b02SDimitry Andric return true; 13343ca95b02SDimitry Andric } 13353ca95b02SDimitry Andric return false; 13363ca95b02SDimitry Andric } 13373ca95b02SDimitry Andric 1338f22ef01cSRoman Divacky /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of 1339f22ef01cSRoman Divacky /// the specific register or -1 if it is not found. It further tightens 1340f22ef01cSRoman Divacky /// the search criteria to a use that kills the register if isKill is true. 1341d88c1a5aSDimitry Andric int MachineInstr::findRegisterUseOperandIdx( 1342d88c1a5aSDimitry Andric unsigned Reg, bool isKill, const TargetRegisterInfo *TRI) const { 1343f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1344f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1345f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse()) 1346f22ef01cSRoman Divacky continue; 1347f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1348f22ef01cSRoman Divacky if (!MOReg) 1349f22ef01cSRoman Divacky continue; 1350d88c1a5aSDimitry Andric if (MOReg == Reg || (TRI && TargetRegisterInfo::isPhysicalRegister(MOReg) && 1351f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg) && 1352f22ef01cSRoman Divacky TRI->isSubRegister(MOReg, Reg))) 1353f22ef01cSRoman Divacky if (!isKill || MO.isKill()) 1354f22ef01cSRoman Divacky return i; 1355f22ef01cSRoman Divacky } 1356f22ef01cSRoman Divacky return -1; 1357f22ef01cSRoman Divacky } 1358f22ef01cSRoman Divacky 1359f22ef01cSRoman Divacky /// readsWritesVirtualRegister - Return a pair of bools (reads, writes) 1360f22ef01cSRoman Divacky /// indicating if this instruction reads or writes Reg. This also considers 1361f22ef01cSRoman Divacky /// partial defines. 1362f22ef01cSRoman Divacky std::pair<bool,bool> 1363f22ef01cSRoman Divacky MachineInstr::readsWritesVirtualRegister(unsigned Reg, 1364f22ef01cSRoman Divacky SmallVectorImpl<unsigned> *Ops) const { 1365f22ef01cSRoman Divacky bool PartDef = false; // Partial redefine. 1366f22ef01cSRoman Divacky bool FullDef = false; // Full define. 1367f22ef01cSRoman Divacky bool Use = false; 1368f22ef01cSRoman Divacky 1369f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1370f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1371f22ef01cSRoman Divacky if (!MO.isReg() || MO.getReg() != Reg) 1372f22ef01cSRoman Divacky continue; 1373f22ef01cSRoman Divacky if (Ops) 1374f22ef01cSRoman Divacky Ops->push_back(i); 1375f22ef01cSRoman Divacky if (MO.isUse()) 1376f22ef01cSRoman Divacky Use |= !MO.isUndef(); 13776122f3e6SDimitry Andric else if (MO.getSubReg() && !MO.isUndef()) 13786122f3e6SDimitry Andric // A partial <def,undef> doesn't count as reading the register. 1379f22ef01cSRoman Divacky PartDef = true; 1380f22ef01cSRoman Divacky else 1381f22ef01cSRoman Divacky FullDef = true; 1382f22ef01cSRoman Divacky } 1383f22ef01cSRoman Divacky // A partial redefine uses Reg unless there is also a full define. 1384f22ef01cSRoman Divacky return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef); 1385f22ef01cSRoman Divacky } 1386f22ef01cSRoman Divacky 1387f22ef01cSRoman Divacky /// findRegisterDefOperandIdx() - Returns the operand index that is a def of 1388f22ef01cSRoman Divacky /// the specified register or -1 if it is not found. If isDead is true, defs 1389f22ef01cSRoman Divacky /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it 1390f22ef01cSRoman Divacky /// also checks if there is a def of a super-register. 1391f22ef01cSRoman Divacky int 1392f22ef01cSRoman Divacky MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap, 1393f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 1394f22ef01cSRoman Divacky bool isPhys = TargetRegisterInfo::isPhysicalRegister(Reg); 1395f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1396f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1397dff0c46cSDimitry Andric // Accept regmask operands when Overlap is set. 1398dff0c46cSDimitry Andric // Ignore them when looking for a specific def operand (Overlap == false). 1399dff0c46cSDimitry Andric if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg)) 1400dff0c46cSDimitry Andric return i; 1401f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 1402f22ef01cSRoman Divacky continue; 1403f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1404f22ef01cSRoman Divacky bool Found = (MOReg == Reg); 1405f22ef01cSRoman Divacky if (!Found && TRI && isPhys && 1406f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg)) { 1407f22ef01cSRoman Divacky if (Overlap) 1408f22ef01cSRoman Divacky Found = TRI->regsOverlap(MOReg, Reg); 1409f22ef01cSRoman Divacky else 1410f22ef01cSRoman Divacky Found = TRI->isSubRegister(MOReg, Reg); 1411f22ef01cSRoman Divacky } 1412f22ef01cSRoman Divacky if (Found && (!isDead || MO.isDead())) 1413f22ef01cSRoman Divacky return i; 1414f22ef01cSRoman Divacky } 1415f22ef01cSRoman Divacky return -1; 1416f22ef01cSRoman Divacky } 1417f22ef01cSRoman Divacky 1418f22ef01cSRoman Divacky /// findFirstPredOperandIdx() - Find the index of the first operand in the 1419f22ef01cSRoman Divacky /// operand list that is used to represent the predicate. It returns -1 if 1420f22ef01cSRoman Divacky /// none is found. 1421f22ef01cSRoman Divacky int MachineInstr::findFirstPredOperandIdx() const { 14226122f3e6SDimitry Andric // Don't call MCID.findFirstPredOperandIdx() because this variant 14236122f3e6SDimitry Andric // is sometimes called on an instruction that's not yet complete, and 14246122f3e6SDimitry Andric // so the number of operands is less than the MCID indicates. In 14256122f3e6SDimitry Andric // particular, the PTX target does this. 142617a519f9SDimitry Andric const MCInstrDesc &MCID = getDesc(); 142717a519f9SDimitry Andric if (MCID.isPredicable()) { 1428f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 142917a519f9SDimitry Andric if (MCID.OpInfo[i].isPredicate()) 1430f22ef01cSRoman Divacky return i; 1431f22ef01cSRoman Divacky } 1432f22ef01cSRoman Divacky 1433f22ef01cSRoman Divacky return -1; 1434f22ef01cSRoman Divacky } 1435f22ef01cSRoman Divacky 14363861d79fSDimitry Andric // MachineOperand::TiedTo is 4 bits wide. 14373861d79fSDimitry Andric const unsigned TiedMax = 15; 14386122f3e6SDimitry Andric 14393861d79fSDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other. 14403861d79fSDimitry Andric /// 14413861d79fSDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo 14423861d79fSDimitry Andric /// field. TiedTo can have these values: 14433861d79fSDimitry Andric /// 14443861d79fSDimitry Andric /// 0: Operand is not tied to anything. 14453861d79fSDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1). 14463861d79fSDimitry Andric /// TiedMax: Tied to an operand >= TiedMax-1. 14473861d79fSDimitry Andric /// 14483861d79fSDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal 14493861d79fSDimitry Andric /// instruction. INLINEASM instructions allow more tied defs. 14503861d79fSDimitry Andric /// 14513861d79fSDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) { 14523861d79fSDimitry Andric MachineOperand &DefMO = getOperand(DefIdx); 14533861d79fSDimitry Andric MachineOperand &UseMO = getOperand(UseIdx); 14543861d79fSDimitry Andric assert(DefMO.isDef() && "DefIdx must be a def operand"); 14553861d79fSDimitry Andric assert(UseMO.isUse() && "UseIdx must be a use operand"); 14563861d79fSDimitry Andric assert(!DefMO.isTied() && "Def is already tied to another use"); 14573861d79fSDimitry Andric assert(!UseMO.isTied() && "Use is already tied to another def"); 14586122f3e6SDimitry Andric 14593861d79fSDimitry Andric if (DefIdx < TiedMax) 14603861d79fSDimitry Andric UseMO.TiedTo = DefIdx + 1; 14613861d79fSDimitry Andric else { 14623861d79fSDimitry Andric // Inline asm can use the group descriptors to find tied operands, but on 14633861d79fSDimitry Andric // normal instruction, the tied def must be within the first TiedMax 14643861d79fSDimitry Andric // operands. 14653861d79fSDimitry Andric assert(isInlineAsm() && "DefIdx out of range"); 14663861d79fSDimitry Andric UseMO.TiedTo = TiedMax; 14673861d79fSDimitry Andric } 14683861d79fSDimitry Andric 14693861d79fSDimitry Andric // UseIdx can be out of range, we'll search for it in findTiedOperandIdx(). 14703861d79fSDimitry Andric DefMO.TiedTo = std::min(UseIdx + 1, TiedMax); 14713861d79fSDimitry Andric } 14723861d79fSDimitry Andric 14733861d79fSDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to. 14743861d79fSDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand 14753861d79fSDimitry Andric /// which must exist. 14763861d79fSDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const { 14773861d79fSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 14783861d79fSDimitry Andric assert(MO.isTied() && "Operand isn't tied"); 14793861d79fSDimitry Andric 14803861d79fSDimitry Andric // Normally TiedTo is in range. 14813861d79fSDimitry Andric if (MO.TiedTo < TiedMax) 14823861d79fSDimitry Andric return MO.TiedTo - 1; 14833861d79fSDimitry Andric 14843861d79fSDimitry Andric // Uses on normal instructions can be out of range. 14853861d79fSDimitry Andric if (!isInlineAsm()) { 14863861d79fSDimitry Andric // Normal tied defs must be in the 0..TiedMax-1 range. 14873861d79fSDimitry Andric if (MO.isUse()) 14883861d79fSDimitry Andric return TiedMax - 1; 14893861d79fSDimitry Andric // MO is a def. Search for the tied use. 14903861d79fSDimitry Andric for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) { 14913861d79fSDimitry Andric const MachineOperand &UseMO = getOperand(i); 14923861d79fSDimitry Andric if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1) 14933861d79fSDimitry Andric return i; 14943861d79fSDimitry Andric } 14953861d79fSDimitry Andric llvm_unreachable("Can't find tied use"); 14963861d79fSDimitry Andric } 14973861d79fSDimitry Andric 14983861d79fSDimitry Andric // Now deal with inline asm by parsing the operand group descriptor flags. 14993861d79fSDimitry Andric // Find the beginning of each operand group. 15003861d79fSDimitry Andric SmallVector<unsigned, 8> GroupIdx; 15013861d79fSDimitry Andric unsigned OpIdxGroup = ~0u; 15023861d79fSDimitry Andric unsigned NumOps; 15033861d79fSDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 15043861d79fSDimitry Andric i += NumOps) { 15053861d79fSDimitry Andric const MachineOperand &FlagMO = getOperand(i); 15063861d79fSDimitry Andric assert(FlagMO.isImm() && "Invalid tied operand on inline asm"); 15073861d79fSDimitry Andric unsigned CurGroup = GroupIdx.size(); 15083861d79fSDimitry Andric GroupIdx.push_back(i); 15093861d79fSDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 15103861d79fSDimitry Andric // OpIdx belongs to this operand group. 15113861d79fSDimitry Andric if (OpIdx > i && OpIdx < i + NumOps) 15123861d79fSDimitry Andric OpIdxGroup = CurGroup; 15133861d79fSDimitry Andric unsigned TiedGroup; 15143861d79fSDimitry Andric if (!InlineAsm::isUseOperandTiedToDef(FlagMO.getImm(), TiedGroup)) 1515f22ef01cSRoman Divacky continue; 15163861d79fSDimitry Andric // Operands in this group are tied to operands in TiedGroup which must be 15173861d79fSDimitry Andric // earlier. Find the number of operands between the two groups. 15183861d79fSDimitry Andric unsigned Delta = i - GroupIdx[TiedGroup]; 1519f22ef01cSRoman Divacky 15203861d79fSDimitry Andric // OpIdx is a use tied to TiedGroup. 15213861d79fSDimitry Andric if (OpIdxGroup == CurGroup) 15223861d79fSDimitry Andric return OpIdx - Delta; 1523f22ef01cSRoman Divacky 15243861d79fSDimitry Andric // OpIdx is a def tied to this use group. 15253861d79fSDimitry Andric if (OpIdxGroup == TiedGroup) 15263861d79fSDimitry Andric return OpIdx + Delta; 1527f22ef01cSRoman Divacky } 15283861d79fSDimitry Andric llvm_unreachable("Invalid tied operand on inline asm"); 1529f22ef01cSRoman Divacky } 1530f22ef01cSRoman Divacky 1531f22ef01cSRoman Divacky /// clearKillInfo - Clears kill flags on all operands. 1532f22ef01cSRoman Divacky /// 1533f22ef01cSRoman Divacky void MachineInstr::clearKillInfo() { 1534ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1535f22ef01cSRoman Divacky if (MO.isReg() && MO.isUse()) 1536f22ef01cSRoman Divacky MO.setIsKill(false); 1537f22ef01cSRoman Divacky } 1538f22ef01cSRoman Divacky } 1539f22ef01cSRoman Divacky 1540ffd1746dSEd Schouten void MachineInstr::substituteRegister(unsigned FromReg, 1541ffd1746dSEd Schouten unsigned ToReg, 1542ffd1746dSEd Schouten unsigned SubIdx, 1543ffd1746dSEd Schouten const TargetRegisterInfo &RegInfo) { 1544ffd1746dSEd Schouten if (TargetRegisterInfo::isPhysicalRegister(ToReg)) { 1545ffd1746dSEd Schouten if (SubIdx) 1546ffd1746dSEd Schouten ToReg = RegInfo.getSubReg(ToReg, SubIdx); 1547ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1548ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1549ffd1746dSEd Schouten continue; 1550ffd1746dSEd Schouten MO.substPhysReg(ToReg, RegInfo); 1551ffd1746dSEd Schouten } 1552ffd1746dSEd Schouten } else { 1553ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1554ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1555ffd1746dSEd Schouten continue; 1556ffd1746dSEd Schouten MO.substVirtReg(ToReg, SubIdx, RegInfo); 1557ffd1746dSEd Schouten } 1558ffd1746dSEd Schouten } 1559ffd1746dSEd Schouten } 1560ffd1746dSEd Schouten 1561f22ef01cSRoman Divacky /// isSafeToMove - Return true if it is safe to move this instruction. If 1562f22ef01cSRoman Divacky /// SawStore is set to true, it means that there is a store (or call) between 1563f22ef01cSRoman Divacky /// the instruction's location and its intended destination. 1564ff0cc061SDimitry Andric bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const { 1565f22ef01cSRoman Divacky // Ignore stuff that we obviously can't move. 15663861d79fSDimitry Andric // 15673861d79fSDimitry Andric // Treat volatile loads as stores. This is not strictly necessary for 15683861d79fSDimitry Andric // volatiles, but it is required for atomic loads. It is not allowed to move 15693861d79fSDimitry Andric // a load across an atomic load with Ordering > Monotonic. 15703861d79fSDimitry Andric if (mayStore() || isCall() || 15713861d79fSDimitry Andric (mayLoad() && hasOrderedMemoryRef())) { 1572f22ef01cSRoman Divacky SawStore = true; 1573f22ef01cSRoman Divacky return false; 1574f22ef01cSRoman Divacky } 15752754fe60SDimitry Andric 157691bc56edSDimitry Andric if (isPosition() || isDebugValue() || isTerminator() || 157791bc56edSDimitry Andric hasUnmodeledSideEffects()) 1578f22ef01cSRoman Divacky return false; 1579f22ef01cSRoman Divacky 1580f22ef01cSRoman Divacky // See if this instruction does a load. If so, we have to guarantee that the 1581f22ef01cSRoman Divacky // loaded value doesn't change between the load and the its intended 1582f22ef01cSRoman Divacky // destination. The check for isInvariantLoad gives the targe the chance to 1583f22ef01cSRoman Divacky // classify the load as always returning a constant, e.g. a constant pool 1584f22ef01cSRoman Divacky // load. 1585d88c1a5aSDimitry Andric if (mayLoad() && !isDereferenceableInvariantLoad(AA)) 1586f22ef01cSRoman Divacky // Otherwise, this is a real load. If there is a store between the load and 15873861d79fSDimitry Andric // end of block, we can't move it. 15883861d79fSDimitry Andric return !SawStore; 1589f22ef01cSRoman Divacky 1590f22ef01cSRoman Divacky return true; 1591f22ef01cSRoman Divacky } 1592f22ef01cSRoman Divacky 15937a7e6055SDimitry Andric bool MachineInstr::mayAlias(AliasAnalysis *AA, MachineInstr &Other, 15947a7e6055SDimitry Andric bool UseTBAA) { 15957a7e6055SDimitry Andric const MachineFunction *MF = getParent()->getParent(); 15967a7e6055SDimitry Andric const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 15977a7e6055SDimitry Andric 15987a7e6055SDimitry Andric // If neither instruction stores to memory, they can't alias in any 15997a7e6055SDimitry Andric // meaningful way, even if they read from the same address. 16007a7e6055SDimitry Andric if (!mayStore() && !Other.mayStore()) 16017a7e6055SDimitry Andric return false; 16027a7e6055SDimitry Andric 16037a7e6055SDimitry Andric // Let the target decide if memory accesses cannot possibly overlap. 16047a7e6055SDimitry Andric if (TII->areMemAccessesTriviallyDisjoint(*this, Other, AA)) 16057a7e6055SDimitry Andric return false; 16067a7e6055SDimitry Andric 16077a7e6055SDimitry Andric if (!AA) 16087a7e6055SDimitry Andric return true; 16097a7e6055SDimitry Andric 16107a7e6055SDimitry Andric // FIXME: Need to handle multiple memory operands to support all targets. 16117a7e6055SDimitry Andric if (!hasOneMemOperand() || !Other.hasOneMemOperand()) 16127a7e6055SDimitry Andric return true; 16137a7e6055SDimitry Andric 16147a7e6055SDimitry Andric MachineMemOperand *MMOa = *memoperands_begin(); 16157a7e6055SDimitry Andric MachineMemOperand *MMOb = *Other.memoperands_begin(); 16167a7e6055SDimitry Andric 16177a7e6055SDimitry Andric if (!MMOa->getValue() || !MMOb->getValue()) 16187a7e6055SDimitry Andric return true; 16197a7e6055SDimitry Andric 16207a7e6055SDimitry Andric // The following interface to AA is fashioned after DAGCombiner::isAlias 16217a7e6055SDimitry Andric // and operates with MachineMemOperand offset with some important 16227a7e6055SDimitry Andric // assumptions: 16237a7e6055SDimitry Andric // - LLVM fundamentally assumes flat address spaces. 16247a7e6055SDimitry Andric // - MachineOperand offset can *only* result from legalization and 16257a7e6055SDimitry Andric // cannot affect queries other than the trivial case of overlap 16267a7e6055SDimitry Andric // checking. 16277a7e6055SDimitry Andric // - These offsets never wrap and never step outside 16287a7e6055SDimitry Andric // of allocated objects. 16297a7e6055SDimitry Andric // - There should never be any negative offsets here. 16307a7e6055SDimitry Andric // 16317a7e6055SDimitry Andric // FIXME: Modify API to hide this math from "user" 16327a7e6055SDimitry Andric // FIXME: Even before we go to AA we can reason locally about some 16337a7e6055SDimitry Andric // memory objects. It can save compile time, and possibly catch some 16347a7e6055SDimitry Andric // corner cases not currently covered. 16357a7e6055SDimitry Andric 16367a7e6055SDimitry Andric assert ((MMOa->getOffset() >= 0) && "Negative MachineMemOperand offset"); 16377a7e6055SDimitry Andric assert ((MMOb->getOffset() >= 0) && "Negative MachineMemOperand offset"); 16387a7e6055SDimitry Andric 16397a7e6055SDimitry Andric int64_t MinOffset = std::min(MMOa->getOffset(), MMOb->getOffset()); 16407a7e6055SDimitry Andric int64_t Overlapa = MMOa->getSize() + MMOa->getOffset() - MinOffset; 16417a7e6055SDimitry Andric int64_t Overlapb = MMOb->getSize() + MMOb->getOffset() - MinOffset; 16427a7e6055SDimitry Andric 16437a7e6055SDimitry Andric AliasResult AAResult = 16447a7e6055SDimitry Andric AA->alias(MemoryLocation(MMOa->getValue(), Overlapa, 16457a7e6055SDimitry Andric UseTBAA ? MMOa->getAAInfo() : AAMDNodes()), 16467a7e6055SDimitry Andric MemoryLocation(MMOb->getValue(), Overlapb, 16477a7e6055SDimitry Andric UseTBAA ? MMOb->getAAInfo() : AAMDNodes())); 16487a7e6055SDimitry Andric 16497a7e6055SDimitry Andric return (AAResult != NoAlias); 16507a7e6055SDimitry Andric } 16517a7e6055SDimitry Andric 16523861d79fSDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered 16533861d79fSDimitry Andric /// or volatile memory reference, or if the information describing the memory 16543861d79fSDimitry Andric /// reference is not available. Return false if it is known to have no ordered 16553861d79fSDimitry Andric /// memory references. 16563861d79fSDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const { 1657f22ef01cSRoman Divacky // An instruction known never to access memory won't have a volatile access. 1658dff0c46cSDimitry Andric if (!mayStore() && 1659dff0c46cSDimitry Andric !mayLoad() && 1660dff0c46cSDimitry Andric !isCall() && 16612754fe60SDimitry Andric !hasUnmodeledSideEffects()) 1662f22ef01cSRoman Divacky return false; 1663f22ef01cSRoman Divacky 1664f22ef01cSRoman Divacky // Otherwise, if the instruction has no memory reference information, 1665f22ef01cSRoman Divacky // conservatively assume it wasn't preserved. 1666f22ef01cSRoman Divacky if (memoperands_empty()) 1667f22ef01cSRoman Divacky return true; 1668f22ef01cSRoman Divacky 16693ca95b02SDimitry Andric // Check if any of our memory operands are ordered. 16703ca95b02SDimitry Andric return any_of(memoperands(), [](const MachineMemOperand *MMO) { 16713ca95b02SDimitry Andric return !MMO->isUnordered(); 16723ca95b02SDimitry Andric }); 1673f22ef01cSRoman Divacky } 1674f22ef01cSRoman Divacky 1675d88c1a5aSDimitry Andric /// isDereferenceableInvariantLoad - Return true if this instruction will never 1676d88c1a5aSDimitry Andric /// trap and is loading from a location whose value is invariant across a run of 1677d88c1a5aSDimitry Andric /// this function. 1678d88c1a5aSDimitry Andric bool MachineInstr::isDereferenceableInvariantLoad(AliasAnalysis *AA) const { 1679f22ef01cSRoman Divacky // If the instruction doesn't load at all, it isn't an invariant load. 1680dff0c46cSDimitry Andric if (!mayLoad()) 1681f22ef01cSRoman Divacky return false; 1682f22ef01cSRoman Divacky 1683f22ef01cSRoman Divacky // If the instruction has lost its memoperands, conservatively assume that 1684f22ef01cSRoman Divacky // it may not be an invariant load. 1685f22ef01cSRoman Divacky if (memoperands_empty()) 1686f22ef01cSRoman Divacky return false; 1687f22ef01cSRoman Divacky 1688d88c1a5aSDimitry Andric const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo(); 1689f22ef01cSRoman Divacky 16903ca95b02SDimitry Andric for (MachineMemOperand *MMO : memoperands()) { 16913ca95b02SDimitry Andric if (MMO->isVolatile()) return false; 16923ca95b02SDimitry Andric if (MMO->isStore()) return false; 1693d88c1a5aSDimitry Andric if (MMO->isInvariant() && MMO->isDereferenceable()) 1694d88c1a5aSDimitry Andric continue; 169591bc56edSDimitry Andric 1696f22ef01cSRoman Divacky // A load from a constant PseudoSourceValue is invariant. 16973ca95b02SDimitry Andric if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) 1698d88c1a5aSDimitry Andric if (PSV->isConstant(&MFI)) 1699f22ef01cSRoman Divacky continue; 170091bc56edSDimitry Andric 17013ca95b02SDimitry Andric if (const Value *V = MMO->getValue()) { 1702f22ef01cSRoman Divacky // If we have an AliasAnalysis, ask it whether the memory is constant. 17038f0fd8f6SDimitry Andric if (AA && 17048f0fd8f6SDimitry Andric AA->pointsToConstantMemory( 17053ca95b02SDimitry Andric MemoryLocation(V, MMO->getSize(), MMO->getAAInfo()))) 1706f22ef01cSRoman Divacky continue; 1707f22ef01cSRoman Divacky } 1708f22ef01cSRoman Divacky 1709f22ef01cSRoman Divacky // Otherwise assume conservatively. 1710f22ef01cSRoman Divacky return false; 1711f22ef01cSRoman Divacky } 1712f22ef01cSRoman Divacky 1713f22ef01cSRoman Divacky // Everything checks out. 1714f22ef01cSRoman Divacky return true; 1715f22ef01cSRoman Divacky } 1716f22ef01cSRoman Divacky 1717f22ef01cSRoman Divacky /// isConstantValuePHI - If the specified instruction is a PHI that always 1718f22ef01cSRoman Divacky /// merges together the same virtual register, return the register, otherwise 1719f22ef01cSRoman Divacky /// return 0. 1720f22ef01cSRoman Divacky unsigned MachineInstr::isConstantValuePHI() const { 1721f22ef01cSRoman Divacky if (!isPHI()) 1722f22ef01cSRoman Divacky return 0; 1723f22ef01cSRoman Divacky assert(getNumOperands() >= 3 && 1724f22ef01cSRoman Divacky "It's illegal to have a PHI without source operands"); 1725f22ef01cSRoman Divacky 1726f22ef01cSRoman Divacky unsigned Reg = getOperand(1).getReg(); 1727f22ef01cSRoman Divacky for (unsigned i = 3, e = getNumOperands(); i < e; i += 2) 1728f22ef01cSRoman Divacky if (getOperand(i).getReg() != Reg) 1729f22ef01cSRoman Divacky return 0; 1730f22ef01cSRoman Divacky return Reg; 1731f22ef01cSRoman Divacky } 1732f22ef01cSRoman Divacky 17332754fe60SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const { 1734dff0c46cSDimitry Andric if (hasProperty(MCID::UnmodeledSideEffects)) 17352754fe60SDimitry Andric return true; 17362754fe60SDimitry Andric if (isInlineAsm()) { 17372754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 17382754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 17392754fe60SDimitry Andric return true; 17402754fe60SDimitry Andric } 17412754fe60SDimitry Andric 17422754fe60SDimitry Andric return false; 17432754fe60SDimitry Andric } 17442754fe60SDimitry Andric 17457d523365SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const { 17467d523365SDimitry Andric return mayStore() || isCall() || hasUnmodeledSideEffects(); 17477d523365SDimitry Andric } 17487d523365SDimitry Andric 1749f22ef01cSRoman Divacky /// allDefsAreDead - Return true if all the defs of this instruction are dead. 1750f22ef01cSRoman Divacky /// 1751f22ef01cSRoman Divacky bool MachineInstr::allDefsAreDead() const { 1752ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 1753f22ef01cSRoman Divacky if (!MO.isReg() || MO.isUse()) 1754f22ef01cSRoman Divacky continue; 1755f22ef01cSRoman Divacky if (!MO.isDead()) 1756f22ef01cSRoman Divacky return false; 1757f22ef01cSRoman Divacky } 1758f22ef01cSRoman Divacky return true; 1759f22ef01cSRoman Divacky } 1760f22ef01cSRoman Divacky 17612754fe60SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified 17622754fe60SDimitry Andric /// instruction to this instruction. 1763139f7f9bSDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF, 17643ca95b02SDimitry Andric const MachineInstr &MI) { 17653ca95b02SDimitry Andric for (unsigned i = MI.getDesc().getNumOperands(), e = MI.getNumOperands(); 17662754fe60SDimitry Andric i != e; ++i) { 17673ca95b02SDimitry Andric const MachineOperand &MO = MI.getOperand(i); 176891bc56edSDimitry Andric if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask()) 1769139f7f9bSDimitry Andric addOperand(MF, MO); 17702754fe60SDimitry Andric } 17712754fe60SDimitry Andric } 17722754fe60SDimitry Andric 17733861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 17747a7e6055SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dump() const { 1775d88c1a5aSDimitry Andric dbgs() << " "; 17767a7e6055SDimitry Andric print(dbgs()); 1777f22ef01cSRoman Divacky } 17787a7e6055SDimitry Andric #endif 1779f22ef01cSRoman Divacky 17807a7e6055SDimitry Andric void MachineInstr::print(raw_ostream &OS, bool SkipOpers, bool SkipDebugLoc, 1781d88c1a5aSDimitry Andric const TargetInstrInfo *TII) const { 17823dac3a9bSDimitry Andric const Module *M = nullptr; 17833dac3a9bSDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 17843dac3a9bSDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 17853dac3a9bSDimitry Andric M = MF->getFunction()->getParent(); 17863dac3a9bSDimitry Andric 17873dac3a9bSDimitry Andric ModuleSlotTracker MST(M); 17887a7e6055SDimitry Andric print(OS, MST, SkipOpers, SkipDebugLoc, TII); 17893dac3a9bSDimitry Andric } 17903dac3a9bSDimitry Andric 17913dac3a9bSDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, 17927a7e6055SDimitry Andric bool SkipOpers, bool SkipDebugLoc, 17937a7e6055SDimitry Andric const TargetInstrInfo *TII) const { 1794ff0cc061SDimitry Andric // We can be a bit tidier if we know the MachineFunction. 179591bc56edSDimitry Andric const MachineFunction *MF = nullptr; 1796ff0cc061SDimitry Andric const TargetRegisterInfo *TRI = nullptr; 179791bc56edSDimitry Andric const MachineRegisterInfo *MRI = nullptr; 1798d88c1a5aSDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo = nullptr; 1799d88c1a5aSDimitry Andric 1800f22ef01cSRoman Divacky if (const MachineBasicBlock *MBB = getParent()) { 1801f22ef01cSRoman Divacky MF = MBB->getParent(); 1802ff0cc061SDimitry Andric if (MF) { 1803e580952dSDimitry Andric MRI = &MF->getRegInfo(); 1804ff0cc061SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo(); 1805d88c1a5aSDimitry Andric if (!TII) 1806ff0cc061SDimitry Andric TII = MF->getSubtarget().getInstrInfo(); 1807d88c1a5aSDimitry Andric IntrinsicInfo = MF->getTarget().getIntrinsicInfo(); 1808ff0cc061SDimitry Andric } 1809f22ef01cSRoman Divacky } 1810f22ef01cSRoman Divacky 1811e580952dSDimitry Andric // Save a list of virtual registers. 1812e580952dSDimitry Andric SmallVector<unsigned, 8> VirtRegs; 1813e580952dSDimitry Andric 1814f22ef01cSRoman Divacky // Print explicitly defined operands on the left of an assignment syntax. 1815f22ef01cSRoman Divacky unsigned StartOp = 0, e = getNumOperands(); 1816f22ef01cSRoman Divacky for (; StartOp < e && getOperand(StartOp).isReg() && 1817f22ef01cSRoman Divacky getOperand(StartOp).isDef() && 1818f22ef01cSRoman Divacky !getOperand(StartOp).isImplicit(); 1819f22ef01cSRoman Divacky ++StartOp) { 1820f22ef01cSRoman Divacky if (StartOp != 0) OS << ", "; 1821d88c1a5aSDimitry Andric getOperand(StartOp).print(OS, MST, TRI, IntrinsicInfo); 1822e580952dSDimitry Andric unsigned Reg = getOperand(StartOp).getReg(); 18233ca95b02SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(Reg)) { 1824e580952dSDimitry Andric VirtRegs.push_back(Reg); 1825d88c1a5aSDimitry Andric LLT Ty = MRI ? MRI->getType(Reg) : LLT{}; 1826d88c1a5aSDimitry Andric if (Ty.isValid()) 1827d88c1a5aSDimitry Andric OS << '(' << Ty << ')'; 18283ca95b02SDimitry Andric } 1829f22ef01cSRoman Divacky } 1830f22ef01cSRoman Divacky 1831f22ef01cSRoman Divacky if (StartOp != 0) 1832f22ef01cSRoman Divacky OS << " = "; 1833f22ef01cSRoman Divacky 1834f22ef01cSRoman Divacky // Print the opcode name. 1835ff0cc061SDimitry Andric if (TII) 1836ff0cc061SDimitry Andric OS << TII->getName(getOpcode()); 1837dff0c46cSDimitry Andric else 1838dff0c46cSDimitry Andric OS << "UNKNOWN"; 1839f22ef01cSRoman Divacky 1840139f7f9bSDimitry Andric if (SkipOpers) 1841139f7f9bSDimitry Andric return; 1842139f7f9bSDimitry Andric 1843f22ef01cSRoman Divacky // Print the rest of the operands. 1844f22ef01cSRoman Divacky bool OmittedAnyCallClobbers = false; 1845f22ef01cSRoman Divacky bool FirstOp = true; 184617a519f9SDimitry Andric unsigned AsmDescOp = ~0u; 184717a519f9SDimitry Andric unsigned AsmOpCount = 0; 18482754fe60SDimitry Andric 18496122f3e6SDimitry Andric if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { 18502754fe60SDimitry Andric // Print asm string. 18512754fe60SDimitry Andric OS << " "; 18523dac3a9bSDimitry Andric getOperand(InlineAsm::MIOp_AsmString).print(OS, MST, TRI); 18532754fe60SDimitry Andric 1854139f7f9bSDimitry Andric // Print HasSideEffects, MayLoad, MayStore, IsAlignStack 18552754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 18562754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 18572754fe60SDimitry Andric OS << " [sideeffect]"; 1858139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayLoad) 1859139f7f9bSDimitry Andric OS << " [mayload]"; 1860139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayStore) 1861139f7f9bSDimitry Andric OS << " [maystore]"; 18623ca95b02SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsConvergent) 18633ca95b02SDimitry Andric OS << " [isconvergent]"; 18642754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 18652754fe60SDimitry Andric OS << " [alignstack]"; 18663861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_ATT) 18673861d79fSDimitry Andric OS << " [attdialect]"; 18683861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_Intel) 18693861d79fSDimitry Andric OS << " [inteldialect]"; 18702754fe60SDimitry Andric 187117a519f9SDimitry Andric StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand; 18722754fe60SDimitry Andric FirstOp = false; 18732754fe60SDimitry Andric } 18742754fe60SDimitry Andric 1875f22ef01cSRoman Divacky for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 1876f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1877f22ef01cSRoman Divacky 18782754fe60SDimitry Andric if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) 1879e580952dSDimitry Andric VirtRegs.push_back(MO.getReg()); 1880e580952dSDimitry Andric 1881f22ef01cSRoman Divacky // Omit call-clobbered registers which aren't used anywhere. This makes 1882f22ef01cSRoman Divacky // call instructions much less noisy on targets where calls clobber lots 1883f22ef01cSRoman Divacky // of registers. Don't rely on MO.isDead() because we may be called before 1884f22ef01cSRoman Divacky // LiveVariables is run, or we may be looking at a non-allocatable reg. 188539d628a0SDimitry Andric if (MRI && isCall() && 1886f22ef01cSRoman Divacky MO.isReg() && MO.isImplicit() && MO.isDef()) { 1887f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 18882754fe60SDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 188939d628a0SDimitry Andric if (MRI->use_empty(Reg)) { 1890f22ef01cSRoman Divacky bool HasAliasLive = false; 1891ff0cc061SDimitry Andric for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { 18927ae0e2c9SDimitry Andric unsigned AliasReg = *AI; 189339d628a0SDimitry Andric if (!MRI->use_empty(AliasReg)) { 1894f22ef01cSRoman Divacky HasAliasLive = true; 1895f22ef01cSRoman Divacky break; 1896f22ef01cSRoman Divacky } 18977ae0e2c9SDimitry Andric } 1898f22ef01cSRoman Divacky if (!HasAliasLive) { 1899f22ef01cSRoman Divacky OmittedAnyCallClobbers = true; 1900f22ef01cSRoman Divacky continue; 1901f22ef01cSRoman Divacky } 1902f22ef01cSRoman Divacky } 1903f22ef01cSRoman Divacky } 1904f22ef01cSRoman Divacky } 1905f22ef01cSRoman Divacky 1906f22ef01cSRoman Divacky if (FirstOp) FirstOp = false; else OS << ","; 1907f22ef01cSRoman Divacky OS << " "; 1908f22ef01cSRoman Divacky if (i < getDesc().NumOperands) { 190917a519f9SDimitry Andric const MCOperandInfo &MCOI = getDesc().OpInfo[i]; 191017a519f9SDimitry Andric if (MCOI.isPredicate()) 1911f22ef01cSRoman Divacky OS << "pred:"; 191217a519f9SDimitry Andric if (MCOI.isOptionalDef()) 1913f22ef01cSRoman Divacky OS << "opt:"; 1914f22ef01cSRoman Divacky } 1915f22ef01cSRoman Divacky if (isDebugValue() && MO.isMetadata()) { 1916f22ef01cSRoman Divacky // Pretty print DBG_VALUE instructions. 1917ff0cc061SDimitry Andric auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata()); 1918ff0cc061SDimitry Andric if (DIV && !DIV->getName().empty()) 1919ff0cc061SDimitry Andric OS << "!\"" << DIV->getName() << '\"'; 1920f22ef01cSRoman Divacky else 19213dac3a9bSDimitry Andric MO.print(OS, MST, TRI); 1922f1a29dd3SDimitry Andric } else if (TRI && (isInsertSubreg() || isRegSequence() || 1923f1a29dd3SDimitry Andric (isSubregToReg() && i == 3)) && MO.isImm()) { 1924ff0cc061SDimitry Andric OS << TRI->getSubRegIndexName(MO.getImm()); 192517a519f9SDimitry Andric } else if (i == AsmDescOp && MO.isImm()) { 192617a519f9SDimitry Andric // Pretty print the inline asm operand descriptor. 192717a519f9SDimitry Andric OS << '$' << AsmOpCount++; 192817a519f9SDimitry Andric unsigned Flag = MO.getImm(); 192917a519f9SDimitry Andric switch (InlineAsm::getKind(Flag)) { 19306122f3e6SDimitry Andric case InlineAsm::Kind_RegUse: OS << ":[reguse"; break; 19316122f3e6SDimitry Andric case InlineAsm::Kind_RegDef: OS << ":[regdef"; break; 19326122f3e6SDimitry Andric case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec"; break; 19336122f3e6SDimitry Andric case InlineAsm::Kind_Clobber: OS << ":[clobber"; break; 19346122f3e6SDimitry Andric case InlineAsm::Kind_Imm: OS << ":[imm"; break; 19356122f3e6SDimitry Andric case InlineAsm::Kind_Mem: OS << ":[mem"; break; 19366122f3e6SDimitry Andric default: OS << ":[??" << InlineAsm::getKind(Flag); break; 19376122f3e6SDimitry Andric } 19386122f3e6SDimitry Andric 19396122f3e6SDimitry Andric unsigned RCID = 0; 19403ca95b02SDimitry Andric if (!InlineAsm::isImmKind(Flag) && !InlineAsm::isMemKind(Flag) && 19413ca95b02SDimitry Andric InlineAsm::hasRegClassConstraint(Flag, RCID)) { 1942ff0cc061SDimitry Andric if (TRI) { 1943ff0cc061SDimitry Andric OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID)); 194439d628a0SDimitry Andric } else 19456122f3e6SDimitry Andric OS << ":RC" << RCID; 194617a519f9SDimitry Andric } 194717a519f9SDimitry Andric 19483ca95b02SDimitry Andric if (InlineAsm::isMemKind(Flag)) { 19493ca95b02SDimitry Andric unsigned MCID = InlineAsm::getMemoryConstraintID(Flag); 19503ca95b02SDimitry Andric switch (MCID) { 19513ca95b02SDimitry Andric case InlineAsm::Constraint_es: OS << ":es"; break; 19523ca95b02SDimitry Andric case InlineAsm::Constraint_i: OS << ":i"; break; 19533ca95b02SDimitry Andric case InlineAsm::Constraint_m: OS << ":m"; break; 19543ca95b02SDimitry Andric case InlineAsm::Constraint_o: OS << ":o"; break; 19553ca95b02SDimitry Andric case InlineAsm::Constraint_v: OS << ":v"; break; 19563ca95b02SDimitry Andric case InlineAsm::Constraint_Q: OS << ":Q"; break; 19573ca95b02SDimitry Andric case InlineAsm::Constraint_R: OS << ":R"; break; 19583ca95b02SDimitry Andric case InlineAsm::Constraint_S: OS << ":S"; break; 19593ca95b02SDimitry Andric case InlineAsm::Constraint_T: OS << ":T"; break; 19603ca95b02SDimitry Andric case InlineAsm::Constraint_Um: OS << ":Um"; break; 19613ca95b02SDimitry Andric case InlineAsm::Constraint_Un: OS << ":Un"; break; 19623ca95b02SDimitry Andric case InlineAsm::Constraint_Uq: OS << ":Uq"; break; 19633ca95b02SDimitry Andric case InlineAsm::Constraint_Us: OS << ":Us"; break; 19643ca95b02SDimitry Andric case InlineAsm::Constraint_Ut: OS << ":Ut"; break; 19653ca95b02SDimitry Andric case InlineAsm::Constraint_Uv: OS << ":Uv"; break; 19663ca95b02SDimitry Andric case InlineAsm::Constraint_Uy: OS << ":Uy"; break; 19673ca95b02SDimitry Andric case InlineAsm::Constraint_X: OS << ":X"; break; 19683ca95b02SDimitry Andric case InlineAsm::Constraint_Z: OS << ":Z"; break; 19693ca95b02SDimitry Andric case InlineAsm::Constraint_ZC: OS << ":ZC"; break; 19703ca95b02SDimitry Andric case InlineAsm::Constraint_Zy: OS << ":Zy"; break; 19713ca95b02SDimitry Andric default: OS << ":?"; break; 19723ca95b02SDimitry Andric } 19733ca95b02SDimitry Andric } 19743ca95b02SDimitry Andric 197517a519f9SDimitry Andric unsigned TiedTo = 0; 197617a519f9SDimitry Andric if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo)) 19776122f3e6SDimitry Andric OS << " tiedto:$" << TiedTo; 19786122f3e6SDimitry Andric 19796122f3e6SDimitry Andric OS << ']'; 198017a519f9SDimitry Andric 198117a519f9SDimitry Andric // Compute the index of the next operand descriptor. 198217a519f9SDimitry Andric AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); 1983f22ef01cSRoman Divacky } else 19843dac3a9bSDimitry Andric MO.print(OS, MST, TRI); 1985f22ef01cSRoman Divacky } 1986f22ef01cSRoman Divacky 1987f22ef01cSRoman Divacky // Briefly indicate whether any call clobbers were omitted. 1988f22ef01cSRoman Divacky if (OmittedAnyCallClobbers) { 1989f22ef01cSRoman Divacky if (!FirstOp) OS << ","; 1990f22ef01cSRoman Divacky OS << " ..."; 1991f22ef01cSRoman Divacky } 1992f22ef01cSRoman Divacky 1993f22ef01cSRoman Divacky bool HaveSemi = false; 19947d523365SDimitry Andric const unsigned PrintableFlags = FrameSetup | FrameDestroy; 1995139f7f9bSDimitry Andric if (Flags & PrintableFlags) { 19964d0b32cdSDimitry Andric if (!HaveSemi) { 19974d0b32cdSDimitry Andric OS << ";"; 19984d0b32cdSDimitry Andric HaveSemi = true; 19994d0b32cdSDimitry Andric } 20003b0f4066SDimitry Andric OS << " flags: "; 20013b0f4066SDimitry Andric 20023b0f4066SDimitry Andric if (Flags & FrameSetup) 20033b0f4066SDimitry Andric OS << "FrameSetup"; 20047d523365SDimitry Andric 20057d523365SDimitry Andric if (Flags & FrameDestroy) 20067d523365SDimitry Andric OS << "FrameDestroy"; 20073b0f4066SDimitry Andric } 20083b0f4066SDimitry Andric 2009f22ef01cSRoman Divacky if (!memoperands_empty()) { 20104d0b32cdSDimitry Andric if (!HaveSemi) { 20114d0b32cdSDimitry Andric OS << ";"; 20124d0b32cdSDimitry Andric HaveSemi = true; 20134d0b32cdSDimitry Andric } 2014f22ef01cSRoman Divacky 2015f22ef01cSRoman Divacky OS << " mem:"; 2016f22ef01cSRoman Divacky for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); 2017f22ef01cSRoman Divacky i != e; ++i) { 20183dac3a9bSDimitry Andric (*i)->print(OS, MST); 201991bc56edSDimitry Andric if (std::next(i) != e) 2020f22ef01cSRoman Divacky OS << " "; 2021f22ef01cSRoman Divacky } 2022f22ef01cSRoman Divacky } 2023f22ef01cSRoman Divacky 2024e580952dSDimitry Andric // Print the regclass of any virtual registers encountered. 2025e580952dSDimitry Andric if (MRI && !VirtRegs.empty()) { 20264d0b32cdSDimitry Andric if (!HaveSemi) { 20274d0b32cdSDimitry Andric OS << ";"; 20284d0b32cdSDimitry Andric HaveSemi = true; 20294d0b32cdSDimitry Andric } 2030e580952dSDimitry Andric for (unsigned i = 0; i != VirtRegs.size(); ++i) { 20313ca95b02SDimitry Andric const RegClassOrRegBank &RC = MRI->getRegClassOrRegBank(VirtRegs[i]); 20323ca95b02SDimitry Andric if (!RC) 20333ca95b02SDimitry Andric continue; 20343ca95b02SDimitry Andric // Generic virtual registers do not have register classes. 20353ca95b02SDimitry Andric if (RC.is<const RegisterBank *>()) 20363ca95b02SDimitry Andric OS << " " << RC.get<const RegisterBank *>()->getName(); 20373ca95b02SDimitry Andric else 20383ca95b02SDimitry Andric OS << " " 20393ca95b02SDimitry Andric << TRI->getRegClassName(RC.get<const TargetRegisterClass *>()); 20403ca95b02SDimitry Andric OS << ':' << PrintReg(VirtRegs[i]); 2041e580952dSDimitry Andric for (unsigned j = i+1; j != VirtRegs.size();) { 20423ca95b02SDimitry Andric if (MRI->getRegClassOrRegBank(VirtRegs[j]) != RC) { 2043e580952dSDimitry Andric ++j; 2044e580952dSDimitry Andric continue; 2045e580952dSDimitry Andric } 2046e580952dSDimitry Andric if (VirtRegs[i] != VirtRegs[j]) 20472754fe60SDimitry Andric OS << "," << PrintReg(VirtRegs[j]); 2048e580952dSDimitry Andric VirtRegs.erase(VirtRegs.begin()+j); 2049e580952dSDimitry Andric } 2050e580952dSDimitry Andric } 2051e580952dSDimitry Andric } 2052e580952dSDimitry Andric 20533b0f4066SDimitry Andric // Print debug location information. 2054ff0cc061SDimitry Andric if (isDebugValue() && getOperand(e - 2).isMetadata()) { 20554d0b32cdSDimitry Andric if (!HaveSemi) 20564d0b32cdSDimitry Andric OS << ";"; 2057ff0cc061SDimitry Andric auto *DV = cast<DILocalVariable>(getOperand(e - 2).getMetadata()); 2058ff0cc061SDimitry Andric OS << " line no:" << DV->getLine(); 2059ff0cc061SDimitry Andric if (auto *InlinedAt = debugLoc->getInlinedAt()) { 2060ff0cc061SDimitry Andric DebugLoc InlinedAtDL(InlinedAt); 2061ff0cc061SDimitry Andric if (InlinedAtDL && MF) { 20626122f3e6SDimitry Andric OS << " inlined @[ "; 2063ff0cc061SDimitry Andric InlinedAtDL.print(OS); 20646122f3e6SDimitry Andric OS << " ]"; 20656122f3e6SDimitry Andric } 20666122f3e6SDimitry Andric } 206739d628a0SDimitry Andric if (isIndirectDebugValue()) 206839d628a0SDimitry Andric OS << " indirect"; 20697a7e6055SDimitry Andric } else if (SkipDebugLoc) { 20707a7e6055SDimitry Andric return; 2071ff0cc061SDimitry Andric } else if (debugLoc && MF) { 20724d0b32cdSDimitry Andric if (!HaveSemi) 20734d0b32cdSDimitry Andric OS << ";"; 2074f22ef01cSRoman Divacky OS << " dbg:"; 2075ff0cc061SDimitry Andric debugLoc.print(OS); 2076f22ef01cSRoman Divacky } 2077f22ef01cSRoman Divacky 20783b0f4066SDimitry Andric OS << '\n'; 2079f22ef01cSRoman Divacky } 2080f22ef01cSRoman Divacky 2081f22ef01cSRoman Divacky bool MachineInstr::addRegisterKilled(unsigned IncomingReg, 2082f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 2083f22ef01cSRoman Divacky bool AddIfNotFound) { 2084f22ef01cSRoman Divacky bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); 20857ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 20867ae0e2c9SDimitry Andric MCRegAliasIterator(IncomingReg, RegInfo, false).isValid(); 2087f22ef01cSRoman Divacky bool Found = false; 2088f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 2089f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 2090f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 2091f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse() || MO.isUndef()) 2092f22ef01cSRoman Divacky continue; 20933ca95b02SDimitry Andric 20943ca95b02SDimitry Andric // DEBUG_VALUE nodes do not contribute to code generation and should 20953ca95b02SDimitry Andric // always be ignored. Failure to do so may result in trying to modify 20963ca95b02SDimitry Andric // KILL flags on DEBUG_VALUE nodes. 20973ca95b02SDimitry Andric if (MO.isDebug()) 20983ca95b02SDimitry Andric continue; 20993ca95b02SDimitry Andric 2100f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 2101f22ef01cSRoman Divacky if (!Reg) 2102f22ef01cSRoman Divacky continue; 2103f22ef01cSRoman Divacky 2104f22ef01cSRoman Divacky if (Reg == IncomingReg) { 2105f22ef01cSRoman Divacky if (!Found) { 2106f22ef01cSRoman Divacky if (MO.isKill()) 2107f22ef01cSRoman Divacky // The register is already marked kill. 2108f22ef01cSRoman Divacky return true; 2109f22ef01cSRoman Divacky if (isPhysReg && isRegTiedToDefOperand(i)) 2110f22ef01cSRoman Divacky // Two-address uses of physregs must not be marked kill. 2111f22ef01cSRoman Divacky return true; 2112f22ef01cSRoman Divacky MO.setIsKill(); 2113f22ef01cSRoman Divacky Found = true; 2114f22ef01cSRoman Divacky } 2115f22ef01cSRoman Divacky } else if (hasAliases && MO.isKill() && 2116f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg)) { 2117f22ef01cSRoman Divacky // A super-register kill already exists. 2118f22ef01cSRoman Divacky if (RegInfo->isSuperRegister(IncomingReg, Reg)) 2119f22ef01cSRoman Divacky return true; 2120f22ef01cSRoman Divacky if (RegInfo->isSubRegister(IncomingReg, Reg)) 2121f22ef01cSRoman Divacky DeadOps.push_back(i); 2122f22ef01cSRoman Divacky } 2123f22ef01cSRoman Divacky } 2124f22ef01cSRoman Divacky 2125f22ef01cSRoman Divacky // Trim unneeded kill operands. 2126f22ef01cSRoman Divacky while (!DeadOps.empty()) { 2127f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 2128f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 2129f22ef01cSRoman Divacky RemoveOperand(OpIdx); 2130f22ef01cSRoman Divacky else 2131f22ef01cSRoman Divacky getOperand(OpIdx).setIsKill(false); 2132f22ef01cSRoman Divacky DeadOps.pop_back(); 2133f22ef01cSRoman Divacky } 2134f22ef01cSRoman Divacky 2135f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is killed. Add a 2136f22ef01cSRoman Divacky // new implicit operand if required. 2137f22ef01cSRoman Divacky if (!Found && AddIfNotFound) { 2138f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(IncomingReg, 2139f22ef01cSRoman Divacky false /*IsDef*/, 2140f22ef01cSRoman Divacky true /*IsImp*/, 2141f22ef01cSRoman Divacky true /*IsKill*/)); 2142f22ef01cSRoman Divacky return true; 2143f22ef01cSRoman Divacky } 2144f22ef01cSRoman Divacky return Found; 2145f22ef01cSRoman Divacky } 2146f22ef01cSRoman Divacky 2147dff0c46cSDimitry Andric void MachineInstr::clearRegisterKills(unsigned Reg, 2148dff0c46cSDimitry Andric const TargetRegisterInfo *RegInfo) { 2149dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) 215091bc56edSDimitry Andric RegInfo = nullptr; 2151ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2152dff0c46cSDimitry Andric if (!MO.isReg() || !MO.isUse() || !MO.isKill()) 2153dff0c46cSDimitry Andric continue; 2154dff0c46cSDimitry Andric unsigned OpReg = MO.getReg(); 21553ca95b02SDimitry Andric if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg) 2156dff0c46cSDimitry Andric MO.setIsKill(false); 2157dff0c46cSDimitry Andric } 2158dff0c46cSDimitry Andric } 2159dff0c46cSDimitry Andric 2160f785676fSDimitry Andric bool MachineInstr::addRegisterDead(unsigned Reg, 2161f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 2162f22ef01cSRoman Divacky bool AddIfNotFound) { 2163f785676fSDimitry Andric bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(Reg); 21647ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 2165f785676fSDimitry Andric MCRegAliasIterator(Reg, RegInfo, false).isValid(); 2166f22ef01cSRoman Divacky bool Found = false; 2167f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 2168f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 2169f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 2170f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 2171f22ef01cSRoman Divacky continue; 2172f785676fSDimitry Andric unsigned MOReg = MO.getReg(); 2173f785676fSDimitry Andric if (!MOReg) 2174f22ef01cSRoman Divacky continue; 2175f22ef01cSRoman Divacky 2176f785676fSDimitry Andric if (MOReg == Reg) { 2177f22ef01cSRoman Divacky MO.setIsDead(); 2178f22ef01cSRoman Divacky Found = true; 2179f22ef01cSRoman Divacky } else if (hasAliases && MO.isDead() && 2180f785676fSDimitry Andric TargetRegisterInfo::isPhysicalRegister(MOReg)) { 2181f22ef01cSRoman Divacky // There exists a super-register that's marked dead. 2182f785676fSDimitry Andric if (RegInfo->isSuperRegister(Reg, MOReg)) 2183f22ef01cSRoman Divacky return true; 2184f785676fSDimitry Andric if (RegInfo->isSubRegister(Reg, MOReg)) 2185f22ef01cSRoman Divacky DeadOps.push_back(i); 2186f22ef01cSRoman Divacky } 2187f22ef01cSRoman Divacky } 2188f22ef01cSRoman Divacky 2189f22ef01cSRoman Divacky // Trim unneeded dead operands. 2190f22ef01cSRoman Divacky while (!DeadOps.empty()) { 2191f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 2192f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 2193f22ef01cSRoman Divacky RemoveOperand(OpIdx); 2194f22ef01cSRoman Divacky else 2195f22ef01cSRoman Divacky getOperand(OpIdx).setIsDead(false); 2196f22ef01cSRoman Divacky DeadOps.pop_back(); 2197f22ef01cSRoman Divacky } 2198f22ef01cSRoman Divacky 2199f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is dead. Add a 2200f22ef01cSRoman Divacky // new implicit operand if required. 2201f22ef01cSRoman Divacky if (Found || !AddIfNotFound) 2202f22ef01cSRoman Divacky return Found; 2203f22ef01cSRoman Divacky 2204f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 2205f22ef01cSRoman Divacky true /*IsDef*/, 2206f22ef01cSRoman Divacky true /*IsImp*/, 2207f22ef01cSRoman Divacky false /*IsKill*/, 2208f22ef01cSRoman Divacky true /*IsDead*/)); 2209f22ef01cSRoman Divacky return true; 2210f22ef01cSRoman Divacky } 2211f22ef01cSRoman Divacky 2212ff0cc061SDimitry Andric void MachineInstr::clearRegisterDeads(unsigned Reg) { 2213ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2214ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg) 2215ff0cc061SDimitry Andric continue; 2216ff0cc061SDimitry Andric MO.setIsDead(false); 2217ff0cc061SDimitry Andric } 2218ff0cc061SDimitry Andric } 2219ff0cc061SDimitry Andric 22207d523365SDimitry Andric void MachineInstr::setRegisterDefReadUndef(unsigned Reg, bool IsUndef) { 2221ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2222ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0) 2223ff0cc061SDimitry Andric continue; 22247d523365SDimitry Andric MO.setIsUndef(IsUndef); 2225ff0cc061SDimitry Andric } 2226ff0cc061SDimitry Andric } 2227ff0cc061SDimitry Andric 2228f785676fSDimitry Andric void MachineInstr::addRegisterDefined(unsigned Reg, 2229f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo) { 2230f785676fSDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 2231f785676fSDimitry Andric MachineOperand *MO = findRegisterDefOperand(Reg, false, RegInfo); 2232f22ef01cSRoman Divacky if (MO) 2233f22ef01cSRoman Divacky return; 2234f22ef01cSRoman Divacky } else { 2235ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 2236f785676fSDimitry Andric if (MO.isReg() && MO.getReg() == Reg && MO.isDef() && 2237f22ef01cSRoman Divacky MO.getSubReg() == 0) 2238f22ef01cSRoman Divacky return; 2239f22ef01cSRoman Divacky } 2240f22ef01cSRoman Divacky } 2241f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 2242f22ef01cSRoman Divacky true /*IsDef*/, 2243f22ef01cSRoman Divacky true /*IsImp*/)); 2244f22ef01cSRoman Divacky } 2245f22ef01cSRoman Divacky 2246dff0c46cSDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs, 2247ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 2248dff0c46cSDimitry Andric bool HasRegMask = false; 2249ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2250dff0c46cSDimitry Andric if (MO.isRegMask()) { 2251dff0c46cSDimitry Andric HasRegMask = true; 2252dff0c46cSDimitry Andric continue; 2253dff0c46cSDimitry Andric } 2254ffd1746dSEd Schouten if (!MO.isReg() || !MO.isDef()) continue; 2255ffd1746dSEd Schouten unsigned Reg = MO.getReg(); 2256dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; 2257ffd1746dSEd Schouten // If there are no uses, including partial uses, the def is dead. 2258d88c1a5aSDimitry Andric if (none_of(UsedRegs, 2259ff0cc061SDimitry Andric [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); })) 2260ff0cc061SDimitry Andric MO.setIsDead(); 2261ffd1746dSEd Schouten } 2262dff0c46cSDimitry Andric 2263dff0c46cSDimitry Andric // This is a call with a register mask operand. 2264dff0c46cSDimitry Andric // Mask clobbers are always dead, so add defs for the non-dead defines. 2265dff0c46cSDimitry Andric if (HasRegMask) 2266dff0c46cSDimitry Andric for (ArrayRef<unsigned>::iterator I = UsedRegs.begin(), E = UsedRegs.end(); 2267dff0c46cSDimitry Andric I != E; ++I) 2268dff0c46cSDimitry Andric addRegisterDefined(*I, &TRI); 2269ffd1746dSEd Schouten } 2270ffd1746dSEd Schouten 2271f22ef01cSRoman Divacky unsigned 2272f22ef01cSRoman Divacky MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { 2273dff0c46cSDimitry Andric // Build up a buffer of hash code components. 2274dff0c46cSDimitry Andric SmallVector<size_t, 8> HashComponents; 2275dff0c46cSDimitry Andric HashComponents.reserve(MI->getNumOperands() + 1); 2276dff0c46cSDimitry Andric HashComponents.push_back(MI->getOpcode()); 2277ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 22787ae0e2c9SDimitry Andric if (MO.isReg() && MO.isDef() && 22797ae0e2c9SDimitry Andric TargetRegisterInfo::isVirtualRegister(MO.getReg())) 2280f22ef01cSRoman Divacky continue; // Skip virtual register defs. 22817ae0e2c9SDimitry Andric 22827ae0e2c9SDimitry Andric HashComponents.push_back(hash_value(MO)); 2283f22ef01cSRoman Divacky } 2284dff0c46cSDimitry Andric return hash_combine_range(HashComponents.begin(), HashComponents.end()); 2285f22ef01cSRoman Divacky } 228617a519f9SDimitry Andric 228717a519f9SDimitry Andric void MachineInstr::emitError(StringRef Msg) const { 228817a519f9SDimitry Andric // Find the source location cookie. 228917a519f9SDimitry Andric unsigned LocCookie = 0; 229091bc56edSDimitry Andric const MDNode *LocMD = nullptr; 229117a519f9SDimitry Andric for (unsigned i = getNumOperands(); i != 0; --i) { 229217a519f9SDimitry Andric if (getOperand(i-1).isMetadata() && 229317a519f9SDimitry Andric (LocMD = getOperand(i-1).getMetadata()) && 229417a519f9SDimitry Andric LocMD->getNumOperands() != 0) { 229539d628a0SDimitry Andric if (const ConstantInt *CI = 229639d628a0SDimitry Andric mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) { 229717a519f9SDimitry Andric LocCookie = CI->getZExtValue(); 229817a519f9SDimitry Andric break; 229917a519f9SDimitry Andric } 230017a519f9SDimitry Andric } 230117a519f9SDimitry Andric } 230217a519f9SDimitry Andric 230317a519f9SDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 230417a519f9SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 230517a519f9SDimitry Andric return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg); 230617a519f9SDimitry Andric report_fatal_error(Msg); 230717a519f9SDimitry Andric } 23083ca95b02SDimitry Andric 23093ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, 23103ca95b02SDimitry Andric const MCInstrDesc &MCID, bool IsIndirect, 23113ca95b02SDimitry Andric unsigned Reg, unsigned Offset, 23123ca95b02SDimitry Andric const MDNode *Variable, const MDNode *Expr) { 23133ca95b02SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 23143ca95b02SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 23153ca95b02SDimitry Andric assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 23163ca95b02SDimitry Andric "Expected inlined-at fields to agree"); 23173ca95b02SDimitry Andric if (IsIndirect) 23183ca95b02SDimitry Andric return BuildMI(MF, DL, MCID) 23193ca95b02SDimitry Andric .addReg(Reg, RegState::Debug) 23203ca95b02SDimitry Andric .addImm(Offset) 23213ca95b02SDimitry Andric .addMetadata(Variable) 23223ca95b02SDimitry Andric .addMetadata(Expr); 23233ca95b02SDimitry Andric else { 23243ca95b02SDimitry Andric assert(Offset == 0 && "A direct address cannot have an offset."); 23253ca95b02SDimitry Andric return BuildMI(MF, DL, MCID) 23263ca95b02SDimitry Andric .addReg(Reg, RegState::Debug) 23273ca95b02SDimitry Andric .addReg(0U, RegState::Debug) 23283ca95b02SDimitry Andric .addMetadata(Variable) 23293ca95b02SDimitry Andric .addMetadata(Expr); 23303ca95b02SDimitry Andric } 23313ca95b02SDimitry Andric } 23323ca95b02SDimitry Andric 23333ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, 23343ca95b02SDimitry Andric MachineBasicBlock::iterator I, 23353ca95b02SDimitry Andric const DebugLoc &DL, const MCInstrDesc &MCID, 23363ca95b02SDimitry Andric bool IsIndirect, unsigned Reg, 23373ca95b02SDimitry Andric unsigned Offset, const MDNode *Variable, 23383ca95b02SDimitry Andric const MDNode *Expr) { 23393ca95b02SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 23403ca95b02SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 23413ca95b02SDimitry Andric MachineFunction &MF = *BB.getParent(); 23423ca95b02SDimitry Andric MachineInstr *MI = 23433ca95b02SDimitry Andric BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr); 23443ca95b02SDimitry Andric BB.insert(I, MI); 23453ca95b02SDimitry Andric return MachineInstrBuilder(MF, MI); 23463ca95b02SDimitry Andric } 23476bc11b14SDimitry Andric 23486bc11b14SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB, 23496bc11b14SDimitry Andric MachineBasicBlock::iterator I, 23506bc11b14SDimitry Andric const MachineInstr &Orig, 23516bc11b14SDimitry Andric int FrameIndex) { 23526bc11b14SDimitry Andric const MDNode *Var = Orig.getDebugVariable(); 2353f37b6182SDimitry Andric const auto *Expr = cast_or_null<DIExpression>(Orig.getDebugExpression()); 23546bc11b14SDimitry Andric bool IsIndirect = Orig.isIndirectDebugValue(); 23556bc11b14SDimitry Andric uint64_t Offset = IsIndirect ? Orig.getOperand(1).getImm() : 0; 23566bc11b14SDimitry Andric DebugLoc DL = Orig.getDebugLoc(); 23576bc11b14SDimitry Andric assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) && 23586bc11b14SDimitry Andric "Expected inlined-at fields to agree"); 23596bc11b14SDimitry Andric // If the DBG_VALUE already was a memory location, add an extra 23606bc11b14SDimitry Andric // DW_OP_deref. Otherwise just turning this from a register into a 23616bc11b14SDimitry Andric // memory/indirect location is sufficient. 2362f37b6182SDimitry Andric if (IsIndirect) 2363f37b6182SDimitry Andric Expr = DIExpression::prepend(Expr, DIExpression::WithDeref); 23646bc11b14SDimitry Andric return BuildMI(BB, I, DL, Orig.getDesc()) 23656bc11b14SDimitry Andric .addFrameIndex(FrameIndex) 23666bc11b14SDimitry Andric .addImm(Offset) 23676bc11b14SDimitry Andric .addMetadata(Var) 23686bc11b14SDimitry Andric .addMetadata(Expr); 23696bc11b14SDimitry Andric } 2370