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" 29139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h" 30139f7f9bSDimitry Andric #include "llvm/IR/Metadata.h" 31139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 323dac3a9bSDimitry Andric #include "llvm/IR/ModuleSlotTracker.h" 33139f7f9bSDimitry Andric #include "llvm/IR/Type.h" 34139f7f9bSDimitry Andric #include "llvm/IR/Value.h" 3517a519f9SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 36f22ef01cSRoman Divacky #include "llvm/MC/MCSymbol.h" 377d523365SDimitry Andric #include "llvm/Support/CommandLine.h" 38f22ef01cSRoman Divacky #include "llvm/Support/Debug.h" 39f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 40f22ef01cSRoman Divacky #include "llvm/Support/MathExtras.h" 41f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 42139f7f9bSDimitry Andric #include "llvm/Target/TargetInstrInfo.h" 43139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h" 44139f7f9bSDimitry Andric #include "llvm/Target/TargetRegisterInfo.h" 4539d628a0SDimitry Andric #include "llvm/Target/TargetSubtargetInfo.h" 46f22ef01cSRoman Divacky using namespace llvm; 47f22ef01cSRoman Divacky 487d523365SDimitry Andric static cl::opt<bool> PrintWholeRegMask( 497d523365SDimitry Andric "print-whole-regmask", 507d523365SDimitry Andric cl::desc("Print the full contents of regmask operands in IR dumps"), 517d523365SDimitry Andric cl::init(true), cl::Hidden); 527d523365SDimitry Andric 53f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 54f22ef01cSRoman Divacky // MachineOperand Implementation 55f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 56f22ef01cSRoman Divacky 57f22ef01cSRoman Divacky void MachineOperand::setReg(unsigned Reg) { 58f22ef01cSRoman Divacky if (getReg() == Reg) return; // No change. 59f22ef01cSRoman Divacky 60f22ef01cSRoman Divacky // Otherwise, we have to change the register. If this operand is embedded 61f22ef01cSRoman Divacky // into a machine function, we need to update the old and new register's 62f22ef01cSRoman Divacky // use/def lists. 63f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 64f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 65f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) { 667ae0e2c9SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 677ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(this); 682754fe60SDimitry Andric SmallContents.RegNo = Reg; 697ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(this); 70f22ef01cSRoman Divacky return; 71f22ef01cSRoman Divacky } 72f22ef01cSRoman Divacky 73f22ef01cSRoman Divacky // Otherwise, just change the register, no problem. :) 742754fe60SDimitry Andric SmallContents.RegNo = Reg; 75f22ef01cSRoman Divacky } 76f22ef01cSRoman Divacky 77ffd1746dSEd Schouten void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, 78ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 79ffd1746dSEd Schouten assert(TargetRegisterInfo::isVirtualRegister(Reg)); 80ffd1746dSEd Schouten if (SubIdx && getSubReg()) 81ffd1746dSEd Schouten SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); 82ffd1746dSEd Schouten setReg(Reg); 83ffd1746dSEd Schouten if (SubIdx) 84ffd1746dSEd Schouten setSubReg(SubIdx); 85ffd1746dSEd Schouten } 86ffd1746dSEd Schouten 87ffd1746dSEd Schouten void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { 88ffd1746dSEd Schouten assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 89ffd1746dSEd Schouten if (getSubReg()) { 90ffd1746dSEd Schouten Reg = TRI.getSubReg(Reg, getSubReg()); 91bd5abe19SDimitry Andric // Note that getSubReg() may return 0 if the sub-register doesn't exist. 92bd5abe19SDimitry Andric // That won't happen in legal code. 93ffd1746dSEd Schouten setSubReg(0); 94ffd1746dSEd Schouten } 95ffd1746dSEd Schouten setReg(Reg); 96ffd1746dSEd Schouten } 97ffd1746dSEd Schouten 987ae0e2c9SDimitry Andric /// Change a def to a use, or a use to a def. 997ae0e2c9SDimitry Andric void MachineOperand::setIsDef(bool Val) { 1007ae0e2c9SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 1017ae0e2c9SDimitry Andric assert((!Val || !isDebug()) && "Marking a debug operation as def"); 1027ae0e2c9SDimitry Andric if (IsDef == Val) 1037ae0e2c9SDimitry Andric return; 1047ae0e2c9SDimitry Andric // MRI may keep uses and defs in different list positions. 1057ae0e2c9SDimitry Andric if (MachineInstr *MI = getParent()) 1067ae0e2c9SDimitry Andric if (MachineBasicBlock *MBB = MI->getParent()) 1077ae0e2c9SDimitry Andric if (MachineFunction *MF = MBB->getParent()) { 1087ae0e2c9SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 1097ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(this); 1107ae0e2c9SDimitry Andric IsDef = Val; 1117ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(this); 1127ae0e2c9SDimitry Andric return; 1137ae0e2c9SDimitry Andric } 1147ae0e2c9SDimitry Andric IsDef = Val; 1157ae0e2c9SDimitry Andric } 1167ae0e2c9SDimitry Andric 11739d628a0SDimitry Andric // If this operand is currently a register operand, and if this is in a 11839d628a0SDimitry Andric // function, deregister the operand from the register's use/def list. 11939d628a0SDimitry Andric void MachineOperand::removeRegFromUses() { 12039d628a0SDimitry Andric if (!isReg() || !isOnRegUseList()) 12139d628a0SDimitry Andric return; 12239d628a0SDimitry Andric 12339d628a0SDimitry Andric if (MachineInstr *MI = getParent()) { 12439d628a0SDimitry Andric if (MachineBasicBlock *MBB = MI->getParent()) { 12539d628a0SDimitry Andric if (MachineFunction *MF = MBB->getParent()) 12639d628a0SDimitry Andric MF->getRegInfo().removeRegOperandFromUseList(this); 12739d628a0SDimitry Andric } 12839d628a0SDimitry Andric } 12939d628a0SDimitry Andric } 13039d628a0SDimitry Andric 131f22ef01cSRoman Divacky /// ChangeToImmediate - Replace this operand with a new immediate operand of 132f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an immediate already, 133f22ef01cSRoman Divacky /// the setImm method should be used. 134f22ef01cSRoman Divacky void MachineOperand::ChangeToImmediate(int64_t ImmVal) { 1353861d79fSDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 13639d628a0SDimitry Andric 13739d628a0SDimitry Andric removeRegFromUses(); 138f22ef01cSRoman Divacky 139f22ef01cSRoman Divacky OpKind = MO_Immediate; 140f22ef01cSRoman Divacky Contents.ImmVal = ImmVal; 141f22ef01cSRoman Divacky } 142f22ef01cSRoman Divacky 14339d628a0SDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) { 14439d628a0SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 14539d628a0SDimitry Andric 14639d628a0SDimitry Andric removeRegFromUses(); 14739d628a0SDimitry Andric 14839d628a0SDimitry Andric OpKind = MO_FPImmediate; 14939d628a0SDimitry Andric Contents.CFP = FPImm; 15039d628a0SDimitry Andric } 15139d628a0SDimitry Andric 152ff0cc061SDimitry Andric void MachineOperand::ChangeToES(const char *SymName, unsigned char TargetFlags) { 153ff0cc061SDimitry Andric assert((!isReg() || !isTied()) && 154ff0cc061SDimitry Andric "Cannot change a tied operand into an external symbol"); 155ff0cc061SDimitry Andric 156ff0cc061SDimitry Andric removeRegFromUses(); 157ff0cc061SDimitry Andric 158ff0cc061SDimitry Andric OpKind = MO_ExternalSymbol; 159ff0cc061SDimitry Andric Contents.OffsetedInfo.Val.SymbolName = SymName; 160ff0cc061SDimitry Andric setOffset(0); // Offset is always 0. 161ff0cc061SDimitry Andric setTargetFlags(TargetFlags); 162ff0cc061SDimitry Andric } 163ff0cc061SDimitry Andric 164ff0cc061SDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) { 165ff0cc061SDimitry Andric assert((!isReg() || !isTied()) && 166ff0cc061SDimitry Andric "Cannot change a tied operand into an MCSymbol"); 167ff0cc061SDimitry Andric 168ff0cc061SDimitry Andric removeRegFromUses(); 169ff0cc061SDimitry Andric 170ff0cc061SDimitry Andric OpKind = MO_MCSymbol; 171ff0cc061SDimitry Andric Contents.Sym = Sym; 172ff0cc061SDimitry Andric } 173ff0cc061SDimitry Andric 174f22ef01cSRoman Divacky /// ChangeToRegister - Replace this operand with a new register operand of 175f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an register already, 176f22ef01cSRoman Divacky /// the setReg method should be used. 177f22ef01cSRoman Divacky void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, 178f22ef01cSRoman Divacky bool isKill, bool isDead, bool isUndef, 179f22ef01cSRoman Divacky bool isDebug) { 18091bc56edSDimitry Andric MachineRegisterInfo *RegInfo = nullptr; 181f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 182f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 183f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) 1847ae0e2c9SDimitry Andric RegInfo = &MF->getRegInfo(); 1857ae0e2c9SDimitry Andric // If this operand is already a register operand, remove it from the 1867ae0e2c9SDimitry Andric // register's use/def lists. 1873861d79fSDimitry Andric bool WasReg = isReg(); 1883861d79fSDimitry Andric if (RegInfo && WasReg) 1897ae0e2c9SDimitry Andric RegInfo->removeRegOperandFromUseList(this); 190f22ef01cSRoman Divacky 1917ae0e2c9SDimitry Andric // Change this to a register and set the reg#. 1927ae0e2c9SDimitry Andric OpKind = MO_Register; 1937ae0e2c9SDimitry Andric SmallContents.RegNo = Reg; 194139f7f9bSDimitry Andric SubReg_TargetFlags = 0; 195f22ef01cSRoman Divacky IsDef = isDef; 196f22ef01cSRoman Divacky IsImp = isImp; 197f22ef01cSRoman Divacky IsKill = isKill; 198f22ef01cSRoman Divacky IsDead = isDead; 199f22ef01cSRoman Divacky IsUndef = isUndef; 200dff0c46cSDimitry Andric IsInternalRead = false; 201f22ef01cSRoman Divacky IsEarlyClobber = false; 202f22ef01cSRoman Divacky IsDebug = isDebug; 2037ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false. 20491bc56edSDimitry Andric Contents.Reg.Prev = nullptr; 2053861d79fSDimitry Andric // Preserve the tie when the operand was already a register. 2063861d79fSDimitry Andric if (!WasReg) 2073861d79fSDimitry Andric TiedTo = 0; 2087ae0e2c9SDimitry Andric 2097ae0e2c9SDimitry Andric // If this operand is embedded in a function, add the operand to the 2107ae0e2c9SDimitry Andric // register's use/def list. 2117ae0e2c9SDimitry Andric if (RegInfo) 2127ae0e2c9SDimitry Andric RegInfo->addRegOperandToUseList(this); 213f22ef01cSRoman Divacky } 214f22ef01cSRoman Divacky 215f22ef01cSRoman Divacky /// isIdenticalTo - Return true if this operand is identical to the specified 2167ae0e2c9SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload 2177ae0e2c9SDimitry Andric /// below. 218f22ef01cSRoman Divacky bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 219f22ef01cSRoman Divacky if (getType() != Other.getType() || 220f22ef01cSRoman Divacky getTargetFlags() != Other.getTargetFlags()) 221f22ef01cSRoman Divacky return false; 222f22ef01cSRoman Divacky 223f22ef01cSRoman Divacky switch (getType()) { 224f22ef01cSRoman Divacky case MachineOperand::MO_Register: 225f22ef01cSRoman Divacky return getReg() == Other.getReg() && isDef() == Other.isDef() && 226f22ef01cSRoman Divacky getSubReg() == Other.getSubReg(); 227f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 228f22ef01cSRoman Divacky return getImm() == Other.getImm(); 22917a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 23017a519f9SDimitry Andric return getCImm() == Other.getCImm(); 231f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 232f22ef01cSRoman Divacky return getFPImm() == Other.getFPImm(); 233f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 234f22ef01cSRoman Divacky return getMBB() == Other.getMBB(); 235f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 236f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 237f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 2387ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 239f22ef01cSRoman Divacky return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 240f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 241f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 242f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 243f22ef01cSRoman Divacky return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 244f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 245f22ef01cSRoman Divacky return !strcmp(getSymbolName(), Other.getSymbolName()) && 246f22ef01cSRoman Divacky getOffset() == Other.getOffset(); 247f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 2483861d79fSDimitry Andric return getBlockAddress() == Other.getBlockAddress() && 2493861d79fSDimitry Andric getOffset() == Other.getOffset(); 25091bc56edSDimitry Andric case MachineOperand::MO_RegisterMask: 25191bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 252dff0c46cSDimitry Andric return getRegMask() == Other.getRegMask(); 253f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 254f22ef01cSRoman Divacky return getMCSymbol() == Other.getMCSymbol(); 25591bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 25691bc56edSDimitry Andric return getCFIIndex() == Other.getCFIIndex(); 257f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 258f22ef01cSRoman Divacky return getMetadata() == Other.getMetadata(); 259f22ef01cSRoman Divacky } 260dff0c46cSDimitry Andric llvm_unreachable("Invalid machine operand type"); 261f22ef01cSRoman Divacky } 262f22ef01cSRoman Divacky 2637ae0e2c9SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above. 2647ae0e2c9SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) { 2657ae0e2c9SDimitry Andric switch (MO.getType()) { 2667ae0e2c9SDimitry Andric case MachineOperand::MO_Register: 2673861d79fSDimitry Andric // Register operands don't have target flags. 2683861d79fSDimitry Andric return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef()); 2697ae0e2c9SDimitry Andric case MachineOperand::MO_Immediate: 2707ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 2717ae0e2c9SDimitry Andric case MachineOperand::MO_CImmediate: 2727ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 2737ae0e2c9SDimitry Andric case MachineOperand::MO_FPImmediate: 2747ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 2757ae0e2c9SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 2767ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 2777ae0e2c9SDimitry Andric case MachineOperand::MO_FrameIndex: 2787ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 2797ae0e2c9SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 2807ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 2817ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 2827ae0e2c9SDimitry Andric MO.getOffset()); 2837ae0e2c9SDimitry Andric case MachineOperand::MO_JumpTableIndex: 2847ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 2857ae0e2c9SDimitry Andric case MachineOperand::MO_ExternalSymbol: 2867ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 2877ae0e2c9SDimitry Andric MO.getSymbolName()); 2887ae0e2c9SDimitry Andric case MachineOperand::MO_GlobalAddress: 2897ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 2907ae0e2c9SDimitry Andric MO.getOffset()); 2917ae0e2c9SDimitry Andric case MachineOperand::MO_BlockAddress: 2927ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), 2933861d79fSDimitry Andric MO.getBlockAddress(), MO.getOffset()); 2947ae0e2c9SDimitry Andric case MachineOperand::MO_RegisterMask: 29591bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 2967ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); 2977ae0e2c9SDimitry Andric case MachineOperand::MO_Metadata: 2987ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 2997ae0e2c9SDimitry Andric case MachineOperand::MO_MCSymbol: 3007ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 30191bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 30291bc56edSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 3037ae0e2c9SDimitry Andric } 3047ae0e2c9SDimitry Andric llvm_unreachable("Invalid machine operand type"); 3057ae0e2c9SDimitry Andric } 3067ae0e2c9SDimitry Andric 307ff0cc061SDimitry Andric void MachineOperand::print(raw_ostream &OS, 308ff0cc061SDimitry Andric const TargetRegisterInfo *TRI) const { 3093dac3a9bSDimitry Andric ModuleSlotTracker DummyMST(nullptr); 3103dac3a9bSDimitry Andric print(OS, DummyMST, TRI); 3113dac3a9bSDimitry Andric } 3123dac3a9bSDimitry Andric 3133dac3a9bSDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 3143dac3a9bSDimitry Andric const TargetRegisterInfo *TRI) const { 315f22ef01cSRoman Divacky switch (getType()) { 316f22ef01cSRoman Divacky case MachineOperand::MO_Register: 3172754fe60SDimitry Andric OS << PrintReg(getReg(), TRI, getSubReg()); 318f22ef01cSRoman Divacky 319f22ef01cSRoman Divacky if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || 3203861d79fSDimitry Andric isInternalRead() || isEarlyClobber() || isTied()) { 321f22ef01cSRoman Divacky OS << '<'; 322f22ef01cSRoman Divacky bool NeedComma = false; 323f22ef01cSRoman Divacky if (isDef()) { 324f22ef01cSRoman Divacky if (NeedComma) OS << ','; 325f22ef01cSRoman Divacky if (isEarlyClobber()) 326f22ef01cSRoman Divacky OS << "earlyclobber,"; 327f22ef01cSRoman Divacky if (isImplicit()) 328f22ef01cSRoman Divacky OS << "imp-"; 329f22ef01cSRoman Divacky OS << "def"; 330f22ef01cSRoman Divacky NeedComma = true; 3317ae0e2c9SDimitry Andric // <def,read-undef> only makes sense when getSubReg() is set. 3327ae0e2c9SDimitry Andric // Don't clutter the output otherwise. 3337ae0e2c9SDimitry Andric if (isUndef() && getSubReg()) 3347ae0e2c9SDimitry Andric OS << ",read-undef"; 335f22ef01cSRoman Divacky } else if (isImplicit()) { 336f22ef01cSRoman Divacky OS << "imp-use"; 337f22ef01cSRoman Divacky NeedComma = true; 338f22ef01cSRoman Divacky } 339f22ef01cSRoman Divacky 340dff0c46cSDimitry Andric if (isKill()) { 3413861d79fSDimitry Andric if (NeedComma) OS << ','; 342dff0c46cSDimitry Andric OS << "kill"; 343dff0c46cSDimitry Andric NeedComma = true; 344dff0c46cSDimitry Andric } 345dff0c46cSDimitry Andric if (isDead()) { 3463861d79fSDimitry Andric if (NeedComma) OS << ','; 347dff0c46cSDimitry Andric OS << "dead"; 348dff0c46cSDimitry Andric NeedComma = true; 349dff0c46cSDimitry Andric } 3507ae0e2c9SDimitry Andric if (isUndef() && isUse()) { 351dff0c46cSDimitry Andric if (NeedComma) OS << ','; 352f22ef01cSRoman Divacky OS << "undef"; 353dff0c46cSDimitry Andric NeedComma = true; 354dff0c46cSDimitry Andric } 355dff0c46cSDimitry Andric if (isInternalRead()) { 356dff0c46cSDimitry Andric if (NeedComma) OS << ','; 357dff0c46cSDimitry Andric OS << "internal"; 358dff0c46cSDimitry Andric NeedComma = true; 359f22ef01cSRoman Divacky } 3603861d79fSDimitry Andric if (isTied()) { 3613861d79fSDimitry Andric if (NeedComma) OS << ','; 3623861d79fSDimitry Andric OS << "tied"; 3633861d79fSDimitry Andric if (TiedTo != 15) 3643861d79fSDimitry Andric OS << unsigned(TiedTo - 1); 365f22ef01cSRoman Divacky } 366f22ef01cSRoman Divacky OS << '>'; 367f22ef01cSRoman Divacky } 368f22ef01cSRoman Divacky break; 369f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 370f22ef01cSRoman Divacky OS << getImm(); 371f22ef01cSRoman Divacky break; 37217a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 37317a519f9SDimitry Andric getCImm()->getValue().print(OS, false); 37417a519f9SDimitry Andric break; 375f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 3763ca95b02SDimitry Andric if (getFPImm()->getType()->isFloatTy()) { 377f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToFloat(); 3783ca95b02SDimitry Andric } else if (getFPImm()->getType()->isHalfTy()) { 3793ca95b02SDimitry Andric APFloat APF = getFPImm()->getValueAPF(); 3803ca95b02SDimitry Andric bool Unused; 3813ca95b02SDimitry Andric APF.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &Unused); 3823ca95b02SDimitry Andric OS << "half " << APF.convertToFloat(); 3833ca95b02SDimitry Andric } else { 384f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToDouble(); 3853ca95b02SDimitry Andric } 386f22ef01cSRoman Divacky break; 387f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 388f22ef01cSRoman Divacky OS << "<BB#" << getMBB()->getNumber() << ">"; 389f22ef01cSRoman Divacky break; 390f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 391f22ef01cSRoman Divacky OS << "<fi#" << getIndex() << '>'; 392f22ef01cSRoman Divacky break; 393f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 394f22ef01cSRoman Divacky OS << "<cp#" << getIndex(); 395f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 396f22ef01cSRoman Divacky OS << '>'; 397f22ef01cSRoman Divacky break; 3987ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 3997ae0e2c9SDimitry Andric OS << "<ti#" << getIndex(); 4007ae0e2c9SDimitry Andric if (getOffset()) OS << "+" << getOffset(); 4017ae0e2c9SDimitry Andric OS << '>'; 4027ae0e2c9SDimitry Andric break; 403f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 404f22ef01cSRoman Divacky OS << "<jt#" << getIndex() << '>'; 405f22ef01cSRoman Divacky break; 406f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 407f22ef01cSRoman Divacky OS << "<ga:"; 4083dac3a9bSDimitry Andric getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 409f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 410f22ef01cSRoman Divacky OS << '>'; 411f22ef01cSRoman Divacky break; 412f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 413f22ef01cSRoman Divacky OS << "<es:" << getSymbolName(); 414f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 415f22ef01cSRoman Divacky OS << '>'; 416f22ef01cSRoman Divacky break; 417f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 418f22ef01cSRoman Divacky OS << '<'; 4193dac3a9bSDimitry Andric getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST); 4203861d79fSDimitry Andric if (getOffset()) OS << "+" << getOffset(); 421f22ef01cSRoman Divacky OS << '>'; 422f22ef01cSRoman Divacky break; 4237d523365SDimitry Andric case MachineOperand::MO_RegisterMask: { 4247d523365SDimitry Andric unsigned NumRegsInMask = 0; 4257d523365SDimitry Andric unsigned NumRegsEmitted = 0; 4267d523365SDimitry Andric OS << "<regmask"; 4277d523365SDimitry Andric for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { 4287d523365SDimitry Andric unsigned MaskWord = i / 32; 4297d523365SDimitry Andric unsigned MaskBit = i % 32; 4307d523365SDimitry Andric if (getRegMask()[MaskWord] & (1 << MaskBit)) { 4317d523365SDimitry Andric if (PrintWholeRegMask || NumRegsEmitted <= 10) { 4327d523365SDimitry Andric OS << " " << PrintReg(i, TRI); 4337d523365SDimitry Andric NumRegsEmitted++; 4347d523365SDimitry Andric } 4357d523365SDimitry Andric NumRegsInMask++; 4367d523365SDimitry Andric } 4377d523365SDimitry Andric } 4387d523365SDimitry Andric if (NumRegsEmitted != NumRegsInMask) 4397d523365SDimitry Andric OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; 4407d523365SDimitry Andric OS << ">"; 441dff0c46cSDimitry Andric break; 4427d523365SDimitry Andric } 44391bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 44491bc56edSDimitry Andric OS << "<regliveout>"; 44591bc56edSDimitry Andric break; 446f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 447f22ef01cSRoman Divacky OS << '<'; 4483dac3a9bSDimitry Andric getMetadata()->printAsOperand(OS, MST); 449f22ef01cSRoman Divacky OS << '>'; 450f22ef01cSRoman Divacky break; 451f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 452f22ef01cSRoman Divacky OS << "<MCSym=" << *getMCSymbol() << '>'; 453f22ef01cSRoman Divacky break; 45491bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 45591bc56edSDimitry Andric OS << "<call frame instruction>"; 45691bc56edSDimitry Andric break; 457f22ef01cSRoman Divacky } 458f22ef01cSRoman Divacky 459f22ef01cSRoman Divacky if (unsigned TF = getTargetFlags()) 460f22ef01cSRoman Divacky OS << "[TF=" << TF << ']'; 461f22ef01cSRoman Divacky } 462f22ef01cSRoman Divacky 463f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 464f22ef01cSRoman Divacky // MachineMemOperand Implementation 465f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 466f22ef01cSRoman Divacky 4672754fe60SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer 4682754fe60SDimitry Andric /// points into. 4692754fe60SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { 47091bc56edSDimitry Andric if (V.isNull() || V.is<const PseudoSourceValue*>()) return 0; 47191bc56edSDimitry Andric return cast<PointerType>(V.get<const Value*>()->getType())->getAddressSpace(); 4722754fe60SDimitry Andric } 4732754fe60SDimitry Andric 4742754fe60SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the 4752754fe60SDimitry Andric /// constant pool. 4767d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { 4777d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getConstantPool()); 4782754fe60SDimitry Andric } 4792754fe60SDimitry Andric 4802754fe60SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the 4812754fe60SDimitry Andric /// the specified FrameIndex. 4827d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, 4837d523365SDimitry Andric int FI, int64_t Offset) { 4847d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); 4852754fe60SDimitry Andric } 4862754fe60SDimitry Andric 4877d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { 4887d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getJumpTable()); 4892754fe60SDimitry Andric } 4902754fe60SDimitry Andric 4917d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { 4927d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getGOT()); 4932754fe60SDimitry Andric } 4942754fe60SDimitry Andric 4957d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, 4967d523365SDimitry Andric int64_t Offset) { 4977d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getStack(), Offset); 4982754fe60SDimitry Andric } 4992754fe60SDimitry Andric 5003ca95b02SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f, 5012754fe60SDimitry Andric uint64_t s, unsigned int a, 50239d628a0SDimitry Andric const AAMDNodes &AAInfo, 503dff0c46cSDimitry Andric const MDNode *Ranges) 5043ca95b02SDimitry Andric : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1), 50539d628a0SDimitry Andric AAInfo(AAInfo), Ranges(Ranges) { 50691bc56edSDimitry Andric assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue*>() || 50791bc56edSDimitry Andric isa<PointerType>(PtrInfo.V.get<const Value*>()->getType())) && 5082754fe60SDimitry Andric "invalid pointer value"); 509f22ef01cSRoman Divacky assert(getBaseAlignment() == a && "Alignment is not a power of 2!"); 510f22ef01cSRoman Divacky assert((isLoad() || isStore()) && "Not a load/store!"); 511f22ef01cSRoman Divacky } 512f22ef01cSRoman Divacky 513f22ef01cSRoman Divacky /// Profile - Gather unique data for the object. 514f22ef01cSRoman Divacky /// 515f22ef01cSRoman Divacky void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 5162754fe60SDimitry Andric ID.AddInteger(getOffset()); 517f22ef01cSRoman Divacky ID.AddInteger(Size); 51891bc56edSDimitry Andric ID.AddPointer(getOpaqueValue()); 5193ca95b02SDimitry Andric ID.AddInteger(getFlags()); 5203ca95b02SDimitry Andric ID.AddInteger(getBaseAlignment()); 521f22ef01cSRoman Divacky } 522f22ef01cSRoman Divacky 523f22ef01cSRoman Divacky void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 524f22ef01cSRoman Divacky // The Value and Offset may differ due to CSE. But the flags and size 525f22ef01cSRoman Divacky // should be the same. 526f22ef01cSRoman Divacky assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 527f22ef01cSRoman Divacky assert(MMO->getSize() == getSize() && "Size mismatch!"); 528f22ef01cSRoman Divacky 529f22ef01cSRoman Divacky if (MMO->getBaseAlignment() >= getBaseAlignment()) { 530f22ef01cSRoman Divacky // Update the alignment value. 5313ca95b02SDimitry Andric BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1; 532f22ef01cSRoman Divacky // Also update the base and offset, because the new alignment may 533f22ef01cSRoman Divacky // not be applicable with the old ones. 5342754fe60SDimitry Andric PtrInfo = MMO->PtrInfo; 535f22ef01cSRoman Divacky } 536f22ef01cSRoman Divacky } 537f22ef01cSRoman Divacky 538f22ef01cSRoman Divacky /// getAlignment - Return the minimum known alignment in bytes of the 539f22ef01cSRoman Divacky /// actual memory reference. 540f22ef01cSRoman Divacky uint64_t MachineMemOperand::getAlignment() const { 541f22ef01cSRoman Divacky return MinAlign(getBaseAlignment(), getOffset()); 542f22ef01cSRoman Divacky } 543f22ef01cSRoman Divacky 5443dac3a9bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS) const { 5453dac3a9bSDimitry Andric ModuleSlotTracker DummyMST(nullptr); 5463dac3a9bSDimitry Andric print(OS, DummyMST); 5473dac3a9bSDimitry Andric } 5483dac3a9bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const { 5493dac3a9bSDimitry Andric assert((isLoad() || isStore()) && 550f22ef01cSRoman Divacky "SV has to be a load, store or both."); 551f22ef01cSRoman Divacky 5523dac3a9bSDimitry Andric if (isVolatile()) 553f22ef01cSRoman Divacky OS << "Volatile "; 554f22ef01cSRoman Divacky 5553dac3a9bSDimitry Andric if (isLoad()) 556f22ef01cSRoman Divacky OS << "LD"; 5573dac3a9bSDimitry Andric if (isStore()) 558f22ef01cSRoman Divacky OS << "ST"; 5593dac3a9bSDimitry Andric OS << getSize(); 560f22ef01cSRoman Divacky 561f22ef01cSRoman Divacky // Print the address information. 562f22ef01cSRoman Divacky OS << "["; 5633dac3a9bSDimitry Andric if (const Value *V = getValue()) 5643dac3a9bSDimitry Andric V->printAsOperand(OS, /*PrintType=*/false, MST); 5653dac3a9bSDimitry Andric else if (const PseudoSourceValue *PSV = getPseudoValue()) 56691bc56edSDimitry Andric PSV->printCustom(OS); 567f22ef01cSRoman Divacky else 56891bc56edSDimitry Andric OS << "<unknown>"; 56991bc56edSDimitry Andric 5703dac3a9bSDimitry Andric unsigned AS = getAddrSpace(); 57191bc56edSDimitry Andric if (AS != 0) 57291bc56edSDimitry Andric OS << "(addrspace=" << AS << ')'; 573f22ef01cSRoman Divacky 574f22ef01cSRoman Divacky // If the alignment of the memory reference itself differs from the alignment 575f22ef01cSRoman Divacky // of the base pointer, print the base alignment explicitly, next to the base 576f22ef01cSRoman Divacky // pointer. 5773dac3a9bSDimitry Andric if (getBaseAlignment() != getAlignment()) 5783dac3a9bSDimitry Andric OS << "(align=" << getBaseAlignment() << ")"; 579f22ef01cSRoman Divacky 5803dac3a9bSDimitry Andric if (getOffset() != 0) 5813dac3a9bSDimitry Andric OS << "+" << getOffset(); 582f22ef01cSRoman Divacky OS << "]"; 583f22ef01cSRoman Divacky 584f22ef01cSRoman Divacky // Print the alignment of the reference. 5853dac3a9bSDimitry Andric if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize()) 5863dac3a9bSDimitry Andric OS << "(align=" << getAlignment() << ")"; 587f22ef01cSRoman Divacky 5882754fe60SDimitry Andric // Print TBAA info. 5893dac3a9bSDimitry Andric if (const MDNode *TBAAInfo = getAAInfo().TBAA) { 5902754fe60SDimitry Andric OS << "(tbaa="; 5912754fe60SDimitry Andric if (TBAAInfo->getNumOperands() > 0) 5923dac3a9bSDimitry Andric TBAAInfo->getOperand(0)->printAsOperand(OS, MST); 59339d628a0SDimitry Andric else 59439d628a0SDimitry Andric OS << "<unknown>"; 59539d628a0SDimitry Andric OS << ")"; 59639d628a0SDimitry Andric } 59739d628a0SDimitry Andric 59839d628a0SDimitry Andric // Print AA scope info. 5993dac3a9bSDimitry Andric if (const MDNode *ScopeInfo = getAAInfo().Scope) { 60039d628a0SDimitry Andric OS << "(alias.scope="; 60139d628a0SDimitry Andric if (ScopeInfo->getNumOperands() > 0) 60239d628a0SDimitry Andric for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { 6033dac3a9bSDimitry Andric ScopeInfo->getOperand(i)->printAsOperand(OS, MST); 60439d628a0SDimitry Andric if (i != ie-1) 60539d628a0SDimitry Andric OS << ","; 60639d628a0SDimitry Andric } 60739d628a0SDimitry Andric else 60839d628a0SDimitry Andric OS << "<unknown>"; 60939d628a0SDimitry Andric OS << ")"; 61039d628a0SDimitry Andric } 61139d628a0SDimitry Andric 61239d628a0SDimitry Andric // Print AA noalias scope info. 6133dac3a9bSDimitry Andric if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) { 61439d628a0SDimitry Andric OS << "(noalias="; 61539d628a0SDimitry Andric if (NoAliasInfo->getNumOperands() > 0) 61639d628a0SDimitry Andric for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { 6173dac3a9bSDimitry Andric NoAliasInfo->getOperand(i)->printAsOperand(OS, MST); 61839d628a0SDimitry Andric if (i != ie-1) 61939d628a0SDimitry Andric OS << ","; 62039d628a0SDimitry Andric } 6212754fe60SDimitry Andric else 6222754fe60SDimitry Andric OS << "<unknown>"; 6232754fe60SDimitry Andric OS << ")"; 6242754fe60SDimitry Andric } 6252754fe60SDimitry Andric 6263b0f4066SDimitry Andric // Print nontemporal info. 6273dac3a9bSDimitry Andric if (isNonTemporal()) 6283b0f4066SDimitry Andric OS << "(nontemporal)"; 6293b0f4066SDimitry Andric 6303dac3a9bSDimitry Andric if (isInvariant()) 6313dac3a9bSDimitry Andric OS << "(invariant)"; 632f22ef01cSRoman Divacky } 633f22ef01cSRoman Divacky 634f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 635f22ef01cSRoman Divacky // MachineInstr Implementation 636f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 637f22ef01cSRoman Divacky 638139f7f9bSDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { 63917a519f9SDimitry Andric if (MCID->ImplicitDefs) 6407d523365SDimitry Andric for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; 6417d523365SDimitry Andric ++ImpDefs) 642139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true)); 64317a519f9SDimitry Andric if (MCID->ImplicitUses) 6447d523365SDimitry Andric for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses; 6457d523365SDimitry Andric ++ImpUses) 646139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true)); 647f22ef01cSRoman Divacky } 648f22ef01cSRoman Divacky 649f22ef01cSRoman Divacky /// MachineInstr ctor - This constructor creates a MachineInstr and adds the 650f22ef01cSRoman Divacky /// implicit operands. It reserves space for the number of operands specified by 65117a519f9SDimitry Andric /// the MCInstrDesc. 652139f7f9bSDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid, 653ff0cc061SDimitry Andric DebugLoc dl, bool NoImp) 654ff0cc061SDimitry Andric : MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), Flags(0), 655ff0cc061SDimitry Andric AsmPrinterFlags(0), NumMemRefs(0), MemRefs(nullptr), 6563ca95b02SDimitry Andric debugLoc(std::move(dl)) 6573ca95b02SDimitry Andric #ifdef LLVM_BUILD_GLOBAL_ISEL 6583ca95b02SDimitry Andric , 6593ca95b02SDimitry Andric Ty(nullptr) 6603ca95b02SDimitry Andric #endif 6613ca95b02SDimitry Andric { 66239d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 66339d628a0SDimitry Andric 664139f7f9bSDimitry Andric // Reserve space for the expected number of operands. 665139f7f9bSDimitry Andric if (unsigned NumOps = MCID->getNumOperands() + 666139f7f9bSDimitry Andric MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) { 667139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(NumOps); 668139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 669f22ef01cSRoman Divacky } 670f22ef01cSRoman Divacky 671139f7f9bSDimitry Andric if (!NoImp) 672139f7f9bSDimitry Andric addImplicitDefUseOperands(MF); 673f22ef01cSRoman Divacky } 674f22ef01cSRoman Divacky 675f22ef01cSRoman Divacky /// MachineInstr ctor - Copies MachineInstr arg exactly 676f22ef01cSRoman Divacky /// 677f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) 67891bc56edSDimitry Andric : MCID(&MI.getDesc()), Parent(nullptr), Operands(nullptr), NumOperands(0), 6793ca95b02SDimitry Andric Flags(0), AsmPrinterFlags(0), NumMemRefs(MI.NumMemRefs), 6803ca95b02SDimitry Andric MemRefs(MI.MemRefs), debugLoc(MI.getDebugLoc()) 6813ca95b02SDimitry Andric #ifdef LLVM_BUILD_GLOBAL_ISEL 6823ca95b02SDimitry Andric , 6833ca95b02SDimitry Andric Ty(nullptr) 6843ca95b02SDimitry Andric #endif 6853ca95b02SDimitry Andric { 68639d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 68739d628a0SDimitry Andric 688139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(MI.getNumOperands()); 689139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 690f22ef01cSRoman Divacky 691139f7f9bSDimitry Andric // Copy operands. 692ff0cc061SDimitry Andric for (const MachineOperand &MO : MI.operands()) 693ff0cc061SDimitry Andric addOperand(MF, MO); 694f22ef01cSRoman Divacky 695139f7f9bSDimitry Andric // Copy all the sensible flags. 696139f7f9bSDimitry Andric setFlags(MI.Flags); 697f22ef01cSRoman Divacky } 698f22ef01cSRoman Divacky 699f22ef01cSRoman Divacky /// getRegInfo - If this instruction is embedded into a MachineFunction, 700f22ef01cSRoman Divacky /// return the MachineRegisterInfo object for the current function, otherwise 701f22ef01cSRoman Divacky /// return null. 702f22ef01cSRoman Divacky MachineRegisterInfo *MachineInstr::getRegInfo() { 703f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = getParent()) 704f22ef01cSRoman Divacky return &MBB->getParent()->getRegInfo(); 70591bc56edSDimitry Andric return nullptr; 706f22ef01cSRoman Divacky } 707f22ef01cSRoman Divacky 7083ca95b02SDimitry Andric // Implement dummy setter and getter for type when 7093ca95b02SDimitry Andric // global-isel is not built. 7103ca95b02SDimitry Andric // The proper implementation is WIP and is tracked here: 7113ca95b02SDimitry Andric // PR26576. 7123ca95b02SDimitry Andric #ifndef LLVM_BUILD_GLOBAL_ISEL 7133ca95b02SDimitry Andric void MachineInstr::setType(Type *Ty) {} 7143ca95b02SDimitry Andric 7153ca95b02SDimitry Andric Type *MachineInstr::getType() const { return nullptr; } 7163ca95b02SDimitry Andric 7173ca95b02SDimitry Andric #else 7183ca95b02SDimitry Andric void MachineInstr::setType(Type *Ty) { 7193ca95b02SDimitry Andric assert((!Ty || isPreISelGenericOpcode(getOpcode())) && 7203ca95b02SDimitry Andric "Non generic instructions are not supposed to be typed"); 7213ca95b02SDimitry Andric this->Ty = Ty; 7223ca95b02SDimitry Andric } 7233ca95b02SDimitry Andric 7243ca95b02SDimitry Andric Type *MachineInstr::getType() const { return Ty; } 7253ca95b02SDimitry Andric #endif // LLVM_BUILD_GLOBAL_ISEL 7263ca95b02SDimitry Andric 727f22ef01cSRoman Divacky /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in 728f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 729f22ef01cSRoman Divacky /// operands already be on their use lists. 7307ae0e2c9SDimitry Andric void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) { 731ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 732ff0cc061SDimitry Andric if (MO.isReg()) 733ff0cc061SDimitry Andric MRI.removeRegOperandFromUseList(&MO); 734f22ef01cSRoman Divacky } 735f22ef01cSRoman Divacky 736f22ef01cSRoman Divacky /// AddRegOperandsToUseLists - Add all of the register operands in 737f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 738f22ef01cSRoman Divacky /// operands not be on their use lists yet. 7397ae0e2c9SDimitry Andric void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) { 740ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 741ff0cc061SDimitry Andric if (MO.isReg()) 742ff0cc061SDimitry Andric MRI.addRegOperandToUseList(&MO); 743f22ef01cSRoman Divacky } 744f22ef01cSRoman Divacky 745139f7f9bSDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) { 746139f7f9bSDimitry Andric MachineBasicBlock *MBB = getParent(); 747139f7f9bSDimitry Andric assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs"); 748139f7f9bSDimitry Andric MachineFunction *MF = MBB->getParent(); 749139f7f9bSDimitry Andric assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs"); 750139f7f9bSDimitry Andric addOperand(*MF, Op); 751139f7f9bSDimitry Andric } 752139f7f9bSDimitry Andric 753139f7f9bSDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping 754139f7f9bSDimitry Andric /// ranges. If MRI is non-null also update use-def chains. 755139f7f9bSDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src, 756139f7f9bSDimitry Andric unsigned NumOps, MachineRegisterInfo *MRI) { 757139f7f9bSDimitry Andric if (MRI) 758139f7f9bSDimitry Andric return MRI->moveOperands(Dst, Src, NumOps); 759139f7f9bSDimitry Andric 760ff0cc061SDimitry Andric // MachineOperand is a trivially copyable type so we can just use memmove. 761ff0cc061SDimitry Andric std::memmove(Dst, Src, NumOps * sizeof(MachineOperand)); 762139f7f9bSDimitry Andric } 763139f7f9bSDimitry Andric 764f22ef01cSRoman Divacky /// addOperand - Add the specified operand to the instruction. If it is an 765f22ef01cSRoman Divacky /// implicit operand, it is added to the end of the operand list. If it is 766f22ef01cSRoman Divacky /// an explicit operand it is added at the end of the explicit operand list 767f22ef01cSRoman Divacky /// (before the first implicit operand). 768139f7f9bSDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { 7696122f3e6SDimitry Andric assert(MCID && "Cannot add operands before providing an instr descriptor"); 770f22ef01cSRoman Divacky 771139f7f9bSDimitry Andric // Check if we're adding one of our existing operands. 772139f7f9bSDimitry Andric if (&Op >= Operands && &Op < Operands + NumOperands) { 773139f7f9bSDimitry Andric // This is unusual: MI->addOperand(MI->getOperand(i)). 774139f7f9bSDimitry Andric // If adding Op requires reallocating or moving existing operands around, 775139f7f9bSDimitry Andric // the Op reference could go stale. Support it by copying Op. 776139f7f9bSDimitry Andric MachineOperand CopyOp(Op); 777139f7f9bSDimitry Andric return addOperand(MF, CopyOp); 778139f7f9bSDimitry Andric } 779f22ef01cSRoman Divacky 7806122f3e6SDimitry Andric // Find the insert location for the new operand. Implicit registers go at 781139f7f9bSDimitry Andric // the end, everything else goes before the implicit regs. 782139f7f9bSDimitry Andric // 7836122f3e6SDimitry Andric // FIXME: Allow mixed explicit and implicit operands on inline asm. 7846122f3e6SDimitry Andric // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as 7856122f3e6SDimitry Andric // implicit-defs, but they must not be moved around. See the FIXME in 7866122f3e6SDimitry Andric // InstrEmitter.cpp. 787139f7f9bSDimitry Andric unsigned OpNo = getNumOperands(); 788139f7f9bSDimitry Andric bool isImpReg = Op.isReg() && Op.isImplicit(); 7896122f3e6SDimitry Andric if (!isImpReg && !isInlineAsm()) { 7906122f3e6SDimitry Andric while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) { 7916122f3e6SDimitry Andric --OpNo; 7923861d79fSDimitry Andric assert(!Operands[OpNo].isTied() && "Cannot move tied operands"); 793f22ef01cSRoman Divacky } 794f22ef01cSRoman Divacky } 795f22ef01cSRoman Divacky 796f785676fSDimitry Andric #ifndef NDEBUG 797f785676fSDimitry Andric bool isMetaDataOp = Op.getType() == MachineOperand::MO_Metadata; 7986122f3e6SDimitry Andric // OpNo now points as the desired insertion point. Unless this is a variadic 7996122f3e6SDimitry Andric // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). 8007ae0e2c9SDimitry Andric // RegMask operands go between the explicit and implicit operands. 8017ae0e2c9SDimitry Andric assert((isImpReg || Op.isRegMask() || MCID->isVariadic() || 802f785676fSDimitry Andric OpNo < MCID->getNumOperands() || isMetaDataOp) && 8036122f3e6SDimitry Andric "Trying to add an operand to a machine instr that is already done!"); 804f785676fSDimitry Andric #endif 805f22ef01cSRoman Divacky 806139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 807f22ef01cSRoman Divacky 808139f7f9bSDimitry Andric // Determine if the Operands array needs to be reallocated. 809139f7f9bSDimitry Andric // Save the old capacity and operand array. 810139f7f9bSDimitry Andric OperandCapacity OldCap = CapOperands; 811139f7f9bSDimitry Andric MachineOperand *OldOperands = Operands; 812139f7f9bSDimitry Andric if (!OldOperands || OldCap.getSize() == getNumOperands()) { 813139f7f9bSDimitry Andric CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1); 814139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 815139f7f9bSDimitry Andric // Move the operands before the insertion point. 816139f7f9bSDimitry Andric if (OpNo) 817139f7f9bSDimitry Andric moveOperands(Operands, OldOperands, OpNo, MRI); 818139f7f9bSDimitry Andric } 819f22ef01cSRoman Divacky 820139f7f9bSDimitry Andric // Move the operands following the insertion point. 821139f7f9bSDimitry Andric if (OpNo != NumOperands) 822139f7f9bSDimitry Andric moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo, 823139f7f9bSDimitry Andric MRI); 824139f7f9bSDimitry Andric ++NumOperands; 8256122f3e6SDimitry Andric 826139f7f9bSDimitry Andric // Deallocate the old operand array. 827139f7f9bSDimitry Andric if (OldOperands != Operands && OldOperands) 828139f7f9bSDimitry Andric MF.deallocateOperandArray(OldCap, OldOperands); 829139f7f9bSDimitry Andric 830139f7f9bSDimitry Andric // Copy Op into place. It still needs to be inserted into the MRI use lists. 831139f7f9bSDimitry Andric MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op); 832139f7f9bSDimitry Andric NewMO->ParentMI = this; 833139f7f9bSDimitry Andric 834139f7f9bSDimitry Andric // When adding a register operand, tell MRI about it. 835139f7f9bSDimitry Andric if (NewMO->isReg()) { 8367ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false, regardless of Op's status. 83791bc56edSDimitry Andric NewMO->Contents.Reg.Prev = nullptr; 8383861d79fSDimitry Andric // Ignore existing ties. This is not a property that can be copied. 839139f7f9bSDimitry Andric NewMO->TiedTo = 0; 840139f7f9bSDimitry Andric // Add the new operand to MRI, but only for instructions in an MBB. 841139f7f9bSDimitry Andric if (MRI) 842139f7f9bSDimitry Andric MRI->addRegOperandToUseList(NewMO); 8433861d79fSDimitry Andric // The MCID operand information isn't accurate until we start adding 8443861d79fSDimitry Andric // explicit operands. The implicit operands are added first, then the 8453861d79fSDimitry Andric // explicits are inserted before them. 8463861d79fSDimitry Andric if (!isImpReg) { 8473861d79fSDimitry Andric // Tie uses to defs as indicated in MCInstrDesc. 848139f7f9bSDimitry Andric if (NewMO->isUse()) { 8493861d79fSDimitry Andric int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO); 8503861d79fSDimitry Andric if (DefIdx != -1) 8513861d79fSDimitry Andric tieOperands(DefIdx, OpNo); 8523861d79fSDimitry Andric } 8536122f3e6SDimitry Andric // If the register operand is flagged as early, mark the operand as such. 85417a519f9SDimitry Andric if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) 855139f7f9bSDimitry Andric NewMO->setIsEarlyClobber(true); 856f22ef01cSRoman Divacky } 857f22ef01cSRoman Divacky } 858f22ef01cSRoman Divacky } 859f22ef01cSRoman Divacky 860f22ef01cSRoman Divacky /// RemoveOperand - Erase an operand from an instruction, leaving it with one 861f22ef01cSRoman Divacky /// fewer operand than it started with. 862f22ef01cSRoman Divacky /// 863f22ef01cSRoman Divacky void MachineInstr::RemoveOperand(unsigned OpNo) { 864139f7f9bSDimitry Andric assert(OpNo < getNumOperands() && "Invalid operand number"); 8653861d79fSDimitry Andric untieRegOperand(OpNo); 866f22ef01cSRoman Divacky 8673861d79fSDimitry Andric #ifndef NDEBUG 8683861d79fSDimitry Andric // Moving tied operands would break the ties. 869139f7f9bSDimitry Andric for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i) 8703861d79fSDimitry Andric if (Operands[i].isReg()) 8713861d79fSDimitry Andric assert(!Operands[i].isTied() && "Cannot move tied operands"); 8723861d79fSDimitry Andric #endif 8733861d79fSDimitry Andric 874139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 875139f7f9bSDimitry Andric if (MRI && Operands[OpNo].isReg()) 876139f7f9bSDimitry Andric MRI->removeRegOperandFromUseList(Operands + OpNo); 877f22ef01cSRoman Divacky 878139f7f9bSDimitry Andric // Don't call the MachineOperand destructor. A lot of this code depends on 879139f7f9bSDimitry Andric // MachineOperand having a trivial destructor anyway, and adding a call here 880139f7f9bSDimitry Andric // wouldn't make it 'destructor-correct'. 881139f7f9bSDimitry Andric 882139f7f9bSDimitry Andric if (unsigned N = NumOperands - 1 - OpNo) 883139f7f9bSDimitry Andric moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI); 884139f7f9bSDimitry Andric --NumOperands; 885f22ef01cSRoman Divacky } 886f22ef01cSRoman Divacky 887f22ef01cSRoman Divacky /// addMemOperand - Add a MachineMemOperand to the machine instruction. 888f22ef01cSRoman Divacky /// This function should be used only occasionally. The setMemRefs function 889f22ef01cSRoman Divacky /// is the primary method for setting up a MachineInstr's MemRefs list. 890f22ef01cSRoman Divacky void MachineInstr::addMemOperand(MachineFunction &MF, 891f22ef01cSRoman Divacky MachineMemOperand *MO) { 892f22ef01cSRoman Divacky mmo_iterator OldMemRefs = MemRefs; 893139f7f9bSDimitry Andric unsigned OldNumMemRefs = NumMemRefs; 894f22ef01cSRoman Divacky 895139f7f9bSDimitry Andric unsigned NewNum = NumMemRefs + 1; 896f22ef01cSRoman Divacky mmo_iterator NewMemRefs = MF.allocateMemRefsArray(NewNum); 897f22ef01cSRoman Divacky 898dff0c46cSDimitry Andric std::copy(OldMemRefs, OldMemRefs + OldNumMemRefs, NewMemRefs); 899f22ef01cSRoman Divacky NewMemRefs[NewNum - 1] = MO; 900139f7f9bSDimitry Andric setMemRefs(NewMemRefs, NewMemRefs + NewNum); 901dff0c46cSDimitry Andric } 902dff0c46cSDimitry Andric 903444ed5c5SDimitry Andric /// Check to see if the MMOs pointed to by the two MemRefs arrays are 904444ed5c5SDimitry Andric /// identical. 905444ed5c5SDimitry Andric static bool hasIdenticalMMOs(const MachineInstr &MI1, const MachineInstr &MI2) { 906444ed5c5SDimitry Andric auto I1 = MI1.memoperands_begin(), E1 = MI1.memoperands_end(); 907444ed5c5SDimitry Andric auto I2 = MI2.memoperands_begin(), E2 = MI2.memoperands_end(); 908444ed5c5SDimitry Andric if ((E1 - I1) != (E2 - I2)) 909444ed5c5SDimitry Andric return false; 910444ed5c5SDimitry Andric for (; I1 != E1; ++I1, ++I2) { 911444ed5c5SDimitry Andric if (**I1 != **I2) 912444ed5c5SDimitry Andric return false; 913444ed5c5SDimitry Andric } 914444ed5c5SDimitry Andric return true; 915444ed5c5SDimitry Andric } 916444ed5c5SDimitry Andric 9174d0b32cdSDimitry Andric std::pair<MachineInstr::mmo_iterator, unsigned> 9184d0b32cdSDimitry Andric MachineInstr::mergeMemRefsWith(const MachineInstr& Other) { 919444ed5c5SDimitry Andric 920444ed5c5SDimitry Andric // If either of the incoming memrefs are empty, we must be conservative and 921444ed5c5SDimitry Andric // treat this as if we've exhausted our space for memrefs and dropped them. 922444ed5c5SDimitry Andric if (memoperands_empty() || Other.memoperands_empty()) 923444ed5c5SDimitry Andric return std::make_pair(nullptr, 0); 924444ed5c5SDimitry Andric 925444ed5c5SDimitry Andric // If both instructions have identical memrefs, we don't need to merge them. 926444ed5c5SDimitry Andric // Since many instructions have a single memref, and we tend to merge things 927444ed5c5SDimitry Andric // like pairs of loads from the same location, this catches a large number of 928444ed5c5SDimitry Andric // cases in practice. 929444ed5c5SDimitry Andric if (hasIdenticalMMOs(*this, Other)) 930444ed5c5SDimitry Andric return std::make_pair(MemRefs, NumMemRefs); 931444ed5c5SDimitry Andric 9324d0b32cdSDimitry Andric // TODO: consider uniquing elements within the operand lists to reduce 9334d0b32cdSDimitry Andric // space usage and fall back to conservative information less often. 934444ed5c5SDimitry Andric size_t CombinedNumMemRefs = NumMemRefs + Other.NumMemRefs; 935444ed5c5SDimitry Andric 936444ed5c5SDimitry Andric // If we don't have enough room to store this many memrefs, be conservative 937444ed5c5SDimitry Andric // and drop them. Otherwise, we'd fail asserts when trying to add them to 938444ed5c5SDimitry Andric // the new instruction. 939444ed5c5SDimitry Andric if (CombinedNumMemRefs != uint8_t(CombinedNumMemRefs)) 940444ed5c5SDimitry Andric return std::make_pair(nullptr, 0); 9414d0b32cdSDimitry Andric 9424d0b32cdSDimitry Andric MachineFunction *MF = getParent()->getParent(); 9434d0b32cdSDimitry Andric mmo_iterator MemBegin = MF->allocateMemRefsArray(CombinedNumMemRefs); 9444d0b32cdSDimitry Andric mmo_iterator MemEnd = std::copy(memoperands_begin(), memoperands_end(), 9454d0b32cdSDimitry Andric MemBegin); 9464d0b32cdSDimitry Andric MemEnd = std::copy(Other.memoperands_begin(), Other.memoperands_end(), 9474d0b32cdSDimitry Andric MemEnd); 9484d0b32cdSDimitry Andric assert(MemEnd - MemBegin == (ptrdiff_t)CombinedNumMemRefs && 9494d0b32cdSDimitry Andric "missing memrefs"); 9504d0b32cdSDimitry Andric 9514d0b32cdSDimitry Andric return std::make_pair(MemBegin, CombinedNumMemRefs); 9524d0b32cdSDimitry Andric } 9534d0b32cdSDimitry Andric 954dff0c46cSDimitry Andric bool MachineInstr::hasPropertyInBundle(unsigned Mask, QueryType Type) const { 955139f7f9bSDimitry Andric assert(!isBundledWithPred() && "Must be called on bundle header"); 9567d523365SDimitry Andric for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) { 957dff0c46cSDimitry Andric if (MII->getDesc().getFlags() & Mask) { 958dff0c46cSDimitry Andric if (Type == AnyInBundle) 959dff0c46cSDimitry Andric return true; 960dff0c46cSDimitry Andric } else { 961139f7f9bSDimitry Andric if (Type == AllInBundle && !MII->isBundle()) 962dff0c46cSDimitry Andric return false; 963dff0c46cSDimitry Andric } 964139f7f9bSDimitry Andric // This was the last instruction in the bundle. 965139f7f9bSDimitry Andric if (!MII->isBundledWithSucc()) 966dff0c46cSDimitry Andric return Type == AllInBundle; 967f22ef01cSRoman Divacky } 968139f7f9bSDimitry Andric } 969f22ef01cSRoman Divacky 9703ca95b02SDimitry Andric bool MachineInstr::isIdenticalTo(const MachineInstr &Other, 971f22ef01cSRoman Divacky MICheckType Check) const { 972f22ef01cSRoman Divacky // If opcodes or number of operands are not the same then the two 973f22ef01cSRoman Divacky // instructions are obviously not identical. 9743ca95b02SDimitry Andric if (Other.getOpcode() != getOpcode() || 9753ca95b02SDimitry Andric Other.getNumOperands() != getNumOperands()) 976f22ef01cSRoman Divacky return false; 977f22ef01cSRoman Divacky 978dff0c46cSDimitry Andric if (isBundle()) { 979dff0c46cSDimitry Andric // Both instructions are bundles, compare MIs inside the bundle. 9807d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I1 = getIterator(); 981dff0c46cSDimitry Andric MachineBasicBlock::const_instr_iterator E1 = getParent()->instr_end(); 9823ca95b02SDimitry Andric MachineBasicBlock::const_instr_iterator I2 = Other.getIterator(); 9833ca95b02SDimitry Andric MachineBasicBlock::const_instr_iterator E2 = Other.getParent()->instr_end(); 984dff0c46cSDimitry Andric while (++I1 != E1 && I1->isInsideBundle()) { 985dff0c46cSDimitry Andric ++I2; 9863ca95b02SDimitry Andric if (I2 == E2 || !I2->isInsideBundle() || !I1->isIdenticalTo(*I2, Check)) 987dff0c46cSDimitry Andric return false; 988dff0c46cSDimitry Andric } 989dff0c46cSDimitry Andric } 990dff0c46cSDimitry Andric 991f22ef01cSRoman Divacky // Check operands to make sure they match. 992f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 993f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 9943ca95b02SDimitry Andric const MachineOperand &OMO = Other.getOperand(i); 995bd5abe19SDimitry Andric if (!MO.isReg()) { 996bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 997bd5abe19SDimitry Andric return false; 998bd5abe19SDimitry Andric continue; 999bd5abe19SDimitry Andric } 1000bd5abe19SDimitry Andric 1001f22ef01cSRoman Divacky // Clients may or may not want to ignore defs when testing for equality. 1002f22ef01cSRoman Divacky // For example, machine CSE pass only cares about finding common 1003f22ef01cSRoman Divacky // subexpressions, so it's safe to ignore virtual register defs. 1004bd5abe19SDimitry Andric if (MO.isDef()) { 1005f22ef01cSRoman Divacky if (Check == IgnoreDefs) 1006f22ef01cSRoman Divacky continue; 1007bd5abe19SDimitry Andric else if (Check == IgnoreVRegDefs) { 1008f22ef01cSRoman Divacky if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) || 1009f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(OMO.getReg())) 1010f22ef01cSRoman Divacky if (MO.getReg() != OMO.getReg()) 1011f22ef01cSRoman Divacky return false; 1012bd5abe19SDimitry Andric } else { 1013bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1014f22ef01cSRoman Divacky return false; 1015bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isDead() != OMO.isDead()) 1016bd5abe19SDimitry Andric return false; 1017bd5abe19SDimitry Andric } 1018bd5abe19SDimitry Andric } else { 1019bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 1020bd5abe19SDimitry Andric return false; 1021bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isKill() != OMO.isKill()) 1022bd5abe19SDimitry Andric return false; 1023bd5abe19SDimitry Andric } 1024f22ef01cSRoman Divacky } 102517a519f9SDimitry Andric // If DebugLoc does not match then two dbg.values are not identical. 102617a519f9SDimitry Andric if (isDebugValue()) 10273ca95b02SDimitry Andric if (getDebugLoc() && Other.getDebugLoc() && 10283ca95b02SDimitry Andric getDebugLoc() != Other.getDebugLoc()) 102917a519f9SDimitry Andric return false; 1030f22ef01cSRoman Divacky return true; 1031f22ef01cSRoman Divacky } 1032f22ef01cSRoman Divacky 1033f22ef01cSRoman Divacky MachineInstr *MachineInstr::removeFromParent() { 1034f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 1035139f7f9bSDimitry Andric return getParent()->remove(this); 1036f22ef01cSRoman Divacky } 1037f22ef01cSRoman Divacky 1038139f7f9bSDimitry Andric MachineInstr *MachineInstr::removeFromBundle() { 1039139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 1040139f7f9bSDimitry Andric return getParent()->remove_instr(this); 1041139f7f9bSDimitry Andric } 1042f22ef01cSRoman Divacky 1043f22ef01cSRoman Divacky void MachineInstr::eraseFromParent() { 1044f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 1045139f7f9bSDimitry Andric getParent()->erase(this); 1046f22ef01cSRoman Divacky } 1047f22ef01cSRoman Divacky 104839d628a0SDimitry Andric void MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval() { 104939d628a0SDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 105039d628a0SDimitry Andric MachineBasicBlock *MBB = getParent(); 105139d628a0SDimitry Andric MachineFunction *MF = MBB->getParent(); 105239d628a0SDimitry Andric assert(MF && "Not embedded in a function!"); 105339d628a0SDimitry Andric 105439d628a0SDimitry Andric MachineInstr *MI = (MachineInstr *)this; 105539d628a0SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 105639d628a0SDimitry Andric 1057ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 105839d628a0SDimitry Andric if (!MO.isReg() || !MO.isDef()) 105939d628a0SDimitry Andric continue; 106039d628a0SDimitry Andric unsigned Reg = MO.getReg(); 106139d628a0SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg)) 106239d628a0SDimitry Andric continue; 106339d628a0SDimitry Andric MRI.markUsesInDebugValueAsUndef(Reg); 106439d628a0SDimitry Andric } 106539d628a0SDimitry Andric MI->eraseFromParent(); 106639d628a0SDimitry Andric } 106739d628a0SDimitry Andric 1068139f7f9bSDimitry Andric void MachineInstr::eraseFromBundle() { 1069139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 1070139f7f9bSDimitry Andric getParent()->erase_instr(this); 1071139f7f9bSDimitry Andric } 1072f22ef01cSRoman Divacky 1073f22ef01cSRoman Divacky /// getNumExplicitOperands - Returns the number of non-implicit operands. 1074f22ef01cSRoman Divacky /// 1075f22ef01cSRoman Divacky unsigned MachineInstr::getNumExplicitOperands() const { 107617a519f9SDimitry Andric unsigned NumOperands = MCID->getNumOperands(); 107717a519f9SDimitry Andric if (!MCID->isVariadic()) 1078f22ef01cSRoman Divacky return NumOperands; 1079f22ef01cSRoman Divacky 1080f22ef01cSRoman Divacky for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) { 1081f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1082f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isImplicit()) 1083f22ef01cSRoman Divacky NumOperands++; 1084f22ef01cSRoman Divacky } 1085f22ef01cSRoman Divacky return NumOperands; 1086f22ef01cSRoman Divacky } 1087f22ef01cSRoman Divacky 1088139f7f9bSDimitry Andric void MachineInstr::bundleWithPred() { 1089139f7f9bSDimitry Andric assert(!isBundledWithPred() && "MI is already bundled with its predecessor"); 1090139f7f9bSDimitry Andric setFlag(BundledPred); 10917d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 1092139f7f9bSDimitry Andric --Pred; 1093139f7f9bSDimitry Andric assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 1094139f7f9bSDimitry Andric Pred->setFlag(BundledSucc); 1095139f7f9bSDimitry Andric } 1096139f7f9bSDimitry Andric 1097139f7f9bSDimitry Andric void MachineInstr::bundleWithSucc() { 1098139f7f9bSDimitry Andric assert(!isBundledWithSucc() && "MI is already bundled with its successor"); 1099139f7f9bSDimitry Andric setFlag(BundledSucc); 11007d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 1101139f7f9bSDimitry Andric ++Succ; 1102139f7f9bSDimitry Andric assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags"); 1103139f7f9bSDimitry Andric Succ->setFlag(BundledPred); 1104139f7f9bSDimitry Andric } 1105139f7f9bSDimitry Andric 1106139f7f9bSDimitry Andric void MachineInstr::unbundleFromPred() { 1107139f7f9bSDimitry Andric assert(isBundledWithPred() && "MI isn't bundled with its predecessor"); 1108139f7f9bSDimitry Andric clearFlag(BundledPred); 11097d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 1110139f7f9bSDimitry Andric --Pred; 1111139f7f9bSDimitry Andric assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 1112139f7f9bSDimitry Andric Pred->clearFlag(BundledSucc); 1113139f7f9bSDimitry Andric } 1114139f7f9bSDimitry Andric 1115139f7f9bSDimitry Andric void MachineInstr::unbundleFromSucc() { 1116139f7f9bSDimitry Andric assert(isBundledWithSucc() && "MI isn't bundled with its successor"); 1117139f7f9bSDimitry Andric clearFlag(BundledSucc); 11187d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 1119139f7f9bSDimitry Andric ++Succ; 1120139f7f9bSDimitry Andric assert(Succ->isBundledWithPred() && "Inconsistent bundle flags"); 1121139f7f9bSDimitry Andric Succ->clearFlag(BundledPred); 1122dff0c46cSDimitry Andric } 1123dff0c46cSDimitry Andric 11242754fe60SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const { 11252754fe60SDimitry Andric if (isInlineAsm()) { 11262754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 11272754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 11282754fe60SDimitry Andric return true; 11292754fe60SDimitry Andric } 11302754fe60SDimitry Andric return false; 11312754fe60SDimitry Andric } 1132f22ef01cSRoman Divacky 11333861d79fSDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const { 11343861d79fSDimitry Andric assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!"); 11353861d79fSDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 11363861d79fSDimitry Andric return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0); 11373861d79fSDimitry Andric } 11383861d79fSDimitry Andric 11396122f3e6SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx, 11406122f3e6SDimitry Andric unsigned *GroupNo) const { 11416122f3e6SDimitry Andric assert(isInlineAsm() && "Expected an inline asm instruction"); 11426122f3e6SDimitry Andric assert(OpIdx < getNumOperands() && "OpIdx out of range"); 11436122f3e6SDimitry Andric 11446122f3e6SDimitry Andric // Ignore queries about the initial operands. 11456122f3e6SDimitry Andric if (OpIdx < InlineAsm::MIOp_FirstOperand) 11466122f3e6SDimitry Andric return -1; 11476122f3e6SDimitry Andric 11486122f3e6SDimitry Andric unsigned Group = 0; 11496122f3e6SDimitry Andric unsigned NumOps; 11506122f3e6SDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 11516122f3e6SDimitry Andric i += NumOps) { 11526122f3e6SDimitry Andric const MachineOperand &FlagMO = getOperand(i); 11536122f3e6SDimitry Andric // If we reach the implicit register operands, stop looking. 11546122f3e6SDimitry Andric if (!FlagMO.isImm()) 11556122f3e6SDimitry Andric return -1; 11566122f3e6SDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 11576122f3e6SDimitry Andric if (i + NumOps > OpIdx) { 11586122f3e6SDimitry Andric if (GroupNo) 11596122f3e6SDimitry Andric *GroupNo = Group; 11606122f3e6SDimitry Andric return i; 11616122f3e6SDimitry Andric } 11626122f3e6SDimitry Andric ++Group; 11636122f3e6SDimitry Andric } 11646122f3e6SDimitry Andric return -1; 11656122f3e6SDimitry Andric } 11666122f3e6SDimitry Andric 11673ca95b02SDimitry Andric const DILocalVariable *MachineInstr::getDebugVariable() const { 11683ca95b02SDimitry Andric assert(isDebugValue() && "not a DBG_VALUE"); 11693ca95b02SDimitry Andric return cast<DILocalVariable>(getOperand(2).getMetadata()); 11703ca95b02SDimitry Andric } 11713ca95b02SDimitry Andric 11723ca95b02SDimitry Andric const DIExpression *MachineInstr::getDebugExpression() const { 11733ca95b02SDimitry Andric assert(isDebugValue() && "not a DBG_VALUE"); 11743ca95b02SDimitry Andric return cast<DIExpression>(getOperand(3).getMetadata()); 11753ca95b02SDimitry Andric } 11763ca95b02SDimitry Andric 11776122f3e6SDimitry Andric const TargetRegisterClass* 11786122f3e6SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx, 11796122f3e6SDimitry Andric const TargetInstrInfo *TII, 11806122f3e6SDimitry Andric const TargetRegisterInfo *TRI) const { 11817ae0e2c9SDimitry Andric assert(getParent() && "Can't have an MBB reference here!"); 11827ae0e2c9SDimitry Andric assert(getParent()->getParent() && "Can't have an MF reference here!"); 11837ae0e2c9SDimitry Andric const MachineFunction &MF = *getParent()->getParent(); 11847ae0e2c9SDimitry Andric 11856122f3e6SDimitry Andric // Most opcodes have fixed constraints in their MCInstrDesc. 11866122f3e6SDimitry Andric if (!isInlineAsm()) 11877ae0e2c9SDimitry Andric return TII->getRegClass(getDesc(), OpIdx, TRI, MF); 11886122f3e6SDimitry Andric 11896122f3e6SDimitry Andric if (!getOperand(OpIdx).isReg()) 119091bc56edSDimitry Andric return nullptr; 11916122f3e6SDimitry Andric 11926122f3e6SDimitry Andric // For tied uses on inline asm, get the constraint from the def. 11936122f3e6SDimitry Andric unsigned DefIdx; 11946122f3e6SDimitry Andric if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx)) 11956122f3e6SDimitry Andric OpIdx = DefIdx; 11966122f3e6SDimitry Andric 11976122f3e6SDimitry Andric // Inline asm stores register class constraints in the flag word. 11986122f3e6SDimitry Andric int FlagIdx = findInlineAsmFlagIdx(OpIdx); 11996122f3e6SDimitry Andric if (FlagIdx < 0) 120091bc56edSDimitry Andric return nullptr; 12016122f3e6SDimitry Andric 12026122f3e6SDimitry Andric unsigned Flag = getOperand(FlagIdx).getImm(); 12036122f3e6SDimitry Andric unsigned RCID; 12043ca95b02SDimitry Andric if ((InlineAsm::getKind(Flag) == InlineAsm::Kind_RegUse || 12053ca95b02SDimitry Andric InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDef || 12063ca95b02SDimitry Andric InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDefEarlyClobber) && 12073ca95b02SDimitry Andric InlineAsm::hasRegClassConstraint(Flag, RCID)) 12086122f3e6SDimitry Andric return TRI->getRegClass(RCID); 12096122f3e6SDimitry Andric 12106122f3e6SDimitry Andric // Assume that all registers in a memory operand are pointers. 12116122f3e6SDimitry Andric if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem) 12127ae0e2c9SDimitry Andric return TRI->getPointerRegClass(MF); 12136122f3e6SDimitry Andric 121491bc56edSDimitry Andric return nullptr; 121591bc56edSDimitry Andric } 121691bc56edSDimitry Andric 121791bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( 121891bc56edSDimitry Andric unsigned Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, 121991bc56edSDimitry Andric const TargetRegisterInfo *TRI, bool ExploreBundle) const { 122091bc56edSDimitry Andric // Check every operands inside the bundle if we have 122191bc56edSDimitry Andric // been asked to. 122291bc56edSDimitry Andric if (ExploreBundle) 12233ca95b02SDimitry Andric for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC; 122491bc56edSDimitry Andric ++OpndIt) 122591bc56edSDimitry Andric CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl( 122691bc56edSDimitry Andric OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); 122791bc56edSDimitry Andric else 122891bc56edSDimitry Andric // Otherwise, just check the current operands. 122997bc6c73SDimitry Andric for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) 123097bc6c73SDimitry Andric CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); 123191bc56edSDimitry Andric return CurRC; 123291bc56edSDimitry Andric } 123391bc56edSDimitry Andric 123491bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl( 123591bc56edSDimitry Andric unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC, 123691bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 123791bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 123891bc56edSDimitry Andric // Check if Reg is constrained by some of its use/def from MI. 123991bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 124091bc56edSDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 124191bc56edSDimitry Andric return CurRC; 124291bc56edSDimitry Andric // If yes, accumulate the constraints through the operand. 124391bc56edSDimitry Andric return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI); 124491bc56edSDimitry Andric } 124591bc56edSDimitry Andric 124691bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( 124791bc56edSDimitry Andric unsigned OpIdx, const TargetRegisterClass *CurRC, 124891bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 124991bc56edSDimitry Andric const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI); 125091bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 125191bc56edSDimitry Andric assert(MO.isReg() && 125291bc56edSDimitry Andric "Cannot get register constraints for non-register operand"); 125391bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 125491bc56edSDimitry Andric if (unsigned SubIdx = MO.getSubReg()) { 125591bc56edSDimitry Andric if (OpRC) 125691bc56edSDimitry Andric CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx); 125791bc56edSDimitry Andric else 125891bc56edSDimitry Andric CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx); 125991bc56edSDimitry Andric } else if (OpRC) 126091bc56edSDimitry Andric CurRC = TRI->getCommonSubClass(CurRC, OpRC); 126191bc56edSDimitry Andric return CurRC; 12626122f3e6SDimitry Andric } 12636122f3e6SDimitry Andric 1264139f7f9bSDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the 1265139f7f9bSDimitry Andric /// header instruction. 1266dff0c46cSDimitry Andric unsigned MachineInstr::getBundleSize() const { 12677d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I = getIterator(); 1268dff0c46cSDimitry Andric unsigned Size = 0; 12693ca95b02SDimitry Andric while (I->isBundledWithSucc()) { 12703ca95b02SDimitry Andric ++Size; 12713ca95b02SDimitry Andric ++I; 12723ca95b02SDimitry Andric } 1273dff0c46cSDimitry Andric return Size; 1274dff0c46cSDimitry Andric } 1275dff0c46cSDimitry Andric 12763ca95b02SDimitry Andric /// Returns true if the MachineInstr has an implicit-use operand of exactly 12773ca95b02SDimitry Andric /// the given register (not considering sub/super-registers). 12783ca95b02SDimitry Andric bool MachineInstr::hasRegisterImplicitUseOperand(unsigned Reg) const { 12793ca95b02SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 12803ca95b02SDimitry Andric const MachineOperand &MO = getOperand(i); 12813ca95b02SDimitry Andric if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == Reg) 12823ca95b02SDimitry Andric return true; 12833ca95b02SDimitry Andric } 12843ca95b02SDimitry Andric return false; 12853ca95b02SDimitry Andric } 12863ca95b02SDimitry Andric 1287f22ef01cSRoman Divacky /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of 1288f22ef01cSRoman Divacky /// the specific register or -1 if it is not found. It further tightens 1289f22ef01cSRoman Divacky /// the search criteria to a use that kills the register if isKill is true. 1290f22ef01cSRoman Divacky int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill, 1291f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 1292f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1293f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1294f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse()) 1295f22ef01cSRoman Divacky continue; 1296f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1297f22ef01cSRoman Divacky if (!MOReg) 1298f22ef01cSRoman Divacky continue; 1299f22ef01cSRoman Divacky if (MOReg == Reg || 1300f22ef01cSRoman Divacky (TRI && 1301f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg) && 1302f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg) && 1303f22ef01cSRoman Divacky TRI->isSubRegister(MOReg, Reg))) 1304f22ef01cSRoman Divacky if (!isKill || MO.isKill()) 1305f22ef01cSRoman Divacky return i; 1306f22ef01cSRoman Divacky } 1307f22ef01cSRoman Divacky return -1; 1308f22ef01cSRoman Divacky } 1309f22ef01cSRoman Divacky 1310f22ef01cSRoman Divacky /// readsWritesVirtualRegister - Return a pair of bools (reads, writes) 1311f22ef01cSRoman Divacky /// indicating if this instruction reads or writes Reg. This also considers 1312f22ef01cSRoman Divacky /// partial defines. 1313f22ef01cSRoman Divacky std::pair<bool,bool> 1314f22ef01cSRoman Divacky MachineInstr::readsWritesVirtualRegister(unsigned Reg, 1315f22ef01cSRoman Divacky SmallVectorImpl<unsigned> *Ops) const { 1316f22ef01cSRoman Divacky bool PartDef = false; // Partial redefine. 1317f22ef01cSRoman Divacky bool FullDef = false; // Full define. 1318f22ef01cSRoman Divacky bool Use = false; 1319f22ef01cSRoman Divacky 1320f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1321f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1322f22ef01cSRoman Divacky if (!MO.isReg() || MO.getReg() != Reg) 1323f22ef01cSRoman Divacky continue; 1324f22ef01cSRoman Divacky if (Ops) 1325f22ef01cSRoman Divacky Ops->push_back(i); 1326f22ef01cSRoman Divacky if (MO.isUse()) 1327f22ef01cSRoman Divacky Use |= !MO.isUndef(); 13286122f3e6SDimitry Andric else if (MO.getSubReg() && !MO.isUndef()) 13296122f3e6SDimitry Andric // A partial <def,undef> doesn't count as reading the register. 1330f22ef01cSRoman Divacky PartDef = true; 1331f22ef01cSRoman Divacky else 1332f22ef01cSRoman Divacky FullDef = true; 1333f22ef01cSRoman Divacky } 1334f22ef01cSRoman Divacky // A partial redefine uses Reg unless there is also a full define. 1335f22ef01cSRoman Divacky return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef); 1336f22ef01cSRoman Divacky } 1337f22ef01cSRoman Divacky 1338f22ef01cSRoman Divacky /// findRegisterDefOperandIdx() - Returns the operand index that is a def of 1339f22ef01cSRoman Divacky /// the specified register or -1 if it is not found. If isDead is true, defs 1340f22ef01cSRoman Divacky /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it 1341f22ef01cSRoman Divacky /// also checks if there is a def of a super-register. 1342f22ef01cSRoman Divacky int 1343f22ef01cSRoman Divacky MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap, 1344f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 1345f22ef01cSRoman Divacky bool isPhys = TargetRegisterInfo::isPhysicalRegister(Reg); 1346f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1347f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1348dff0c46cSDimitry Andric // Accept regmask operands when Overlap is set. 1349dff0c46cSDimitry Andric // Ignore them when looking for a specific def operand (Overlap == false). 1350dff0c46cSDimitry Andric if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg)) 1351dff0c46cSDimitry Andric return i; 1352f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 1353f22ef01cSRoman Divacky continue; 1354f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1355f22ef01cSRoman Divacky bool Found = (MOReg == Reg); 1356f22ef01cSRoman Divacky if (!Found && TRI && isPhys && 1357f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg)) { 1358f22ef01cSRoman Divacky if (Overlap) 1359f22ef01cSRoman Divacky Found = TRI->regsOverlap(MOReg, Reg); 1360f22ef01cSRoman Divacky else 1361f22ef01cSRoman Divacky Found = TRI->isSubRegister(MOReg, Reg); 1362f22ef01cSRoman Divacky } 1363f22ef01cSRoman Divacky if (Found && (!isDead || MO.isDead())) 1364f22ef01cSRoman Divacky return i; 1365f22ef01cSRoman Divacky } 1366f22ef01cSRoman Divacky return -1; 1367f22ef01cSRoman Divacky } 1368f22ef01cSRoman Divacky 1369f22ef01cSRoman Divacky /// findFirstPredOperandIdx() - Find the index of the first operand in the 1370f22ef01cSRoman Divacky /// operand list that is used to represent the predicate. It returns -1 if 1371f22ef01cSRoman Divacky /// none is found. 1372f22ef01cSRoman Divacky int MachineInstr::findFirstPredOperandIdx() const { 13736122f3e6SDimitry Andric // Don't call MCID.findFirstPredOperandIdx() because this variant 13746122f3e6SDimitry Andric // is sometimes called on an instruction that's not yet complete, and 13756122f3e6SDimitry Andric // so the number of operands is less than the MCID indicates. In 13766122f3e6SDimitry Andric // particular, the PTX target does this. 137717a519f9SDimitry Andric const MCInstrDesc &MCID = getDesc(); 137817a519f9SDimitry Andric if (MCID.isPredicable()) { 1379f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 138017a519f9SDimitry Andric if (MCID.OpInfo[i].isPredicate()) 1381f22ef01cSRoman Divacky return i; 1382f22ef01cSRoman Divacky } 1383f22ef01cSRoman Divacky 1384f22ef01cSRoman Divacky return -1; 1385f22ef01cSRoman Divacky } 1386f22ef01cSRoman Divacky 13873861d79fSDimitry Andric // MachineOperand::TiedTo is 4 bits wide. 13883861d79fSDimitry Andric const unsigned TiedMax = 15; 13896122f3e6SDimitry Andric 13903861d79fSDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other. 13913861d79fSDimitry Andric /// 13923861d79fSDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo 13933861d79fSDimitry Andric /// field. TiedTo can have these values: 13943861d79fSDimitry Andric /// 13953861d79fSDimitry Andric /// 0: Operand is not tied to anything. 13963861d79fSDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1). 13973861d79fSDimitry Andric /// TiedMax: Tied to an operand >= TiedMax-1. 13983861d79fSDimitry Andric /// 13993861d79fSDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal 14003861d79fSDimitry Andric /// instruction. INLINEASM instructions allow more tied defs. 14013861d79fSDimitry Andric /// 14023861d79fSDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) { 14033861d79fSDimitry Andric MachineOperand &DefMO = getOperand(DefIdx); 14043861d79fSDimitry Andric MachineOperand &UseMO = getOperand(UseIdx); 14053861d79fSDimitry Andric assert(DefMO.isDef() && "DefIdx must be a def operand"); 14063861d79fSDimitry Andric assert(UseMO.isUse() && "UseIdx must be a use operand"); 14073861d79fSDimitry Andric assert(!DefMO.isTied() && "Def is already tied to another use"); 14083861d79fSDimitry Andric assert(!UseMO.isTied() && "Use is already tied to another def"); 14096122f3e6SDimitry Andric 14103861d79fSDimitry Andric if (DefIdx < TiedMax) 14113861d79fSDimitry Andric UseMO.TiedTo = DefIdx + 1; 14123861d79fSDimitry Andric else { 14133861d79fSDimitry Andric // Inline asm can use the group descriptors to find tied operands, but on 14143861d79fSDimitry Andric // normal instruction, the tied def must be within the first TiedMax 14153861d79fSDimitry Andric // operands. 14163861d79fSDimitry Andric assert(isInlineAsm() && "DefIdx out of range"); 14173861d79fSDimitry Andric UseMO.TiedTo = TiedMax; 14183861d79fSDimitry Andric } 14193861d79fSDimitry Andric 14203861d79fSDimitry Andric // UseIdx can be out of range, we'll search for it in findTiedOperandIdx(). 14213861d79fSDimitry Andric DefMO.TiedTo = std::min(UseIdx + 1, TiedMax); 14223861d79fSDimitry Andric } 14233861d79fSDimitry Andric 14243861d79fSDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to. 14253861d79fSDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand 14263861d79fSDimitry Andric /// which must exist. 14273861d79fSDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const { 14283861d79fSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 14293861d79fSDimitry Andric assert(MO.isTied() && "Operand isn't tied"); 14303861d79fSDimitry Andric 14313861d79fSDimitry Andric // Normally TiedTo is in range. 14323861d79fSDimitry Andric if (MO.TiedTo < TiedMax) 14333861d79fSDimitry Andric return MO.TiedTo - 1; 14343861d79fSDimitry Andric 14353861d79fSDimitry Andric // Uses on normal instructions can be out of range. 14363861d79fSDimitry Andric if (!isInlineAsm()) { 14373861d79fSDimitry Andric // Normal tied defs must be in the 0..TiedMax-1 range. 14383861d79fSDimitry Andric if (MO.isUse()) 14393861d79fSDimitry Andric return TiedMax - 1; 14403861d79fSDimitry Andric // MO is a def. Search for the tied use. 14413861d79fSDimitry Andric for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) { 14423861d79fSDimitry Andric const MachineOperand &UseMO = getOperand(i); 14433861d79fSDimitry Andric if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1) 14443861d79fSDimitry Andric return i; 14453861d79fSDimitry Andric } 14463861d79fSDimitry Andric llvm_unreachable("Can't find tied use"); 14473861d79fSDimitry Andric } 14483861d79fSDimitry Andric 14493861d79fSDimitry Andric // Now deal with inline asm by parsing the operand group descriptor flags. 14503861d79fSDimitry Andric // Find the beginning of each operand group. 14513861d79fSDimitry Andric SmallVector<unsigned, 8> GroupIdx; 14523861d79fSDimitry Andric unsigned OpIdxGroup = ~0u; 14533861d79fSDimitry Andric unsigned NumOps; 14543861d79fSDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 14553861d79fSDimitry Andric i += NumOps) { 14563861d79fSDimitry Andric const MachineOperand &FlagMO = getOperand(i); 14573861d79fSDimitry Andric assert(FlagMO.isImm() && "Invalid tied operand on inline asm"); 14583861d79fSDimitry Andric unsigned CurGroup = GroupIdx.size(); 14593861d79fSDimitry Andric GroupIdx.push_back(i); 14603861d79fSDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 14613861d79fSDimitry Andric // OpIdx belongs to this operand group. 14623861d79fSDimitry Andric if (OpIdx > i && OpIdx < i + NumOps) 14633861d79fSDimitry Andric OpIdxGroup = CurGroup; 14643861d79fSDimitry Andric unsigned TiedGroup; 14653861d79fSDimitry Andric if (!InlineAsm::isUseOperandTiedToDef(FlagMO.getImm(), TiedGroup)) 1466f22ef01cSRoman Divacky continue; 14673861d79fSDimitry Andric // Operands in this group are tied to operands in TiedGroup which must be 14683861d79fSDimitry Andric // earlier. Find the number of operands between the two groups. 14693861d79fSDimitry Andric unsigned Delta = i - GroupIdx[TiedGroup]; 1470f22ef01cSRoman Divacky 14713861d79fSDimitry Andric // OpIdx is a use tied to TiedGroup. 14723861d79fSDimitry Andric if (OpIdxGroup == CurGroup) 14733861d79fSDimitry Andric return OpIdx - Delta; 1474f22ef01cSRoman Divacky 14753861d79fSDimitry Andric // OpIdx is a def tied to this use group. 14763861d79fSDimitry Andric if (OpIdxGroup == TiedGroup) 14773861d79fSDimitry Andric return OpIdx + Delta; 1478f22ef01cSRoman Divacky } 14793861d79fSDimitry Andric llvm_unreachable("Invalid tied operand on inline asm"); 1480f22ef01cSRoman Divacky } 1481f22ef01cSRoman Divacky 1482f22ef01cSRoman Divacky /// clearKillInfo - Clears kill flags on all operands. 1483f22ef01cSRoman Divacky /// 1484f22ef01cSRoman Divacky void MachineInstr::clearKillInfo() { 1485ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1486f22ef01cSRoman Divacky if (MO.isReg() && MO.isUse()) 1487f22ef01cSRoman Divacky MO.setIsKill(false); 1488f22ef01cSRoman Divacky } 1489f22ef01cSRoman Divacky } 1490f22ef01cSRoman Divacky 1491ffd1746dSEd Schouten void MachineInstr::substituteRegister(unsigned FromReg, 1492ffd1746dSEd Schouten unsigned ToReg, 1493ffd1746dSEd Schouten unsigned SubIdx, 1494ffd1746dSEd Schouten const TargetRegisterInfo &RegInfo) { 1495ffd1746dSEd Schouten if (TargetRegisterInfo::isPhysicalRegister(ToReg)) { 1496ffd1746dSEd Schouten if (SubIdx) 1497ffd1746dSEd Schouten ToReg = RegInfo.getSubReg(ToReg, SubIdx); 1498ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1499ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1500ffd1746dSEd Schouten continue; 1501ffd1746dSEd Schouten MO.substPhysReg(ToReg, RegInfo); 1502ffd1746dSEd Schouten } 1503ffd1746dSEd Schouten } else { 1504ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1505ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1506ffd1746dSEd Schouten continue; 1507ffd1746dSEd Schouten MO.substVirtReg(ToReg, SubIdx, RegInfo); 1508ffd1746dSEd Schouten } 1509ffd1746dSEd Schouten } 1510ffd1746dSEd Schouten } 1511ffd1746dSEd Schouten 1512f22ef01cSRoman Divacky /// isSafeToMove - Return true if it is safe to move this instruction. If 1513f22ef01cSRoman Divacky /// SawStore is set to true, it means that there is a store (or call) between 1514f22ef01cSRoman Divacky /// the instruction's location and its intended destination. 1515ff0cc061SDimitry Andric bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const { 1516f22ef01cSRoman Divacky // Ignore stuff that we obviously can't move. 15173861d79fSDimitry Andric // 15183861d79fSDimitry Andric // Treat volatile loads as stores. This is not strictly necessary for 15193861d79fSDimitry Andric // volatiles, but it is required for atomic loads. It is not allowed to move 15203861d79fSDimitry Andric // a load across an atomic load with Ordering > Monotonic. 15213861d79fSDimitry Andric if (mayStore() || isCall() || 15223861d79fSDimitry Andric (mayLoad() && hasOrderedMemoryRef())) { 1523f22ef01cSRoman Divacky SawStore = true; 1524f22ef01cSRoman Divacky return false; 1525f22ef01cSRoman Divacky } 15262754fe60SDimitry Andric 152791bc56edSDimitry Andric if (isPosition() || isDebugValue() || isTerminator() || 152891bc56edSDimitry Andric hasUnmodeledSideEffects()) 1529f22ef01cSRoman Divacky return false; 1530f22ef01cSRoman Divacky 1531f22ef01cSRoman Divacky // See if this instruction does a load. If so, we have to guarantee that the 1532f22ef01cSRoman Divacky // loaded value doesn't change between the load and the its intended 1533f22ef01cSRoman Divacky // destination. The check for isInvariantLoad gives the targe the chance to 1534f22ef01cSRoman Divacky // classify the load as always returning a constant, e.g. a constant pool 1535f22ef01cSRoman Divacky // load. 1536dff0c46cSDimitry Andric if (mayLoad() && !isInvariantLoad(AA)) 1537f22ef01cSRoman Divacky // Otherwise, this is a real load. If there is a store between the load and 15383861d79fSDimitry Andric // end of block, we can't move it. 15393861d79fSDimitry Andric return !SawStore; 1540f22ef01cSRoman Divacky 1541f22ef01cSRoman Divacky return true; 1542f22ef01cSRoman Divacky } 1543f22ef01cSRoman Divacky 15443861d79fSDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered 15453861d79fSDimitry Andric /// or volatile memory reference, or if the information describing the memory 15463861d79fSDimitry Andric /// reference is not available. Return false if it is known to have no ordered 15473861d79fSDimitry Andric /// memory references. 15483861d79fSDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const { 1549f22ef01cSRoman Divacky // An instruction known never to access memory won't have a volatile access. 1550dff0c46cSDimitry Andric if (!mayStore() && 1551dff0c46cSDimitry Andric !mayLoad() && 1552dff0c46cSDimitry Andric !isCall() && 15532754fe60SDimitry Andric !hasUnmodeledSideEffects()) 1554f22ef01cSRoman Divacky return false; 1555f22ef01cSRoman Divacky 1556f22ef01cSRoman Divacky // Otherwise, if the instruction has no memory reference information, 1557f22ef01cSRoman Divacky // conservatively assume it wasn't preserved. 1558f22ef01cSRoman Divacky if (memoperands_empty()) 1559f22ef01cSRoman Divacky return true; 1560f22ef01cSRoman Divacky 15613ca95b02SDimitry Andric // Check if any of our memory operands are ordered. 15623ca95b02SDimitry Andric return any_of(memoperands(), [](const MachineMemOperand *MMO) { 15633ca95b02SDimitry Andric return !MMO->isUnordered(); 15643ca95b02SDimitry Andric }); 1565f22ef01cSRoman Divacky } 1566f22ef01cSRoman Divacky 1567f22ef01cSRoman Divacky /// isInvariantLoad - Return true if this instruction is loading from a 1568f22ef01cSRoman Divacky /// location whose value is invariant across the function. For example, 1569f22ef01cSRoman Divacky /// loading a value from the constant pool or from the argument area 1570f22ef01cSRoman Divacky /// of a function if it does not change. This should only return true of 1571f22ef01cSRoman Divacky /// *all* loads the instruction does are invariant (if it does multiple loads). 1572f22ef01cSRoman Divacky bool MachineInstr::isInvariantLoad(AliasAnalysis *AA) const { 1573f22ef01cSRoman Divacky // If the instruction doesn't load at all, it isn't an invariant load. 1574dff0c46cSDimitry Andric if (!mayLoad()) 1575f22ef01cSRoman Divacky return false; 1576f22ef01cSRoman Divacky 1577f22ef01cSRoman Divacky // If the instruction has lost its memoperands, conservatively assume that 1578f22ef01cSRoman Divacky // it may not be an invariant load. 1579f22ef01cSRoman Divacky if (memoperands_empty()) 1580f22ef01cSRoman Divacky return false; 1581f22ef01cSRoman Divacky 1582f22ef01cSRoman Divacky const MachineFrameInfo *MFI = getParent()->getParent()->getFrameInfo(); 1583f22ef01cSRoman Divacky 15843ca95b02SDimitry Andric for (MachineMemOperand *MMO : memoperands()) { 15853ca95b02SDimitry Andric if (MMO->isVolatile()) return false; 15863ca95b02SDimitry Andric if (MMO->isStore()) return false; 15873ca95b02SDimitry Andric if (MMO->isInvariant()) continue; 158891bc56edSDimitry Andric 1589f22ef01cSRoman Divacky // A load from a constant PseudoSourceValue is invariant. 15903ca95b02SDimitry Andric if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) 1591f22ef01cSRoman Divacky if (PSV->isConstant(MFI)) 1592f22ef01cSRoman Divacky continue; 159391bc56edSDimitry Andric 15943ca95b02SDimitry Andric if (const Value *V = MMO->getValue()) { 1595f22ef01cSRoman Divacky // If we have an AliasAnalysis, ask it whether the memory is constant. 15968f0fd8f6SDimitry Andric if (AA && 15978f0fd8f6SDimitry Andric AA->pointsToConstantMemory( 15983ca95b02SDimitry Andric MemoryLocation(V, MMO->getSize(), MMO->getAAInfo()))) 1599f22ef01cSRoman Divacky continue; 1600f22ef01cSRoman Divacky } 1601f22ef01cSRoman Divacky 1602f22ef01cSRoman Divacky // Otherwise assume conservatively. 1603f22ef01cSRoman Divacky return false; 1604f22ef01cSRoman Divacky } 1605f22ef01cSRoman Divacky 1606f22ef01cSRoman Divacky // Everything checks out. 1607f22ef01cSRoman Divacky return true; 1608f22ef01cSRoman Divacky } 1609f22ef01cSRoman Divacky 1610f22ef01cSRoman Divacky /// isConstantValuePHI - If the specified instruction is a PHI that always 1611f22ef01cSRoman Divacky /// merges together the same virtual register, return the register, otherwise 1612f22ef01cSRoman Divacky /// return 0. 1613f22ef01cSRoman Divacky unsigned MachineInstr::isConstantValuePHI() const { 1614f22ef01cSRoman Divacky if (!isPHI()) 1615f22ef01cSRoman Divacky return 0; 1616f22ef01cSRoman Divacky assert(getNumOperands() >= 3 && 1617f22ef01cSRoman Divacky "It's illegal to have a PHI without source operands"); 1618f22ef01cSRoman Divacky 1619f22ef01cSRoman Divacky unsigned Reg = getOperand(1).getReg(); 1620f22ef01cSRoman Divacky for (unsigned i = 3, e = getNumOperands(); i < e; i += 2) 1621f22ef01cSRoman Divacky if (getOperand(i).getReg() != Reg) 1622f22ef01cSRoman Divacky return 0; 1623f22ef01cSRoman Divacky return Reg; 1624f22ef01cSRoman Divacky } 1625f22ef01cSRoman Divacky 16262754fe60SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const { 1627dff0c46cSDimitry Andric if (hasProperty(MCID::UnmodeledSideEffects)) 16282754fe60SDimitry Andric return true; 16292754fe60SDimitry Andric if (isInlineAsm()) { 16302754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 16312754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 16322754fe60SDimitry Andric return true; 16332754fe60SDimitry Andric } 16342754fe60SDimitry Andric 16352754fe60SDimitry Andric return false; 16362754fe60SDimitry Andric } 16372754fe60SDimitry Andric 16387d523365SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const { 16397d523365SDimitry Andric return mayStore() || isCall() || hasUnmodeledSideEffects(); 16407d523365SDimitry Andric } 16417d523365SDimitry Andric 1642f22ef01cSRoman Divacky /// allDefsAreDead - Return true if all the defs of this instruction are dead. 1643f22ef01cSRoman Divacky /// 1644f22ef01cSRoman Divacky bool MachineInstr::allDefsAreDead() const { 1645ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 1646f22ef01cSRoman Divacky if (!MO.isReg() || MO.isUse()) 1647f22ef01cSRoman Divacky continue; 1648f22ef01cSRoman Divacky if (!MO.isDead()) 1649f22ef01cSRoman Divacky return false; 1650f22ef01cSRoman Divacky } 1651f22ef01cSRoman Divacky return true; 1652f22ef01cSRoman Divacky } 1653f22ef01cSRoman Divacky 16542754fe60SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified 16552754fe60SDimitry Andric /// instruction to this instruction. 1656139f7f9bSDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF, 16573ca95b02SDimitry Andric const MachineInstr &MI) { 16583ca95b02SDimitry Andric for (unsigned i = MI.getDesc().getNumOperands(), e = MI.getNumOperands(); 16592754fe60SDimitry Andric i != e; ++i) { 16603ca95b02SDimitry Andric const MachineOperand &MO = MI.getOperand(i); 166191bc56edSDimitry Andric if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask()) 1662139f7f9bSDimitry Andric addOperand(MF, MO); 16632754fe60SDimitry Andric } 16642754fe60SDimitry Andric } 16652754fe60SDimitry Andric 16663ca95b02SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dump() const { 16673861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1668f22ef01cSRoman Divacky dbgs() << " " << *this; 16693861d79fSDimitry Andric #endif 1670f22ef01cSRoman Divacky } 1671f22ef01cSRoman Divacky 1672ff0cc061SDimitry Andric void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const { 16733dac3a9bSDimitry Andric const Module *M = nullptr; 16743dac3a9bSDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 16753dac3a9bSDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 16763dac3a9bSDimitry Andric M = MF->getFunction()->getParent(); 16773dac3a9bSDimitry Andric 16783dac3a9bSDimitry Andric ModuleSlotTracker MST(M); 16793dac3a9bSDimitry Andric print(OS, MST, SkipOpers); 16803dac3a9bSDimitry Andric } 16813dac3a9bSDimitry Andric 16823dac3a9bSDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, 16833dac3a9bSDimitry Andric bool SkipOpers) const { 1684ff0cc061SDimitry Andric // We can be a bit tidier if we know the MachineFunction. 168591bc56edSDimitry Andric const MachineFunction *MF = nullptr; 1686ff0cc061SDimitry Andric const TargetRegisterInfo *TRI = nullptr; 168791bc56edSDimitry Andric const MachineRegisterInfo *MRI = nullptr; 1688ff0cc061SDimitry Andric const TargetInstrInfo *TII = nullptr; 1689f22ef01cSRoman Divacky if (const MachineBasicBlock *MBB = getParent()) { 1690f22ef01cSRoman Divacky MF = MBB->getParent(); 1691ff0cc061SDimitry Andric if (MF) { 1692e580952dSDimitry Andric MRI = &MF->getRegInfo(); 1693ff0cc061SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo(); 1694ff0cc061SDimitry Andric TII = MF->getSubtarget().getInstrInfo(); 1695ff0cc061SDimitry Andric } 1696f22ef01cSRoman Divacky } 1697f22ef01cSRoman Divacky 1698e580952dSDimitry Andric // Save a list of virtual registers. 1699e580952dSDimitry Andric SmallVector<unsigned, 8> VirtRegs; 1700e580952dSDimitry Andric 1701f22ef01cSRoman Divacky // Print explicitly defined operands on the left of an assignment syntax. 1702f22ef01cSRoman Divacky unsigned StartOp = 0, e = getNumOperands(); 1703f22ef01cSRoman Divacky for (; StartOp < e && getOperand(StartOp).isReg() && 1704f22ef01cSRoman Divacky getOperand(StartOp).isDef() && 1705f22ef01cSRoman Divacky !getOperand(StartOp).isImplicit(); 1706f22ef01cSRoman Divacky ++StartOp) { 1707f22ef01cSRoman Divacky if (StartOp != 0) OS << ", "; 17083dac3a9bSDimitry Andric getOperand(StartOp).print(OS, MST, TRI); 1709e580952dSDimitry Andric unsigned Reg = getOperand(StartOp).getReg(); 17103ca95b02SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(Reg)) { 1711e580952dSDimitry Andric VirtRegs.push_back(Reg); 17123ca95b02SDimitry Andric unsigned Size; 17133ca95b02SDimitry Andric if (MRI && (Size = MRI->getSize(Reg))) 17143ca95b02SDimitry Andric OS << '(' << Size << ')'; 17153ca95b02SDimitry Andric } 1716f22ef01cSRoman Divacky } 1717f22ef01cSRoman Divacky 1718f22ef01cSRoman Divacky if (StartOp != 0) 1719f22ef01cSRoman Divacky OS << " = "; 1720f22ef01cSRoman Divacky 1721f22ef01cSRoman Divacky // Print the opcode name. 1722ff0cc061SDimitry Andric if (TII) 1723ff0cc061SDimitry Andric OS << TII->getName(getOpcode()); 1724dff0c46cSDimitry Andric else 1725dff0c46cSDimitry Andric OS << "UNKNOWN"; 1726f22ef01cSRoman Divacky 17273ca95b02SDimitry Andric if (getType()) { 17283ca95b02SDimitry Andric OS << ' '; 17293ca95b02SDimitry Andric getType()->print(OS, /*IsForDebug*/ false, /*NoDetails*/ true); 17303ca95b02SDimitry Andric OS << ' '; 17313ca95b02SDimitry Andric } 17323ca95b02SDimitry Andric 1733139f7f9bSDimitry Andric if (SkipOpers) 1734139f7f9bSDimitry Andric return; 1735139f7f9bSDimitry Andric 1736f22ef01cSRoman Divacky // Print the rest of the operands. 1737f22ef01cSRoman Divacky bool OmittedAnyCallClobbers = false; 1738f22ef01cSRoman Divacky bool FirstOp = true; 173917a519f9SDimitry Andric unsigned AsmDescOp = ~0u; 174017a519f9SDimitry Andric unsigned AsmOpCount = 0; 17412754fe60SDimitry Andric 17426122f3e6SDimitry Andric if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { 17432754fe60SDimitry Andric // Print asm string. 17442754fe60SDimitry Andric OS << " "; 17453dac3a9bSDimitry Andric getOperand(InlineAsm::MIOp_AsmString).print(OS, MST, TRI); 17462754fe60SDimitry Andric 1747139f7f9bSDimitry Andric // Print HasSideEffects, MayLoad, MayStore, IsAlignStack 17482754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 17492754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 17502754fe60SDimitry Andric OS << " [sideeffect]"; 1751139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayLoad) 1752139f7f9bSDimitry Andric OS << " [mayload]"; 1753139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayStore) 1754139f7f9bSDimitry Andric OS << " [maystore]"; 17553ca95b02SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsConvergent) 17563ca95b02SDimitry Andric OS << " [isconvergent]"; 17572754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 17582754fe60SDimitry Andric OS << " [alignstack]"; 17593861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_ATT) 17603861d79fSDimitry Andric OS << " [attdialect]"; 17613861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_Intel) 17623861d79fSDimitry Andric OS << " [inteldialect]"; 17632754fe60SDimitry Andric 176417a519f9SDimitry Andric StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand; 17652754fe60SDimitry Andric FirstOp = false; 17662754fe60SDimitry Andric } 17672754fe60SDimitry Andric 1768f22ef01cSRoman Divacky for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 1769f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1770f22ef01cSRoman Divacky 17712754fe60SDimitry Andric if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) 1772e580952dSDimitry Andric VirtRegs.push_back(MO.getReg()); 1773e580952dSDimitry Andric 1774f22ef01cSRoman Divacky // Omit call-clobbered registers which aren't used anywhere. This makes 1775f22ef01cSRoman Divacky // call instructions much less noisy on targets where calls clobber lots 1776f22ef01cSRoman Divacky // of registers. Don't rely on MO.isDead() because we may be called before 1777f22ef01cSRoman Divacky // LiveVariables is run, or we may be looking at a non-allocatable reg. 177839d628a0SDimitry Andric if (MRI && isCall() && 1779f22ef01cSRoman Divacky MO.isReg() && MO.isImplicit() && MO.isDef()) { 1780f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 17812754fe60SDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 178239d628a0SDimitry Andric if (MRI->use_empty(Reg)) { 1783f22ef01cSRoman Divacky bool HasAliasLive = false; 1784ff0cc061SDimitry Andric for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { 17857ae0e2c9SDimitry Andric unsigned AliasReg = *AI; 178639d628a0SDimitry Andric if (!MRI->use_empty(AliasReg)) { 1787f22ef01cSRoman Divacky HasAliasLive = true; 1788f22ef01cSRoman Divacky break; 1789f22ef01cSRoman Divacky } 17907ae0e2c9SDimitry Andric } 1791f22ef01cSRoman Divacky if (!HasAliasLive) { 1792f22ef01cSRoman Divacky OmittedAnyCallClobbers = true; 1793f22ef01cSRoman Divacky continue; 1794f22ef01cSRoman Divacky } 1795f22ef01cSRoman Divacky } 1796f22ef01cSRoman Divacky } 1797f22ef01cSRoman Divacky } 1798f22ef01cSRoman Divacky 1799f22ef01cSRoman Divacky if (FirstOp) FirstOp = false; else OS << ","; 1800f22ef01cSRoman Divacky OS << " "; 1801f22ef01cSRoman Divacky if (i < getDesc().NumOperands) { 180217a519f9SDimitry Andric const MCOperandInfo &MCOI = getDesc().OpInfo[i]; 180317a519f9SDimitry Andric if (MCOI.isPredicate()) 1804f22ef01cSRoman Divacky OS << "pred:"; 180517a519f9SDimitry Andric if (MCOI.isOptionalDef()) 1806f22ef01cSRoman Divacky OS << "opt:"; 1807f22ef01cSRoman Divacky } 1808f22ef01cSRoman Divacky if (isDebugValue() && MO.isMetadata()) { 1809f22ef01cSRoman Divacky // Pretty print DBG_VALUE instructions. 1810ff0cc061SDimitry Andric auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata()); 1811ff0cc061SDimitry Andric if (DIV && !DIV->getName().empty()) 1812ff0cc061SDimitry Andric OS << "!\"" << DIV->getName() << '\"'; 1813f22ef01cSRoman Divacky else 18143dac3a9bSDimitry Andric MO.print(OS, MST, TRI); 1815ff0cc061SDimitry Andric } else if (TRI && (isInsertSubreg() || isRegSequence()) && MO.isImm()) { 1816ff0cc061SDimitry Andric OS << TRI->getSubRegIndexName(MO.getImm()); 181717a519f9SDimitry Andric } else if (i == AsmDescOp && MO.isImm()) { 181817a519f9SDimitry Andric // Pretty print the inline asm operand descriptor. 181917a519f9SDimitry Andric OS << '$' << AsmOpCount++; 182017a519f9SDimitry Andric unsigned Flag = MO.getImm(); 182117a519f9SDimitry Andric switch (InlineAsm::getKind(Flag)) { 18226122f3e6SDimitry Andric case InlineAsm::Kind_RegUse: OS << ":[reguse"; break; 18236122f3e6SDimitry Andric case InlineAsm::Kind_RegDef: OS << ":[regdef"; break; 18246122f3e6SDimitry Andric case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec"; break; 18256122f3e6SDimitry Andric case InlineAsm::Kind_Clobber: OS << ":[clobber"; break; 18266122f3e6SDimitry Andric case InlineAsm::Kind_Imm: OS << ":[imm"; break; 18276122f3e6SDimitry Andric case InlineAsm::Kind_Mem: OS << ":[mem"; break; 18286122f3e6SDimitry Andric default: OS << ":[??" << InlineAsm::getKind(Flag); break; 18296122f3e6SDimitry Andric } 18306122f3e6SDimitry Andric 18316122f3e6SDimitry Andric unsigned RCID = 0; 18323ca95b02SDimitry Andric if (!InlineAsm::isImmKind(Flag) && !InlineAsm::isMemKind(Flag) && 18333ca95b02SDimitry Andric InlineAsm::hasRegClassConstraint(Flag, RCID)) { 1834ff0cc061SDimitry Andric if (TRI) { 1835ff0cc061SDimitry Andric OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID)); 183639d628a0SDimitry Andric } else 18376122f3e6SDimitry Andric OS << ":RC" << RCID; 183817a519f9SDimitry Andric } 183917a519f9SDimitry Andric 18403ca95b02SDimitry Andric if (InlineAsm::isMemKind(Flag)) { 18413ca95b02SDimitry Andric unsigned MCID = InlineAsm::getMemoryConstraintID(Flag); 18423ca95b02SDimitry Andric switch (MCID) { 18433ca95b02SDimitry Andric case InlineAsm::Constraint_es: OS << ":es"; break; 18443ca95b02SDimitry Andric case InlineAsm::Constraint_i: OS << ":i"; break; 18453ca95b02SDimitry Andric case InlineAsm::Constraint_m: OS << ":m"; break; 18463ca95b02SDimitry Andric case InlineAsm::Constraint_o: OS << ":o"; break; 18473ca95b02SDimitry Andric case InlineAsm::Constraint_v: OS << ":v"; break; 18483ca95b02SDimitry Andric case InlineAsm::Constraint_Q: OS << ":Q"; break; 18493ca95b02SDimitry Andric case InlineAsm::Constraint_R: OS << ":R"; break; 18503ca95b02SDimitry Andric case InlineAsm::Constraint_S: OS << ":S"; break; 18513ca95b02SDimitry Andric case InlineAsm::Constraint_T: OS << ":T"; break; 18523ca95b02SDimitry Andric case InlineAsm::Constraint_Um: OS << ":Um"; break; 18533ca95b02SDimitry Andric case InlineAsm::Constraint_Un: OS << ":Un"; break; 18543ca95b02SDimitry Andric case InlineAsm::Constraint_Uq: OS << ":Uq"; break; 18553ca95b02SDimitry Andric case InlineAsm::Constraint_Us: OS << ":Us"; break; 18563ca95b02SDimitry Andric case InlineAsm::Constraint_Ut: OS << ":Ut"; break; 18573ca95b02SDimitry Andric case InlineAsm::Constraint_Uv: OS << ":Uv"; break; 18583ca95b02SDimitry Andric case InlineAsm::Constraint_Uy: OS << ":Uy"; break; 18593ca95b02SDimitry Andric case InlineAsm::Constraint_X: OS << ":X"; break; 18603ca95b02SDimitry Andric case InlineAsm::Constraint_Z: OS << ":Z"; break; 18613ca95b02SDimitry Andric case InlineAsm::Constraint_ZC: OS << ":ZC"; break; 18623ca95b02SDimitry Andric case InlineAsm::Constraint_Zy: OS << ":Zy"; break; 18633ca95b02SDimitry Andric default: OS << ":?"; break; 18643ca95b02SDimitry Andric } 18653ca95b02SDimitry Andric } 18663ca95b02SDimitry Andric 186717a519f9SDimitry Andric unsigned TiedTo = 0; 186817a519f9SDimitry Andric if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo)) 18696122f3e6SDimitry Andric OS << " tiedto:$" << TiedTo; 18706122f3e6SDimitry Andric 18716122f3e6SDimitry Andric OS << ']'; 187217a519f9SDimitry Andric 187317a519f9SDimitry Andric // Compute the index of the next operand descriptor. 187417a519f9SDimitry Andric AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); 1875f22ef01cSRoman Divacky } else 18763dac3a9bSDimitry Andric MO.print(OS, MST, TRI); 1877f22ef01cSRoman Divacky } 1878f22ef01cSRoman Divacky 1879f22ef01cSRoman Divacky // Briefly indicate whether any call clobbers were omitted. 1880f22ef01cSRoman Divacky if (OmittedAnyCallClobbers) { 1881f22ef01cSRoman Divacky if (!FirstOp) OS << ","; 1882f22ef01cSRoman Divacky OS << " ..."; 1883f22ef01cSRoman Divacky } 1884f22ef01cSRoman Divacky 1885f22ef01cSRoman Divacky bool HaveSemi = false; 18867d523365SDimitry Andric const unsigned PrintableFlags = FrameSetup | FrameDestroy; 1887139f7f9bSDimitry Andric if (Flags & PrintableFlags) { 18884d0b32cdSDimitry Andric if (!HaveSemi) { 18894d0b32cdSDimitry Andric OS << ";"; 18904d0b32cdSDimitry Andric HaveSemi = true; 18914d0b32cdSDimitry Andric } 18923b0f4066SDimitry Andric OS << " flags: "; 18933b0f4066SDimitry Andric 18943b0f4066SDimitry Andric if (Flags & FrameSetup) 18953b0f4066SDimitry Andric OS << "FrameSetup"; 18967d523365SDimitry Andric 18977d523365SDimitry Andric if (Flags & FrameDestroy) 18987d523365SDimitry Andric OS << "FrameDestroy"; 18993b0f4066SDimitry Andric } 19003b0f4066SDimitry Andric 1901f22ef01cSRoman Divacky if (!memoperands_empty()) { 19024d0b32cdSDimitry Andric if (!HaveSemi) { 19034d0b32cdSDimitry Andric OS << ";"; 19044d0b32cdSDimitry Andric HaveSemi = true; 19054d0b32cdSDimitry Andric } 1906f22ef01cSRoman Divacky 1907f22ef01cSRoman Divacky OS << " mem:"; 1908f22ef01cSRoman Divacky for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); 1909f22ef01cSRoman Divacky i != e; ++i) { 19103dac3a9bSDimitry Andric (*i)->print(OS, MST); 191191bc56edSDimitry Andric if (std::next(i) != e) 1912f22ef01cSRoman Divacky OS << " "; 1913f22ef01cSRoman Divacky } 1914f22ef01cSRoman Divacky } 1915f22ef01cSRoman Divacky 1916e580952dSDimitry Andric // Print the regclass of any virtual registers encountered. 1917e580952dSDimitry Andric if (MRI && !VirtRegs.empty()) { 19184d0b32cdSDimitry Andric if (!HaveSemi) { 19194d0b32cdSDimitry Andric OS << ";"; 19204d0b32cdSDimitry Andric HaveSemi = true; 19214d0b32cdSDimitry Andric } 1922e580952dSDimitry Andric for (unsigned i = 0; i != VirtRegs.size(); ++i) { 19233ca95b02SDimitry Andric const RegClassOrRegBank &RC = MRI->getRegClassOrRegBank(VirtRegs[i]); 19243ca95b02SDimitry Andric if (!RC) 19253ca95b02SDimitry Andric continue; 19263ca95b02SDimitry Andric // Generic virtual registers do not have register classes. 19273ca95b02SDimitry Andric if (RC.is<const RegisterBank *>()) 19283ca95b02SDimitry Andric OS << " " << RC.get<const RegisterBank *>()->getName(); 19293ca95b02SDimitry Andric else 19303ca95b02SDimitry Andric OS << " " 19313ca95b02SDimitry Andric << TRI->getRegClassName(RC.get<const TargetRegisterClass *>()); 19323ca95b02SDimitry Andric OS << ':' << PrintReg(VirtRegs[i]); 1933e580952dSDimitry Andric for (unsigned j = i+1; j != VirtRegs.size();) { 19343ca95b02SDimitry Andric if (MRI->getRegClassOrRegBank(VirtRegs[j]) != RC) { 1935e580952dSDimitry Andric ++j; 1936e580952dSDimitry Andric continue; 1937e580952dSDimitry Andric } 1938e580952dSDimitry Andric if (VirtRegs[i] != VirtRegs[j]) 19392754fe60SDimitry Andric OS << "," << PrintReg(VirtRegs[j]); 1940e580952dSDimitry Andric VirtRegs.erase(VirtRegs.begin()+j); 1941e580952dSDimitry Andric } 1942e580952dSDimitry Andric } 1943e580952dSDimitry Andric } 1944e580952dSDimitry Andric 19453b0f4066SDimitry Andric // Print debug location information. 1946ff0cc061SDimitry Andric if (isDebugValue() && getOperand(e - 2).isMetadata()) { 19474d0b32cdSDimitry Andric if (!HaveSemi) 19484d0b32cdSDimitry Andric OS << ";"; 1949ff0cc061SDimitry Andric auto *DV = cast<DILocalVariable>(getOperand(e - 2).getMetadata()); 1950ff0cc061SDimitry Andric OS << " line no:" << DV->getLine(); 1951ff0cc061SDimitry Andric if (auto *InlinedAt = debugLoc->getInlinedAt()) { 1952ff0cc061SDimitry Andric DebugLoc InlinedAtDL(InlinedAt); 1953ff0cc061SDimitry Andric if (InlinedAtDL && MF) { 19546122f3e6SDimitry Andric OS << " inlined @[ "; 1955ff0cc061SDimitry Andric InlinedAtDL.print(OS); 19566122f3e6SDimitry Andric OS << " ]"; 19576122f3e6SDimitry Andric } 19586122f3e6SDimitry Andric } 195939d628a0SDimitry Andric if (isIndirectDebugValue()) 196039d628a0SDimitry Andric OS << " indirect"; 1961ff0cc061SDimitry Andric } else if (debugLoc && MF) { 19624d0b32cdSDimitry Andric if (!HaveSemi) 19634d0b32cdSDimitry Andric OS << ";"; 1964f22ef01cSRoman Divacky OS << " dbg:"; 1965ff0cc061SDimitry Andric debugLoc.print(OS); 1966f22ef01cSRoman Divacky } 1967f22ef01cSRoman Divacky 19683b0f4066SDimitry Andric OS << '\n'; 1969f22ef01cSRoman Divacky } 1970f22ef01cSRoman Divacky 1971f22ef01cSRoman Divacky bool MachineInstr::addRegisterKilled(unsigned IncomingReg, 1972f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 1973f22ef01cSRoman Divacky bool AddIfNotFound) { 1974f22ef01cSRoman Divacky bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); 19757ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 19767ae0e2c9SDimitry Andric MCRegAliasIterator(IncomingReg, RegInfo, false).isValid(); 1977f22ef01cSRoman Divacky bool Found = false; 1978f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 1979f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1980f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1981f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse() || MO.isUndef()) 1982f22ef01cSRoman Divacky continue; 19833ca95b02SDimitry Andric 19843ca95b02SDimitry Andric // DEBUG_VALUE nodes do not contribute to code generation and should 19853ca95b02SDimitry Andric // always be ignored. Failure to do so may result in trying to modify 19863ca95b02SDimitry Andric // KILL flags on DEBUG_VALUE nodes. 19873ca95b02SDimitry Andric if (MO.isDebug()) 19883ca95b02SDimitry Andric continue; 19893ca95b02SDimitry Andric 1990f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 1991f22ef01cSRoman Divacky if (!Reg) 1992f22ef01cSRoman Divacky continue; 1993f22ef01cSRoman Divacky 1994f22ef01cSRoman Divacky if (Reg == IncomingReg) { 1995f22ef01cSRoman Divacky if (!Found) { 1996f22ef01cSRoman Divacky if (MO.isKill()) 1997f22ef01cSRoman Divacky // The register is already marked kill. 1998f22ef01cSRoman Divacky return true; 1999f22ef01cSRoman Divacky if (isPhysReg && isRegTiedToDefOperand(i)) 2000f22ef01cSRoman Divacky // Two-address uses of physregs must not be marked kill. 2001f22ef01cSRoman Divacky return true; 2002f22ef01cSRoman Divacky MO.setIsKill(); 2003f22ef01cSRoman Divacky Found = true; 2004f22ef01cSRoman Divacky } 2005f22ef01cSRoman Divacky } else if (hasAliases && MO.isKill() && 2006f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg)) { 2007f22ef01cSRoman Divacky // A super-register kill already exists. 2008f22ef01cSRoman Divacky if (RegInfo->isSuperRegister(IncomingReg, Reg)) 2009f22ef01cSRoman Divacky return true; 2010f22ef01cSRoman Divacky if (RegInfo->isSubRegister(IncomingReg, Reg)) 2011f22ef01cSRoman Divacky DeadOps.push_back(i); 2012f22ef01cSRoman Divacky } 2013f22ef01cSRoman Divacky } 2014f22ef01cSRoman Divacky 2015f22ef01cSRoman Divacky // Trim unneeded kill operands. 2016f22ef01cSRoman Divacky while (!DeadOps.empty()) { 2017f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 2018f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 2019f22ef01cSRoman Divacky RemoveOperand(OpIdx); 2020f22ef01cSRoman Divacky else 2021f22ef01cSRoman Divacky getOperand(OpIdx).setIsKill(false); 2022f22ef01cSRoman Divacky DeadOps.pop_back(); 2023f22ef01cSRoman Divacky } 2024f22ef01cSRoman Divacky 2025f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is killed. Add a 2026f22ef01cSRoman Divacky // new implicit operand if required. 2027f22ef01cSRoman Divacky if (!Found && AddIfNotFound) { 2028f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(IncomingReg, 2029f22ef01cSRoman Divacky false /*IsDef*/, 2030f22ef01cSRoman Divacky true /*IsImp*/, 2031f22ef01cSRoman Divacky true /*IsKill*/)); 2032f22ef01cSRoman Divacky return true; 2033f22ef01cSRoman Divacky } 2034f22ef01cSRoman Divacky return Found; 2035f22ef01cSRoman Divacky } 2036f22ef01cSRoman Divacky 2037dff0c46cSDimitry Andric void MachineInstr::clearRegisterKills(unsigned Reg, 2038dff0c46cSDimitry Andric const TargetRegisterInfo *RegInfo) { 2039dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) 204091bc56edSDimitry Andric RegInfo = nullptr; 2041ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2042dff0c46cSDimitry Andric if (!MO.isReg() || !MO.isUse() || !MO.isKill()) 2043dff0c46cSDimitry Andric continue; 2044dff0c46cSDimitry Andric unsigned OpReg = MO.getReg(); 20453ca95b02SDimitry Andric if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg) 2046dff0c46cSDimitry Andric MO.setIsKill(false); 2047dff0c46cSDimitry Andric } 2048dff0c46cSDimitry Andric } 2049dff0c46cSDimitry Andric 2050f785676fSDimitry Andric bool MachineInstr::addRegisterDead(unsigned Reg, 2051f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 2052f22ef01cSRoman Divacky bool AddIfNotFound) { 2053f785676fSDimitry Andric bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(Reg); 20547ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 2055f785676fSDimitry Andric MCRegAliasIterator(Reg, RegInfo, false).isValid(); 2056f22ef01cSRoman Divacky bool Found = false; 2057f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 2058f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 2059f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 2060f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 2061f22ef01cSRoman Divacky continue; 2062f785676fSDimitry Andric unsigned MOReg = MO.getReg(); 2063f785676fSDimitry Andric if (!MOReg) 2064f22ef01cSRoman Divacky continue; 2065f22ef01cSRoman Divacky 2066f785676fSDimitry Andric if (MOReg == Reg) { 2067f22ef01cSRoman Divacky MO.setIsDead(); 2068f22ef01cSRoman Divacky Found = true; 2069f22ef01cSRoman Divacky } else if (hasAliases && MO.isDead() && 2070f785676fSDimitry Andric TargetRegisterInfo::isPhysicalRegister(MOReg)) { 2071f22ef01cSRoman Divacky // There exists a super-register that's marked dead. 2072f785676fSDimitry Andric if (RegInfo->isSuperRegister(Reg, MOReg)) 2073f22ef01cSRoman Divacky return true; 2074f785676fSDimitry Andric if (RegInfo->isSubRegister(Reg, MOReg)) 2075f22ef01cSRoman Divacky DeadOps.push_back(i); 2076f22ef01cSRoman Divacky } 2077f22ef01cSRoman Divacky } 2078f22ef01cSRoman Divacky 2079f22ef01cSRoman Divacky // Trim unneeded dead operands. 2080f22ef01cSRoman Divacky while (!DeadOps.empty()) { 2081f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 2082f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 2083f22ef01cSRoman Divacky RemoveOperand(OpIdx); 2084f22ef01cSRoman Divacky else 2085f22ef01cSRoman Divacky getOperand(OpIdx).setIsDead(false); 2086f22ef01cSRoman Divacky DeadOps.pop_back(); 2087f22ef01cSRoman Divacky } 2088f22ef01cSRoman Divacky 2089f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is dead. Add a 2090f22ef01cSRoman Divacky // new implicit operand if required. 2091f22ef01cSRoman Divacky if (Found || !AddIfNotFound) 2092f22ef01cSRoman Divacky return Found; 2093f22ef01cSRoman Divacky 2094f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 2095f22ef01cSRoman Divacky true /*IsDef*/, 2096f22ef01cSRoman Divacky true /*IsImp*/, 2097f22ef01cSRoman Divacky false /*IsKill*/, 2098f22ef01cSRoman Divacky true /*IsDead*/)); 2099f22ef01cSRoman Divacky return true; 2100f22ef01cSRoman Divacky } 2101f22ef01cSRoman Divacky 2102ff0cc061SDimitry Andric void MachineInstr::clearRegisterDeads(unsigned Reg) { 2103ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2104ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg) 2105ff0cc061SDimitry Andric continue; 2106ff0cc061SDimitry Andric MO.setIsDead(false); 2107ff0cc061SDimitry Andric } 2108ff0cc061SDimitry Andric } 2109ff0cc061SDimitry Andric 21107d523365SDimitry Andric void MachineInstr::setRegisterDefReadUndef(unsigned Reg, bool IsUndef) { 2111ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2112ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0) 2113ff0cc061SDimitry Andric continue; 21147d523365SDimitry Andric MO.setIsUndef(IsUndef); 2115ff0cc061SDimitry Andric } 2116ff0cc061SDimitry Andric } 2117ff0cc061SDimitry Andric 2118f785676fSDimitry Andric void MachineInstr::addRegisterDefined(unsigned Reg, 2119f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo) { 2120f785676fSDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 2121f785676fSDimitry Andric MachineOperand *MO = findRegisterDefOperand(Reg, false, RegInfo); 2122f22ef01cSRoman Divacky if (MO) 2123f22ef01cSRoman Divacky return; 2124f22ef01cSRoman Divacky } else { 2125ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 2126f785676fSDimitry Andric if (MO.isReg() && MO.getReg() == Reg && MO.isDef() && 2127f22ef01cSRoman Divacky MO.getSubReg() == 0) 2128f22ef01cSRoman Divacky return; 2129f22ef01cSRoman Divacky } 2130f22ef01cSRoman Divacky } 2131f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 2132f22ef01cSRoman Divacky true /*IsDef*/, 2133f22ef01cSRoman Divacky true /*IsImp*/)); 2134f22ef01cSRoman Divacky } 2135f22ef01cSRoman Divacky 2136dff0c46cSDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs, 2137ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 2138dff0c46cSDimitry Andric bool HasRegMask = false; 2139ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2140dff0c46cSDimitry Andric if (MO.isRegMask()) { 2141dff0c46cSDimitry Andric HasRegMask = true; 2142dff0c46cSDimitry Andric continue; 2143dff0c46cSDimitry Andric } 2144ffd1746dSEd Schouten if (!MO.isReg() || !MO.isDef()) continue; 2145ffd1746dSEd Schouten unsigned Reg = MO.getReg(); 2146dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; 2147ffd1746dSEd Schouten // If there are no uses, including partial uses, the def is dead. 2148ff0cc061SDimitry Andric if (std::none_of(UsedRegs.begin(), UsedRegs.end(), 2149ff0cc061SDimitry Andric [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); })) 2150ff0cc061SDimitry Andric MO.setIsDead(); 2151ffd1746dSEd Schouten } 2152dff0c46cSDimitry Andric 2153dff0c46cSDimitry Andric // This is a call with a register mask operand. 2154dff0c46cSDimitry Andric // Mask clobbers are always dead, so add defs for the non-dead defines. 2155dff0c46cSDimitry Andric if (HasRegMask) 2156dff0c46cSDimitry Andric for (ArrayRef<unsigned>::iterator I = UsedRegs.begin(), E = UsedRegs.end(); 2157dff0c46cSDimitry Andric I != E; ++I) 2158dff0c46cSDimitry Andric addRegisterDefined(*I, &TRI); 2159ffd1746dSEd Schouten } 2160ffd1746dSEd Schouten 2161f22ef01cSRoman Divacky unsigned 2162f22ef01cSRoman Divacky MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { 2163dff0c46cSDimitry Andric // Build up a buffer of hash code components. 2164dff0c46cSDimitry Andric SmallVector<size_t, 8> HashComponents; 2165dff0c46cSDimitry Andric HashComponents.reserve(MI->getNumOperands() + 1); 2166dff0c46cSDimitry Andric HashComponents.push_back(MI->getOpcode()); 2167ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 21687ae0e2c9SDimitry Andric if (MO.isReg() && MO.isDef() && 21697ae0e2c9SDimitry Andric TargetRegisterInfo::isVirtualRegister(MO.getReg())) 2170f22ef01cSRoman Divacky continue; // Skip virtual register defs. 21717ae0e2c9SDimitry Andric 21727ae0e2c9SDimitry Andric HashComponents.push_back(hash_value(MO)); 2173f22ef01cSRoman Divacky } 2174dff0c46cSDimitry Andric return hash_combine_range(HashComponents.begin(), HashComponents.end()); 2175f22ef01cSRoman Divacky } 217617a519f9SDimitry Andric 217717a519f9SDimitry Andric void MachineInstr::emitError(StringRef Msg) const { 217817a519f9SDimitry Andric // Find the source location cookie. 217917a519f9SDimitry Andric unsigned LocCookie = 0; 218091bc56edSDimitry Andric const MDNode *LocMD = nullptr; 218117a519f9SDimitry Andric for (unsigned i = getNumOperands(); i != 0; --i) { 218217a519f9SDimitry Andric if (getOperand(i-1).isMetadata() && 218317a519f9SDimitry Andric (LocMD = getOperand(i-1).getMetadata()) && 218417a519f9SDimitry Andric LocMD->getNumOperands() != 0) { 218539d628a0SDimitry Andric if (const ConstantInt *CI = 218639d628a0SDimitry Andric mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) { 218717a519f9SDimitry Andric LocCookie = CI->getZExtValue(); 218817a519f9SDimitry Andric break; 218917a519f9SDimitry Andric } 219017a519f9SDimitry Andric } 219117a519f9SDimitry Andric } 219217a519f9SDimitry Andric 219317a519f9SDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 219417a519f9SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 219517a519f9SDimitry Andric return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg); 219617a519f9SDimitry Andric report_fatal_error(Msg); 219717a519f9SDimitry Andric } 21983ca95b02SDimitry Andric 21993ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, 22003ca95b02SDimitry Andric const MCInstrDesc &MCID, bool IsIndirect, 22013ca95b02SDimitry Andric unsigned Reg, unsigned Offset, 22023ca95b02SDimitry Andric const MDNode *Variable, const MDNode *Expr) { 22033ca95b02SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 22043ca95b02SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 22053ca95b02SDimitry Andric assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 22063ca95b02SDimitry Andric "Expected inlined-at fields to agree"); 22073ca95b02SDimitry Andric if (IsIndirect) 22083ca95b02SDimitry Andric return BuildMI(MF, DL, MCID) 22093ca95b02SDimitry Andric .addReg(Reg, RegState::Debug) 22103ca95b02SDimitry Andric .addImm(Offset) 22113ca95b02SDimitry Andric .addMetadata(Variable) 22123ca95b02SDimitry Andric .addMetadata(Expr); 22133ca95b02SDimitry Andric else { 22143ca95b02SDimitry Andric assert(Offset == 0 && "A direct address cannot have an offset."); 22153ca95b02SDimitry Andric return BuildMI(MF, DL, MCID) 22163ca95b02SDimitry Andric .addReg(Reg, RegState::Debug) 22173ca95b02SDimitry Andric .addReg(0U, RegState::Debug) 22183ca95b02SDimitry Andric .addMetadata(Variable) 22193ca95b02SDimitry Andric .addMetadata(Expr); 22203ca95b02SDimitry Andric } 22213ca95b02SDimitry Andric } 22223ca95b02SDimitry Andric 22233ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, 22243ca95b02SDimitry Andric MachineBasicBlock::iterator I, 22253ca95b02SDimitry Andric const DebugLoc &DL, const MCInstrDesc &MCID, 22263ca95b02SDimitry Andric bool IsIndirect, unsigned Reg, 22273ca95b02SDimitry Andric unsigned Offset, const MDNode *Variable, 22283ca95b02SDimitry Andric const MDNode *Expr) { 22293ca95b02SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 22303ca95b02SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 22313ca95b02SDimitry Andric MachineFunction &MF = *BB.getParent(); 22323ca95b02SDimitry Andric MachineInstr *MI = 22333ca95b02SDimitry Andric BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr); 22343ca95b02SDimitry Andric BB.insert(I, MI); 22353ca95b02SDimitry Andric return MachineInstrBuilder(MF, MI); 22363ca95b02SDimitry Andric } 2237