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: 26591bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 266dff0c46cSDimitry Andric return getRegMask() == Other.getRegMask(); 267f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 268f22ef01cSRoman Divacky return getMCSymbol() == Other.getMCSymbol(); 26991bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 27091bc56edSDimitry Andric return getCFIIndex() == Other.getCFIIndex(); 271f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 272f22ef01cSRoman Divacky return getMetadata() == Other.getMetadata(); 273d88c1a5aSDimitry Andric case MachineOperand::MO_IntrinsicID: 274d88c1a5aSDimitry Andric return getIntrinsicID() == Other.getIntrinsicID(); 275d88c1a5aSDimitry Andric case MachineOperand::MO_Predicate: 276d88c1a5aSDimitry Andric return getPredicate() == Other.getPredicate(); 277f22ef01cSRoman Divacky } 278dff0c46cSDimitry Andric llvm_unreachable("Invalid machine operand type"); 279f22ef01cSRoman Divacky } 280f22ef01cSRoman Divacky 2817ae0e2c9SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above. 2827ae0e2c9SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) { 2837ae0e2c9SDimitry Andric switch (MO.getType()) { 2847ae0e2c9SDimitry Andric case MachineOperand::MO_Register: 2853861d79fSDimitry Andric // Register operands don't have target flags. 2863861d79fSDimitry Andric return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef()); 2877ae0e2c9SDimitry Andric case MachineOperand::MO_Immediate: 2887ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 2897ae0e2c9SDimitry Andric case MachineOperand::MO_CImmediate: 2907ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 2917ae0e2c9SDimitry Andric case MachineOperand::MO_FPImmediate: 2927ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 2937ae0e2c9SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 2947ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 2957ae0e2c9SDimitry Andric case MachineOperand::MO_FrameIndex: 2967ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 2977ae0e2c9SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 2987ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 2997ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 3007ae0e2c9SDimitry Andric MO.getOffset()); 3017ae0e2c9SDimitry Andric case MachineOperand::MO_JumpTableIndex: 3027ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 3037ae0e2c9SDimitry Andric case MachineOperand::MO_ExternalSymbol: 3047ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 3057ae0e2c9SDimitry Andric MO.getSymbolName()); 3067ae0e2c9SDimitry Andric case MachineOperand::MO_GlobalAddress: 3077ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 3087ae0e2c9SDimitry Andric MO.getOffset()); 3097ae0e2c9SDimitry Andric case MachineOperand::MO_BlockAddress: 3107ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), 3113861d79fSDimitry Andric MO.getBlockAddress(), MO.getOffset()); 3127ae0e2c9SDimitry Andric case MachineOperand::MO_RegisterMask: 31391bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 3147ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); 3157ae0e2c9SDimitry Andric case MachineOperand::MO_Metadata: 3167ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 3177ae0e2c9SDimitry Andric case MachineOperand::MO_MCSymbol: 3187ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 31991bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 32091bc56edSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 321d88c1a5aSDimitry Andric case MachineOperand::MO_IntrinsicID: 322d88c1a5aSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); 323d88c1a5aSDimitry Andric case MachineOperand::MO_Predicate: 324d88c1a5aSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); 3257ae0e2c9SDimitry Andric } 3267ae0e2c9SDimitry Andric llvm_unreachable("Invalid machine operand type"); 3277ae0e2c9SDimitry Andric } 3287ae0e2c9SDimitry Andric 329d88c1a5aSDimitry Andric void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, 330d88c1a5aSDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 3313dac3a9bSDimitry Andric ModuleSlotTracker DummyMST(nullptr); 332d88c1a5aSDimitry Andric print(OS, DummyMST, TRI, IntrinsicInfo); 3333dac3a9bSDimitry Andric } 3343dac3a9bSDimitry Andric 3353dac3a9bSDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 336d88c1a5aSDimitry Andric const TargetRegisterInfo *TRI, 337d88c1a5aSDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo) const { 338f22ef01cSRoman Divacky switch (getType()) { 339f22ef01cSRoman Divacky case MachineOperand::MO_Register: 3402754fe60SDimitry Andric OS << PrintReg(getReg(), TRI, getSubReg()); 341f22ef01cSRoman Divacky 342f22ef01cSRoman Divacky if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || 3433861d79fSDimitry Andric isInternalRead() || isEarlyClobber() || isTied()) { 344f22ef01cSRoman Divacky OS << '<'; 345f22ef01cSRoman Divacky bool NeedComma = false; 346f22ef01cSRoman Divacky if (isDef()) { 347f22ef01cSRoman Divacky if (NeedComma) OS << ','; 348f22ef01cSRoman Divacky if (isEarlyClobber()) 349f22ef01cSRoman Divacky OS << "earlyclobber,"; 350f22ef01cSRoman Divacky if (isImplicit()) 351f22ef01cSRoman Divacky OS << "imp-"; 352f22ef01cSRoman Divacky OS << "def"; 353f22ef01cSRoman Divacky NeedComma = true; 3547ae0e2c9SDimitry Andric // <def,read-undef> only makes sense when getSubReg() is set. 3557ae0e2c9SDimitry Andric // Don't clutter the output otherwise. 3567ae0e2c9SDimitry Andric if (isUndef() && getSubReg()) 3577ae0e2c9SDimitry Andric OS << ",read-undef"; 358f22ef01cSRoman Divacky } else if (isImplicit()) { 359f22ef01cSRoman Divacky OS << "imp-use"; 360f22ef01cSRoman Divacky NeedComma = true; 361f22ef01cSRoman Divacky } 362f22ef01cSRoman Divacky 363dff0c46cSDimitry Andric if (isKill()) { 3643861d79fSDimitry Andric if (NeedComma) OS << ','; 365dff0c46cSDimitry Andric OS << "kill"; 366dff0c46cSDimitry Andric NeedComma = true; 367dff0c46cSDimitry Andric } 368dff0c46cSDimitry Andric if (isDead()) { 3693861d79fSDimitry Andric if (NeedComma) OS << ','; 370dff0c46cSDimitry Andric OS << "dead"; 371dff0c46cSDimitry Andric NeedComma = true; 372dff0c46cSDimitry Andric } 3737ae0e2c9SDimitry Andric if (isUndef() && isUse()) { 374dff0c46cSDimitry Andric if (NeedComma) OS << ','; 375f22ef01cSRoman Divacky OS << "undef"; 376dff0c46cSDimitry Andric NeedComma = true; 377dff0c46cSDimitry Andric } 378dff0c46cSDimitry Andric if (isInternalRead()) { 379dff0c46cSDimitry Andric if (NeedComma) OS << ','; 380dff0c46cSDimitry Andric OS << "internal"; 381dff0c46cSDimitry Andric NeedComma = true; 382f22ef01cSRoman Divacky } 3833861d79fSDimitry Andric if (isTied()) { 3843861d79fSDimitry Andric if (NeedComma) OS << ','; 3853861d79fSDimitry Andric OS << "tied"; 3863861d79fSDimitry Andric if (TiedTo != 15) 3873861d79fSDimitry Andric OS << unsigned(TiedTo - 1); 388f22ef01cSRoman Divacky } 389f22ef01cSRoman Divacky OS << '>'; 390f22ef01cSRoman Divacky } 391f22ef01cSRoman Divacky break; 392f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 393f22ef01cSRoman Divacky OS << getImm(); 394f22ef01cSRoman Divacky break; 39517a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 39617a519f9SDimitry Andric getCImm()->getValue().print(OS, false); 39717a519f9SDimitry Andric break; 398f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 3993ca95b02SDimitry Andric if (getFPImm()->getType()->isFloatTy()) { 400f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToFloat(); 4013ca95b02SDimitry Andric } else if (getFPImm()->getType()->isHalfTy()) { 4023ca95b02SDimitry Andric APFloat APF = getFPImm()->getValueAPF(); 4033ca95b02SDimitry Andric bool Unused; 404d88c1a5aSDimitry Andric APF.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &Unused); 4053ca95b02SDimitry Andric OS << "half " << APF.convertToFloat(); 4063ca95b02SDimitry Andric } else { 407f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToDouble(); 4083ca95b02SDimitry Andric } 409f22ef01cSRoman Divacky break; 410f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 411f22ef01cSRoman Divacky OS << "<BB#" << getMBB()->getNumber() << ">"; 412f22ef01cSRoman Divacky break; 413f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 414f22ef01cSRoman Divacky OS << "<fi#" << getIndex() << '>'; 415f22ef01cSRoman Divacky break; 416f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 417f22ef01cSRoman Divacky OS << "<cp#" << getIndex(); 418f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 419f22ef01cSRoman Divacky OS << '>'; 420f22ef01cSRoman Divacky break; 4217ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 4227ae0e2c9SDimitry Andric OS << "<ti#" << getIndex(); 4237ae0e2c9SDimitry Andric if (getOffset()) OS << "+" << getOffset(); 4247ae0e2c9SDimitry Andric OS << '>'; 4257ae0e2c9SDimitry Andric break; 426f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 427f22ef01cSRoman Divacky OS << "<jt#" << getIndex() << '>'; 428f22ef01cSRoman Divacky break; 429f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 430f22ef01cSRoman Divacky OS << "<ga:"; 4313dac3a9bSDimitry Andric getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 432f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 433f22ef01cSRoman Divacky OS << '>'; 434f22ef01cSRoman Divacky break; 435f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 436f22ef01cSRoman Divacky OS << "<es:" << getSymbolName(); 437f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 438f22ef01cSRoman Divacky OS << '>'; 439f22ef01cSRoman Divacky break; 440f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 441f22ef01cSRoman Divacky OS << '<'; 4423dac3a9bSDimitry Andric getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST); 4433861d79fSDimitry Andric if (getOffset()) OS << "+" << getOffset(); 444f22ef01cSRoman Divacky OS << '>'; 445f22ef01cSRoman Divacky break; 4467d523365SDimitry Andric case MachineOperand::MO_RegisterMask: { 4477d523365SDimitry Andric unsigned NumRegsInMask = 0; 4487d523365SDimitry Andric unsigned NumRegsEmitted = 0; 4497d523365SDimitry Andric OS << "<regmask"; 4507d523365SDimitry Andric for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { 4517d523365SDimitry Andric unsigned MaskWord = i / 32; 4527d523365SDimitry Andric unsigned MaskBit = i % 32; 4537d523365SDimitry Andric if (getRegMask()[MaskWord] & (1 << MaskBit)) { 4547d523365SDimitry Andric if (PrintWholeRegMask || NumRegsEmitted <= 10) { 4557d523365SDimitry Andric OS << " " << PrintReg(i, TRI); 4567d523365SDimitry Andric NumRegsEmitted++; 4577d523365SDimitry Andric } 4587d523365SDimitry Andric NumRegsInMask++; 4597d523365SDimitry Andric } 4607d523365SDimitry Andric } 4617d523365SDimitry Andric if (NumRegsEmitted != NumRegsInMask) 4627d523365SDimitry Andric OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; 4637d523365SDimitry Andric OS << ">"; 464dff0c46cSDimitry Andric break; 4657d523365SDimitry Andric } 46691bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 46791bc56edSDimitry Andric OS << "<regliveout>"; 46891bc56edSDimitry Andric break; 469f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 470f22ef01cSRoman Divacky OS << '<'; 4713dac3a9bSDimitry Andric getMetadata()->printAsOperand(OS, MST); 472f22ef01cSRoman Divacky OS << '>'; 473f22ef01cSRoman Divacky break; 474f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 475f22ef01cSRoman Divacky OS << "<MCSym=" << *getMCSymbol() << '>'; 476f22ef01cSRoman Divacky break; 47791bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 47891bc56edSDimitry Andric OS << "<call frame instruction>"; 47991bc56edSDimitry Andric break; 480d88c1a5aSDimitry Andric case MachineOperand::MO_IntrinsicID: { 481d88c1a5aSDimitry Andric Intrinsic::ID ID = getIntrinsicID(); 482d88c1a5aSDimitry Andric if (ID < Intrinsic::num_intrinsics) 483d88c1a5aSDimitry Andric OS << "<intrinsic:@" << Intrinsic::getName(ID, None) << '>'; 484d88c1a5aSDimitry Andric else if (IntrinsicInfo) 485d88c1a5aSDimitry Andric OS << "<intrinsic:@" << IntrinsicInfo->getName(ID) << '>'; 486d88c1a5aSDimitry Andric else 487d88c1a5aSDimitry Andric OS << "<intrinsic:" << ID << '>'; 488d88c1a5aSDimitry Andric break; 489f22ef01cSRoman Divacky } 490d88c1a5aSDimitry Andric case MachineOperand::MO_Predicate: { 491d88c1a5aSDimitry Andric auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); 492d88c1a5aSDimitry Andric OS << '<' << (CmpInst::isIntPredicate(Pred) ? "intpred" : "floatpred") 493d88c1a5aSDimitry Andric << CmpInst::getPredicateName(Pred) << '>'; 494d88c1a5aSDimitry Andric } 495d88c1a5aSDimitry Andric } 496f22ef01cSRoman Divacky if (unsigned TF = getTargetFlags()) 497f22ef01cSRoman Divacky OS << "[TF=" << TF << ']'; 498f22ef01cSRoman Divacky } 499f22ef01cSRoman Divacky 500d88c1a5aSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 501d88c1a5aSDimitry Andric LLVM_DUMP_METHOD void MachineOperand::dump() const { 502d88c1a5aSDimitry Andric dbgs() << *this << '\n'; 503d88c1a5aSDimitry Andric } 504d88c1a5aSDimitry Andric #endif 505d88c1a5aSDimitry Andric 506f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 507f22ef01cSRoman Divacky // MachineMemOperand Implementation 508f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 509f22ef01cSRoman Divacky 5102754fe60SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer 5112754fe60SDimitry Andric /// points into. 5122754fe60SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { 51391bc56edSDimitry Andric if (V.isNull() || V.is<const PseudoSourceValue*>()) return 0; 51491bc56edSDimitry Andric return cast<PointerType>(V.get<const Value*>()->getType())->getAddressSpace(); 5152754fe60SDimitry Andric } 5162754fe60SDimitry Andric 5172754fe60SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the 5182754fe60SDimitry Andric /// constant pool. 5197d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { 5207d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getConstantPool()); 5212754fe60SDimitry Andric } 5222754fe60SDimitry Andric 5232754fe60SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the 5242754fe60SDimitry Andric /// the specified FrameIndex. 5257d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, 5267d523365SDimitry Andric int FI, int64_t Offset) { 5277d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); 5282754fe60SDimitry Andric } 5292754fe60SDimitry Andric 5307d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { 5317d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getJumpTable()); 5322754fe60SDimitry Andric } 5332754fe60SDimitry Andric 5347d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { 5357d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getGOT()); 5362754fe60SDimitry Andric } 5372754fe60SDimitry Andric 5387d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, 5397d523365SDimitry Andric int64_t Offset) { 5407d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getStack(), Offset); 5412754fe60SDimitry Andric } 5422754fe60SDimitry Andric 5433ca95b02SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f, 5442754fe60SDimitry Andric uint64_t s, unsigned int a, 54539d628a0SDimitry Andric const AAMDNodes &AAInfo, 546d88c1a5aSDimitry Andric const MDNode *Ranges, 547d88c1a5aSDimitry Andric SynchronizationScope SynchScope, 548d88c1a5aSDimitry Andric AtomicOrdering Ordering, 549d88c1a5aSDimitry Andric AtomicOrdering FailureOrdering) 5503ca95b02SDimitry Andric : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1), 55139d628a0SDimitry Andric AAInfo(AAInfo), Ranges(Ranges) { 55291bc56edSDimitry Andric assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue*>() || 55391bc56edSDimitry Andric isa<PointerType>(PtrInfo.V.get<const Value*>()->getType())) && 5542754fe60SDimitry Andric "invalid pointer value"); 555f22ef01cSRoman Divacky assert(getBaseAlignment() == a && "Alignment is not a power of 2!"); 556f22ef01cSRoman Divacky assert((isLoad() || isStore()) && "Not a load/store!"); 557d88c1a5aSDimitry Andric 558d88c1a5aSDimitry Andric AtomicInfo.SynchScope = static_cast<unsigned>(SynchScope); 559d88c1a5aSDimitry Andric assert(getSynchScope() == SynchScope && "Value truncated"); 560d88c1a5aSDimitry Andric AtomicInfo.Ordering = static_cast<unsigned>(Ordering); 561d88c1a5aSDimitry Andric assert(getOrdering() == Ordering && "Value truncated"); 562d88c1a5aSDimitry Andric AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering); 563d88c1a5aSDimitry Andric assert(getFailureOrdering() == FailureOrdering && "Value truncated"); 564f22ef01cSRoman Divacky } 565f22ef01cSRoman Divacky 566f22ef01cSRoman Divacky /// Profile - Gather unique data for the object. 567f22ef01cSRoman Divacky /// 568f22ef01cSRoman Divacky void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 5692754fe60SDimitry Andric ID.AddInteger(getOffset()); 570f22ef01cSRoman Divacky ID.AddInteger(Size); 57191bc56edSDimitry Andric ID.AddPointer(getOpaqueValue()); 5723ca95b02SDimitry Andric ID.AddInteger(getFlags()); 5733ca95b02SDimitry Andric ID.AddInteger(getBaseAlignment()); 574f22ef01cSRoman Divacky } 575f22ef01cSRoman Divacky 576f22ef01cSRoman Divacky void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 577f22ef01cSRoman Divacky // The Value and Offset may differ due to CSE. But the flags and size 578f22ef01cSRoman Divacky // should be the same. 579f22ef01cSRoman Divacky assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 580f22ef01cSRoman Divacky assert(MMO->getSize() == getSize() && "Size mismatch!"); 581f22ef01cSRoman Divacky 582f22ef01cSRoman Divacky if (MMO->getBaseAlignment() >= getBaseAlignment()) { 583f22ef01cSRoman Divacky // Update the alignment value. 5843ca95b02SDimitry Andric BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1; 585f22ef01cSRoman Divacky // Also update the base and offset, because the new alignment may 586f22ef01cSRoman Divacky // not be applicable with the old ones. 5872754fe60SDimitry Andric PtrInfo = MMO->PtrInfo; 588f22ef01cSRoman Divacky } 589f22ef01cSRoman Divacky } 590f22ef01cSRoman Divacky 591f22ef01cSRoman Divacky /// getAlignment - Return the minimum known alignment in bytes of the 592f22ef01cSRoman Divacky /// actual memory reference. 593f22ef01cSRoman Divacky uint64_t MachineMemOperand::getAlignment() const { 594f22ef01cSRoman Divacky return MinAlign(getBaseAlignment(), getOffset()); 595f22ef01cSRoman Divacky } 596f22ef01cSRoman Divacky 5973dac3a9bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS) const { 5983dac3a9bSDimitry Andric ModuleSlotTracker DummyMST(nullptr); 5993dac3a9bSDimitry Andric print(OS, DummyMST); 6003dac3a9bSDimitry Andric } 6013dac3a9bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const { 6023dac3a9bSDimitry Andric assert((isLoad() || isStore()) && 603f22ef01cSRoman Divacky "SV has to be a load, store or both."); 604f22ef01cSRoman Divacky 6053dac3a9bSDimitry Andric if (isVolatile()) 606f22ef01cSRoman Divacky OS << "Volatile "; 607f22ef01cSRoman Divacky 6083dac3a9bSDimitry Andric if (isLoad()) 609f22ef01cSRoman Divacky OS << "LD"; 6103dac3a9bSDimitry Andric if (isStore()) 611f22ef01cSRoman Divacky OS << "ST"; 6123dac3a9bSDimitry Andric OS << getSize(); 613f22ef01cSRoman Divacky 614f22ef01cSRoman Divacky // Print the address information. 615f22ef01cSRoman Divacky OS << "["; 6163dac3a9bSDimitry Andric if (const Value *V = getValue()) 6173dac3a9bSDimitry Andric V->printAsOperand(OS, /*PrintType=*/false, MST); 6183dac3a9bSDimitry Andric else if (const PseudoSourceValue *PSV = getPseudoValue()) 61991bc56edSDimitry Andric PSV->printCustom(OS); 620f22ef01cSRoman Divacky else 62191bc56edSDimitry Andric OS << "<unknown>"; 62291bc56edSDimitry Andric 6233dac3a9bSDimitry Andric unsigned AS = getAddrSpace(); 62491bc56edSDimitry Andric if (AS != 0) 62591bc56edSDimitry Andric OS << "(addrspace=" << AS << ')'; 626f22ef01cSRoman Divacky 627f22ef01cSRoman Divacky // If the alignment of the memory reference itself differs from the alignment 628f22ef01cSRoman Divacky // of the base pointer, print the base alignment explicitly, next to the base 629f22ef01cSRoman Divacky // pointer. 6303dac3a9bSDimitry Andric if (getBaseAlignment() != getAlignment()) 6313dac3a9bSDimitry Andric OS << "(align=" << getBaseAlignment() << ")"; 632f22ef01cSRoman Divacky 6333dac3a9bSDimitry Andric if (getOffset() != 0) 6343dac3a9bSDimitry Andric OS << "+" << getOffset(); 635f22ef01cSRoman Divacky OS << "]"; 636f22ef01cSRoman Divacky 637f22ef01cSRoman Divacky // Print the alignment of the reference. 6383dac3a9bSDimitry Andric if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize()) 6393dac3a9bSDimitry Andric OS << "(align=" << getAlignment() << ")"; 640f22ef01cSRoman Divacky 6412754fe60SDimitry Andric // Print TBAA info. 6423dac3a9bSDimitry Andric if (const MDNode *TBAAInfo = getAAInfo().TBAA) { 6432754fe60SDimitry Andric OS << "(tbaa="; 6442754fe60SDimitry Andric if (TBAAInfo->getNumOperands() > 0) 6453dac3a9bSDimitry Andric TBAAInfo->getOperand(0)->printAsOperand(OS, MST); 64639d628a0SDimitry Andric else 64739d628a0SDimitry Andric OS << "<unknown>"; 64839d628a0SDimitry Andric OS << ")"; 64939d628a0SDimitry Andric } 65039d628a0SDimitry Andric 65139d628a0SDimitry Andric // Print AA scope info. 6523dac3a9bSDimitry Andric if (const MDNode *ScopeInfo = getAAInfo().Scope) { 65339d628a0SDimitry Andric OS << "(alias.scope="; 65439d628a0SDimitry Andric if (ScopeInfo->getNumOperands() > 0) 65539d628a0SDimitry Andric for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { 6563dac3a9bSDimitry Andric ScopeInfo->getOperand(i)->printAsOperand(OS, MST); 65739d628a0SDimitry Andric if (i != ie-1) 65839d628a0SDimitry Andric OS << ","; 65939d628a0SDimitry Andric } 66039d628a0SDimitry Andric else 66139d628a0SDimitry Andric OS << "<unknown>"; 66239d628a0SDimitry Andric OS << ")"; 66339d628a0SDimitry Andric } 66439d628a0SDimitry Andric 66539d628a0SDimitry Andric // Print AA noalias scope info. 6663dac3a9bSDimitry Andric if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) { 66739d628a0SDimitry Andric OS << "(noalias="; 66839d628a0SDimitry Andric if (NoAliasInfo->getNumOperands() > 0) 66939d628a0SDimitry Andric for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { 6703dac3a9bSDimitry Andric NoAliasInfo->getOperand(i)->printAsOperand(OS, MST); 67139d628a0SDimitry Andric if (i != ie-1) 67239d628a0SDimitry Andric OS << ","; 67339d628a0SDimitry Andric } 6742754fe60SDimitry Andric else 6752754fe60SDimitry Andric OS << "<unknown>"; 6762754fe60SDimitry Andric OS << ")"; 6772754fe60SDimitry Andric } 6782754fe60SDimitry Andric 6793dac3a9bSDimitry Andric if (isNonTemporal()) 6803b0f4066SDimitry Andric OS << "(nontemporal)"; 681d88c1a5aSDimitry Andric if (isDereferenceable()) 682d88c1a5aSDimitry Andric OS << "(dereferenceable)"; 6833dac3a9bSDimitry Andric if (isInvariant()) 6843dac3a9bSDimitry Andric OS << "(invariant)"; 685f22ef01cSRoman Divacky } 686f22ef01cSRoman Divacky 687f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 688f22ef01cSRoman Divacky // MachineInstr Implementation 689f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 690f22ef01cSRoman Divacky 691139f7f9bSDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { 69217a519f9SDimitry Andric if (MCID->ImplicitDefs) 6937d523365SDimitry Andric for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; 6947d523365SDimitry Andric ++ImpDefs) 695139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true)); 69617a519f9SDimitry Andric if (MCID->ImplicitUses) 6977d523365SDimitry Andric for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses; 6987d523365SDimitry Andric ++ImpUses) 699139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true)); 700f22ef01cSRoman Divacky } 701f22ef01cSRoman Divacky 702f22ef01cSRoman Divacky /// MachineInstr ctor - This constructor creates a MachineInstr and adds the 703f22ef01cSRoman Divacky /// implicit operands. It reserves space for the number of operands specified by 70417a519f9SDimitry Andric /// the MCInstrDesc. 705139f7f9bSDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid, 706ff0cc061SDimitry Andric DebugLoc dl, bool NoImp) 707ff0cc061SDimitry Andric : MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), Flags(0), 708ff0cc061SDimitry Andric AsmPrinterFlags(0), NumMemRefs(0), MemRefs(nullptr), 709d88c1a5aSDimitry Andric debugLoc(std::move(dl)) { 71039d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 71139d628a0SDimitry Andric 712139f7f9bSDimitry Andric // Reserve space for the expected number of operands. 713139f7f9bSDimitry Andric if (unsigned NumOps = MCID->getNumOperands() + 714139f7f9bSDimitry Andric MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) { 715139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(NumOps); 716139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 717f22ef01cSRoman Divacky } 718f22ef01cSRoman Divacky 719139f7f9bSDimitry Andric if (!NoImp) 720139f7f9bSDimitry Andric addImplicitDefUseOperands(MF); 721f22ef01cSRoman Divacky } 722f22ef01cSRoman Divacky 723f22ef01cSRoman Divacky /// MachineInstr ctor - Copies MachineInstr arg exactly 724f22ef01cSRoman Divacky /// 725f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) 72691bc56edSDimitry Andric : MCID(&MI.getDesc()), Parent(nullptr), Operands(nullptr), NumOperands(0), 7273ca95b02SDimitry Andric Flags(0), AsmPrinterFlags(0), NumMemRefs(MI.NumMemRefs), 728d88c1a5aSDimitry Andric MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc()) { 72939d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 73039d628a0SDimitry Andric 731139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(MI.getNumOperands()); 732139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 733f22ef01cSRoman Divacky 734139f7f9bSDimitry Andric // Copy operands. 735ff0cc061SDimitry Andric for (const MachineOperand &MO : MI.operands()) 736ff0cc061SDimitry Andric addOperand(MF, MO); 737f22ef01cSRoman Divacky 738139f7f9bSDimitry Andric // Copy all the sensible flags. 739139f7f9bSDimitry Andric setFlags(MI.Flags); 740f22ef01cSRoman Divacky } 741f22ef01cSRoman Divacky 742f22ef01cSRoman Divacky /// getRegInfo - If this instruction is embedded into a MachineFunction, 743f22ef01cSRoman Divacky /// return the MachineRegisterInfo object for the current function, otherwise 744f22ef01cSRoman Divacky /// return null. 745f22ef01cSRoman Divacky MachineRegisterInfo *MachineInstr::getRegInfo() { 746f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = getParent()) 747f22ef01cSRoman Divacky return &MBB->getParent()->getRegInfo(); 74891bc56edSDimitry Andric return nullptr; 749f22ef01cSRoman Divacky } 750f22ef01cSRoman Divacky 751f22ef01cSRoman Divacky /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in 752f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 753f22ef01cSRoman Divacky /// operands already be on their use lists. 7547ae0e2c9SDimitry Andric void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) { 755ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 756ff0cc061SDimitry Andric if (MO.isReg()) 757ff0cc061SDimitry Andric MRI.removeRegOperandFromUseList(&MO); 758f22ef01cSRoman Divacky } 759f22ef01cSRoman Divacky 760f22ef01cSRoman Divacky /// AddRegOperandsToUseLists - Add all of the register operands in 761f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 762f22ef01cSRoman Divacky /// operands not be on their use lists yet. 7637ae0e2c9SDimitry Andric void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) { 764ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 765ff0cc061SDimitry Andric if (MO.isReg()) 766ff0cc061SDimitry Andric MRI.addRegOperandToUseList(&MO); 767f22ef01cSRoman Divacky } 768f22ef01cSRoman Divacky 769139f7f9bSDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) { 770139f7f9bSDimitry Andric MachineBasicBlock *MBB = getParent(); 771139f7f9bSDimitry Andric assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs"); 772139f7f9bSDimitry Andric MachineFunction *MF = MBB->getParent(); 773139f7f9bSDimitry Andric assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs"); 774139f7f9bSDimitry Andric addOperand(*MF, Op); 775139f7f9bSDimitry Andric } 776139f7f9bSDimitry Andric 777139f7f9bSDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping 778139f7f9bSDimitry Andric /// ranges. If MRI is non-null also update use-def chains. 779139f7f9bSDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src, 780139f7f9bSDimitry Andric unsigned NumOps, MachineRegisterInfo *MRI) { 781139f7f9bSDimitry Andric if (MRI) 782139f7f9bSDimitry Andric return MRI->moveOperands(Dst, Src, NumOps); 783139f7f9bSDimitry Andric 784ff0cc061SDimitry Andric // MachineOperand is a trivially copyable type so we can just use memmove. 785ff0cc061SDimitry Andric std::memmove(Dst, Src, NumOps * sizeof(MachineOperand)); 786139f7f9bSDimitry Andric } 787139f7f9bSDimitry Andric 788f22ef01cSRoman Divacky /// addOperand - Add the specified operand to the instruction. If it is an 789f22ef01cSRoman Divacky /// implicit operand, it is added to the end of the operand list. If it is 790f22ef01cSRoman Divacky /// an explicit operand it is added at the end of the explicit operand list 791f22ef01cSRoman Divacky /// (before the first implicit operand). 792139f7f9bSDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { 7936122f3e6SDimitry Andric assert(MCID && "Cannot add operands before providing an instr descriptor"); 794f22ef01cSRoman Divacky 795139f7f9bSDimitry Andric // Check if we're adding one of our existing operands. 796139f7f9bSDimitry Andric if (&Op >= Operands && &Op < Operands + NumOperands) { 797139f7f9bSDimitry Andric // This is unusual: MI->addOperand(MI->getOperand(i)). 798139f7f9bSDimitry Andric // If adding Op requires reallocating or moving existing operands around, 799139f7f9bSDimitry Andric // the Op reference could go stale. Support it by copying Op. 800139f7f9bSDimitry Andric MachineOperand CopyOp(Op); 801139f7f9bSDimitry Andric return addOperand(MF, CopyOp); 802139f7f9bSDimitry Andric } 803f22ef01cSRoman Divacky 8046122f3e6SDimitry Andric // Find the insert location for the new operand. Implicit registers go at 805139f7f9bSDimitry Andric // the end, everything else goes before the implicit regs. 806139f7f9bSDimitry Andric // 8076122f3e6SDimitry Andric // FIXME: Allow mixed explicit and implicit operands on inline asm. 8086122f3e6SDimitry Andric // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as 8096122f3e6SDimitry Andric // implicit-defs, but they must not be moved around. See the FIXME in 8106122f3e6SDimitry Andric // InstrEmitter.cpp. 811139f7f9bSDimitry Andric unsigned OpNo = getNumOperands(); 812139f7f9bSDimitry Andric bool isImpReg = Op.isReg() && Op.isImplicit(); 8136122f3e6SDimitry Andric if (!isImpReg && !isInlineAsm()) { 8146122f3e6SDimitry Andric while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) { 8156122f3e6SDimitry Andric --OpNo; 8163861d79fSDimitry Andric assert(!Operands[OpNo].isTied() && "Cannot move tied operands"); 817f22ef01cSRoman Divacky } 818f22ef01cSRoman Divacky } 819f22ef01cSRoman Divacky 820f785676fSDimitry Andric #ifndef NDEBUG 821f785676fSDimitry Andric bool isMetaDataOp = Op.getType() == MachineOperand::MO_Metadata; 8226122f3e6SDimitry Andric // OpNo now points as the desired insertion point. Unless this is a variadic 8236122f3e6SDimitry Andric // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). 8247ae0e2c9SDimitry Andric // RegMask operands go between the explicit and implicit operands. 8257ae0e2c9SDimitry Andric assert((isImpReg || Op.isRegMask() || MCID->isVariadic() || 826f785676fSDimitry Andric OpNo < MCID->getNumOperands() || isMetaDataOp) && 8276122f3e6SDimitry Andric "Trying to add an operand to a machine instr that is already done!"); 828f785676fSDimitry Andric #endif 829f22ef01cSRoman Divacky 830139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 831f22ef01cSRoman Divacky 832139f7f9bSDimitry Andric // Determine if the Operands array needs to be reallocated. 833139f7f9bSDimitry Andric // Save the old capacity and operand array. 834139f7f9bSDimitry Andric OperandCapacity OldCap = CapOperands; 835139f7f9bSDimitry Andric MachineOperand *OldOperands = Operands; 836139f7f9bSDimitry Andric if (!OldOperands || OldCap.getSize() == getNumOperands()) { 837139f7f9bSDimitry Andric CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1); 838139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 839139f7f9bSDimitry Andric // Move the operands before the insertion point. 840139f7f9bSDimitry Andric if (OpNo) 841139f7f9bSDimitry Andric moveOperands(Operands, OldOperands, OpNo, MRI); 842139f7f9bSDimitry Andric } 843f22ef01cSRoman Divacky 844139f7f9bSDimitry Andric // Move the operands following the insertion point. 845139f7f9bSDimitry Andric if (OpNo != NumOperands) 846139f7f9bSDimitry Andric moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo, 847139f7f9bSDimitry Andric MRI); 848139f7f9bSDimitry Andric ++NumOperands; 8496122f3e6SDimitry Andric 850139f7f9bSDimitry Andric // Deallocate the old operand array. 851139f7f9bSDimitry Andric if (OldOperands != Operands && OldOperands) 852139f7f9bSDimitry Andric MF.deallocateOperandArray(OldCap, OldOperands); 853139f7f9bSDimitry Andric 854139f7f9bSDimitry Andric // Copy Op into place. It still needs to be inserted into the MRI use lists. 855139f7f9bSDimitry Andric MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op); 856139f7f9bSDimitry Andric NewMO->ParentMI = this; 857139f7f9bSDimitry Andric 858139f7f9bSDimitry Andric // When adding a register operand, tell MRI about it. 859139f7f9bSDimitry Andric if (NewMO->isReg()) { 8607ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false, regardless of Op's status. 86191bc56edSDimitry Andric NewMO->Contents.Reg.Prev = nullptr; 8623861d79fSDimitry Andric // Ignore existing ties. This is not a property that can be copied. 863139f7f9bSDimitry Andric NewMO->TiedTo = 0; 864139f7f9bSDimitry Andric // Add the new operand to MRI, but only for instructions in an MBB. 865139f7f9bSDimitry Andric if (MRI) 866139f7f9bSDimitry Andric MRI->addRegOperandToUseList(NewMO); 8673861d79fSDimitry Andric // The MCID operand information isn't accurate until we start adding 8683861d79fSDimitry Andric // explicit operands. The implicit operands are added first, then the 8693861d79fSDimitry Andric // explicits are inserted before them. 8703861d79fSDimitry Andric if (!isImpReg) { 8713861d79fSDimitry Andric // Tie uses to defs as indicated in MCInstrDesc. 872139f7f9bSDimitry Andric if (NewMO->isUse()) { 8733861d79fSDimitry Andric int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO); 8743861d79fSDimitry Andric if (DefIdx != -1) 8753861d79fSDimitry Andric tieOperands(DefIdx, OpNo); 8763861d79fSDimitry Andric } 8776122f3e6SDimitry Andric // If the register operand is flagged as early, mark the operand as such. 87817a519f9SDimitry Andric if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) 879139f7f9bSDimitry Andric NewMO->setIsEarlyClobber(true); 880f22ef01cSRoman Divacky } 881f22ef01cSRoman Divacky } 882f22ef01cSRoman Divacky } 883f22ef01cSRoman Divacky 884f22ef01cSRoman Divacky /// RemoveOperand - Erase an operand from an instruction, leaving it with one 885f22ef01cSRoman Divacky /// fewer operand than it started with. 886f22ef01cSRoman Divacky /// 887f22ef01cSRoman Divacky void MachineInstr::RemoveOperand(unsigned OpNo) { 888139f7f9bSDimitry Andric assert(OpNo < getNumOperands() && "Invalid operand number"); 8893861d79fSDimitry Andric untieRegOperand(OpNo); 890f22ef01cSRoman Divacky 8913861d79fSDimitry Andric #ifndef NDEBUG 8923861d79fSDimitry Andric // Moving tied operands would break the ties. 893139f7f9bSDimitry Andric for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i) 8943861d79fSDimitry Andric if (Operands[i].isReg()) 8953861d79fSDimitry Andric assert(!Operands[i].isTied() && "Cannot move tied operands"); 8963861d79fSDimitry Andric #endif 8973861d79fSDimitry Andric 898139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 899139f7f9bSDimitry Andric if (MRI && Operands[OpNo].isReg()) 900139f7f9bSDimitry Andric MRI->removeRegOperandFromUseList(Operands + OpNo); 901f22ef01cSRoman Divacky 902139f7f9bSDimitry Andric // Don't call the MachineOperand destructor. A lot of this code depends on 903139f7f9bSDimitry Andric // MachineOperand having a trivial destructor anyway, and adding a call here 904139f7f9bSDimitry Andric // wouldn't make it 'destructor-correct'. 905139f7f9bSDimitry Andric 906139f7f9bSDimitry Andric if (unsigned N = NumOperands - 1 - OpNo) 907139f7f9bSDimitry Andric moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI); 908139f7f9bSDimitry Andric --NumOperands; 909f22ef01cSRoman Divacky } 910f22ef01cSRoman Divacky 911f22ef01cSRoman Divacky /// addMemOperand - Add a MachineMemOperand to the machine instruction. 912f22ef01cSRoman Divacky /// This function should be used only occasionally. The setMemRefs function 913f22ef01cSRoman Divacky /// is the primary method for setting up a MachineInstr's MemRefs list. 914f22ef01cSRoman Divacky void MachineInstr::addMemOperand(MachineFunction &MF, 915f22ef01cSRoman Divacky MachineMemOperand *MO) { 916f22ef01cSRoman Divacky mmo_iterator OldMemRefs = MemRefs; 917139f7f9bSDimitry Andric unsigned OldNumMemRefs = NumMemRefs; 918f22ef01cSRoman Divacky 919139f7f9bSDimitry Andric unsigned NewNum = NumMemRefs + 1; 920f22ef01cSRoman Divacky mmo_iterator NewMemRefs = MF.allocateMemRefsArray(NewNum); 921f22ef01cSRoman Divacky 922dff0c46cSDimitry Andric std::copy(OldMemRefs, OldMemRefs + OldNumMemRefs, NewMemRefs); 923f22ef01cSRoman Divacky NewMemRefs[NewNum - 1] = MO; 924139f7f9bSDimitry Andric setMemRefs(NewMemRefs, NewMemRefs + NewNum); 925dff0c46cSDimitry Andric } 926dff0c46cSDimitry Andric 927444ed5c5SDimitry Andric /// Check to see if the MMOs pointed to by the two MemRefs arrays are 928444ed5c5SDimitry Andric /// identical. 929444ed5c5SDimitry Andric static bool hasIdenticalMMOs(const MachineInstr &MI1, const MachineInstr &MI2) { 930444ed5c5SDimitry Andric auto I1 = MI1.memoperands_begin(), E1 = MI1.memoperands_end(); 931444ed5c5SDimitry Andric auto I2 = MI2.memoperands_begin(), E2 = MI2.memoperands_end(); 932444ed5c5SDimitry Andric if ((E1 - I1) != (E2 - I2)) 933444ed5c5SDimitry Andric return false; 934444ed5c5SDimitry Andric for (; I1 != E1; ++I1, ++I2) { 935444ed5c5SDimitry Andric if (**I1 != **I2) 936444ed5c5SDimitry Andric return false; 937444ed5c5SDimitry Andric } 938444ed5c5SDimitry Andric return true; 939444ed5c5SDimitry Andric } 940444ed5c5SDimitry Andric 9414d0b32cdSDimitry Andric std::pair<MachineInstr::mmo_iterator, unsigned> 9424d0b32cdSDimitry Andric MachineInstr::mergeMemRefsWith(const MachineInstr& Other) { 943444ed5c5SDimitry Andric 944444ed5c5SDimitry Andric // If either of the incoming memrefs are empty, we must be conservative and 945444ed5c5SDimitry Andric // treat this as if we've exhausted our space for memrefs and dropped them. 946444ed5c5SDimitry Andric if (memoperands_empty() || Other.memoperands_empty()) 947444ed5c5SDimitry Andric return std::make_pair(nullptr, 0); 948444ed5c5SDimitry Andric 949444ed5c5SDimitry Andric // If both instructions have identical memrefs, we don't need to merge them. 950444ed5c5SDimitry Andric // Since many instructions have a single memref, and we tend to merge things 951444ed5c5SDimitry Andric // like pairs of loads from the same location, this catches a large number of 952444ed5c5SDimitry Andric // cases in practice. 953444ed5c5SDimitry Andric if (hasIdenticalMMOs(*this, Other)) 954444ed5c5SDimitry Andric return std::make_pair(MemRefs, NumMemRefs); 955444ed5c5SDimitry Andric 9564d0b32cdSDimitry Andric // TODO: consider uniquing elements within the operand lists to reduce 9574d0b32cdSDimitry Andric // space usage and fall back to conservative information less often. 958444ed5c5SDimitry Andric size_t CombinedNumMemRefs = NumMemRefs + Other.NumMemRefs; 959444ed5c5SDimitry Andric 960444ed5c5SDimitry Andric // If we don't have enough room to store this many memrefs, be conservative 961444ed5c5SDimitry Andric // and drop them. Otherwise, we'd fail asserts when trying to add them to 962444ed5c5SDimitry Andric // the new instruction. 963444ed5c5SDimitry Andric if (CombinedNumMemRefs != uint8_t(CombinedNumMemRefs)) 964444ed5c5SDimitry Andric return std::make_pair(nullptr, 0); 9654d0b32cdSDimitry Andric 9664d0b32cdSDimitry Andric MachineFunction *MF = getParent()->getParent(); 9674d0b32cdSDimitry Andric mmo_iterator MemBegin = MF->allocateMemRefsArray(CombinedNumMemRefs); 9684d0b32cdSDimitry Andric mmo_iterator MemEnd = std::copy(memoperands_begin(), memoperands_end(), 9694d0b32cdSDimitry Andric MemBegin); 9704d0b32cdSDimitry Andric MemEnd = std::copy(Other.memoperands_begin(), Other.memoperands_end(), 9714d0b32cdSDimitry Andric MemEnd); 9724d0b32cdSDimitry Andric assert(MemEnd - MemBegin == (ptrdiff_t)CombinedNumMemRefs && 9734d0b32cdSDimitry Andric "missing memrefs"); 9744d0b32cdSDimitry Andric 9754d0b32cdSDimitry Andric return std::make_pair(MemBegin, CombinedNumMemRefs); 9764d0b32cdSDimitry Andric } 9774d0b32cdSDimitry Andric 978dff0c46cSDimitry Andric bool MachineInstr::hasPropertyInBundle(unsigned Mask, QueryType Type) const { 979139f7f9bSDimitry Andric assert(!isBundledWithPred() && "Must be called on bundle header"); 9807d523365SDimitry Andric for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) { 981dff0c46cSDimitry Andric if (MII->getDesc().getFlags() & Mask) { 982dff0c46cSDimitry Andric if (Type == AnyInBundle) 983dff0c46cSDimitry Andric return true; 984dff0c46cSDimitry Andric } else { 985139f7f9bSDimitry Andric if (Type == AllInBundle && !MII->isBundle()) 986dff0c46cSDimitry Andric return false; 987dff0c46cSDimitry Andric } 988139f7f9bSDimitry Andric // This was the last instruction in the bundle. 989139f7f9bSDimitry Andric if (!MII->isBundledWithSucc()) 990dff0c46cSDimitry Andric return Type == AllInBundle; 991f22ef01cSRoman Divacky } 992139f7f9bSDimitry Andric } 993f22ef01cSRoman Divacky 9943ca95b02SDimitry Andric bool MachineInstr::isIdenticalTo(const MachineInstr &Other, 995f22ef01cSRoman Divacky MICheckType Check) const { 996f22ef01cSRoman Divacky // If opcodes or number of operands are not the same then the two 997f22ef01cSRoman Divacky // instructions are obviously not identical. 9983ca95b02SDimitry Andric if (Other.getOpcode() != getOpcode() || 9993ca95b02SDimitry Andric Other.getNumOperands() != getNumOperands()) 1000f22ef01cSRoman Divacky return false; 1001f22ef01cSRoman Divacky 1002dff0c46cSDimitry Andric if (isBundle()) { 1003d88c1a5aSDimitry Andric // We have passed the test above that both instructions have the same 1004d88c1a5aSDimitry Andric // opcode, so we know that both instructions are bundles here. Let's compare 1005d88c1a5aSDimitry Andric // MIs inside the bundle. 1006d88c1a5aSDimitry Andric assert(Other.isBundle() && "Expected that both instructions are bundles."); 10077d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I1 = getIterator(); 10083ca95b02SDimitry Andric MachineBasicBlock::const_instr_iterator I2 = Other.getIterator(); 1009d88c1a5aSDimitry Andric // Loop until we analysed the last intruction inside at least one of the 1010d88c1a5aSDimitry Andric // bundles. 1011d88c1a5aSDimitry Andric while (I1->isBundledWithSucc() && I2->isBundledWithSucc()) { 1012d88c1a5aSDimitry Andric ++I1; 1013dff0c46cSDimitry Andric ++I2; 1014d88c1a5aSDimitry Andric if (!I1->isIdenticalTo(*I2, Check)) 1015dff0c46cSDimitry Andric return false; 1016dff0c46cSDimitry Andric } 1017d88c1a5aSDimitry Andric // If we've reached the end of just one of the two bundles, but not both, 1018d88c1a5aSDimitry Andric // the instructions are not identical. 1019d88c1a5aSDimitry Andric if (I1->isBundledWithSucc() || I2->isBundledWithSucc()) 1020d88c1a5aSDimitry Andric return false; 1021dff0c46cSDimitry Andric } 1022dff0c46cSDimitry Andric 1023f22ef01cSRoman Divacky // Check operands to make sure they match. 1024f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1025f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 10263ca95b02SDimitry Andric const MachineOperand &OMO = Other.getOperand(i); 1027bd5abe19SDimitry Andric if (!MO.isReg()) { 1028bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1029bd5abe19SDimitry Andric return false; 1030bd5abe19SDimitry Andric continue; 1031bd5abe19SDimitry Andric } 1032bd5abe19SDimitry Andric 1033f22ef01cSRoman Divacky // Clients may or may not want to ignore defs when testing for equality. 1034f22ef01cSRoman Divacky // For example, machine CSE pass only cares about finding common 1035f22ef01cSRoman Divacky // subexpressions, so it's safe to ignore virtual register defs. 1036bd5abe19SDimitry Andric if (MO.isDef()) { 1037f22ef01cSRoman Divacky if (Check == IgnoreDefs) 1038f22ef01cSRoman Divacky continue; 1039bd5abe19SDimitry Andric else if (Check == IgnoreVRegDefs) { 1040f22ef01cSRoman Divacky if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) || 1041f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(OMO.getReg())) 1042f22ef01cSRoman Divacky if (MO.getReg() != OMO.getReg()) 1043f22ef01cSRoman Divacky return false; 1044bd5abe19SDimitry Andric } else { 1045bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1046f22ef01cSRoman Divacky return false; 1047bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isDead() != OMO.isDead()) 1048bd5abe19SDimitry Andric return false; 1049bd5abe19SDimitry Andric } 1050bd5abe19SDimitry Andric } else { 1051bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1052bd5abe19SDimitry Andric return false; 1053bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isKill() != OMO.isKill()) 1054bd5abe19SDimitry Andric return false; 1055bd5abe19SDimitry Andric } 1056f22ef01cSRoman Divacky } 105717a519f9SDimitry Andric // If DebugLoc does not match then two dbg.values are not identical. 105817a519f9SDimitry Andric if (isDebugValue()) 10593ca95b02SDimitry Andric if (getDebugLoc() && Other.getDebugLoc() && 10603ca95b02SDimitry Andric getDebugLoc() != Other.getDebugLoc()) 106117a519f9SDimitry Andric return false; 1062f22ef01cSRoman Divacky return true; 1063f22ef01cSRoman Divacky } 1064f22ef01cSRoman Divacky 1065f22ef01cSRoman Divacky MachineInstr *MachineInstr::removeFromParent() { 1066f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 1067139f7f9bSDimitry Andric return getParent()->remove(this); 1068f22ef01cSRoman Divacky } 1069f22ef01cSRoman Divacky 1070139f7f9bSDimitry Andric MachineInstr *MachineInstr::removeFromBundle() { 1071139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 1072139f7f9bSDimitry Andric return getParent()->remove_instr(this); 1073139f7f9bSDimitry Andric } 1074f22ef01cSRoman Divacky 1075f22ef01cSRoman Divacky void MachineInstr::eraseFromParent() { 1076f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 1077139f7f9bSDimitry Andric getParent()->erase(this); 1078f22ef01cSRoman Divacky } 1079f22ef01cSRoman Divacky 108039d628a0SDimitry Andric void MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval() { 108139d628a0SDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 108239d628a0SDimitry Andric MachineBasicBlock *MBB = getParent(); 108339d628a0SDimitry Andric MachineFunction *MF = MBB->getParent(); 108439d628a0SDimitry Andric assert(MF && "Not embedded in a function!"); 108539d628a0SDimitry Andric 108639d628a0SDimitry Andric MachineInstr *MI = (MachineInstr *)this; 108739d628a0SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 108839d628a0SDimitry Andric 1089ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 109039d628a0SDimitry Andric if (!MO.isReg() || !MO.isDef()) 109139d628a0SDimitry Andric continue; 109239d628a0SDimitry Andric unsigned Reg = MO.getReg(); 109339d628a0SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg)) 109439d628a0SDimitry Andric continue; 109539d628a0SDimitry Andric MRI.markUsesInDebugValueAsUndef(Reg); 109639d628a0SDimitry Andric } 109739d628a0SDimitry Andric MI->eraseFromParent(); 109839d628a0SDimitry Andric } 109939d628a0SDimitry Andric 1100139f7f9bSDimitry Andric void MachineInstr::eraseFromBundle() { 1101139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 1102139f7f9bSDimitry Andric getParent()->erase_instr(this); 1103139f7f9bSDimitry Andric } 1104f22ef01cSRoman Divacky 1105f22ef01cSRoman Divacky /// getNumExplicitOperands - Returns the number of non-implicit operands. 1106f22ef01cSRoman Divacky /// 1107f22ef01cSRoman Divacky unsigned MachineInstr::getNumExplicitOperands() const { 110817a519f9SDimitry Andric unsigned NumOperands = MCID->getNumOperands(); 110917a519f9SDimitry Andric if (!MCID->isVariadic()) 1110f22ef01cSRoman Divacky return NumOperands; 1111f22ef01cSRoman Divacky 1112f22ef01cSRoman Divacky for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) { 1113f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1114f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isImplicit()) 1115f22ef01cSRoman Divacky NumOperands++; 1116f22ef01cSRoman Divacky } 1117f22ef01cSRoman Divacky return NumOperands; 1118f22ef01cSRoman Divacky } 1119f22ef01cSRoman Divacky 1120139f7f9bSDimitry Andric void MachineInstr::bundleWithPred() { 1121139f7f9bSDimitry Andric assert(!isBundledWithPred() && "MI is already bundled with its predecessor"); 1122139f7f9bSDimitry Andric setFlag(BundledPred); 11237d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 1124139f7f9bSDimitry Andric --Pred; 1125139f7f9bSDimitry Andric assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 1126139f7f9bSDimitry Andric Pred->setFlag(BundledSucc); 1127139f7f9bSDimitry Andric } 1128139f7f9bSDimitry Andric 1129139f7f9bSDimitry Andric void MachineInstr::bundleWithSucc() { 1130139f7f9bSDimitry Andric assert(!isBundledWithSucc() && "MI is already bundled with its successor"); 1131139f7f9bSDimitry Andric setFlag(BundledSucc); 11327d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 1133139f7f9bSDimitry Andric ++Succ; 1134139f7f9bSDimitry Andric assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags"); 1135139f7f9bSDimitry Andric Succ->setFlag(BundledPred); 1136139f7f9bSDimitry Andric } 1137139f7f9bSDimitry Andric 1138139f7f9bSDimitry Andric void MachineInstr::unbundleFromPred() { 1139139f7f9bSDimitry Andric assert(isBundledWithPred() && "MI isn't bundled with its predecessor"); 1140139f7f9bSDimitry Andric clearFlag(BundledPred); 11417d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 1142139f7f9bSDimitry Andric --Pred; 1143139f7f9bSDimitry Andric assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 1144139f7f9bSDimitry Andric Pred->clearFlag(BundledSucc); 1145139f7f9bSDimitry Andric } 1146139f7f9bSDimitry Andric 1147139f7f9bSDimitry Andric void MachineInstr::unbundleFromSucc() { 1148139f7f9bSDimitry Andric assert(isBundledWithSucc() && "MI isn't bundled with its successor"); 1149139f7f9bSDimitry Andric clearFlag(BundledSucc); 11507d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 1151139f7f9bSDimitry Andric ++Succ; 1152139f7f9bSDimitry Andric assert(Succ->isBundledWithPred() && "Inconsistent bundle flags"); 1153139f7f9bSDimitry Andric Succ->clearFlag(BundledPred); 1154dff0c46cSDimitry Andric } 1155dff0c46cSDimitry Andric 11562754fe60SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const { 11572754fe60SDimitry Andric if (isInlineAsm()) { 11582754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 11592754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 11602754fe60SDimitry Andric return true; 11612754fe60SDimitry Andric } 11622754fe60SDimitry Andric return false; 11632754fe60SDimitry Andric } 1164f22ef01cSRoman Divacky 11653861d79fSDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const { 11663861d79fSDimitry Andric assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!"); 11673861d79fSDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 11683861d79fSDimitry Andric return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0); 11693861d79fSDimitry Andric } 11703861d79fSDimitry Andric 11716122f3e6SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx, 11726122f3e6SDimitry Andric unsigned *GroupNo) const { 11736122f3e6SDimitry Andric assert(isInlineAsm() && "Expected an inline asm instruction"); 11746122f3e6SDimitry Andric assert(OpIdx < getNumOperands() && "OpIdx out of range"); 11756122f3e6SDimitry Andric 11766122f3e6SDimitry Andric // Ignore queries about the initial operands. 11776122f3e6SDimitry Andric if (OpIdx < InlineAsm::MIOp_FirstOperand) 11786122f3e6SDimitry Andric return -1; 11796122f3e6SDimitry Andric 11806122f3e6SDimitry Andric unsigned Group = 0; 11816122f3e6SDimitry Andric unsigned NumOps; 11826122f3e6SDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 11836122f3e6SDimitry Andric i += NumOps) { 11846122f3e6SDimitry Andric const MachineOperand &FlagMO = getOperand(i); 11856122f3e6SDimitry Andric // If we reach the implicit register operands, stop looking. 11866122f3e6SDimitry Andric if (!FlagMO.isImm()) 11876122f3e6SDimitry Andric return -1; 11886122f3e6SDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 11896122f3e6SDimitry Andric if (i + NumOps > OpIdx) { 11906122f3e6SDimitry Andric if (GroupNo) 11916122f3e6SDimitry Andric *GroupNo = Group; 11926122f3e6SDimitry Andric return i; 11936122f3e6SDimitry Andric } 11946122f3e6SDimitry Andric ++Group; 11956122f3e6SDimitry Andric } 11966122f3e6SDimitry Andric return -1; 11976122f3e6SDimitry Andric } 11986122f3e6SDimitry Andric 11993ca95b02SDimitry Andric const DILocalVariable *MachineInstr::getDebugVariable() const { 12003ca95b02SDimitry Andric assert(isDebugValue() && "not a DBG_VALUE"); 12013ca95b02SDimitry Andric return cast<DILocalVariable>(getOperand(2).getMetadata()); 12023ca95b02SDimitry Andric } 12033ca95b02SDimitry Andric 12043ca95b02SDimitry Andric const DIExpression *MachineInstr::getDebugExpression() const { 12053ca95b02SDimitry Andric assert(isDebugValue() && "not a DBG_VALUE"); 12063ca95b02SDimitry Andric return cast<DIExpression>(getOperand(3).getMetadata()); 12073ca95b02SDimitry Andric } 12083ca95b02SDimitry Andric 12096122f3e6SDimitry Andric const TargetRegisterClass* 12106122f3e6SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx, 12116122f3e6SDimitry Andric const TargetInstrInfo *TII, 12126122f3e6SDimitry Andric const TargetRegisterInfo *TRI) const { 12137ae0e2c9SDimitry Andric assert(getParent() && "Can't have an MBB reference here!"); 12147ae0e2c9SDimitry Andric assert(getParent()->getParent() && "Can't have an MF reference here!"); 12157ae0e2c9SDimitry Andric const MachineFunction &MF = *getParent()->getParent(); 12167ae0e2c9SDimitry Andric 12176122f3e6SDimitry Andric // Most opcodes have fixed constraints in their MCInstrDesc. 12186122f3e6SDimitry Andric if (!isInlineAsm()) 12197ae0e2c9SDimitry Andric return TII->getRegClass(getDesc(), OpIdx, TRI, MF); 12206122f3e6SDimitry Andric 12216122f3e6SDimitry Andric if (!getOperand(OpIdx).isReg()) 122291bc56edSDimitry Andric return nullptr; 12236122f3e6SDimitry Andric 12246122f3e6SDimitry Andric // For tied uses on inline asm, get the constraint from the def. 12256122f3e6SDimitry Andric unsigned DefIdx; 12266122f3e6SDimitry Andric if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx)) 12276122f3e6SDimitry Andric OpIdx = DefIdx; 12286122f3e6SDimitry Andric 12296122f3e6SDimitry Andric // Inline asm stores register class constraints in the flag word. 12306122f3e6SDimitry Andric int FlagIdx = findInlineAsmFlagIdx(OpIdx); 12316122f3e6SDimitry Andric if (FlagIdx < 0) 123291bc56edSDimitry Andric return nullptr; 12336122f3e6SDimitry Andric 12346122f3e6SDimitry Andric unsigned Flag = getOperand(FlagIdx).getImm(); 12356122f3e6SDimitry Andric unsigned RCID; 12363ca95b02SDimitry Andric if ((InlineAsm::getKind(Flag) == InlineAsm::Kind_RegUse || 12373ca95b02SDimitry Andric InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDef || 12383ca95b02SDimitry Andric InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDefEarlyClobber) && 12393ca95b02SDimitry Andric InlineAsm::hasRegClassConstraint(Flag, RCID)) 12406122f3e6SDimitry Andric return TRI->getRegClass(RCID); 12416122f3e6SDimitry Andric 12426122f3e6SDimitry Andric // Assume that all registers in a memory operand are pointers. 12436122f3e6SDimitry Andric if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem) 12447ae0e2c9SDimitry Andric return TRI->getPointerRegClass(MF); 12456122f3e6SDimitry Andric 124691bc56edSDimitry Andric return nullptr; 124791bc56edSDimitry Andric } 124891bc56edSDimitry Andric 124991bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( 125091bc56edSDimitry Andric unsigned Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, 125191bc56edSDimitry Andric const TargetRegisterInfo *TRI, bool ExploreBundle) const { 125291bc56edSDimitry Andric // Check every operands inside the bundle if we have 125391bc56edSDimitry Andric // been asked to. 125491bc56edSDimitry Andric if (ExploreBundle) 12553ca95b02SDimitry Andric for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC; 125691bc56edSDimitry Andric ++OpndIt) 125791bc56edSDimitry Andric CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl( 125891bc56edSDimitry Andric OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); 125991bc56edSDimitry Andric else 126091bc56edSDimitry Andric // Otherwise, just check the current operands. 126197bc6c73SDimitry Andric for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) 126297bc6c73SDimitry Andric CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); 126391bc56edSDimitry Andric return CurRC; 126491bc56edSDimitry Andric } 126591bc56edSDimitry Andric 126691bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl( 126791bc56edSDimitry Andric unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC, 126891bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 126991bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 127091bc56edSDimitry Andric // Check if Reg is constrained by some of its use/def from MI. 127191bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 127291bc56edSDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 127391bc56edSDimitry Andric return CurRC; 127491bc56edSDimitry Andric // If yes, accumulate the constraints through the operand. 127591bc56edSDimitry Andric return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI); 127691bc56edSDimitry Andric } 127791bc56edSDimitry Andric 127891bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( 127991bc56edSDimitry Andric unsigned OpIdx, const TargetRegisterClass *CurRC, 128091bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 128191bc56edSDimitry Andric const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI); 128291bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 128391bc56edSDimitry Andric assert(MO.isReg() && 128491bc56edSDimitry Andric "Cannot get register constraints for non-register operand"); 128591bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 128691bc56edSDimitry Andric if (unsigned SubIdx = MO.getSubReg()) { 128791bc56edSDimitry Andric if (OpRC) 128891bc56edSDimitry Andric CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx); 128991bc56edSDimitry Andric else 129091bc56edSDimitry Andric CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx); 129191bc56edSDimitry Andric } else if (OpRC) 129291bc56edSDimitry Andric CurRC = TRI->getCommonSubClass(CurRC, OpRC); 129391bc56edSDimitry Andric return CurRC; 12946122f3e6SDimitry Andric } 12956122f3e6SDimitry Andric 1296139f7f9bSDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the 1297139f7f9bSDimitry Andric /// header instruction. 1298dff0c46cSDimitry Andric unsigned MachineInstr::getBundleSize() const { 12997d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I = getIterator(); 1300dff0c46cSDimitry Andric unsigned Size = 0; 13013ca95b02SDimitry Andric while (I->isBundledWithSucc()) { 13023ca95b02SDimitry Andric ++Size; 13033ca95b02SDimitry Andric ++I; 13043ca95b02SDimitry Andric } 1305dff0c46cSDimitry Andric return Size; 1306dff0c46cSDimitry Andric } 1307dff0c46cSDimitry Andric 13083ca95b02SDimitry Andric /// Returns true if the MachineInstr has an implicit-use operand of exactly 13093ca95b02SDimitry Andric /// the given register (not considering sub/super-registers). 13103ca95b02SDimitry Andric bool MachineInstr::hasRegisterImplicitUseOperand(unsigned Reg) const { 13113ca95b02SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 13123ca95b02SDimitry Andric const MachineOperand &MO = getOperand(i); 13133ca95b02SDimitry Andric if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == Reg) 13143ca95b02SDimitry Andric return true; 13153ca95b02SDimitry Andric } 13163ca95b02SDimitry Andric return false; 13173ca95b02SDimitry Andric } 13183ca95b02SDimitry Andric 1319f22ef01cSRoman Divacky /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of 1320f22ef01cSRoman Divacky /// the specific register or -1 if it is not found. It further tightens 1321f22ef01cSRoman Divacky /// the search criteria to a use that kills the register if isKill is true. 1322d88c1a5aSDimitry Andric int MachineInstr::findRegisterUseOperandIdx( 1323d88c1a5aSDimitry Andric unsigned Reg, bool isKill, const TargetRegisterInfo *TRI) const { 1324f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1325f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1326f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse()) 1327f22ef01cSRoman Divacky continue; 1328f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1329f22ef01cSRoman Divacky if (!MOReg) 1330f22ef01cSRoman Divacky continue; 1331d88c1a5aSDimitry Andric if (MOReg == Reg || (TRI && TargetRegisterInfo::isPhysicalRegister(MOReg) && 1332f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg) && 1333f22ef01cSRoman Divacky TRI->isSubRegister(MOReg, Reg))) 1334f22ef01cSRoman Divacky if (!isKill || MO.isKill()) 1335f22ef01cSRoman Divacky return i; 1336f22ef01cSRoman Divacky } 1337f22ef01cSRoman Divacky return -1; 1338f22ef01cSRoman Divacky } 1339f22ef01cSRoman Divacky 1340f22ef01cSRoman Divacky /// readsWritesVirtualRegister - Return a pair of bools (reads, writes) 1341f22ef01cSRoman Divacky /// indicating if this instruction reads or writes Reg. This also considers 1342f22ef01cSRoman Divacky /// partial defines. 1343f22ef01cSRoman Divacky std::pair<bool,bool> 1344f22ef01cSRoman Divacky MachineInstr::readsWritesVirtualRegister(unsigned Reg, 1345f22ef01cSRoman Divacky SmallVectorImpl<unsigned> *Ops) const { 1346f22ef01cSRoman Divacky bool PartDef = false; // Partial redefine. 1347f22ef01cSRoman Divacky bool FullDef = false; // Full define. 1348f22ef01cSRoman Divacky bool Use = false; 1349f22ef01cSRoman Divacky 1350f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1351f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1352f22ef01cSRoman Divacky if (!MO.isReg() || MO.getReg() != Reg) 1353f22ef01cSRoman Divacky continue; 1354f22ef01cSRoman Divacky if (Ops) 1355f22ef01cSRoman Divacky Ops->push_back(i); 1356f22ef01cSRoman Divacky if (MO.isUse()) 1357f22ef01cSRoman Divacky Use |= !MO.isUndef(); 13586122f3e6SDimitry Andric else if (MO.getSubReg() && !MO.isUndef()) 13596122f3e6SDimitry Andric // A partial <def,undef> doesn't count as reading the register. 1360f22ef01cSRoman Divacky PartDef = true; 1361f22ef01cSRoman Divacky else 1362f22ef01cSRoman Divacky FullDef = true; 1363f22ef01cSRoman Divacky } 1364f22ef01cSRoman Divacky // A partial redefine uses Reg unless there is also a full define. 1365f22ef01cSRoman Divacky return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef); 1366f22ef01cSRoman Divacky } 1367f22ef01cSRoman Divacky 1368f22ef01cSRoman Divacky /// findRegisterDefOperandIdx() - Returns the operand index that is a def of 1369f22ef01cSRoman Divacky /// the specified register or -1 if it is not found. If isDead is true, defs 1370f22ef01cSRoman Divacky /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it 1371f22ef01cSRoman Divacky /// also checks if there is a def of a super-register. 1372f22ef01cSRoman Divacky int 1373f22ef01cSRoman Divacky MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap, 1374f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 1375f22ef01cSRoman Divacky bool isPhys = TargetRegisterInfo::isPhysicalRegister(Reg); 1376f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1377f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1378dff0c46cSDimitry Andric // Accept regmask operands when Overlap is set. 1379dff0c46cSDimitry Andric // Ignore them when looking for a specific def operand (Overlap == false). 1380dff0c46cSDimitry Andric if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg)) 1381dff0c46cSDimitry Andric return i; 1382f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 1383f22ef01cSRoman Divacky continue; 1384f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1385f22ef01cSRoman Divacky bool Found = (MOReg == Reg); 1386f22ef01cSRoman Divacky if (!Found && TRI && isPhys && 1387f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg)) { 1388f22ef01cSRoman Divacky if (Overlap) 1389f22ef01cSRoman Divacky Found = TRI->regsOverlap(MOReg, Reg); 1390f22ef01cSRoman Divacky else 1391f22ef01cSRoman Divacky Found = TRI->isSubRegister(MOReg, Reg); 1392f22ef01cSRoman Divacky } 1393f22ef01cSRoman Divacky if (Found && (!isDead || MO.isDead())) 1394f22ef01cSRoman Divacky return i; 1395f22ef01cSRoman Divacky } 1396f22ef01cSRoman Divacky return -1; 1397f22ef01cSRoman Divacky } 1398f22ef01cSRoman Divacky 1399f22ef01cSRoman Divacky /// findFirstPredOperandIdx() - Find the index of the first operand in the 1400f22ef01cSRoman Divacky /// operand list that is used to represent the predicate. It returns -1 if 1401f22ef01cSRoman Divacky /// none is found. 1402f22ef01cSRoman Divacky int MachineInstr::findFirstPredOperandIdx() const { 14036122f3e6SDimitry Andric // Don't call MCID.findFirstPredOperandIdx() because this variant 14046122f3e6SDimitry Andric // is sometimes called on an instruction that's not yet complete, and 14056122f3e6SDimitry Andric // so the number of operands is less than the MCID indicates. In 14066122f3e6SDimitry Andric // particular, the PTX target does this. 140717a519f9SDimitry Andric const MCInstrDesc &MCID = getDesc(); 140817a519f9SDimitry Andric if (MCID.isPredicable()) { 1409f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 141017a519f9SDimitry Andric if (MCID.OpInfo[i].isPredicate()) 1411f22ef01cSRoman Divacky return i; 1412f22ef01cSRoman Divacky } 1413f22ef01cSRoman Divacky 1414f22ef01cSRoman Divacky return -1; 1415f22ef01cSRoman Divacky } 1416f22ef01cSRoman Divacky 14173861d79fSDimitry Andric // MachineOperand::TiedTo is 4 bits wide. 14183861d79fSDimitry Andric const unsigned TiedMax = 15; 14196122f3e6SDimitry Andric 14203861d79fSDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other. 14213861d79fSDimitry Andric /// 14223861d79fSDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo 14233861d79fSDimitry Andric /// field. TiedTo can have these values: 14243861d79fSDimitry Andric /// 14253861d79fSDimitry Andric /// 0: Operand is not tied to anything. 14263861d79fSDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1). 14273861d79fSDimitry Andric /// TiedMax: Tied to an operand >= TiedMax-1. 14283861d79fSDimitry Andric /// 14293861d79fSDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal 14303861d79fSDimitry Andric /// instruction. INLINEASM instructions allow more tied defs. 14313861d79fSDimitry Andric /// 14323861d79fSDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) { 14333861d79fSDimitry Andric MachineOperand &DefMO = getOperand(DefIdx); 14343861d79fSDimitry Andric MachineOperand &UseMO = getOperand(UseIdx); 14353861d79fSDimitry Andric assert(DefMO.isDef() && "DefIdx must be a def operand"); 14363861d79fSDimitry Andric assert(UseMO.isUse() && "UseIdx must be a use operand"); 14373861d79fSDimitry Andric assert(!DefMO.isTied() && "Def is already tied to another use"); 14383861d79fSDimitry Andric assert(!UseMO.isTied() && "Use is already tied to another def"); 14396122f3e6SDimitry Andric 14403861d79fSDimitry Andric if (DefIdx < TiedMax) 14413861d79fSDimitry Andric UseMO.TiedTo = DefIdx + 1; 14423861d79fSDimitry Andric else { 14433861d79fSDimitry Andric // Inline asm can use the group descriptors to find tied operands, but on 14443861d79fSDimitry Andric // normal instruction, the tied def must be within the first TiedMax 14453861d79fSDimitry Andric // operands. 14463861d79fSDimitry Andric assert(isInlineAsm() && "DefIdx out of range"); 14473861d79fSDimitry Andric UseMO.TiedTo = TiedMax; 14483861d79fSDimitry Andric } 14493861d79fSDimitry Andric 14503861d79fSDimitry Andric // UseIdx can be out of range, we'll search for it in findTiedOperandIdx(). 14513861d79fSDimitry Andric DefMO.TiedTo = std::min(UseIdx + 1, TiedMax); 14523861d79fSDimitry Andric } 14533861d79fSDimitry Andric 14543861d79fSDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to. 14553861d79fSDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand 14563861d79fSDimitry Andric /// which must exist. 14573861d79fSDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const { 14583861d79fSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 14593861d79fSDimitry Andric assert(MO.isTied() && "Operand isn't tied"); 14603861d79fSDimitry Andric 14613861d79fSDimitry Andric // Normally TiedTo is in range. 14623861d79fSDimitry Andric if (MO.TiedTo < TiedMax) 14633861d79fSDimitry Andric return MO.TiedTo - 1; 14643861d79fSDimitry Andric 14653861d79fSDimitry Andric // Uses on normal instructions can be out of range. 14663861d79fSDimitry Andric if (!isInlineAsm()) { 14673861d79fSDimitry Andric // Normal tied defs must be in the 0..TiedMax-1 range. 14683861d79fSDimitry Andric if (MO.isUse()) 14693861d79fSDimitry Andric return TiedMax - 1; 14703861d79fSDimitry Andric // MO is a def. Search for the tied use. 14713861d79fSDimitry Andric for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) { 14723861d79fSDimitry Andric const MachineOperand &UseMO = getOperand(i); 14733861d79fSDimitry Andric if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1) 14743861d79fSDimitry Andric return i; 14753861d79fSDimitry Andric } 14763861d79fSDimitry Andric llvm_unreachable("Can't find tied use"); 14773861d79fSDimitry Andric } 14783861d79fSDimitry Andric 14793861d79fSDimitry Andric // Now deal with inline asm by parsing the operand group descriptor flags. 14803861d79fSDimitry Andric // Find the beginning of each operand group. 14813861d79fSDimitry Andric SmallVector<unsigned, 8> GroupIdx; 14823861d79fSDimitry Andric unsigned OpIdxGroup = ~0u; 14833861d79fSDimitry Andric unsigned NumOps; 14843861d79fSDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 14853861d79fSDimitry Andric i += NumOps) { 14863861d79fSDimitry Andric const MachineOperand &FlagMO = getOperand(i); 14873861d79fSDimitry Andric assert(FlagMO.isImm() && "Invalid tied operand on inline asm"); 14883861d79fSDimitry Andric unsigned CurGroup = GroupIdx.size(); 14893861d79fSDimitry Andric GroupIdx.push_back(i); 14903861d79fSDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 14913861d79fSDimitry Andric // OpIdx belongs to this operand group. 14923861d79fSDimitry Andric if (OpIdx > i && OpIdx < i + NumOps) 14933861d79fSDimitry Andric OpIdxGroup = CurGroup; 14943861d79fSDimitry Andric unsigned TiedGroup; 14953861d79fSDimitry Andric if (!InlineAsm::isUseOperandTiedToDef(FlagMO.getImm(), TiedGroup)) 1496f22ef01cSRoman Divacky continue; 14973861d79fSDimitry Andric // Operands in this group are tied to operands in TiedGroup which must be 14983861d79fSDimitry Andric // earlier. Find the number of operands between the two groups. 14993861d79fSDimitry Andric unsigned Delta = i - GroupIdx[TiedGroup]; 1500f22ef01cSRoman Divacky 15013861d79fSDimitry Andric // OpIdx is a use tied to TiedGroup. 15023861d79fSDimitry Andric if (OpIdxGroup == CurGroup) 15033861d79fSDimitry Andric return OpIdx - Delta; 1504f22ef01cSRoman Divacky 15053861d79fSDimitry Andric // OpIdx is a def tied to this use group. 15063861d79fSDimitry Andric if (OpIdxGroup == TiedGroup) 15073861d79fSDimitry Andric return OpIdx + Delta; 1508f22ef01cSRoman Divacky } 15093861d79fSDimitry Andric llvm_unreachable("Invalid tied operand on inline asm"); 1510f22ef01cSRoman Divacky } 1511f22ef01cSRoman Divacky 1512f22ef01cSRoman Divacky /// clearKillInfo - Clears kill flags on all operands. 1513f22ef01cSRoman Divacky /// 1514f22ef01cSRoman Divacky void MachineInstr::clearKillInfo() { 1515ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1516f22ef01cSRoman Divacky if (MO.isReg() && MO.isUse()) 1517f22ef01cSRoman Divacky MO.setIsKill(false); 1518f22ef01cSRoman Divacky } 1519f22ef01cSRoman Divacky } 1520f22ef01cSRoman Divacky 1521ffd1746dSEd Schouten void MachineInstr::substituteRegister(unsigned FromReg, 1522ffd1746dSEd Schouten unsigned ToReg, 1523ffd1746dSEd Schouten unsigned SubIdx, 1524ffd1746dSEd Schouten const TargetRegisterInfo &RegInfo) { 1525ffd1746dSEd Schouten if (TargetRegisterInfo::isPhysicalRegister(ToReg)) { 1526ffd1746dSEd Schouten if (SubIdx) 1527ffd1746dSEd Schouten ToReg = RegInfo.getSubReg(ToReg, SubIdx); 1528ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1529ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1530ffd1746dSEd Schouten continue; 1531ffd1746dSEd Schouten MO.substPhysReg(ToReg, RegInfo); 1532ffd1746dSEd Schouten } 1533ffd1746dSEd Schouten } else { 1534ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1535ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1536ffd1746dSEd Schouten continue; 1537ffd1746dSEd Schouten MO.substVirtReg(ToReg, SubIdx, RegInfo); 1538ffd1746dSEd Schouten } 1539ffd1746dSEd Schouten } 1540ffd1746dSEd Schouten } 1541ffd1746dSEd Schouten 1542f22ef01cSRoman Divacky /// isSafeToMove - Return true if it is safe to move this instruction. If 1543f22ef01cSRoman Divacky /// SawStore is set to true, it means that there is a store (or call) between 1544f22ef01cSRoman Divacky /// the instruction's location and its intended destination. 1545ff0cc061SDimitry Andric bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const { 1546f22ef01cSRoman Divacky // Ignore stuff that we obviously can't move. 15473861d79fSDimitry Andric // 15483861d79fSDimitry Andric // Treat volatile loads as stores. This is not strictly necessary for 15493861d79fSDimitry Andric // volatiles, but it is required for atomic loads. It is not allowed to move 15503861d79fSDimitry Andric // a load across an atomic load with Ordering > Monotonic. 15513861d79fSDimitry Andric if (mayStore() || isCall() || 15523861d79fSDimitry Andric (mayLoad() && hasOrderedMemoryRef())) { 1553f22ef01cSRoman Divacky SawStore = true; 1554f22ef01cSRoman Divacky return false; 1555f22ef01cSRoman Divacky } 15562754fe60SDimitry Andric 155791bc56edSDimitry Andric if (isPosition() || isDebugValue() || isTerminator() || 155891bc56edSDimitry Andric hasUnmodeledSideEffects()) 1559f22ef01cSRoman Divacky return false; 1560f22ef01cSRoman Divacky 1561f22ef01cSRoman Divacky // See if this instruction does a load. If so, we have to guarantee that the 1562f22ef01cSRoman Divacky // loaded value doesn't change between the load and the its intended 1563f22ef01cSRoman Divacky // destination. The check for isInvariantLoad gives the targe the chance to 1564f22ef01cSRoman Divacky // classify the load as always returning a constant, e.g. a constant pool 1565f22ef01cSRoman Divacky // load. 1566d88c1a5aSDimitry Andric if (mayLoad() && !isDereferenceableInvariantLoad(AA)) 1567f22ef01cSRoman Divacky // Otherwise, this is a real load. If there is a store between the load and 15683861d79fSDimitry Andric // end of block, we can't move it. 15693861d79fSDimitry Andric return !SawStore; 1570f22ef01cSRoman Divacky 1571f22ef01cSRoman Divacky return true; 1572f22ef01cSRoman Divacky } 1573f22ef01cSRoman Divacky 15743861d79fSDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered 15753861d79fSDimitry Andric /// or volatile memory reference, or if the information describing the memory 15763861d79fSDimitry Andric /// reference is not available. Return false if it is known to have no ordered 15773861d79fSDimitry Andric /// memory references. 15783861d79fSDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const { 1579f22ef01cSRoman Divacky // An instruction known never to access memory won't have a volatile access. 1580dff0c46cSDimitry Andric if (!mayStore() && 1581dff0c46cSDimitry Andric !mayLoad() && 1582dff0c46cSDimitry Andric !isCall() && 15832754fe60SDimitry Andric !hasUnmodeledSideEffects()) 1584f22ef01cSRoman Divacky return false; 1585f22ef01cSRoman Divacky 1586f22ef01cSRoman Divacky // Otherwise, if the instruction has no memory reference information, 1587f22ef01cSRoman Divacky // conservatively assume it wasn't preserved. 1588f22ef01cSRoman Divacky if (memoperands_empty()) 1589f22ef01cSRoman Divacky return true; 1590f22ef01cSRoman Divacky 15913ca95b02SDimitry Andric // Check if any of our memory operands are ordered. 15923ca95b02SDimitry Andric return any_of(memoperands(), [](const MachineMemOperand *MMO) { 15933ca95b02SDimitry Andric return !MMO->isUnordered(); 15943ca95b02SDimitry Andric }); 1595f22ef01cSRoman Divacky } 1596f22ef01cSRoman Divacky 1597d88c1a5aSDimitry Andric /// isDereferenceableInvariantLoad - Return true if this instruction will never 1598d88c1a5aSDimitry Andric /// trap and is loading from a location whose value is invariant across a run of 1599d88c1a5aSDimitry Andric /// this function. 1600d88c1a5aSDimitry Andric bool MachineInstr::isDereferenceableInvariantLoad(AliasAnalysis *AA) const { 1601f22ef01cSRoman Divacky // If the instruction doesn't load at all, it isn't an invariant load. 1602dff0c46cSDimitry Andric if (!mayLoad()) 1603f22ef01cSRoman Divacky return false; 1604f22ef01cSRoman Divacky 1605f22ef01cSRoman Divacky // If the instruction has lost its memoperands, conservatively assume that 1606f22ef01cSRoman Divacky // it may not be an invariant load. 1607f22ef01cSRoman Divacky if (memoperands_empty()) 1608f22ef01cSRoman Divacky return false; 1609f22ef01cSRoman Divacky 1610d88c1a5aSDimitry Andric const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo(); 1611f22ef01cSRoman Divacky 16123ca95b02SDimitry Andric for (MachineMemOperand *MMO : memoperands()) { 16133ca95b02SDimitry Andric if (MMO->isVolatile()) return false; 16143ca95b02SDimitry Andric if (MMO->isStore()) return false; 1615d88c1a5aSDimitry Andric if (MMO->isInvariant() && MMO->isDereferenceable()) 1616d88c1a5aSDimitry Andric continue; 161791bc56edSDimitry Andric 1618f22ef01cSRoman Divacky // A load from a constant PseudoSourceValue is invariant. 16193ca95b02SDimitry Andric if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) 1620d88c1a5aSDimitry Andric if (PSV->isConstant(&MFI)) 1621f22ef01cSRoman Divacky continue; 162291bc56edSDimitry Andric 16233ca95b02SDimitry Andric if (const Value *V = MMO->getValue()) { 1624f22ef01cSRoman Divacky // If we have an AliasAnalysis, ask it whether the memory is constant. 16258f0fd8f6SDimitry Andric if (AA && 16268f0fd8f6SDimitry Andric AA->pointsToConstantMemory( 16273ca95b02SDimitry Andric MemoryLocation(V, MMO->getSize(), MMO->getAAInfo()))) 1628f22ef01cSRoman Divacky continue; 1629f22ef01cSRoman Divacky } 1630f22ef01cSRoman Divacky 1631f22ef01cSRoman Divacky // Otherwise assume conservatively. 1632f22ef01cSRoman Divacky return false; 1633f22ef01cSRoman Divacky } 1634f22ef01cSRoman Divacky 1635f22ef01cSRoman Divacky // Everything checks out. 1636f22ef01cSRoman Divacky return true; 1637f22ef01cSRoman Divacky } 1638f22ef01cSRoman Divacky 1639f22ef01cSRoman Divacky /// isConstantValuePHI - If the specified instruction is a PHI that always 1640f22ef01cSRoman Divacky /// merges together the same virtual register, return the register, otherwise 1641f22ef01cSRoman Divacky /// return 0. 1642f22ef01cSRoman Divacky unsigned MachineInstr::isConstantValuePHI() const { 1643f22ef01cSRoman Divacky if (!isPHI()) 1644f22ef01cSRoman Divacky return 0; 1645f22ef01cSRoman Divacky assert(getNumOperands() >= 3 && 1646f22ef01cSRoman Divacky "It's illegal to have a PHI without source operands"); 1647f22ef01cSRoman Divacky 1648f22ef01cSRoman Divacky unsigned Reg = getOperand(1).getReg(); 1649f22ef01cSRoman Divacky for (unsigned i = 3, e = getNumOperands(); i < e; i += 2) 1650f22ef01cSRoman Divacky if (getOperand(i).getReg() != Reg) 1651f22ef01cSRoman Divacky return 0; 1652f22ef01cSRoman Divacky return Reg; 1653f22ef01cSRoman Divacky } 1654f22ef01cSRoman Divacky 16552754fe60SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const { 1656dff0c46cSDimitry Andric if (hasProperty(MCID::UnmodeledSideEffects)) 16572754fe60SDimitry Andric return true; 16582754fe60SDimitry Andric if (isInlineAsm()) { 16592754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 16602754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 16612754fe60SDimitry Andric return true; 16622754fe60SDimitry Andric } 16632754fe60SDimitry Andric 16642754fe60SDimitry Andric return false; 16652754fe60SDimitry Andric } 16662754fe60SDimitry Andric 16677d523365SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const { 16687d523365SDimitry Andric return mayStore() || isCall() || hasUnmodeledSideEffects(); 16697d523365SDimitry Andric } 16707d523365SDimitry Andric 1671f22ef01cSRoman Divacky /// allDefsAreDead - Return true if all the defs of this instruction are dead. 1672f22ef01cSRoman Divacky /// 1673f22ef01cSRoman Divacky bool MachineInstr::allDefsAreDead() const { 1674ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 1675f22ef01cSRoman Divacky if (!MO.isReg() || MO.isUse()) 1676f22ef01cSRoman Divacky continue; 1677f22ef01cSRoman Divacky if (!MO.isDead()) 1678f22ef01cSRoman Divacky return false; 1679f22ef01cSRoman Divacky } 1680f22ef01cSRoman Divacky return true; 1681f22ef01cSRoman Divacky } 1682f22ef01cSRoman Divacky 16832754fe60SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified 16842754fe60SDimitry Andric /// instruction to this instruction. 1685139f7f9bSDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF, 16863ca95b02SDimitry Andric const MachineInstr &MI) { 16873ca95b02SDimitry Andric for (unsigned i = MI.getDesc().getNumOperands(), e = MI.getNumOperands(); 16882754fe60SDimitry Andric i != e; ++i) { 16893ca95b02SDimitry Andric const MachineOperand &MO = MI.getOperand(i); 169091bc56edSDimitry Andric if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask()) 1691139f7f9bSDimitry Andric addOperand(MF, MO); 16922754fe60SDimitry Andric } 16932754fe60SDimitry Andric } 16942754fe60SDimitry Andric 1695d88c1a5aSDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dump(const TargetInstrInfo *TII) const { 16963861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1697d88c1a5aSDimitry Andric dbgs() << " "; 1698d88c1a5aSDimitry Andric print(dbgs(), false /* SkipOpers */, TII); 16993861d79fSDimitry Andric #endif 1700f22ef01cSRoman Divacky } 1701f22ef01cSRoman Divacky 1702d88c1a5aSDimitry Andric void MachineInstr::print(raw_ostream &OS, bool SkipOpers, 1703d88c1a5aSDimitry Andric const TargetInstrInfo *TII) const { 17043dac3a9bSDimitry Andric const Module *M = nullptr; 17053dac3a9bSDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 17063dac3a9bSDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 17073dac3a9bSDimitry Andric M = MF->getFunction()->getParent(); 17083dac3a9bSDimitry Andric 17093dac3a9bSDimitry Andric ModuleSlotTracker MST(M); 1710d88c1a5aSDimitry Andric print(OS, MST, SkipOpers, TII); 17113dac3a9bSDimitry Andric } 17123dac3a9bSDimitry Andric 17133dac3a9bSDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, 1714d88c1a5aSDimitry Andric bool SkipOpers, const TargetInstrInfo *TII) const { 1715ff0cc061SDimitry Andric // We can be a bit tidier if we know the MachineFunction. 171691bc56edSDimitry Andric const MachineFunction *MF = nullptr; 1717ff0cc061SDimitry Andric const TargetRegisterInfo *TRI = nullptr; 171891bc56edSDimitry Andric const MachineRegisterInfo *MRI = nullptr; 1719d88c1a5aSDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo = nullptr; 1720d88c1a5aSDimitry Andric 1721f22ef01cSRoman Divacky if (const MachineBasicBlock *MBB = getParent()) { 1722f22ef01cSRoman Divacky MF = MBB->getParent(); 1723ff0cc061SDimitry Andric if (MF) { 1724e580952dSDimitry Andric MRI = &MF->getRegInfo(); 1725ff0cc061SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo(); 1726d88c1a5aSDimitry Andric if (!TII) 1727ff0cc061SDimitry Andric TII = MF->getSubtarget().getInstrInfo(); 1728d88c1a5aSDimitry Andric IntrinsicInfo = MF->getTarget().getIntrinsicInfo(); 1729ff0cc061SDimitry Andric } 1730f22ef01cSRoman Divacky } 1731f22ef01cSRoman Divacky 1732e580952dSDimitry Andric // Save a list of virtual registers. 1733e580952dSDimitry Andric SmallVector<unsigned, 8> VirtRegs; 1734e580952dSDimitry Andric 1735f22ef01cSRoman Divacky // Print explicitly defined operands on the left of an assignment syntax. 1736f22ef01cSRoman Divacky unsigned StartOp = 0, e = getNumOperands(); 1737f22ef01cSRoman Divacky for (; StartOp < e && getOperand(StartOp).isReg() && 1738f22ef01cSRoman Divacky getOperand(StartOp).isDef() && 1739f22ef01cSRoman Divacky !getOperand(StartOp).isImplicit(); 1740f22ef01cSRoman Divacky ++StartOp) { 1741f22ef01cSRoman Divacky if (StartOp != 0) OS << ", "; 1742d88c1a5aSDimitry Andric getOperand(StartOp).print(OS, MST, TRI, IntrinsicInfo); 1743e580952dSDimitry Andric unsigned Reg = getOperand(StartOp).getReg(); 17443ca95b02SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(Reg)) { 1745e580952dSDimitry Andric VirtRegs.push_back(Reg); 1746d88c1a5aSDimitry Andric LLT Ty = MRI ? MRI->getType(Reg) : LLT{}; 1747d88c1a5aSDimitry Andric if (Ty.isValid()) 1748d88c1a5aSDimitry Andric OS << '(' << Ty << ')'; 17493ca95b02SDimitry Andric } 1750f22ef01cSRoman Divacky } 1751f22ef01cSRoman Divacky 1752f22ef01cSRoman Divacky if (StartOp != 0) 1753f22ef01cSRoman Divacky OS << " = "; 1754f22ef01cSRoman Divacky 1755f22ef01cSRoman Divacky // Print the opcode name. 1756ff0cc061SDimitry Andric if (TII) 1757ff0cc061SDimitry Andric OS << TII->getName(getOpcode()); 1758dff0c46cSDimitry Andric else 1759dff0c46cSDimitry Andric OS << "UNKNOWN"; 1760f22ef01cSRoman Divacky 1761139f7f9bSDimitry Andric if (SkipOpers) 1762139f7f9bSDimitry Andric return; 1763139f7f9bSDimitry Andric 1764f22ef01cSRoman Divacky // Print the rest of the operands. 1765f22ef01cSRoman Divacky bool OmittedAnyCallClobbers = false; 1766f22ef01cSRoman Divacky bool FirstOp = true; 176717a519f9SDimitry Andric unsigned AsmDescOp = ~0u; 176817a519f9SDimitry Andric unsigned AsmOpCount = 0; 17692754fe60SDimitry Andric 17706122f3e6SDimitry Andric if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { 17712754fe60SDimitry Andric // Print asm string. 17722754fe60SDimitry Andric OS << " "; 17733dac3a9bSDimitry Andric getOperand(InlineAsm::MIOp_AsmString).print(OS, MST, TRI); 17742754fe60SDimitry Andric 1775139f7f9bSDimitry Andric // Print HasSideEffects, MayLoad, MayStore, IsAlignStack 17762754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 17772754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 17782754fe60SDimitry Andric OS << " [sideeffect]"; 1779139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayLoad) 1780139f7f9bSDimitry Andric OS << " [mayload]"; 1781139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayStore) 1782139f7f9bSDimitry Andric OS << " [maystore]"; 17833ca95b02SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsConvergent) 17843ca95b02SDimitry Andric OS << " [isconvergent]"; 17852754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 17862754fe60SDimitry Andric OS << " [alignstack]"; 17873861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_ATT) 17883861d79fSDimitry Andric OS << " [attdialect]"; 17893861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_Intel) 17903861d79fSDimitry Andric OS << " [inteldialect]"; 17912754fe60SDimitry Andric 179217a519f9SDimitry Andric StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand; 17932754fe60SDimitry Andric FirstOp = false; 17942754fe60SDimitry Andric } 17952754fe60SDimitry Andric 1796f22ef01cSRoman Divacky for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 1797f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1798f22ef01cSRoman Divacky 17992754fe60SDimitry Andric if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) 1800e580952dSDimitry Andric VirtRegs.push_back(MO.getReg()); 1801e580952dSDimitry Andric 1802f22ef01cSRoman Divacky // Omit call-clobbered registers which aren't used anywhere. This makes 1803f22ef01cSRoman Divacky // call instructions much less noisy on targets where calls clobber lots 1804f22ef01cSRoman Divacky // of registers. Don't rely on MO.isDead() because we may be called before 1805f22ef01cSRoman Divacky // LiveVariables is run, or we may be looking at a non-allocatable reg. 180639d628a0SDimitry Andric if (MRI && isCall() && 1807f22ef01cSRoman Divacky MO.isReg() && MO.isImplicit() && MO.isDef()) { 1808f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 18092754fe60SDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 181039d628a0SDimitry Andric if (MRI->use_empty(Reg)) { 1811f22ef01cSRoman Divacky bool HasAliasLive = false; 1812ff0cc061SDimitry Andric for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { 18137ae0e2c9SDimitry Andric unsigned AliasReg = *AI; 181439d628a0SDimitry Andric if (!MRI->use_empty(AliasReg)) { 1815f22ef01cSRoman Divacky HasAliasLive = true; 1816f22ef01cSRoman Divacky break; 1817f22ef01cSRoman Divacky } 18187ae0e2c9SDimitry Andric } 1819f22ef01cSRoman Divacky if (!HasAliasLive) { 1820f22ef01cSRoman Divacky OmittedAnyCallClobbers = true; 1821f22ef01cSRoman Divacky continue; 1822f22ef01cSRoman Divacky } 1823f22ef01cSRoman Divacky } 1824f22ef01cSRoman Divacky } 1825f22ef01cSRoman Divacky } 1826f22ef01cSRoman Divacky 1827f22ef01cSRoman Divacky if (FirstOp) FirstOp = false; else OS << ","; 1828f22ef01cSRoman Divacky OS << " "; 1829f22ef01cSRoman Divacky if (i < getDesc().NumOperands) { 183017a519f9SDimitry Andric const MCOperandInfo &MCOI = getDesc().OpInfo[i]; 183117a519f9SDimitry Andric if (MCOI.isPredicate()) 1832f22ef01cSRoman Divacky OS << "pred:"; 183317a519f9SDimitry Andric if (MCOI.isOptionalDef()) 1834f22ef01cSRoman Divacky OS << "opt:"; 1835f22ef01cSRoman Divacky } 1836f22ef01cSRoman Divacky if (isDebugValue() && MO.isMetadata()) { 1837f22ef01cSRoman Divacky // Pretty print DBG_VALUE instructions. 1838ff0cc061SDimitry Andric auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata()); 1839ff0cc061SDimitry Andric if (DIV && !DIV->getName().empty()) 1840ff0cc061SDimitry Andric OS << "!\"" << DIV->getName() << '\"'; 1841f22ef01cSRoman Divacky else 18423dac3a9bSDimitry Andric MO.print(OS, MST, TRI); 1843f1a29dd3SDimitry Andric } else if (TRI && (isInsertSubreg() || isRegSequence() || 1844f1a29dd3SDimitry Andric (isSubregToReg() && i == 3)) && MO.isImm()) { 1845ff0cc061SDimitry Andric OS << TRI->getSubRegIndexName(MO.getImm()); 184617a519f9SDimitry Andric } else if (i == AsmDescOp && MO.isImm()) { 184717a519f9SDimitry Andric // Pretty print the inline asm operand descriptor. 184817a519f9SDimitry Andric OS << '$' << AsmOpCount++; 184917a519f9SDimitry Andric unsigned Flag = MO.getImm(); 185017a519f9SDimitry Andric switch (InlineAsm::getKind(Flag)) { 18516122f3e6SDimitry Andric case InlineAsm::Kind_RegUse: OS << ":[reguse"; break; 18526122f3e6SDimitry Andric case InlineAsm::Kind_RegDef: OS << ":[regdef"; break; 18536122f3e6SDimitry Andric case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec"; break; 18546122f3e6SDimitry Andric case InlineAsm::Kind_Clobber: OS << ":[clobber"; break; 18556122f3e6SDimitry Andric case InlineAsm::Kind_Imm: OS << ":[imm"; break; 18566122f3e6SDimitry Andric case InlineAsm::Kind_Mem: OS << ":[mem"; break; 18576122f3e6SDimitry Andric default: OS << ":[??" << InlineAsm::getKind(Flag); break; 18586122f3e6SDimitry Andric } 18596122f3e6SDimitry Andric 18606122f3e6SDimitry Andric unsigned RCID = 0; 18613ca95b02SDimitry Andric if (!InlineAsm::isImmKind(Flag) && !InlineAsm::isMemKind(Flag) && 18623ca95b02SDimitry Andric InlineAsm::hasRegClassConstraint(Flag, RCID)) { 1863ff0cc061SDimitry Andric if (TRI) { 1864ff0cc061SDimitry Andric OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID)); 186539d628a0SDimitry Andric } else 18666122f3e6SDimitry Andric OS << ":RC" << RCID; 186717a519f9SDimitry Andric } 186817a519f9SDimitry Andric 18693ca95b02SDimitry Andric if (InlineAsm::isMemKind(Flag)) { 18703ca95b02SDimitry Andric unsigned MCID = InlineAsm::getMemoryConstraintID(Flag); 18713ca95b02SDimitry Andric switch (MCID) { 18723ca95b02SDimitry Andric case InlineAsm::Constraint_es: OS << ":es"; break; 18733ca95b02SDimitry Andric case InlineAsm::Constraint_i: OS << ":i"; break; 18743ca95b02SDimitry Andric case InlineAsm::Constraint_m: OS << ":m"; break; 18753ca95b02SDimitry Andric case InlineAsm::Constraint_o: OS << ":o"; break; 18763ca95b02SDimitry Andric case InlineAsm::Constraint_v: OS << ":v"; break; 18773ca95b02SDimitry Andric case InlineAsm::Constraint_Q: OS << ":Q"; break; 18783ca95b02SDimitry Andric case InlineAsm::Constraint_R: OS << ":R"; break; 18793ca95b02SDimitry Andric case InlineAsm::Constraint_S: OS << ":S"; break; 18803ca95b02SDimitry Andric case InlineAsm::Constraint_T: OS << ":T"; break; 18813ca95b02SDimitry Andric case InlineAsm::Constraint_Um: OS << ":Um"; break; 18823ca95b02SDimitry Andric case InlineAsm::Constraint_Un: OS << ":Un"; break; 18833ca95b02SDimitry Andric case InlineAsm::Constraint_Uq: OS << ":Uq"; break; 18843ca95b02SDimitry Andric case InlineAsm::Constraint_Us: OS << ":Us"; break; 18853ca95b02SDimitry Andric case InlineAsm::Constraint_Ut: OS << ":Ut"; break; 18863ca95b02SDimitry Andric case InlineAsm::Constraint_Uv: OS << ":Uv"; break; 18873ca95b02SDimitry Andric case InlineAsm::Constraint_Uy: OS << ":Uy"; break; 18883ca95b02SDimitry Andric case InlineAsm::Constraint_X: OS << ":X"; break; 18893ca95b02SDimitry Andric case InlineAsm::Constraint_Z: OS << ":Z"; break; 18903ca95b02SDimitry Andric case InlineAsm::Constraint_ZC: OS << ":ZC"; break; 18913ca95b02SDimitry Andric case InlineAsm::Constraint_Zy: OS << ":Zy"; break; 18923ca95b02SDimitry Andric default: OS << ":?"; break; 18933ca95b02SDimitry Andric } 18943ca95b02SDimitry Andric } 18953ca95b02SDimitry Andric 189617a519f9SDimitry Andric unsigned TiedTo = 0; 189717a519f9SDimitry Andric if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo)) 18986122f3e6SDimitry Andric OS << " tiedto:$" << TiedTo; 18996122f3e6SDimitry Andric 19006122f3e6SDimitry Andric OS << ']'; 190117a519f9SDimitry Andric 190217a519f9SDimitry Andric // Compute the index of the next operand descriptor. 190317a519f9SDimitry Andric AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); 1904f22ef01cSRoman Divacky } else 19053dac3a9bSDimitry Andric MO.print(OS, MST, TRI); 1906f22ef01cSRoman Divacky } 1907f22ef01cSRoman Divacky 1908f22ef01cSRoman Divacky // Briefly indicate whether any call clobbers were omitted. 1909f22ef01cSRoman Divacky if (OmittedAnyCallClobbers) { 1910f22ef01cSRoman Divacky if (!FirstOp) OS << ","; 1911f22ef01cSRoman Divacky OS << " ..."; 1912f22ef01cSRoman Divacky } 1913f22ef01cSRoman Divacky 1914f22ef01cSRoman Divacky bool HaveSemi = false; 19157d523365SDimitry Andric const unsigned PrintableFlags = FrameSetup | FrameDestroy; 1916139f7f9bSDimitry Andric if (Flags & PrintableFlags) { 19174d0b32cdSDimitry Andric if (!HaveSemi) { 19184d0b32cdSDimitry Andric OS << ";"; 19194d0b32cdSDimitry Andric HaveSemi = true; 19204d0b32cdSDimitry Andric } 19213b0f4066SDimitry Andric OS << " flags: "; 19223b0f4066SDimitry Andric 19233b0f4066SDimitry Andric if (Flags & FrameSetup) 19243b0f4066SDimitry Andric OS << "FrameSetup"; 19257d523365SDimitry Andric 19267d523365SDimitry Andric if (Flags & FrameDestroy) 19277d523365SDimitry Andric OS << "FrameDestroy"; 19283b0f4066SDimitry Andric } 19293b0f4066SDimitry Andric 1930f22ef01cSRoman Divacky if (!memoperands_empty()) { 19314d0b32cdSDimitry Andric if (!HaveSemi) { 19324d0b32cdSDimitry Andric OS << ";"; 19334d0b32cdSDimitry Andric HaveSemi = true; 19344d0b32cdSDimitry Andric } 1935f22ef01cSRoman Divacky 1936f22ef01cSRoman Divacky OS << " mem:"; 1937f22ef01cSRoman Divacky for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); 1938f22ef01cSRoman Divacky i != e; ++i) { 19393dac3a9bSDimitry Andric (*i)->print(OS, MST); 194091bc56edSDimitry Andric if (std::next(i) != e) 1941f22ef01cSRoman Divacky OS << " "; 1942f22ef01cSRoman Divacky } 1943f22ef01cSRoman Divacky } 1944f22ef01cSRoman Divacky 1945e580952dSDimitry Andric // Print the regclass of any virtual registers encountered. 1946e580952dSDimitry Andric if (MRI && !VirtRegs.empty()) { 19474d0b32cdSDimitry Andric if (!HaveSemi) { 19484d0b32cdSDimitry Andric OS << ";"; 19494d0b32cdSDimitry Andric HaveSemi = true; 19504d0b32cdSDimitry Andric } 1951e580952dSDimitry Andric for (unsigned i = 0; i != VirtRegs.size(); ++i) { 19523ca95b02SDimitry Andric const RegClassOrRegBank &RC = MRI->getRegClassOrRegBank(VirtRegs[i]); 19533ca95b02SDimitry Andric if (!RC) 19543ca95b02SDimitry Andric continue; 19553ca95b02SDimitry Andric // Generic virtual registers do not have register classes. 19563ca95b02SDimitry Andric if (RC.is<const RegisterBank *>()) 19573ca95b02SDimitry Andric OS << " " << RC.get<const RegisterBank *>()->getName(); 19583ca95b02SDimitry Andric else 19593ca95b02SDimitry Andric OS << " " 19603ca95b02SDimitry Andric << TRI->getRegClassName(RC.get<const TargetRegisterClass *>()); 19613ca95b02SDimitry Andric OS << ':' << PrintReg(VirtRegs[i]); 1962e580952dSDimitry Andric for (unsigned j = i+1; j != VirtRegs.size();) { 19633ca95b02SDimitry Andric if (MRI->getRegClassOrRegBank(VirtRegs[j]) != RC) { 1964e580952dSDimitry Andric ++j; 1965e580952dSDimitry Andric continue; 1966e580952dSDimitry Andric } 1967e580952dSDimitry Andric if (VirtRegs[i] != VirtRegs[j]) 19682754fe60SDimitry Andric OS << "," << PrintReg(VirtRegs[j]); 1969e580952dSDimitry Andric VirtRegs.erase(VirtRegs.begin()+j); 1970e580952dSDimitry Andric } 1971e580952dSDimitry Andric } 1972e580952dSDimitry Andric } 1973e580952dSDimitry Andric 19743b0f4066SDimitry Andric // Print debug location information. 1975ff0cc061SDimitry Andric if (isDebugValue() && getOperand(e - 2).isMetadata()) { 19764d0b32cdSDimitry Andric if (!HaveSemi) 19774d0b32cdSDimitry Andric OS << ";"; 1978ff0cc061SDimitry Andric auto *DV = cast<DILocalVariable>(getOperand(e - 2).getMetadata()); 1979ff0cc061SDimitry Andric OS << " line no:" << DV->getLine(); 1980ff0cc061SDimitry Andric if (auto *InlinedAt = debugLoc->getInlinedAt()) { 1981ff0cc061SDimitry Andric DebugLoc InlinedAtDL(InlinedAt); 1982ff0cc061SDimitry Andric if (InlinedAtDL && MF) { 19836122f3e6SDimitry Andric OS << " inlined @[ "; 1984ff0cc061SDimitry Andric InlinedAtDL.print(OS); 19856122f3e6SDimitry Andric OS << " ]"; 19866122f3e6SDimitry Andric } 19876122f3e6SDimitry Andric } 198839d628a0SDimitry Andric if (isIndirectDebugValue()) 198939d628a0SDimitry Andric OS << " indirect"; 1990ff0cc061SDimitry Andric } else if (debugLoc && MF) { 19914d0b32cdSDimitry Andric if (!HaveSemi) 19924d0b32cdSDimitry Andric OS << ";"; 1993f22ef01cSRoman Divacky OS << " dbg:"; 1994ff0cc061SDimitry Andric debugLoc.print(OS); 1995f22ef01cSRoman Divacky } 1996f22ef01cSRoman Divacky 19973b0f4066SDimitry Andric OS << '\n'; 1998f22ef01cSRoman Divacky } 1999f22ef01cSRoman Divacky 2000f22ef01cSRoman Divacky bool MachineInstr::addRegisterKilled(unsigned IncomingReg, 2001f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 2002f22ef01cSRoman Divacky bool AddIfNotFound) { 2003f22ef01cSRoman Divacky bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); 20047ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 20057ae0e2c9SDimitry Andric MCRegAliasIterator(IncomingReg, RegInfo, false).isValid(); 2006f22ef01cSRoman Divacky bool Found = false; 2007f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 2008f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 2009f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 2010f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse() || MO.isUndef()) 2011f22ef01cSRoman Divacky continue; 20123ca95b02SDimitry Andric 20133ca95b02SDimitry Andric // DEBUG_VALUE nodes do not contribute to code generation and should 20143ca95b02SDimitry Andric // always be ignored. Failure to do so may result in trying to modify 20153ca95b02SDimitry Andric // KILL flags on DEBUG_VALUE nodes. 20163ca95b02SDimitry Andric if (MO.isDebug()) 20173ca95b02SDimitry Andric continue; 20183ca95b02SDimitry Andric 2019f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 2020f22ef01cSRoman Divacky if (!Reg) 2021f22ef01cSRoman Divacky continue; 2022f22ef01cSRoman Divacky 2023f22ef01cSRoman Divacky if (Reg == IncomingReg) { 2024f22ef01cSRoman Divacky if (!Found) { 2025f22ef01cSRoman Divacky if (MO.isKill()) 2026f22ef01cSRoman Divacky // The register is already marked kill. 2027f22ef01cSRoman Divacky return true; 2028f22ef01cSRoman Divacky if (isPhysReg && isRegTiedToDefOperand(i)) 2029f22ef01cSRoman Divacky // Two-address uses of physregs must not be marked kill. 2030f22ef01cSRoman Divacky return true; 2031f22ef01cSRoman Divacky MO.setIsKill(); 2032f22ef01cSRoman Divacky Found = true; 2033f22ef01cSRoman Divacky } 2034f22ef01cSRoman Divacky } else if (hasAliases && MO.isKill() && 2035f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg)) { 2036f22ef01cSRoman Divacky // A super-register kill already exists. 2037f22ef01cSRoman Divacky if (RegInfo->isSuperRegister(IncomingReg, Reg)) 2038f22ef01cSRoman Divacky return true; 2039f22ef01cSRoman Divacky if (RegInfo->isSubRegister(IncomingReg, Reg)) 2040f22ef01cSRoman Divacky DeadOps.push_back(i); 2041f22ef01cSRoman Divacky } 2042f22ef01cSRoman Divacky } 2043f22ef01cSRoman Divacky 2044f22ef01cSRoman Divacky // Trim unneeded kill operands. 2045f22ef01cSRoman Divacky while (!DeadOps.empty()) { 2046f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 2047f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 2048f22ef01cSRoman Divacky RemoveOperand(OpIdx); 2049f22ef01cSRoman Divacky else 2050f22ef01cSRoman Divacky getOperand(OpIdx).setIsKill(false); 2051f22ef01cSRoman Divacky DeadOps.pop_back(); 2052f22ef01cSRoman Divacky } 2053f22ef01cSRoman Divacky 2054f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is killed. Add a 2055f22ef01cSRoman Divacky // new implicit operand if required. 2056f22ef01cSRoman Divacky if (!Found && AddIfNotFound) { 2057f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(IncomingReg, 2058f22ef01cSRoman Divacky false /*IsDef*/, 2059f22ef01cSRoman Divacky true /*IsImp*/, 2060f22ef01cSRoman Divacky true /*IsKill*/)); 2061f22ef01cSRoman Divacky return true; 2062f22ef01cSRoman Divacky } 2063f22ef01cSRoman Divacky return Found; 2064f22ef01cSRoman Divacky } 2065f22ef01cSRoman Divacky 2066dff0c46cSDimitry Andric void MachineInstr::clearRegisterKills(unsigned Reg, 2067dff0c46cSDimitry Andric const TargetRegisterInfo *RegInfo) { 2068dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) 206991bc56edSDimitry Andric RegInfo = nullptr; 2070ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2071dff0c46cSDimitry Andric if (!MO.isReg() || !MO.isUse() || !MO.isKill()) 2072dff0c46cSDimitry Andric continue; 2073dff0c46cSDimitry Andric unsigned OpReg = MO.getReg(); 20743ca95b02SDimitry Andric if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg) 2075dff0c46cSDimitry Andric MO.setIsKill(false); 2076dff0c46cSDimitry Andric } 2077dff0c46cSDimitry Andric } 2078dff0c46cSDimitry Andric 2079f785676fSDimitry Andric bool MachineInstr::addRegisterDead(unsigned Reg, 2080f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 2081f22ef01cSRoman Divacky bool AddIfNotFound) { 2082f785676fSDimitry Andric bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(Reg); 20837ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 2084f785676fSDimitry Andric MCRegAliasIterator(Reg, RegInfo, false).isValid(); 2085f22ef01cSRoman Divacky bool Found = false; 2086f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 2087f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 2088f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 2089f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 2090f22ef01cSRoman Divacky continue; 2091f785676fSDimitry Andric unsigned MOReg = MO.getReg(); 2092f785676fSDimitry Andric if (!MOReg) 2093f22ef01cSRoman Divacky continue; 2094f22ef01cSRoman Divacky 2095f785676fSDimitry Andric if (MOReg == Reg) { 2096f22ef01cSRoman Divacky MO.setIsDead(); 2097f22ef01cSRoman Divacky Found = true; 2098f22ef01cSRoman Divacky } else if (hasAliases && MO.isDead() && 2099f785676fSDimitry Andric TargetRegisterInfo::isPhysicalRegister(MOReg)) { 2100f22ef01cSRoman Divacky // There exists a super-register that's marked dead. 2101f785676fSDimitry Andric if (RegInfo->isSuperRegister(Reg, MOReg)) 2102f22ef01cSRoman Divacky return true; 2103f785676fSDimitry Andric if (RegInfo->isSubRegister(Reg, MOReg)) 2104f22ef01cSRoman Divacky DeadOps.push_back(i); 2105f22ef01cSRoman Divacky } 2106f22ef01cSRoman Divacky } 2107f22ef01cSRoman Divacky 2108f22ef01cSRoman Divacky // Trim unneeded dead operands. 2109f22ef01cSRoman Divacky while (!DeadOps.empty()) { 2110f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 2111f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 2112f22ef01cSRoman Divacky RemoveOperand(OpIdx); 2113f22ef01cSRoman Divacky else 2114f22ef01cSRoman Divacky getOperand(OpIdx).setIsDead(false); 2115f22ef01cSRoman Divacky DeadOps.pop_back(); 2116f22ef01cSRoman Divacky } 2117f22ef01cSRoman Divacky 2118f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is dead. Add a 2119f22ef01cSRoman Divacky // new implicit operand if required. 2120f22ef01cSRoman Divacky if (Found || !AddIfNotFound) 2121f22ef01cSRoman Divacky return Found; 2122f22ef01cSRoman Divacky 2123f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 2124f22ef01cSRoman Divacky true /*IsDef*/, 2125f22ef01cSRoman Divacky true /*IsImp*/, 2126f22ef01cSRoman Divacky false /*IsKill*/, 2127f22ef01cSRoman Divacky true /*IsDead*/)); 2128f22ef01cSRoman Divacky return true; 2129f22ef01cSRoman Divacky } 2130f22ef01cSRoman Divacky 2131ff0cc061SDimitry Andric void MachineInstr::clearRegisterDeads(unsigned Reg) { 2132ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2133ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg) 2134ff0cc061SDimitry Andric continue; 2135ff0cc061SDimitry Andric MO.setIsDead(false); 2136ff0cc061SDimitry Andric } 2137ff0cc061SDimitry Andric } 2138ff0cc061SDimitry Andric 21397d523365SDimitry Andric void MachineInstr::setRegisterDefReadUndef(unsigned Reg, bool IsUndef) { 2140ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2141ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0) 2142ff0cc061SDimitry Andric continue; 21437d523365SDimitry Andric MO.setIsUndef(IsUndef); 2144ff0cc061SDimitry Andric } 2145ff0cc061SDimitry Andric } 2146ff0cc061SDimitry Andric 2147f785676fSDimitry Andric void MachineInstr::addRegisterDefined(unsigned Reg, 2148f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo) { 2149f785676fSDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 2150f785676fSDimitry Andric MachineOperand *MO = findRegisterDefOperand(Reg, false, RegInfo); 2151f22ef01cSRoman Divacky if (MO) 2152f22ef01cSRoman Divacky return; 2153f22ef01cSRoman Divacky } else { 2154ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 2155f785676fSDimitry Andric if (MO.isReg() && MO.getReg() == Reg && MO.isDef() && 2156f22ef01cSRoman Divacky MO.getSubReg() == 0) 2157f22ef01cSRoman Divacky return; 2158f22ef01cSRoman Divacky } 2159f22ef01cSRoman Divacky } 2160f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 2161f22ef01cSRoman Divacky true /*IsDef*/, 2162f22ef01cSRoman Divacky true /*IsImp*/)); 2163f22ef01cSRoman Divacky } 2164f22ef01cSRoman Divacky 2165dff0c46cSDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs, 2166ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 2167dff0c46cSDimitry Andric bool HasRegMask = false; 2168ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2169dff0c46cSDimitry Andric if (MO.isRegMask()) { 2170dff0c46cSDimitry Andric HasRegMask = true; 2171dff0c46cSDimitry Andric continue; 2172dff0c46cSDimitry Andric } 2173ffd1746dSEd Schouten if (!MO.isReg() || !MO.isDef()) continue; 2174ffd1746dSEd Schouten unsigned Reg = MO.getReg(); 2175dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; 2176ffd1746dSEd Schouten // If there are no uses, including partial uses, the def is dead. 2177d88c1a5aSDimitry Andric if (none_of(UsedRegs, 2178ff0cc061SDimitry Andric [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); })) 2179ff0cc061SDimitry Andric MO.setIsDead(); 2180ffd1746dSEd Schouten } 2181dff0c46cSDimitry Andric 2182dff0c46cSDimitry Andric // This is a call with a register mask operand. 2183dff0c46cSDimitry Andric // Mask clobbers are always dead, so add defs for the non-dead defines. 2184dff0c46cSDimitry Andric if (HasRegMask) 2185dff0c46cSDimitry Andric for (ArrayRef<unsigned>::iterator I = UsedRegs.begin(), E = UsedRegs.end(); 2186dff0c46cSDimitry Andric I != E; ++I) 2187dff0c46cSDimitry Andric addRegisterDefined(*I, &TRI); 2188ffd1746dSEd Schouten } 2189ffd1746dSEd Schouten 2190f22ef01cSRoman Divacky unsigned 2191f22ef01cSRoman Divacky MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { 2192dff0c46cSDimitry Andric // Build up a buffer of hash code components. 2193dff0c46cSDimitry Andric SmallVector<size_t, 8> HashComponents; 2194dff0c46cSDimitry Andric HashComponents.reserve(MI->getNumOperands() + 1); 2195dff0c46cSDimitry Andric HashComponents.push_back(MI->getOpcode()); 2196ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 21977ae0e2c9SDimitry Andric if (MO.isReg() && MO.isDef() && 21987ae0e2c9SDimitry Andric TargetRegisterInfo::isVirtualRegister(MO.getReg())) 2199f22ef01cSRoman Divacky continue; // Skip virtual register defs. 22007ae0e2c9SDimitry Andric 22017ae0e2c9SDimitry Andric HashComponents.push_back(hash_value(MO)); 2202f22ef01cSRoman Divacky } 2203dff0c46cSDimitry Andric return hash_combine_range(HashComponents.begin(), HashComponents.end()); 2204f22ef01cSRoman Divacky } 220517a519f9SDimitry Andric 220617a519f9SDimitry Andric void MachineInstr::emitError(StringRef Msg) const { 220717a519f9SDimitry Andric // Find the source location cookie. 220817a519f9SDimitry Andric unsigned LocCookie = 0; 220991bc56edSDimitry Andric const MDNode *LocMD = nullptr; 221017a519f9SDimitry Andric for (unsigned i = getNumOperands(); i != 0; --i) { 221117a519f9SDimitry Andric if (getOperand(i-1).isMetadata() && 221217a519f9SDimitry Andric (LocMD = getOperand(i-1).getMetadata()) && 221317a519f9SDimitry Andric LocMD->getNumOperands() != 0) { 221439d628a0SDimitry Andric if (const ConstantInt *CI = 221539d628a0SDimitry Andric mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) { 221617a519f9SDimitry Andric LocCookie = CI->getZExtValue(); 221717a519f9SDimitry Andric break; 221817a519f9SDimitry Andric } 221917a519f9SDimitry Andric } 222017a519f9SDimitry Andric } 222117a519f9SDimitry Andric 222217a519f9SDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 222317a519f9SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 222417a519f9SDimitry Andric return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg); 222517a519f9SDimitry Andric report_fatal_error(Msg); 222617a519f9SDimitry Andric } 22273ca95b02SDimitry Andric 22283ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, 22293ca95b02SDimitry Andric const MCInstrDesc &MCID, bool IsIndirect, 22303ca95b02SDimitry Andric unsigned Reg, unsigned Offset, 22313ca95b02SDimitry Andric const MDNode *Variable, const MDNode *Expr) { 22323ca95b02SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 22333ca95b02SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 22343ca95b02SDimitry Andric assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 22353ca95b02SDimitry Andric "Expected inlined-at fields to agree"); 22363ca95b02SDimitry Andric if (IsIndirect) 22373ca95b02SDimitry Andric return BuildMI(MF, DL, MCID) 22383ca95b02SDimitry Andric .addReg(Reg, RegState::Debug) 22393ca95b02SDimitry Andric .addImm(Offset) 22403ca95b02SDimitry Andric .addMetadata(Variable) 22413ca95b02SDimitry Andric .addMetadata(Expr); 22423ca95b02SDimitry Andric else { 22433ca95b02SDimitry Andric assert(Offset == 0 && "A direct address cannot have an offset."); 22443ca95b02SDimitry Andric return BuildMI(MF, DL, MCID) 22453ca95b02SDimitry Andric .addReg(Reg, RegState::Debug) 22463ca95b02SDimitry Andric .addReg(0U, RegState::Debug) 22473ca95b02SDimitry Andric .addMetadata(Variable) 22483ca95b02SDimitry Andric .addMetadata(Expr); 22493ca95b02SDimitry Andric } 22503ca95b02SDimitry Andric } 22513ca95b02SDimitry Andric 22523ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, 22533ca95b02SDimitry Andric MachineBasicBlock::iterator I, 22543ca95b02SDimitry Andric const DebugLoc &DL, const MCInstrDesc &MCID, 22553ca95b02SDimitry Andric bool IsIndirect, unsigned Reg, 22563ca95b02SDimitry Andric unsigned Offset, const MDNode *Variable, 22573ca95b02SDimitry Andric const MDNode *Expr) { 22583ca95b02SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 22593ca95b02SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 22603ca95b02SDimitry Andric MachineFunction &MF = *BB.getParent(); 22613ca95b02SDimitry Andric MachineInstr *MI = 22623ca95b02SDimitry Andric BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr); 22633ca95b02SDimitry Andric BB.insert(I, MI); 22643ca95b02SDimitry Andric return MachineInstrBuilder(MF, MI); 22653ca95b02SDimitry Andric } 2266