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" 20f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineMemOperand.h" 2117a519f9SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 22f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h" 23f22ef01cSRoman Divacky #include "llvm/CodeGen/PseudoSourceValue.h" 24139f7f9bSDimitry Andric #include "llvm/IR/Constants.h" 2591bc56edSDimitry Andric #include "llvm/IR/DebugInfo.h" 26139f7f9bSDimitry Andric #include "llvm/IR/Function.h" 27139f7f9bSDimitry Andric #include "llvm/IR/InlineAsm.h" 28139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h" 29139f7f9bSDimitry Andric #include "llvm/IR/Metadata.h" 30139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 313dac3a9bSDimitry Andric #include "llvm/IR/ModuleSlotTracker.h" 32139f7f9bSDimitry Andric #include "llvm/IR/Type.h" 33139f7f9bSDimitry Andric #include "llvm/IR/Value.h" 3417a519f9SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 35f22ef01cSRoman Divacky #include "llvm/MC/MCSymbol.h" 367d523365SDimitry Andric #include "llvm/Support/CommandLine.h" 37f22ef01cSRoman Divacky #include "llvm/Support/Debug.h" 38f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 39f22ef01cSRoman Divacky #include "llvm/Support/MathExtras.h" 40f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 41139f7f9bSDimitry Andric #include "llvm/Target/TargetInstrInfo.h" 42139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h" 43139f7f9bSDimitry Andric #include "llvm/Target/TargetRegisterInfo.h" 4439d628a0SDimitry Andric #include "llvm/Target/TargetSubtargetInfo.h" 45f22ef01cSRoman Divacky using namespace llvm; 46f22ef01cSRoman Divacky 477d523365SDimitry Andric static cl::opt<bool> PrintWholeRegMask( 487d523365SDimitry Andric "print-whole-regmask", 497d523365SDimitry Andric cl::desc("Print the full contents of regmask operands in IR dumps"), 507d523365SDimitry Andric cl::init(true), cl::Hidden); 517d523365SDimitry Andric 52f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 53f22ef01cSRoman Divacky // MachineOperand Implementation 54f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 55f22ef01cSRoman Divacky 56f22ef01cSRoman Divacky void MachineOperand::setReg(unsigned Reg) { 57f22ef01cSRoman Divacky if (getReg() == Reg) return; // No change. 58f22ef01cSRoman Divacky 59f22ef01cSRoman Divacky // Otherwise, we have to change the register. If this operand is embedded 60f22ef01cSRoman Divacky // into a machine function, we need to update the old and new register's 61f22ef01cSRoman Divacky // use/def lists. 62f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 63f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 64f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) { 657ae0e2c9SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 667ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(this); 672754fe60SDimitry Andric SmallContents.RegNo = Reg; 687ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(this); 69f22ef01cSRoman Divacky return; 70f22ef01cSRoman Divacky } 71f22ef01cSRoman Divacky 72f22ef01cSRoman Divacky // Otherwise, just change the register, no problem. :) 732754fe60SDimitry Andric SmallContents.RegNo = Reg; 74f22ef01cSRoman Divacky } 75f22ef01cSRoman Divacky 76ffd1746dSEd Schouten void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, 77ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 78ffd1746dSEd Schouten assert(TargetRegisterInfo::isVirtualRegister(Reg)); 79ffd1746dSEd Schouten if (SubIdx && getSubReg()) 80ffd1746dSEd Schouten SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); 81ffd1746dSEd Schouten setReg(Reg); 82ffd1746dSEd Schouten if (SubIdx) 83ffd1746dSEd Schouten setSubReg(SubIdx); 84ffd1746dSEd Schouten } 85ffd1746dSEd Schouten 86ffd1746dSEd Schouten void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { 87ffd1746dSEd Schouten assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 88ffd1746dSEd Schouten if (getSubReg()) { 89ffd1746dSEd Schouten Reg = TRI.getSubReg(Reg, getSubReg()); 90bd5abe19SDimitry Andric // Note that getSubReg() may return 0 if the sub-register doesn't exist. 91bd5abe19SDimitry Andric // That won't happen in legal code. 92ffd1746dSEd Schouten setSubReg(0); 93ffd1746dSEd Schouten } 94ffd1746dSEd Schouten setReg(Reg); 95ffd1746dSEd Schouten } 96ffd1746dSEd Schouten 977ae0e2c9SDimitry Andric /// Change a def to a use, or a use to a def. 987ae0e2c9SDimitry Andric void MachineOperand::setIsDef(bool Val) { 997ae0e2c9SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 1007ae0e2c9SDimitry Andric assert((!Val || !isDebug()) && "Marking a debug operation as def"); 1017ae0e2c9SDimitry Andric if (IsDef == Val) 1027ae0e2c9SDimitry Andric return; 1037ae0e2c9SDimitry Andric // MRI may keep uses and defs in different list positions. 1047ae0e2c9SDimitry Andric if (MachineInstr *MI = getParent()) 1057ae0e2c9SDimitry Andric if (MachineBasicBlock *MBB = MI->getParent()) 1067ae0e2c9SDimitry Andric if (MachineFunction *MF = MBB->getParent()) { 1077ae0e2c9SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 1087ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(this); 1097ae0e2c9SDimitry Andric IsDef = Val; 1107ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(this); 1117ae0e2c9SDimitry Andric return; 1127ae0e2c9SDimitry Andric } 1137ae0e2c9SDimitry Andric IsDef = Val; 1147ae0e2c9SDimitry Andric } 1157ae0e2c9SDimitry Andric 11639d628a0SDimitry Andric // If this operand is currently a register operand, and if this is in a 11739d628a0SDimitry Andric // function, deregister the operand from the register's use/def list. 11839d628a0SDimitry Andric void MachineOperand::removeRegFromUses() { 11939d628a0SDimitry Andric if (!isReg() || !isOnRegUseList()) 12039d628a0SDimitry Andric return; 12139d628a0SDimitry Andric 12239d628a0SDimitry Andric if (MachineInstr *MI = getParent()) { 12339d628a0SDimitry Andric if (MachineBasicBlock *MBB = MI->getParent()) { 12439d628a0SDimitry Andric if (MachineFunction *MF = MBB->getParent()) 12539d628a0SDimitry Andric MF->getRegInfo().removeRegOperandFromUseList(this); 12639d628a0SDimitry Andric } 12739d628a0SDimitry Andric } 12839d628a0SDimitry Andric } 12939d628a0SDimitry Andric 130f22ef01cSRoman Divacky /// ChangeToImmediate - Replace this operand with a new immediate operand of 131f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an immediate already, 132f22ef01cSRoman Divacky /// the setImm method should be used. 133f22ef01cSRoman Divacky void MachineOperand::ChangeToImmediate(int64_t ImmVal) { 1343861d79fSDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 13539d628a0SDimitry Andric 13639d628a0SDimitry Andric removeRegFromUses(); 137f22ef01cSRoman Divacky 138f22ef01cSRoman Divacky OpKind = MO_Immediate; 139f22ef01cSRoman Divacky Contents.ImmVal = ImmVal; 140f22ef01cSRoman Divacky } 141f22ef01cSRoman Divacky 14239d628a0SDimitry Andric void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) { 14339d628a0SDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 14439d628a0SDimitry Andric 14539d628a0SDimitry Andric removeRegFromUses(); 14639d628a0SDimitry Andric 14739d628a0SDimitry Andric OpKind = MO_FPImmediate; 14839d628a0SDimitry Andric Contents.CFP = FPImm; 14939d628a0SDimitry Andric } 15039d628a0SDimitry Andric 151ff0cc061SDimitry Andric void MachineOperand::ChangeToES(const char *SymName, unsigned char TargetFlags) { 152ff0cc061SDimitry Andric assert((!isReg() || !isTied()) && 153ff0cc061SDimitry Andric "Cannot change a tied operand into an external symbol"); 154ff0cc061SDimitry Andric 155ff0cc061SDimitry Andric removeRegFromUses(); 156ff0cc061SDimitry Andric 157ff0cc061SDimitry Andric OpKind = MO_ExternalSymbol; 158ff0cc061SDimitry Andric Contents.OffsetedInfo.Val.SymbolName = SymName; 159ff0cc061SDimitry Andric setOffset(0); // Offset is always 0. 160ff0cc061SDimitry Andric setTargetFlags(TargetFlags); 161ff0cc061SDimitry Andric } 162ff0cc061SDimitry Andric 163ff0cc061SDimitry Andric void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) { 164ff0cc061SDimitry Andric assert((!isReg() || !isTied()) && 165ff0cc061SDimitry Andric "Cannot change a tied operand into an MCSymbol"); 166ff0cc061SDimitry Andric 167ff0cc061SDimitry Andric removeRegFromUses(); 168ff0cc061SDimitry Andric 169ff0cc061SDimitry Andric OpKind = MO_MCSymbol; 170ff0cc061SDimitry Andric Contents.Sym = Sym; 171ff0cc061SDimitry Andric } 172ff0cc061SDimitry Andric 173f22ef01cSRoman Divacky /// ChangeToRegister - Replace this operand with a new register operand of 174f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an register already, 175f22ef01cSRoman Divacky /// the setReg method should be used. 176f22ef01cSRoman Divacky void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, 177f22ef01cSRoman Divacky bool isKill, bool isDead, bool isUndef, 178f22ef01cSRoman Divacky bool isDebug) { 17991bc56edSDimitry Andric MachineRegisterInfo *RegInfo = nullptr; 180f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 181f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 182f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) 1837ae0e2c9SDimitry Andric RegInfo = &MF->getRegInfo(); 1847ae0e2c9SDimitry Andric // If this operand is already a register operand, remove it from the 1857ae0e2c9SDimitry Andric // register's use/def lists. 1863861d79fSDimitry Andric bool WasReg = isReg(); 1873861d79fSDimitry Andric if (RegInfo && WasReg) 1887ae0e2c9SDimitry Andric RegInfo->removeRegOperandFromUseList(this); 189f22ef01cSRoman Divacky 1907ae0e2c9SDimitry Andric // Change this to a register and set the reg#. 1917ae0e2c9SDimitry Andric OpKind = MO_Register; 1927ae0e2c9SDimitry Andric SmallContents.RegNo = Reg; 193139f7f9bSDimitry Andric SubReg_TargetFlags = 0; 194f22ef01cSRoman Divacky IsDef = isDef; 195f22ef01cSRoman Divacky IsImp = isImp; 196f22ef01cSRoman Divacky IsKill = isKill; 197f22ef01cSRoman Divacky IsDead = isDead; 198f22ef01cSRoman Divacky IsUndef = isUndef; 199dff0c46cSDimitry Andric IsInternalRead = false; 200f22ef01cSRoman Divacky IsEarlyClobber = false; 201f22ef01cSRoman Divacky IsDebug = isDebug; 2027ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false. 20391bc56edSDimitry Andric Contents.Reg.Prev = nullptr; 2043861d79fSDimitry Andric // Preserve the tie when the operand was already a register. 2053861d79fSDimitry Andric if (!WasReg) 2063861d79fSDimitry Andric TiedTo = 0; 2077ae0e2c9SDimitry Andric 2087ae0e2c9SDimitry Andric // If this operand is embedded in a function, add the operand to the 2097ae0e2c9SDimitry Andric // register's use/def list. 2107ae0e2c9SDimitry Andric if (RegInfo) 2117ae0e2c9SDimitry Andric RegInfo->addRegOperandToUseList(this); 212f22ef01cSRoman Divacky } 213f22ef01cSRoman Divacky 214f22ef01cSRoman Divacky /// isIdenticalTo - Return true if this operand is identical to the specified 2157ae0e2c9SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload 2167ae0e2c9SDimitry Andric /// below. 217f22ef01cSRoman Divacky bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 218f22ef01cSRoman Divacky if (getType() != Other.getType() || 219f22ef01cSRoman Divacky getTargetFlags() != Other.getTargetFlags()) 220f22ef01cSRoman Divacky return false; 221f22ef01cSRoman Divacky 222f22ef01cSRoman Divacky switch (getType()) { 223f22ef01cSRoman Divacky case MachineOperand::MO_Register: 224f22ef01cSRoman Divacky return getReg() == Other.getReg() && isDef() == Other.isDef() && 225f22ef01cSRoman Divacky getSubReg() == Other.getSubReg(); 226f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 227f22ef01cSRoman Divacky return getImm() == Other.getImm(); 22817a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 22917a519f9SDimitry Andric return getCImm() == Other.getCImm(); 230f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 231f22ef01cSRoman Divacky return getFPImm() == Other.getFPImm(); 232f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 233f22ef01cSRoman Divacky return getMBB() == Other.getMBB(); 234f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 235f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 236f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 2377ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 238f22ef01cSRoman Divacky return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 239f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 240f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 241f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 242f22ef01cSRoman Divacky return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 243f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 244f22ef01cSRoman Divacky return !strcmp(getSymbolName(), Other.getSymbolName()) && 245f22ef01cSRoman Divacky getOffset() == Other.getOffset(); 246f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 2473861d79fSDimitry Andric return getBlockAddress() == Other.getBlockAddress() && 2483861d79fSDimitry Andric getOffset() == Other.getOffset(); 24991bc56edSDimitry Andric case MachineOperand::MO_RegisterMask: 25091bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 251dff0c46cSDimitry Andric return getRegMask() == Other.getRegMask(); 252f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 253f22ef01cSRoman Divacky return getMCSymbol() == Other.getMCSymbol(); 25491bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 25591bc56edSDimitry Andric return getCFIIndex() == Other.getCFIIndex(); 256f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 257f22ef01cSRoman Divacky return getMetadata() == Other.getMetadata(); 258f22ef01cSRoman Divacky } 259dff0c46cSDimitry Andric llvm_unreachable("Invalid machine operand type"); 260f22ef01cSRoman Divacky } 261f22ef01cSRoman Divacky 2627ae0e2c9SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above. 2637ae0e2c9SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) { 2647ae0e2c9SDimitry Andric switch (MO.getType()) { 2657ae0e2c9SDimitry Andric case MachineOperand::MO_Register: 2663861d79fSDimitry Andric // Register operands don't have target flags. 2673861d79fSDimitry Andric return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef()); 2687ae0e2c9SDimitry Andric case MachineOperand::MO_Immediate: 2697ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 2707ae0e2c9SDimitry Andric case MachineOperand::MO_CImmediate: 2717ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 2727ae0e2c9SDimitry Andric case MachineOperand::MO_FPImmediate: 2737ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 2747ae0e2c9SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 2757ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 2767ae0e2c9SDimitry Andric case MachineOperand::MO_FrameIndex: 2777ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 2787ae0e2c9SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 2797ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 2807ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 2817ae0e2c9SDimitry Andric MO.getOffset()); 2827ae0e2c9SDimitry Andric case MachineOperand::MO_JumpTableIndex: 2837ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 2847ae0e2c9SDimitry Andric case MachineOperand::MO_ExternalSymbol: 2857ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 2867ae0e2c9SDimitry Andric MO.getSymbolName()); 2877ae0e2c9SDimitry Andric case MachineOperand::MO_GlobalAddress: 2887ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 2897ae0e2c9SDimitry Andric MO.getOffset()); 2907ae0e2c9SDimitry Andric case MachineOperand::MO_BlockAddress: 2917ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), 2923861d79fSDimitry Andric MO.getBlockAddress(), MO.getOffset()); 2937ae0e2c9SDimitry Andric case MachineOperand::MO_RegisterMask: 29491bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 2957ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); 2967ae0e2c9SDimitry Andric case MachineOperand::MO_Metadata: 2977ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 2987ae0e2c9SDimitry Andric case MachineOperand::MO_MCSymbol: 2997ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 30091bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 30191bc56edSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 3027ae0e2c9SDimitry Andric } 3037ae0e2c9SDimitry Andric llvm_unreachable("Invalid machine operand type"); 3047ae0e2c9SDimitry Andric } 3057ae0e2c9SDimitry Andric 306ff0cc061SDimitry Andric void MachineOperand::print(raw_ostream &OS, 307ff0cc061SDimitry Andric const TargetRegisterInfo *TRI) const { 3083dac3a9bSDimitry Andric ModuleSlotTracker DummyMST(nullptr); 3093dac3a9bSDimitry Andric print(OS, DummyMST, TRI); 3103dac3a9bSDimitry Andric } 3113dac3a9bSDimitry Andric 3123dac3a9bSDimitry Andric void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, 3133dac3a9bSDimitry Andric const TargetRegisterInfo *TRI) const { 314f22ef01cSRoman Divacky switch (getType()) { 315f22ef01cSRoman Divacky case MachineOperand::MO_Register: 3162754fe60SDimitry Andric OS << PrintReg(getReg(), TRI, getSubReg()); 317f22ef01cSRoman Divacky 318f22ef01cSRoman Divacky if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || 3193861d79fSDimitry Andric isInternalRead() || isEarlyClobber() || isTied()) { 320f22ef01cSRoman Divacky OS << '<'; 321f22ef01cSRoman Divacky bool NeedComma = false; 322f22ef01cSRoman Divacky if (isDef()) { 323f22ef01cSRoman Divacky if (NeedComma) OS << ','; 324f22ef01cSRoman Divacky if (isEarlyClobber()) 325f22ef01cSRoman Divacky OS << "earlyclobber,"; 326f22ef01cSRoman Divacky if (isImplicit()) 327f22ef01cSRoman Divacky OS << "imp-"; 328f22ef01cSRoman Divacky OS << "def"; 329f22ef01cSRoman Divacky NeedComma = true; 3307ae0e2c9SDimitry Andric // <def,read-undef> only makes sense when getSubReg() is set. 3317ae0e2c9SDimitry Andric // Don't clutter the output otherwise. 3327ae0e2c9SDimitry Andric if (isUndef() && getSubReg()) 3337ae0e2c9SDimitry Andric OS << ",read-undef"; 334f22ef01cSRoman Divacky } else if (isImplicit()) { 335f22ef01cSRoman Divacky OS << "imp-use"; 336f22ef01cSRoman Divacky NeedComma = true; 337f22ef01cSRoman Divacky } 338f22ef01cSRoman Divacky 339dff0c46cSDimitry Andric if (isKill()) { 3403861d79fSDimitry Andric if (NeedComma) OS << ','; 341dff0c46cSDimitry Andric OS << "kill"; 342dff0c46cSDimitry Andric NeedComma = true; 343dff0c46cSDimitry Andric } 344dff0c46cSDimitry Andric if (isDead()) { 3453861d79fSDimitry Andric if (NeedComma) OS << ','; 346dff0c46cSDimitry Andric OS << "dead"; 347dff0c46cSDimitry Andric NeedComma = true; 348dff0c46cSDimitry Andric } 3497ae0e2c9SDimitry Andric if (isUndef() && isUse()) { 350dff0c46cSDimitry Andric if (NeedComma) OS << ','; 351f22ef01cSRoman Divacky OS << "undef"; 352dff0c46cSDimitry Andric NeedComma = true; 353dff0c46cSDimitry Andric } 354dff0c46cSDimitry Andric if (isInternalRead()) { 355dff0c46cSDimitry Andric if (NeedComma) OS << ','; 356dff0c46cSDimitry Andric OS << "internal"; 357dff0c46cSDimitry Andric NeedComma = true; 358f22ef01cSRoman Divacky } 3593861d79fSDimitry Andric if (isTied()) { 3603861d79fSDimitry Andric if (NeedComma) OS << ','; 3613861d79fSDimitry Andric OS << "tied"; 3623861d79fSDimitry Andric if (TiedTo != 15) 3633861d79fSDimitry Andric OS << unsigned(TiedTo - 1); 364f22ef01cSRoman Divacky } 365f22ef01cSRoman Divacky OS << '>'; 366f22ef01cSRoman Divacky } 367f22ef01cSRoman Divacky break; 368f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 369f22ef01cSRoman Divacky OS << getImm(); 370f22ef01cSRoman Divacky break; 37117a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 37217a519f9SDimitry Andric getCImm()->getValue().print(OS, false); 37317a519f9SDimitry Andric break; 374f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 375f22ef01cSRoman Divacky if (getFPImm()->getType()->isFloatTy()) 376f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToFloat(); 377f22ef01cSRoman Divacky else 378f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToDouble(); 379f22ef01cSRoman Divacky break; 380f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 381f22ef01cSRoman Divacky OS << "<BB#" << getMBB()->getNumber() << ">"; 382f22ef01cSRoman Divacky break; 383f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 384f22ef01cSRoman Divacky OS << "<fi#" << getIndex() << '>'; 385f22ef01cSRoman Divacky break; 386f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 387f22ef01cSRoman Divacky OS << "<cp#" << getIndex(); 388f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 389f22ef01cSRoman Divacky OS << '>'; 390f22ef01cSRoman Divacky break; 3917ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 3927ae0e2c9SDimitry Andric OS << "<ti#" << getIndex(); 3937ae0e2c9SDimitry Andric if (getOffset()) OS << "+" << getOffset(); 3947ae0e2c9SDimitry Andric OS << '>'; 3957ae0e2c9SDimitry Andric break; 396f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 397f22ef01cSRoman Divacky OS << "<jt#" << getIndex() << '>'; 398f22ef01cSRoman Divacky break; 399f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 400f22ef01cSRoman Divacky OS << "<ga:"; 4013dac3a9bSDimitry Andric getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); 402f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 403f22ef01cSRoman Divacky OS << '>'; 404f22ef01cSRoman Divacky break; 405f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 406f22ef01cSRoman Divacky OS << "<es:" << getSymbolName(); 407f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 408f22ef01cSRoman Divacky OS << '>'; 409f22ef01cSRoman Divacky break; 410f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 411f22ef01cSRoman Divacky OS << '<'; 4123dac3a9bSDimitry Andric getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST); 4133861d79fSDimitry Andric if (getOffset()) OS << "+" << getOffset(); 414f22ef01cSRoman Divacky OS << '>'; 415f22ef01cSRoman Divacky break; 4167d523365SDimitry Andric case MachineOperand::MO_RegisterMask: { 4177d523365SDimitry Andric unsigned NumRegsInMask = 0; 4187d523365SDimitry Andric unsigned NumRegsEmitted = 0; 4197d523365SDimitry Andric OS << "<regmask"; 4207d523365SDimitry Andric for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { 4217d523365SDimitry Andric unsigned MaskWord = i / 32; 4227d523365SDimitry Andric unsigned MaskBit = i % 32; 4237d523365SDimitry Andric if (getRegMask()[MaskWord] & (1 << MaskBit)) { 4247d523365SDimitry Andric if (PrintWholeRegMask || NumRegsEmitted <= 10) { 4257d523365SDimitry Andric OS << " " << PrintReg(i, TRI); 4267d523365SDimitry Andric NumRegsEmitted++; 4277d523365SDimitry Andric } 4287d523365SDimitry Andric NumRegsInMask++; 4297d523365SDimitry Andric } 4307d523365SDimitry Andric } 4317d523365SDimitry Andric if (NumRegsEmitted != NumRegsInMask) 4327d523365SDimitry Andric OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; 4337d523365SDimitry Andric OS << ">"; 434dff0c46cSDimitry Andric break; 4357d523365SDimitry Andric } 43691bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 43791bc56edSDimitry Andric OS << "<regliveout>"; 43891bc56edSDimitry Andric break; 439f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 440f22ef01cSRoman Divacky OS << '<'; 4413dac3a9bSDimitry Andric getMetadata()->printAsOperand(OS, MST); 442f22ef01cSRoman Divacky OS << '>'; 443f22ef01cSRoman Divacky break; 444f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 445f22ef01cSRoman Divacky OS << "<MCSym=" << *getMCSymbol() << '>'; 446f22ef01cSRoman Divacky break; 44791bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 44891bc56edSDimitry Andric OS << "<call frame instruction>"; 44991bc56edSDimitry Andric break; 450f22ef01cSRoman Divacky } 451f22ef01cSRoman Divacky 452f22ef01cSRoman Divacky if (unsigned TF = getTargetFlags()) 453f22ef01cSRoman Divacky OS << "[TF=" << TF << ']'; 454f22ef01cSRoman Divacky } 455f22ef01cSRoman Divacky 456f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 457f22ef01cSRoman Divacky // MachineMemOperand Implementation 458f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 459f22ef01cSRoman Divacky 4602754fe60SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer 4612754fe60SDimitry Andric /// points into. 4622754fe60SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { 46391bc56edSDimitry Andric if (V.isNull() || V.is<const PseudoSourceValue*>()) return 0; 46491bc56edSDimitry Andric return cast<PointerType>(V.get<const Value*>()->getType())->getAddressSpace(); 4652754fe60SDimitry Andric } 4662754fe60SDimitry Andric 4672754fe60SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the 4682754fe60SDimitry Andric /// constant pool. 4697d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { 4707d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getConstantPool()); 4712754fe60SDimitry Andric } 4722754fe60SDimitry Andric 4732754fe60SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the 4742754fe60SDimitry Andric /// the specified FrameIndex. 4757d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, 4767d523365SDimitry Andric int FI, int64_t Offset) { 4777d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); 4782754fe60SDimitry Andric } 4792754fe60SDimitry Andric 4807d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { 4817d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getJumpTable()); 4822754fe60SDimitry Andric } 4832754fe60SDimitry Andric 4847d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { 4857d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getGOT()); 4862754fe60SDimitry Andric } 4872754fe60SDimitry Andric 4887d523365SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, 4897d523365SDimitry Andric int64_t Offset) { 4907d523365SDimitry Andric return MachinePointerInfo(MF.getPSVManager().getStack(), Offset); 4912754fe60SDimitry Andric } 4922754fe60SDimitry Andric 4932754fe60SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, unsigned f, 4942754fe60SDimitry Andric uint64_t s, unsigned int a, 49539d628a0SDimitry Andric const AAMDNodes &AAInfo, 496dff0c46cSDimitry Andric const MDNode *Ranges) 4972754fe60SDimitry Andric : PtrInfo(ptrinfo), Size(s), 4982754fe60SDimitry Andric Flags((f & ((1 << MOMaxBits) - 1)) | ((Log2_32(a) + 1) << MOMaxBits)), 49939d628a0SDimitry Andric AAInfo(AAInfo), Ranges(Ranges) { 50091bc56edSDimitry Andric assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue*>() || 50191bc56edSDimitry Andric isa<PointerType>(PtrInfo.V.get<const Value*>()->getType())) && 5022754fe60SDimitry Andric "invalid pointer value"); 503f22ef01cSRoman Divacky assert(getBaseAlignment() == a && "Alignment is not a power of 2!"); 504f22ef01cSRoman Divacky assert((isLoad() || isStore()) && "Not a load/store!"); 505f22ef01cSRoman Divacky } 506f22ef01cSRoman Divacky 507f22ef01cSRoman Divacky /// Profile - Gather unique data for the object. 508f22ef01cSRoman Divacky /// 509f22ef01cSRoman Divacky void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 5102754fe60SDimitry Andric ID.AddInteger(getOffset()); 511f22ef01cSRoman Divacky ID.AddInteger(Size); 51291bc56edSDimitry Andric ID.AddPointer(getOpaqueValue()); 513f22ef01cSRoman Divacky ID.AddInteger(Flags); 514f22ef01cSRoman Divacky } 515f22ef01cSRoman Divacky 516f22ef01cSRoman Divacky void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 517f22ef01cSRoman Divacky // The Value and Offset may differ due to CSE. But the flags and size 518f22ef01cSRoman Divacky // should be the same. 519f22ef01cSRoman Divacky assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 520f22ef01cSRoman Divacky assert(MMO->getSize() == getSize() && "Size mismatch!"); 521f22ef01cSRoman Divacky 522f22ef01cSRoman Divacky if (MMO->getBaseAlignment() >= getBaseAlignment()) { 523f22ef01cSRoman Divacky // Update the alignment value. 524f22ef01cSRoman Divacky Flags = (Flags & ((1 << MOMaxBits) - 1)) | 525f22ef01cSRoman Divacky ((Log2_32(MMO->getBaseAlignment()) + 1) << MOMaxBits); 526f22ef01cSRoman Divacky // Also update the base and offset, because the new alignment may 527f22ef01cSRoman Divacky // not be applicable with the old ones. 5282754fe60SDimitry Andric PtrInfo = MMO->PtrInfo; 529f22ef01cSRoman Divacky } 530f22ef01cSRoman Divacky } 531f22ef01cSRoman Divacky 532f22ef01cSRoman Divacky /// getAlignment - Return the minimum known alignment in bytes of the 533f22ef01cSRoman Divacky /// actual memory reference. 534f22ef01cSRoman Divacky uint64_t MachineMemOperand::getAlignment() const { 535f22ef01cSRoman Divacky return MinAlign(getBaseAlignment(), getOffset()); 536f22ef01cSRoman Divacky } 537f22ef01cSRoman Divacky 5383dac3a9bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS) const { 5393dac3a9bSDimitry Andric ModuleSlotTracker DummyMST(nullptr); 5403dac3a9bSDimitry Andric print(OS, DummyMST); 5413dac3a9bSDimitry Andric } 5423dac3a9bSDimitry Andric void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const { 5433dac3a9bSDimitry Andric assert((isLoad() || isStore()) && 544f22ef01cSRoman Divacky "SV has to be a load, store or both."); 545f22ef01cSRoman Divacky 5463dac3a9bSDimitry Andric if (isVolatile()) 547f22ef01cSRoman Divacky OS << "Volatile "; 548f22ef01cSRoman Divacky 5493dac3a9bSDimitry Andric if (isLoad()) 550f22ef01cSRoman Divacky OS << "LD"; 5513dac3a9bSDimitry Andric if (isStore()) 552f22ef01cSRoman Divacky OS << "ST"; 5533dac3a9bSDimitry Andric OS << getSize(); 554f22ef01cSRoman Divacky 555f22ef01cSRoman Divacky // Print the address information. 556f22ef01cSRoman Divacky OS << "["; 5573dac3a9bSDimitry Andric if (const Value *V = getValue()) 5583dac3a9bSDimitry Andric V->printAsOperand(OS, /*PrintType=*/false, MST); 5593dac3a9bSDimitry Andric else if (const PseudoSourceValue *PSV = getPseudoValue()) 56091bc56edSDimitry Andric PSV->printCustom(OS); 561f22ef01cSRoman Divacky else 56291bc56edSDimitry Andric OS << "<unknown>"; 56391bc56edSDimitry Andric 5643dac3a9bSDimitry Andric unsigned AS = getAddrSpace(); 56591bc56edSDimitry Andric if (AS != 0) 56691bc56edSDimitry Andric OS << "(addrspace=" << AS << ')'; 567f22ef01cSRoman Divacky 568f22ef01cSRoman Divacky // If the alignment of the memory reference itself differs from the alignment 569f22ef01cSRoman Divacky // of the base pointer, print the base alignment explicitly, next to the base 570f22ef01cSRoman Divacky // pointer. 5713dac3a9bSDimitry Andric if (getBaseAlignment() != getAlignment()) 5723dac3a9bSDimitry Andric OS << "(align=" << getBaseAlignment() << ")"; 573f22ef01cSRoman Divacky 5743dac3a9bSDimitry Andric if (getOffset() != 0) 5753dac3a9bSDimitry Andric OS << "+" << getOffset(); 576f22ef01cSRoman Divacky OS << "]"; 577f22ef01cSRoman Divacky 578f22ef01cSRoman Divacky // Print the alignment of the reference. 5793dac3a9bSDimitry Andric if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize()) 5803dac3a9bSDimitry Andric OS << "(align=" << getAlignment() << ")"; 581f22ef01cSRoman Divacky 5822754fe60SDimitry Andric // Print TBAA info. 5833dac3a9bSDimitry Andric if (const MDNode *TBAAInfo = getAAInfo().TBAA) { 5842754fe60SDimitry Andric OS << "(tbaa="; 5852754fe60SDimitry Andric if (TBAAInfo->getNumOperands() > 0) 5863dac3a9bSDimitry Andric TBAAInfo->getOperand(0)->printAsOperand(OS, MST); 58739d628a0SDimitry Andric else 58839d628a0SDimitry Andric OS << "<unknown>"; 58939d628a0SDimitry Andric OS << ")"; 59039d628a0SDimitry Andric } 59139d628a0SDimitry Andric 59239d628a0SDimitry Andric // Print AA scope info. 5933dac3a9bSDimitry Andric if (const MDNode *ScopeInfo = getAAInfo().Scope) { 59439d628a0SDimitry Andric OS << "(alias.scope="; 59539d628a0SDimitry Andric if (ScopeInfo->getNumOperands() > 0) 59639d628a0SDimitry Andric for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { 5973dac3a9bSDimitry Andric ScopeInfo->getOperand(i)->printAsOperand(OS, MST); 59839d628a0SDimitry Andric if (i != ie-1) 59939d628a0SDimitry Andric OS << ","; 60039d628a0SDimitry Andric } 60139d628a0SDimitry Andric else 60239d628a0SDimitry Andric OS << "<unknown>"; 60339d628a0SDimitry Andric OS << ")"; 60439d628a0SDimitry Andric } 60539d628a0SDimitry Andric 60639d628a0SDimitry Andric // Print AA noalias scope info. 6073dac3a9bSDimitry Andric if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) { 60839d628a0SDimitry Andric OS << "(noalias="; 60939d628a0SDimitry Andric if (NoAliasInfo->getNumOperands() > 0) 61039d628a0SDimitry Andric for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { 6113dac3a9bSDimitry Andric NoAliasInfo->getOperand(i)->printAsOperand(OS, MST); 61239d628a0SDimitry Andric if (i != ie-1) 61339d628a0SDimitry Andric OS << ","; 61439d628a0SDimitry Andric } 6152754fe60SDimitry Andric else 6162754fe60SDimitry Andric OS << "<unknown>"; 6172754fe60SDimitry Andric OS << ")"; 6182754fe60SDimitry Andric } 6192754fe60SDimitry Andric 6203b0f4066SDimitry Andric // Print nontemporal info. 6213dac3a9bSDimitry Andric if (isNonTemporal()) 6223b0f4066SDimitry Andric OS << "(nontemporal)"; 6233b0f4066SDimitry Andric 6243dac3a9bSDimitry Andric if (isInvariant()) 6253dac3a9bSDimitry Andric OS << "(invariant)"; 626f22ef01cSRoman Divacky } 627f22ef01cSRoman Divacky 628f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 629f22ef01cSRoman Divacky // MachineInstr Implementation 630f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 631f22ef01cSRoman Divacky 632139f7f9bSDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { 63317a519f9SDimitry Andric if (MCID->ImplicitDefs) 6347d523365SDimitry Andric for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; 6357d523365SDimitry Andric ++ImpDefs) 636139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true)); 63717a519f9SDimitry Andric if (MCID->ImplicitUses) 6387d523365SDimitry Andric for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses; 6397d523365SDimitry Andric ++ImpUses) 640139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true)); 641f22ef01cSRoman Divacky } 642f22ef01cSRoman Divacky 643f22ef01cSRoman Divacky /// MachineInstr ctor - This constructor creates a MachineInstr and adds the 644f22ef01cSRoman Divacky /// implicit operands. It reserves space for the number of operands specified by 64517a519f9SDimitry Andric /// the MCInstrDesc. 646139f7f9bSDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid, 647ff0cc061SDimitry Andric DebugLoc dl, bool NoImp) 648ff0cc061SDimitry Andric : MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), Flags(0), 649ff0cc061SDimitry Andric AsmPrinterFlags(0), NumMemRefs(0), MemRefs(nullptr), 650ff0cc061SDimitry Andric debugLoc(std::move(dl)) { 65139d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 65239d628a0SDimitry Andric 653139f7f9bSDimitry Andric // Reserve space for the expected number of operands. 654139f7f9bSDimitry Andric if (unsigned NumOps = MCID->getNumOperands() + 655139f7f9bSDimitry Andric MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) { 656139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(NumOps); 657139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 658f22ef01cSRoman Divacky } 659f22ef01cSRoman Divacky 660139f7f9bSDimitry Andric if (!NoImp) 661139f7f9bSDimitry Andric addImplicitDefUseOperands(MF); 662f22ef01cSRoman Divacky } 663f22ef01cSRoman Divacky 664f22ef01cSRoman Divacky /// MachineInstr ctor - Copies MachineInstr arg exactly 665f22ef01cSRoman Divacky /// 666f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) 66791bc56edSDimitry Andric : MCID(&MI.getDesc()), Parent(nullptr), Operands(nullptr), NumOperands(0), 668139f7f9bSDimitry Andric Flags(0), AsmPrinterFlags(0), 669dff0c46cSDimitry Andric NumMemRefs(MI.NumMemRefs), MemRefs(MI.MemRefs), 670139f7f9bSDimitry Andric debugLoc(MI.getDebugLoc()) { 67139d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 67239d628a0SDimitry Andric 673139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(MI.getNumOperands()); 674139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 675f22ef01cSRoman Divacky 676139f7f9bSDimitry Andric // Copy operands. 677ff0cc061SDimitry Andric for (const MachineOperand &MO : MI.operands()) 678ff0cc061SDimitry Andric addOperand(MF, MO); 679f22ef01cSRoman Divacky 680139f7f9bSDimitry Andric // Copy all the sensible flags. 681139f7f9bSDimitry Andric setFlags(MI.Flags); 682f22ef01cSRoman Divacky } 683f22ef01cSRoman Divacky 684f22ef01cSRoman Divacky /// getRegInfo - If this instruction is embedded into a MachineFunction, 685f22ef01cSRoman Divacky /// return the MachineRegisterInfo object for the current function, otherwise 686f22ef01cSRoman Divacky /// return null. 687f22ef01cSRoman Divacky MachineRegisterInfo *MachineInstr::getRegInfo() { 688f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = getParent()) 689f22ef01cSRoman Divacky return &MBB->getParent()->getRegInfo(); 69091bc56edSDimitry Andric return nullptr; 691f22ef01cSRoman Divacky } 692f22ef01cSRoman Divacky 693f22ef01cSRoman Divacky /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in 694f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 695f22ef01cSRoman Divacky /// operands already be on their use lists. 6967ae0e2c9SDimitry Andric void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) { 697ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 698ff0cc061SDimitry Andric if (MO.isReg()) 699ff0cc061SDimitry Andric MRI.removeRegOperandFromUseList(&MO); 700f22ef01cSRoman Divacky } 701f22ef01cSRoman Divacky 702f22ef01cSRoman Divacky /// AddRegOperandsToUseLists - Add all of the register operands in 703f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 704f22ef01cSRoman Divacky /// operands not be on their use lists yet. 7057ae0e2c9SDimitry Andric void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) { 706ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 707ff0cc061SDimitry Andric if (MO.isReg()) 708ff0cc061SDimitry Andric MRI.addRegOperandToUseList(&MO); 709f22ef01cSRoman Divacky } 710f22ef01cSRoman Divacky 711139f7f9bSDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) { 712139f7f9bSDimitry Andric MachineBasicBlock *MBB = getParent(); 713139f7f9bSDimitry Andric assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs"); 714139f7f9bSDimitry Andric MachineFunction *MF = MBB->getParent(); 715139f7f9bSDimitry Andric assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs"); 716139f7f9bSDimitry Andric addOperand(*MF, Op); 717139f7f9bSDimitry Andric } 718139f7f9bSDimitry Andric 719139f7f9bSDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping 720139f7f9bSDimitry Andric /// ranges. If MRI is non-null also update use-def chains. 721139f7f9bSDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src, 722139f7f9bSDimitry Andric unsigned NumOps, MachineRegisterInfo *MRI) { 723139f7f9bSDimitry Andric if (MRI) 724139f7f9bSDimitry Andric return MRI->moveOperands(Dst, Src, NumOps); 725139f7f9bSDimitry Andric 726ff0cc061SDimitry Andric // MachineOperand is a trivially copyable type so we can just use memmove. 727ff0cc061SDimitry Andric std::memmove(Dst, Src, NumOps * sizeof(MachineOperand)); 728139f7f9bSDimitry Andric } 729139f7f9bSDimitry Andric 730f22ef01cSRoman Divacky /// addOperand - Add the specified operand to the instruction. If it is an 731f22ef01cSRoman Divacky /// implicit operand, it is added to the end of the operand list. If it is 732f22ef01cSRoman Divacky /// an explicit operand it is added at the end of the explicit operand list 733f22ef01cSRoman Divacky /// (before the first implicit operand). 734139f7f9bSDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { 7356122f3e6SDimitry Andric assert(MCID && "Cannot add operands before providing an instr descriptor"); 736f22ef01cSRoman Divacky 737139f7f9bSDimitry Andric // Check if we're adding one of our existing operands. 738139f7f9bSDimitry Andric if (&Op >= Operands && &Op < Operands + NumOperands) { 739139f7f9bSDimitry Andric // This is unusual: MI->addOperand(MI->getOperand(i)). 740139f7f9bSDimitry Andric // If adding Op requires reallocating or moving existing operands around, 741139f7f9bSDimitry Andric // the Op reference could go stale. Support it by copying Op. 742139f7f9bSDimitry Andric MachineOperand CopyOp(Op); 743139f7f9bSDimitry Andric return addOperand(MF, CopyOp); 744139f7f9bSDimitry Andric } 745f22ef01cSRoman Divacky 7466122f3e6SDimitry Andric // Find the insert location for the new operand. Implicit registers go at 747139f7f9bSDimitry Andric // the end, everything else goes before the implicit regs. 748139f7f9bSDimitry Andric // 7496122f3e6SDimitry Andric // FIXME: Allow mixed explicit and implicit operands on inline asm. 7506122f3e6SDimitry Andric // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as 7516122f3e6SDimitry Andric // implicit-defs, but they must not be moved around. See the FIXME in 7526122f3e6SDimitry Andric // InstrEmitter.cpp. 753139f7f9bSDimitry Andric unsigned OpNo = getNumOperands(); 754139f7f9bSDimitry Andric bool isImpReg = Op.isReg() && Op.isImplicit(); 7556122f3e6SDimitry Andric if (!isImpReg && !isInlineAsm()) { 7566122f3e6SDimitry Andric while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) { 7576122f3e6SDimitry Andric --OpNo; 7583861d79fSDimitry Andric assert(!Operands[OpNo].isTied() && "Cannot move tied operands"); 759f22ef01cSRoman Divacky } 760f22ef01cSRoman Divacky } 761f22ef01cSRoman Divacky 762f785676fSDimitry Andric #ifndef NDEBUG 763f785676fSDimitry Andric bool isMetaDataOp = Op.getType() == MachineOperand::MO_Metadata; 7646122f3e6SDimitry Andric // OpNo now points as the desired insertion point. Unless this is a variadic 7656122f3e6SDimitry Andric // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). 7667ae0e2c9SDimitry Andric // RegMask operands go between the explicit and implicit operands. 7677ae0e2c9SDimitry Andric assert((isImpReg || Op.isRegMask() || MCID->isVariadic() || 768f785676fSDimitry Andric OpNo < MCID->getNumOperands() || isMetaDataOp) && 7696122f3e6SDimitry Andric "Trying to add an operand to a machine instr that is already done!"); 770f785676fSDimitry Andric #endif 771f22ef01cSRoman Divacky 772139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 773f22ef01cSRoman Divacky 774139f7f9bSDimitry Andric // Determine if the Operands array needs to be reallocated. 775139f7f9bSDimitry Andric // Save the old capacity and operand array. 776139f7f9bSDimitry Andric OperandCapacity OldCap = CapOperands; 777139f7f9bSDimitry Andric MachineOperand *OldOperands = Operands; 778139f7f9bSDimitry Andric if (!OldOperands || OldCap.getSize() == getNumOperands()) { 779139f7f9bSDimitry Andric CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1); 780139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 781139f7f9bSDimitry Andric // Move the operands before the insertion point. 782139f7f9bSDimitry Andric if (OpNo) 783139f7f9bSDimitry Andric moveOperands(Operands, OldOperands, OpNo, MRI); 784139f7f9bSDimitry Andric } 785f22ef01cSRoman Divacky 786139f7f9bSDimitry Andric // Move the operands following the insertion point. 787139f7f9bSDimitry Andric if (OpNo != NumOperands) 788139f7f9bSDimitry Andric moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo, 789139f7f9bSDimitry Andric MRI); 790139f7f9bSDimitry Andric ++NumOperands; 7916122f3e6SDimitry Andric 792139f7f9bSDimitry Andric // Deallocate the old operand array. 793139f7f9bSDimitry Andric if (OldOperands != Operands && OldOperands) 794139f7f9bSDimitry Andric MF.deallocateOperandArray(OldCap, OldOperands); 795139f7f9bSDimitry Andric 796139f7f9bSDimitry Andric // Copy Op into place. It still needs to be inserted into the MRI use lists. 797139f7f9bSDimitry Andric MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op); 798139f7f9bSDimitry Andric NewMO->ParentMI = this; 799139f7f9bSDimitry Andric 800139f7f9bSDimitry Andric // When adding a register operand, tell MRI about it. 801139f7f9bSDimitry Andric if (NewMO->isReg()) { 8027ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false, regardless of Op's status. 80391bc56edSDimitry Andric NewMO->Contents.Reg.Prev = nullptr; 8043861d79fSDimitry Andric // Ignore existing ties. This is not a property that can be copied. 805139f7f9bSDimitry Andric NewMO->TiedTo = 0; 806139f7f9bSDimitry Andric // Add the new operand to MRI, but only for instructions in an MBB. 807139f7f9bSDimitry Andric if (MRI) 808139f7f9bSDimitry Andric MRI->addRegOperandToUseList(NewMO); 8093861d79fSDimitry Andric // The MCID operand information isn't accurate until we start adding 8103861d79fSDimitry Andric // explicit operands. The implicit operands are added first, then the 8113861d79fSDimitry Andric // explicits are inserted before them. 8123861d79fSDimitry Andric if (!isImpReg) { 8133861d79fSDimitry Andric // Tie uses to defs as indicated in MCInstrDesc. 814139f7f9bSDimitry Andric if (NewMO->isUse()) { 8153861d79fSDimitry Andric int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO); 8163861d79fSDimitry Andric if (DefIdx != -1) 8173861d79fSDimitry Andric tieOperands(DefIdx, OpNo); 8183861d79fSDimitry Andric } 8196122f3e6SDimitry Andric // If the register operand is flagged as early, mark the operand as such. 82017a519f9SDimitry Andric if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) 821139f7f9bSDimitry Andric NewMO->setIsEarlyClobber(true); 822f22ef01cSRoman Divacky } 823f22ef01cSRoman Divacky } 824f22ef01cSRoman Divacky } 825f22ef01cSRoman Divacky 826f22ef01cSRoman Divacky /// RemoveOperand - Erase an operand from an instruction, leaving it with one 827f22ef01cSRoman Divacky /// fewer operand than it started with. 828f22ef01cSRoman Divacky /// 829f22ef01cSRoman Divacky void MachineInstr::RemoveOperand(unsigned OpNo) { 830139f7f9bSDimitry Andric assert(OpNo < getNumOperands() && "Invalid operand number"); 8313861d79fSDimitry Andric untieRegOperand(OpNo); 832f22ef01cSRoman Divacky 8333861d79fSDimitry Andric #ifndef NDEBUG 8343861d79fSDimitry Andric // Moving tied operands would break the ties. 835139f7f9bSDimitry Andric for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i) 8363861d79fSDimitry Andric if (Operands[i].isReg()) 8373861d79fSDimitry Andric assert(!Operands[i].isTied() && "Cannot move tied operands"); 8383861d79fSDimitry Andric #endif 8393861d79fSDimitry Andric 840139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 841139f7f9bSDimitry Andric if (MRI && Operands[OpNo].isReg()) 842139f7f9bSDimitry Andric MRI->removeRegOperandFromUseList(Operands + OpNo); 843f22ef01cSRoman Divacky 844139f7f9bSDimitry Andric // Don't call the MachineOperand destructor. A lot of this code depends on 845139f7f9bSDimitry Andric // MachineOperand having a trivial destructor anyway, and adding a call here 846139f7f9bSDimitry Andric // wouldn't make it 'destructor-correct'. 847139f7f9bSDimitry Andric 848139f7f9bSDimitry Andric if (unsigned N = NumOperands - 1 - OpNo) 849139f7f9bSDimitry Andric moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI); 850139f7f9bSDimitry Andric --NumOperands; 851f22ef01cSRoman Divacky } 852f22ef01cSRoman Divacky 853f22ef01cSRoman Divacky /// addMemOperand - Add a MachineMemOperand to the machine instruction. 854f22ef01cSRoman Divacky /// This function should be used only occasionally. The setMemRefs function 855f22ef01cSRoman Divacky /// is the primary method for setting up a MachineInstr's MemRefs list. 856f22ef01cSRoman Divacky void MachineInstr::addMemOperand(MachineFunction &MF, 857f22ef01cSRoman Divacky MachineMemOperand *MO) { 858f22ef01cSRoman Divacky mmo_iterator OldMemRefs = MemRefs; 859139f7f9bSDimitry Andric unsigned OldNumMemRefs = NumMemRefs; 860f22ef01cSRoman Divacky 861139f7f9bSDimitry Andric unsigned NewNum = NumMemRefs + 1; 862f22ef01cSRoman Divacky mmo_iterator NewMemRefs = MF.allocateMemRefsArray(NewNum); 863f22ef01cSRoman Divacky 864dff0c46cSDimitry Andric std::copy(OldMemRefs, OldMemRefs + OldNumMemRefs, NewMemRefs); 865f22ef01cSRoman Divacky NewMemRefs[NewNum - 1] = MO; 866139f7f9bSDimitry Andric setMemRefs(NewMemRefs, NewMemRefs + NewNum); 867dff0c46cSDimitry Andric } 868dff0c46cSDimitry Andric 8694d0b32cdSDimitry Andric std::pair<MachineInstr::mmo_iterator, unsigned> 8704d0b32cdSDimitry Andric MachineInstr::mergeMemRefsWith(const MachineInstr& Other) { 8714d0b32cdSDimitry Andric // TODO: If we end up with too many memory operands, return the empty 8724d0b32cdSDimitry Andric // conservative set rather than failing asserts. 8734d0b32cdSDimitry Andric // TODO: consider uniquing elements within the operand lists to reduce 8744d0b32cdSDimitry Andric // space usage and fall back to conservative information less often. 8754d0b32cdSDimitry Andric size_t CombinedNumMemRefs = (memoperands_end() - memoperands_begin()) 8764d0b32cdSDimitry Andric + (Other.memoperands_end() - Other.memoperands_begin()); 8774d0b32cdSDimitry Andric 8784d0b32cdSDimitry Andric MachineFunction *MF = getParent()->getParent(); 8794d0b32cdSDimitry Andric mmo_iterator MemBegin = MF->allocateMemRefsArray(CombinedNumMemRefs); 8804d0b32cdSDimitry Andric mmo_iterator MemEnd = std::copy(memoperands_begin(), memoperands_end(), 8814d0b32cdSDimitry Andric MemBegin); 8824d0b32cdSDimitry Andric MemEnd = std::copy(Other.memoperands_begin(), Other.memoperands_end(), 8834d0b32cdSDimitry Andric MemEnd); 8844d0b32cdSDimitry Andric assert(MemEnd - MemBegin == (ptrdiff_t)CombinedNumMemRefs && 8854d0b32cdSDimitry Andric "missing memrefs"); 8864d0b32cdSDimitry Andric 8874d0b32cdSDimitry Andric return std::make_pair(MemBegin, CombinedNumMemRefs); 8884d0b32cdSDimitry Andric } 8894d0b32cdSDimitry Andric 890dff0c46cSDimitry Andric bool MachineInstr::hasPropertyInBundle(unsigned Mask, QueryType Type) const { 891139f7f9bSDimitry Andric assert(!isBundledWithPred() && "Must be called on bundle header"); 8927d523365SDimitry Andric for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) { 893dff0c46cSDimitry Andric if (MII->getDesc().getFlags() & Mask) { 894dff0c46cSDimitry Andric if (Type == AnyInBundle) 895dff0c46cSDimitry Andric return true; 896dff0c46cSDimitry Andric } else { 897139f7f9bSDimitry Andric if (Type == AllInBundle && !MII->isBundle()) 898dff0c46cSDimitry Andric return false; 899dff0c46cSDimitry Andric } 900139f7f9bSDimitry Andric // This was the last instruction in the bundle. 901139f7f9bSDimitry Andric if (!MII->isBundledWithSucc()) 902dff0c46cSDimitry Andric return Type == AllInBundle; 903f22ef01cSRoman Divacky } 904139f7f9bSDimitry Andric } 905f22ef01cSRoman Divacky 906f22ef01cSRoman Divacky bool MachineInstr::isIdenticalTo(const MachineInstr *Other, 907f22ef01cSRoman Divacky MICheckType Check) const { 908f22ef01cSRoman Divacky // If opcodes or number of operands are not the same then the two 909f22ef01cSRoman Divacky // instructions are obviously not identical. 910f22ef01cSRoman Divacky if (Other->getOpcode() != getOpcode() || 911f22ef01cSRoman Divacky Other->getNumOperands() != getNumOperands()) 912f22ef01cSRoman Divacky return false; 913f22ef01cSRoman Divacky 914dff0c46cSDimitry Andric if (isBundle()) { 915dff0c46cSDimitry Andric // Both instructions are bundles, compare MIs inside the bundle. 9167d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I1 = getIterator(); 917dff0c46cSDimitry Andric MachineBasicBlock::const_instr_iterator E1 = getParent()->instr_end(); 9187d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I2 = Other->getIterator(); 919dff0c46cSDimitry Andric MachineBasicBlock::const_instr_iterator E2= Other->getParent()->instr_end(); 920dff0c46cSDimitry Andric while (++I1 != E1 && I1->isInsideBundle()) { 921dff0c46cSDimitry Andric ++I2; 9227d523365SDimitry Andric if (I2 == E2 || !I2->isInsideBundle() || !I1->isIdenticalTo(&*I2, Check)) 923dff0c46cSDimitry Andric return false; 924dff0c46cSDimitry Andric } 925dff0c46cSDimitry Andric } 926dff0c46cSDimitry Andric 927f22ef01cSRoman Divacky // Check operands to make sure they match. 928f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 929f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 930f22ef01cSRoman Divacky const MachineOperand &OMO = Other->getOperand(i); 931bd5abe19SDimitry Andric if (!MO.isReg()) { 932bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 933bd5abe19SDimitry Andric return false; 934bd5abe19SDimitry Andric continue; 935bd5abe19SDimitry Andric } 936bd5abe19SDimitry Andric 937f22ef01cSRoman Divacky // Clients may or may not want to ignore defs when testing for equality. 938f22ef01cSRoman Divacky // For example, machine CSE pass only cares about finding common 939f22ef01cSRoman Divacky // subexpressions, so it's safe to ignore virtual register defs. 940bd5abe19SDimitry Andric if (MO.isDef()) { 941f22ef01cSRoman Divacky if (Check == IgnoreDefs) 942f22ef01cSRoman Divacky continue; 943bd5abe19SDimitry Andric else if (Check == IgnoreVRegDefs) { 944f22ef01cSRoman Divacky if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) || 945f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(OMO.getReg())) 946f22ef01cSRoman Divacky if (MO.getReg() != OMO.getReg()) 947f22ef01cSRoman Divacky return false; 948bd5abe19SDimitry Andric } else { 949bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 950f22ef01cSRoman Divacky return false; 951bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isDead() != OMO.isDead()) 952bd5abe19SDimitry Andric return false; 953bd5abe19SDimitry Andric } 954bd5abe19SDimitry Andric } else { 955bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 956bd5abe19SDimitry Andric return false; 957bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isKill() != OMO.isKill()) 958bd5abe19SDimitry Andric return false; 959bd5abe19SDimitry Andric } 960f22ef01cSRoman Divacky } 96117a519f9SDimitry Andric // If DebugLoc does not match then two dbg.values are not identical. 96217a519f9SDimitry Andric if (isDebugValue()) 963ff0cc061SDimitry Andric if (getDebugLoc() && Other->getDebugLoc() && 964ff0cc061SDimitry Andric getDebugLoc() != Other->getDebugLoc()) 96517a519f9SDimitry Andric return false; 966f22ef01cSRoman Divacky return true; 967f22ef01cSRoman Divacky } 968f22ef01cSRoman Divacky 969f22ef01cSRoman Divacky MachineInstr *MachineInstr::removeFromParent() { 970f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 971139f7f9bSDimitry Andric return getParent()->remove(this); 972f22ef01cSRoman Divacky } 973f22ef01cSRoman Divacky 974139f7f9bSDimitry Andric MachineInstr *MachineInstr::removeFromBundle() { 975139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 976139f7f9bSDimitry Andric return getParent()->remove_instr(this); 977139f7f9bSDimitry Andric } 978f22ef01cSRoman Divacky 979f22ef01cSRoman Divacky void MachineInstr::eraseFromParent() { 980f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 981139f7f9bSDimitry Andric getParent()->erase(this); 982f22ef01cSRoman Divacky } 983f22ef01cSRoman Divacky 98439d628a0SDimitry Andric void MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval() { 98539d628a0SDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 98639d628a0SDimitry Andric MachineBasicBlock *MBB = getParent(); 98739d628a0SDimitry Andric MachineFunction *MF = MBB->getParent(); 98839d628a0SDimitry Andric assert(MF && "Not embedded in a function!"); 98939d628a0SDimitry Andric 99039d628a0SDimitry Andric MachineInstr *MI = (MachineInstr *)this; 99139d628a0SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 99239d628a0SDimitry Andric 993ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 99439d628a0SDimitry Andric if (!MO.isReg() || !MO.isDef()) 99539d628a0SDimitry Andric continue; 99639d628a0SDimitry Andric unsigned Reg = MO.getReg(); 99739d628a0SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg)) 99839d628a0SDimitry Andric continue; 99939d628a0SDimitry Andric MRI.markUsesInDebugValueAsUndef(Reg); 100039d628a0SDimitry Andric } 100139d628a0SDimitry Andric MI->eraseFromParent(); 100239d628a0SDimitry Andric } 100339d628a0SDimitry Andric 1004139f7f9bSDimitry Andric void MachineInstr::eraseFromBundle() { 1005139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 1006139f7f9bSDimitry Andric getParent()->erase_instr(this); 1007139f7f9bSDimitry Andric } 1008f22ef01cSRoman Divacky 1009f22ef01cSRoman Divacky /// getNumExplicitOperands - Returns the number of non-implicit operands. 1010f22ef01cSRoman Divacky /// 1011f22ef01cSRoman Divacky unsigned MachineInstr::getNumExplicitOperands() const { 101217a519f9SDimitry Andric unsigned NumOperands = MCID->getNumOperands(); 101317a519f9SDimitry Andric if (!MCID->isVariadic()) 1014f22ef01cSRoman Divacky return NumOperands; 1015f22ef01cSRoman Divacky 1016f22ef01cSRoman Divacky for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) { 1017f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1018f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isImplicit()) 1019f22ef01cSRoman Divacky NumOperands++; 1020f22ef01cSRoman Divacky } 1021f22ef01cSRoman Divacky return NumOperands; 1022f22ef01cSRoman Divacky } 1023f22ef01cSRoman Divacky 1024139f7f9bSDimitry Andric void MachineInstr::bundleWithPred() { 1025139f7f9bSDimitry Andric assert(!isBundledWithPred() && "MI is already bundled with its predecessor"); 1026139f7f9bSDimitry Andric setFlag(BundledPred); 10277d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 1028139f7f9bSDimitry Andric --Pred; 1029139f7f9bSDimitry Andric assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 1030139f7f9bSDimitry Andric Pred->setFlag(BundledSucc); 1031139f7f9bSDimitry Andric } 1032139f7f9bSDimitry Andric 1033139f7f9bSDimitry Andric void MachineInstr::bundleWithSucc() { 1034139f7f9bSDimitry Andric assert(!isBundledWithSucc() && "MI is already bundled with its successor"); 1035139f7f9bSDimitry Andric setFlag(BundledSucc); 10367d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 1037139f7f9bSDimitry Andric ++Succ; 1038139f7f9bSDimitry Andric assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags"); 1039139f7f9bSDimitry Andric Succ->setFlag(BundledPred); 1040139f7f9bSDimitry Andric } 1041139f7f9bSDimitry Andric 1042139f7f9bSDimitry Andric void MachineInstr::unbundleFromPred() { 1043139f7f9bSDimitry Andric assert(isBundledWithPred() && "MI isn't bundled with its predecessor"); 1044139f7f9bSDimitry Andric clearFlag(BundledPred); 10457d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 1046139f7f9bSDimitry Andric --Pred; 1047139f7f9bSDimitry Andric assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 1048139f7f9bSDimitry Andric Pred->clearFlag(BundledSucc); 1049139f7f9bSDimitry Andric } 1050139f7f9bSDimitry Andric 1051139f7f9bSDimitry Andric void MachineInstr::unbundleFromSucc() { 1052139f7f9bSDimitry Andric assert(isBundledWithSucc() && "MI isn't bundled with its successor"); 1053139f7f9bSDimitry Andric clearFlag(BundledSucc); 10547d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 1055139f7f9bSDimitry Andric ++Succ; 1056139f7f9bSDimitry Andric assert(Succ->isBundledWithPred() && "Inconsistent bundle flags"); 1057139f7f9bSDimitry Andric Succ->clearFlag(BundledPred); 1058dff0c46cSDimitry Andric } 1059dff0c46cSDimitry Andric 10602754fe60SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const { 10612754fe60SDimitry Andric if (isInlineAsm()) { 10622754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 10632754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 10642754fe60SDimitry Andric return true; 10652754fe60SDimitry Andric } 10662754fe60SDimitry Andric return false; 10672754fe60SDimitry Andric } 1068f22ef01cSRoman Divacky 10693861d79fSDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const { 10703861d79fSDimitry Andric assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!"); 10713861d79fSDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 10723861d79fSDimitry Andric return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0); 10733861d79fSDimitry Andric } 10743861d79fSDimitry Andric 10756122f3e6SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx, 10766122f3e6SDimitry Andric unsigned *GroupNo) const { 10776122f3e6SDimitry Andric assert(isInlineAsm() && "Expected an inline asm instruction"); 10786122f3e6SDimitry Andric assert(OpIdx < getNumOperands() && "OpIdx out of range"); 10796122f3e6SDimitry Andric 10806122f3e6SDimitry Andric // Ignore queries about the initial operands. 10816122f3e6SDimitry Andric if (OpIdx < InlineAsm::MIOp_FirstOperand) 10826122f3e6SDimitry Andric return -1; 10836122f3e6SDimitry Andric 10846122f3e6SDimitry Andric unsigned Group = 0; 10856122f3e6SDimitry Andric unsigned NumOps; 10866122f3e6SDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 10876122f3e6SDimitry Andric i += NumOps) { 10886122f3e6SDimitry Andric const MachineOperand &FlagMO = getOperand(i); 10896122f3e6SDimitry Andric // If we reach the implicit register operands, stop looking. 10906122f3e6SDimitry Andric if (!FlagMO.isImm()) 10916122f3e6SDimitry Andric return -1; 10926122f3e6SDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 10936122f3e6SDimitry Andric if (i + NumOps > OpIdx) { 10946122f3e6SDimitry Andric if (GroupNo) 10956122f3e6SDimitry Andric *GroupNo = Group; 10966122f3e6SDimitry Andric return i; 10976122f3e6SDimitry Andric } 10986122f3e6SDimitry Andric ++Group; 10996122f3e6SDimitry Andric } 11006122f3e6SDimitry Andric return -1; 11016122f3e6SDimitry Andric } 11026122f3e6SDimitry Andric 11036122f3e6SDimitry Andric const TargetRegisterClass* 11046122f3e6SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx, 11056122f3e6SDimitry Andric const TargetInstrInfo *TII, 11066122f3e6SDimitry Andric const TargetRegisterInfo *TRI) const { 11077ae0e2c9SDimitry Andric assert(getParent() && "Can't have an MBB reference here!"); 11087ae0e2c9SDimitry Andric assert(getParent()->getParent() && "Can't have an MF reference here!"); 11097ae0e2c9SDimitry Andric const MachineFunction &MF = *getParent()->getParent(); 11107ae0e2c9SDimitry Andric 11116122f3e6SDimitry Andric // Most opcodes have fixed constraints in their MCInstrDesc. 11126122f3e6SDimitry Andric if (!isInlineAsm()) 11137ae0e2c9SDimitry Andric return TII->getRegClass(getDesc(), OpIdx, TRI, MF); 11146122f3e6SDimitry Andric 11156122f3e6SDimitry Andric if (!getOperand(OpIdx).isReg()) 111691bc56edSDimitry Andric return nullptr; 11176122f3e6SDimitry Andric 11186122f3e6SDimitry Andric // For tied uses on inline asm, get the constraint from the def. 11196122f3e6SDimitry Andric unsigned DefIdx; 11206122f3e6SDimitry Andric if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx)) 11216122f3e6SDimitry Andric OpIdx = DefIdx; 11226122f3e6SDimitry Andric 11236122f3e6SDimitry Andric // Inline asm stores register class constraints in the flag word. 11246122f3e6SDimitry Andric int FlagIdx = findInlineAsmFlagIdx(OpIdx); 11256122f3e6SDimitry Andric if (FlagIdx < 0) 112691bc56edSDimitry Andric return nullptr; 11276122f3e6SDimitry Andric 11286122f3e6SDimitry Andric unsigned Flag = getOperand(FlagIdx).getImm(); 11296122f3e6SDimitry Andric unsigned RCID; 11306122f3e6SDimitry Andric if (InlineAsm::hasRegClassConstraint(Flag, RCID)) 11316122f3e6SDimitry Andric return TRI->getRegClass(RCID); 11326122f3e6SDimitry Andric 11336122f3e6SDimitry Andric // Assume that all registers in a memory operand are pointers. 11346122f3e6SDimitry Andric if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem) 11357ae0e2c9SDimitry Andric return TRI->getPointerRegClass(MF); 11366122f3e6SDimitry Andric 113791bc56edSDimitry Andric return nullptr; 113891bc56edSDimitry Andric } 113991bc56edSDimitry Andric 114091bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( 114191bc56edSDimitry Andric unsigned Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, 114291bc56edSDimitry Andric const TargetRegisterInfo *TRI, bool ExploreBundle) const { 114391bc56edSDimitry Andric // Check every operands inside the bundle if we have 114491bc56edSDimitry Andric // been asked to. 114591bc56edSDimitry Andric if (ExploreBundle) 114691bc56edSDimitry Andric for (ConstMIBundleOperands OpndIt(this); OpndIt.isValid() && CurRC; 114791bc56edSDimitry Andric ++OpndIt) 114891bc56edSDimitry Andric CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl( 114991bc56edSDimitry Andric OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); 115091bc56edSDimitry Andric else 115191bc56edSDimitry Andric // Otherwise, just check the current operands. 115297bc6c73SDimitry Andric for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) 115397bc6c73SDimitry Andric CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); 115491bc56edSDimitry Andric return CurRC; 115591bc56edSDimitry Andric } 115691bc56edSDimitry Andric 115791bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl( 115891bc56edSDimitry Andric unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC, 115991bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 116091bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 116191bc56edSDimitry Andric // Check if Reg is constrained by some of its use/def from MI. 116291bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 116391bc56edSDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 116491bc56edSDimitry Andric return CurRC; 116591bc56edSDimitry Andric // If yes, accumulate the constraints through the operand. 116691bc56edSDimitry Andric return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI); 116791bc56edSDimitry Andric } 116891bc56edSDimitry Andric 116991bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( 117091bc56edSDimitry Andric unsigned OpIdx, const TargetRegisterClass *CurRC, 117191bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 117291bc56edSDimitry Andric const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI); 117391bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 117491bc56edSDimitry Andric assert(MO.isReg() && 117591bc56edSDimitry Andric "Cannot get register constraints for non-register operand"); 117691bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 117791bc56edSDimitry Andric if (unsigned SubIdx = MO.getSubReg()) { 117891bc56edSDimitry Andric if (OpRC) 117991bc56edSDimitry Andric CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx); 118091bc56edSDimitry Andric else 118191bc56edSDimitry Andric CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx); 118291bc56edSDimitry Andric } else if (OpRC) 118391bc56edSDimitry Andric CurRC = TRI->getCommonSubClass(CurRC, OpRC); 118491bc56edSDimitry Andric return CurRC; 11856122f3e6SDimitry Andric } 11866122f3e6SDimitry Andric 1187139f7f9bSDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the 1188139f7f9bSDimitry Andric /// header instruction. 1189dff0c46cSDimitry Andric unsigned MachineInstr::getBundleSize() const { 11907d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I = getIterator(); 1191dff0c46cSDimitry Andric unsigned Size = 0; 1192139f7f9bSDimitry Andric while (I->isBundledWithSucc()) 1193139f7f9bSDimitry Andric ++Size, ++I; 1194dff0c46cSDimitry Andric return Size; 1195dff0c46cSDimitry Andric } 1196dff0c46cSDimitry Andric 1197f22ef01cSRoman Divacky /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of 1198f22ef01cSRoman Divacky /// the specific register or -1 if it is not found. It further tightens 1199f22ef01cSRoman Divacky /// the search criteria to a use that kills the register if isKill is true. 1200f22ef01cSRoman Divacky int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill, 1201f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 1202f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1203f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1204f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse()) 1205f22ef01cSRoman Divacky continue; 1206f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1207f22ef01cSRoman Divacky if (!MOReg) 1208f22ef01cSRoman Divacky continue; 1209f22ef01cSRoman Divacky if (MOReg == Reg || 1210f22ef01cSRoman Divacky (TRI && 1211f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg) && 1212f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg) && 1213f22ef01cSRoman Divacky TRI->isSubRegister(MOReg, Reg))) 1214f22ef01cSRoman Divacky if (!isKill || MO.isKill()) 1215f22ef01cSRoman Divacky return i; 1216f22ef01cSRoman Divacky } 1217f22ef01cSRoman Divacky return -1; 1218f22ef01cSRoman Divacky } 1219f22ef01cSRoman Divacky 1220f22ef01cSRoman Divacky /// readsWritesVirtualRegister - Return a pair of bools (reads, writes) 1221f22ef01cSRoman Divacky /// indicating if this instruction reads or writes Reg. This also considers 1222f22ef01cSRoman Divacky /// partial defines. 1223f22ef01cSRoman Divacky std::pair<bool,bool> 1224f22ef01cSRoman Divacky MachineInstr::readsWritesVirtualRegister(unsigned Reg, 1225f22ef01cSRoman Divacky SmallVectorImpl<unsigned> *Ops) const { 1226f22ef01cSRoman Divacky bool PartDef = false; // Partial redefine. 1227f22ef01cSRoman Divacky bool FullDef = false; // Full define. 1228f22ef01cSRoman Divacky bool Use = false; 1229f22ef01cSRoman Divacky 1230f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1231f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1232f22ef01cSRoman Divacky if (!MO.isReg() || MO.getReg() != Reg) 1233f22ef01cSRoman Divacky continue; 1234f22ef01cSRoman Divacky if (Ops) 1235f22ef01cSRoman Divacky Ops->push_back(i); 1236f22ef01cSRoman Divacky if (MO.isUse()) 1237f22ef01cSRoman Divacky Use |= !MO.isUndef(); 12386122f3e6SDimitry Andric else if (MO.getSubReg() && !MO.isUndef()) 12396122f3e6SDimitry Andric // A partial <def,undef> doesn't count as reading the register. 1240f22ef01cSRoman Divacky PartDef = true; 1241f22ef01cSRoman Divacky else 1242f22ef01cSRoman Divacky FullDef = true; 1243f22ef01cSRoman Divacky } 1244f22ef01cSRoman Divacky // A partial redefine uses Reg unless there is also a full define. 1245f22ef01cSRoman Divacky return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef); 1246f22ef01cSRoman Divacky } 1247f22ef01cSRoman Divacky 1248f22ef01cSRoman Divacky /// findRegisterDefOperandIdx() - Returns the operand index that is a def of 1249f22ef01cSRoman Divacky /// the specified register or -1 if it is not found. If isDead is true, defs 1250f22ef01cSRoman Divacky /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it 1251f22ef01cSRoman Divacky /// also checks if there is a def of a super-register. 1252f22ef01cSRoman Divacky int 1253f22ef01cSRoman Divacky MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap, 1254f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 1255f22ef01cSRoman Divacky bool isPhys = TargetRegisterInfo::isPhysicalRegister(Reg); 1256f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1257f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1258dff0c46cSDimitry Andric // Accept regmask operands when Overlap is set. 1259dff0c46cSDimitry Andric // Ignore them when looking for a specific def operand (Overlap == false). 1260dff0c46cSDimitry Andric if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg)) 1261dff0c46cSDimitry Andric return i; 1262f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 1263f22ef01cSRoman Divacky continue; 1264f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1265f22ef01cSRoman Divacky bool Found = (MOReg == Reg); 1266f22ef01cSRoman Divacky if (!Found && TRI && isPhys && 1267f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg)) { 1268f22ef01cSRoman Divacky if (Overlap) 1269f22ef01cSRoman Divacky Found = TRI->regsOverlap(MOReg, Reg); 1270f22ef01cSRoman Divacky else 1271f22ef01cSRoman Divacky Found = TRI->isSubRegister(MOReg, Reg); 1272f22ef01cSRoman Divacky } 1273f22ef01cSRoman Divacky if (Found && (!isDead || MO.isDead())) 1274f22ef01cSRoman Divacky return i; 1275f22ef01cSRoman Divacky } 1276f22ef01cSRoman Divacky return -1; 1277f22ef01cSRoman Divacky } 1278f22ef01cSRoman Divacky 1279f22ef01cSRoman Divacky /// findFirstPredOperandIdx() - Find the index of the first operand in the 1280f22ef01cSRoman Divacky /// operand list that is used to represent the predicate. It returns -1 if 1281f22ef01cSRoman Divacky /// none is found. 1282f22ef01cSRoman Divacky int MachineInstr::findFirstPredOperandIdx() const { 12836122f3e6SDimitry Andric // Don't call MCID.findFirstPredOperandIdx() because this variant 12846122f3e6SDimitry Andric // is sometimes called on an instruction that's not yet complete, and 12856122f3e6SDimitry Andric // so the number of operands is less than the MCID indicates. In 12866122f3e6SDimitry Andric // particular, the PTX target does this. 128717a519f9SDimitry Andric const MCInstrDesc &MCID = getDesc(); 128817a519f9SDimitry Andric if (MCID.isPredicable()) { 1289f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 129017a519f9SDimitry Andric if (MCID.OpInfo[i].isPredicate()) 1291f22ef01cSRoman Divacky return i; 1292f22ef01cSRoman Divacky } 1293f22ef01cSRoman Divacky 1294f22ef01cSRoman Divacky return -1; 1295f22ef01cSRoman Divacky } 1296f22ef01cSRoman Divacky 12973861d79fSDimitry Andric // MachineOperand::TiedTo is 4 bits wide. 12983861d79fSDimitry Andric const unsigned TiedMax = 15; 12996122f3e6SDimitry Andric 13003861d79fSDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other. 13013861d79fSDimitry Andric /// 13023861d79fSDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo 13033861d79fSDimitry Andric /// field. TiedTo can have these values: 13043861d79fSDimitry Andric /// 13053861d79fSDimitry Andric /// 0: Operand is not tied to anything. 13063861d79fSDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1). 13073861d79fSDimitry Andric /// TiedMax: Tied to an operand >= TiedMax-1. 13083861d79fSDimitry Andric /// 13093861d79fSDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal 13103861d79fSDimitry Andric /// instruction. INLINEASM instructions allow more tied defs. 13113861d79fSDimitry Andric /// 13123861d79fSDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) { 13133861d79fSDimitry Andric MachineOperand &DefMO = getOperand(DefIdx); 13143861d79fSDimitry Andric MachineOperand &UseMO = getOperand(UseIdx); 13153861d79fSDimitry Andric assert(DefMO.isDef() && "DefIdx must be a def operand"); 13163861d79fSDimitry Andric assert(UseMO.isUse() && "UseIdx must be a use operand"); 13173861d79fSDimitry Andric assert(!DefMO.isTied() && "Def is already tied to another use"); 13183861d79fSDimitry Andric assert(!UseMO.isTied() && "Use is already tied to another def"); 13196122f3e6SDimitry Andric 13203861d79fSDimitry Andric if (DefIdx < TiedMax) 13213861d79fSDimitry Andric UseMO.TiedTo = DefIdx + 1; 13223861d79fSDimitry Andric else { 13233861d79fSDimitry Andric // Inline asm can use the group descriptors to find tied operands, but on 13243861d79fSDimitry Andric // normal instruction, the tied def must be within the first TiedMax 13253861d79fSDimitry Andric // operands. 13263861d79fSDimitry Andric assert(isInlineAsm() && "DefIdx out of range"); 13273861d79fSDimitry Andric UseMO.TiedTo = TiedMax; 13283861d79fSDimitry Andric } 13293861d79fSDimitry Andric 13303861d79fSDimitry Andric // UseIdx can be out of range, we'll search for it in findTiedOperandIdx(). 13313861d79fSDimitry Andric DefMO.TiedTo = std::min(UseIdx + 1, TiedMax); 13323861d79fSDimitry Andric } 13333861d79fSDimitry Andric 13343861d79fSDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to. 13353861d79fSDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand 13363861d79fSDimitry Andric /// which must exist. 13373861d79fSDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const { 13383861d79fSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 13393861d79fSDimitry Andric assert(MO.isTied() && "Operand isn't tied"); 13403861d79fSDimitry Andric 13413861d79fSDimitry Andric // Normally TiedTo is in range. 13423861d79fSDimitry Andric if (MO.TiedTo < TiedMax) 13433861d79fSDimitry Andric return MO.TiedTo - 1; 13443861d79fSDimitry Andric 13453861d79fSDimitry Andric // Uses on normal instructions can be out of range. 13463861d79fSDimitry Andric if (!isInlineAsm()) { 13473861d79fSDimitry Andric // Normal tied defs must be in the 0..TiedMax-1 range. 13483861d79fSDimitry Andric if (MO.isUse()) 13493861d79fSDimitry Andric return TiedMax - 1; 13503861d79fSDimitry Andric // MO is a def. Search for the tied use. 13513861d79fSDimitry Andric for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) { 13523861d79fSDimitry Andric const MachineOperand &UseMO = getOperand(i); 13533861d79fSDimitry Andric if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1) 13543861d79fSDimitry Andric return i; 13553861d79fSDimitry Andric } 13563861d79fSDimitry Andric llvm_unreachable("Can't find tied use"); 13573861d79fSDimitry Andric } 13583861d79fSDimitry Andric 13593861d79fSDimitry Andric // Now deal with inline asm by parsing the operand group descriptor flags. 13603861d79fSDimitry Andric // Find the beginning of each operand group. 13613861d79fSDimitry Andric SmallVector<unsigned, 8> GroupIdx; 13623861d79fSDimitry Andric unsigned OpIdxGroup = ~0u; 13633861d79fSDimitry Andric unsigned NumOps; 13643861d79fSDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 13653861d79fSDimitry Andric i += NumOps) { 13663861d79fSDimitry Andric const MachineOperand &FlagMO = getOperand(i); 13673861d79fSDimitry Andric assert(FlagMO.isImm() && "Invalid tied operand on inline asm"); 13683861d79fSDimitry Andric unsigned CurGroup = GroupIdx.size(); 13693861d79fSDimitry Andric GroupIdx.push_back(i); 13703861d79fSDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 13713861d79fSDimitry Andric // OpIdx belongs to this operand group. 13723861d79fSDimitry Andric if (OpIdx > i && OpIdx < i + NumOps) 13733861d79fSDimitry Andric OpIdxGroup = CurGroup; 13743861d79fSDimitry Andric unsigned TiedGroup; 13753861d79fSDimitry Andric if (!InlineAsm::isUseOperandTiedToDef(FlagMO.getImm(), TiedGroup)) 1376f22ef01cSRoman Divacky continue; 13773861d79fSDimitry Andric // Operands in this group are tied to operands in TiedGroup which must be 13783861d79fSDimitry Andric // earlier. Find the number of operands between the two groups. 13793861d79fSDimitry Andric unsigned Delta = i - GroupIdx[TiedGroup]; 1380f22ef01cSRoman Divacky 13813861d79fSDimitry Andric // OpIdx is a use tied to TiedGroup. 13823861d79fSDimitry Andric if (OpIdxGroup == CurGroup) 13833861d79fSDimitry Andric return OpIdx - Delta; 1384f22ef01cSRoman Divacky 13853861d79fSDimitry Andric // OpIdx is a def tied to this use group. 13863861d79fSDimitry Andric if (OpIdxGroup == TiedGroup) 13873861d79fSDimitry Andric return OpIdx + Delta; 1388f22ef01cSRoman Divacky } 13893861d79fSDimitry Andric llvm_unreachable("Invalid tied operand on inline asm"); 1390f22ef01cSRoman Divacky } 1391f22ef01cSRoman Divacky 1392f22ef01cSRoman Divacky /// clearKillInfo - Clears kill flags on all operands. 1393f22ef01cSRoman Divacky /// 1394f22ef01cSRoman Divacky void MachineInstr::clearKillInfo() { 1395ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1396f22ef01cSRoman Divacky if (MO.isReg() && MO.isUse()) 1397f22ef01cSRoman Divacky MO.setIsKill(false); 1398f22ef01cSRoman Divacky } 1399f22ef01cSRoman Divacky } 1400f22ef01cSRoman Divacky 1401ffd1746dSEd Schouten void MachineInstr::substituteRegister(unsigned FromReg, 1402ffd1746dSEd Schouten unsigned ToReg, 1403ffd1746dSEd Schouten unsigned SubIdx, 1404ffd1746dSEd Schouten const TargetRegisterInfo &RegInfo) { 1405ffd1746dSEd Schouten if (TargetRegisterInfo::isPhysicalRegister(ToReg)) { 1406ffd1746dSEd Schouten if (SubIdx) 1407ffd1746dSEd Schouten ToReg = RegInfo.getSubReg(ToReg, SubIdx); 1408ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1409ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1410ffd1746dSEd Schouten continue; 1411ffd1746dSEd Schouten MO.substPhysReg(ToReg, RegInfo); 1412ffd1746dSEd Schouten } 1413ffd1746dSEd Schouten } else { 1414ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1415ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1416ffd1746dSEd Schouten continue; 1417ffd1746dSEd Schouten MO.substVirtReg(ToReg, SubIdx, RegInfo); 1418ffd1746dSEd Schouten } 1419ffd1746dSEd Schouten } 1420ffd1746dSEd Schouten } 1421ffd1746dSEd Schouten 1422f22ef01cSRoman Divacky /// isSafeToMove - Return true if it is safe to move this instruction. If 1423f22ef01cSRoman Divacky /// SawStore is set to true, it means that there is a store (or call) between 1424f22ef01cSRoman Divacky /// the instruction's location and its intended destination. 1425ff0cc061SDimitry Andric bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const { 1426f22ef01cSRoman Divacky // Ignore stuff that we obviously can't move. 14273861d79fSDimitry Andric // 14283861d79fSDimitry Andric // Treat volatile loads as stores. This is not strictly necessary for 14293861d79fSDimitry Andric // volatiles, but it is required for atomic loads. It is not allowed to move 14303861d79fSDimitry Andric // a load across an atomic load with Ordering > Monotonic. 14313861d79fSDimitry Andric if (mayStore() || isCall() || 14323861d79fSDimitry Andric (mayLoad() && hasOrderedMemoryRef())) { 1433f22ef01cSRoman Divacky SawStore = true; 1434f22ef01cSRoman Divacky return false; 1435f22ef01cSRoman Divacky } 14362754fe60SDimitry Andric 143791bc56edSDimitry Andric if (isPosition() || isDebugValue() || isTerminator() || 143891bc56edSDimitry Andric hasUnmodeledSideEffects()) 1439f22ef01cSRoman Divacky return false; 1440f22ef01cSRoman Divacky 1441f22ef01cSRoman Divacky // See if this instruction does a load. If so, we have to guarantee that the 1442f22ef01cSRoman Divacky // loaded value doesn't change between the load and the its intended 1443f22ef01cSRoman Divacky // destination. The check for isInvariantLoad gives the targe the chance to 1444f22ef01cSRoman Divacky // classify the load as always returning a constant, e.g. a constant pool 1445f22ef01cSRoman Divacky // load. 1446dff0c46cSDimitry Andric if (mayLoad() && !isInvariantLoad(AA)) 1447f22ef01cSRoman Divacky // Otherwise, this is a real load. If there is a store between the load and 14483861d79fSDimitry Andric // end of block, we can't move it. 14493861d79fSDimitry Andric return !SawStore; 1450f22ef01cSRoman Divacky 1451f22ef01cSRoman Divacky return true; 1452f22ef01cSRoman Divacky } 1453f22ef01cSRoman Divacky 14543861d79fSDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered 14553861d79fSDimitry Andric /// or volatile memory reference, or if the information describing the memory 14563861d79fSDimitry Andric /// reference is not available. Return false if it is known to have no ordered 14573861d79fSDimitry Andric /// memory references. 14583861d79fSDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const { 1459f22ef01cSRoman Divacky // An instruction known never to access memory won't have a volatile access. 1460dff0c46cSDimitry Andric if (!mayStore() && 1461dff0c46cSDimitry Andric !mayLoad() && 1462dff0c46cSDimitry Andric !isCall() && 14632754fe60SDimitry Andric !hasUnmodeledSideEffects()) 1464f22ef01cSRoman Divacky return false; 1465f22ef01cSRoman Divacky 1466f22ef01cSRoman Divacky // Otherwise, if the instruction has no memory reference information, 1467f22ef01cSRoman Divacky // conservatively assume it wasn't preserved. 1468f22ef01cSRoman Divacky if (memoperands_empty()) 1469f22ef01cSRoman Divacky return true; 1470f22ef01cSRoman Divacky 14713861d79fSDimitry Andric // Check the memory reference information for ordered references. 1472f22ef01cSRoman Divacky for (mmo_iterator I = memoperands_begin(), E = memoperands_end(); I != E; ++I) 14733861d79fSDimitry Andric if (!(*I)->isUnordered()) 1474f22ef01cSRoman Divacky return true; 1475f22ef01cSRoman Divacky 1476f22ef01cSRoman Divacky return false; 1477f22ef01cSRoman Divacky } 1478f22ef01cSRoman Divacky 1479f22ef01cSRoman Divacky /// isInvariantLoad - Return true if this instruction is loading from a 1480f22ef01cSRoman Divacky /// location whose value is invariant across the function. For example, 1481f22ef01cSRoman Divacky /// loading a value from the constant pool or from the argument area 1482f22ef01cSRoman Divacky /// of a function if it does not change. This should only return true of 1483f22ef01cSRoman Divacky /// *all* loads the instruction does are invariant (if it does multiple loads). 1484f22ef01cSRoman Divacky bool MachineInstr::isInvariantLoad(AliasAnalysis *AA) const { 1485f22ef01cSRoman Divacky // If the instruction doesn't load at all, it isn't an invariant load. 1486dff0c46cSDimitry Andric if (!mayLoad()) 1487f22ef01cSRoman Divacky return false; 1488f22ef01cSRoman Divacky 1489f22ef01cSRoman Divacky // If the instruction has lost its memoperands, conservatively assume that 1490f22ef01cSRoman Divacky // it may not be an invariant load. 1491f22ef01cSRoman Divacky if (memoperands_empty()) 1492f22ef01cSRoman Divacky return false; 1493f22ef01cSRoman Divacky 1494f22ef01cSRoman Divacky const MachineFrameInfo *MFI = getParent()->getParent()->getFrameInfo(); 1495f22ef01cSRoman Divacky 1496f22ef01cSRoman Divacky for (mmo_iterator I = memoperands_begin(), 1497f22ef01cSRoman Divacky E = memoperands_end(); I != E; ++I) { 1498f22ef01cSRoman Divacky if ((*I)->isVolatile()) return false; 1499f22ef01cSRoman Divacky if ((*I)->isStore()) return false; 1500dff0c46cSDimitry Andric if ((*I)->isInvariant()) return true; 1501f22ef01cSRoman Divacky 150291bc56edSDimitry Andric 1503f22ef01cSRoman Divacky // A load from a constant PseudoSourceValue is invariant. 150491bc56edSDimitry Andric if (const PseudoSourceValue *PSV = (*I)->getPseudoValue()) 1505f22ef01cSRoman Divacky if (PSV->isConstant(MFI)) 1506f22ef01cSRoman Divacky continue; 150791bc56edSDimitry Andric 150891bc56edSDimitry Andric if (const Value *V = (*I)->getValue()) { 1509f22ef01cSRoman Divacky // If we have an AliasAnalysis, ask it whether the memory is constant. 15108f0fd8f6SDimitry Andric if (AA && 15118f0fd8f6SDimitry Andric AA->pointsToConstantMemory( 15128f0fd8f6SDimitry Andric MemoryLocation(V, (*I)->getSize(), (*I)->getAAInfo()))) 1513f22ef01cSRoman Divacky continue; 1514f22ef01cSRoman Divacky } 1515f22ef01cSRoman Divacky 1516f22ef01cSRoman Divacky // Otherwise assume conservatively. 1517f22ef01cSRoman Divacky return false; 1518f22ef01cSRoman Divacky } 1519f22ef01cSRoman Divacky 1520f22ef01cSRoman Divacky // Everything checks out. 1521f22ef01cSRoman Divacky return true; 1522f22ef01cSRoman Divacky } 1523f22ef01cSRoman Divacky 1524f22ef01cSRoman Divacky /// isConstantValuePHI - If the specified instruction is a PHI that always 1525f22ef01cSRoman Divacky /// merges together the same virtual register, return the register, otherwise 1526f22ef01cSRoman Divacky /// return 0. 1527f22ef01cSRoman Divacky unsigned MachineInstr::isConstantValuePHI() const { 1528f22ef01cSRoman Divacky if (!isPHI()) 1529f22ef01cSRoman Divacky return 0; 1530f22ef01cSRoman Divacky assert(getNumOperands() >= 3 && 1531f22ef01cSRoman Divacky "It's illegal to have a PHI without source operands"); 1532f22ef01cSRoman Divacky 1533f22ef01cSRoman Divacky unsigned Reg = getOperand(1).getReg(); 1534f22ef01cSRoman Divacky for (unsigned i = 3, e = getNumOperands(); i < e; i += 2) 1535f22ef01cSRoman Divacky if (getOperand(i).getReg() != Reg) 1536f22ef01cSRoman Divacky return 0; 1537f22ef01cSRoman Divacky return Reg; 1538f22ef01cSRoman Divacky } 1539f22ef01cSRoman Divacky 15402754fe60SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const { 1541dff0c46cSDimitry Andric if (hasProperty(MCID::UnmodeledSideEffects)) 15422754fe60SDimitry Andric return true; 15432754fe60SDimitry Andric if (isInlineAsm()) { 15442754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 15452754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 15462754fe60SDimitry Andric return true; 15472754fe60SDimitry Andric } 15482754fe60SDimitry Andric 15492754fe60SDimitry Andric return false; 15502754fe60SDimitry Andric } 15512754fe60SDimitry Andric 15527d523365SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const { 15537d523365SDimitry Andric return mayStore() || isCall() || hasUnmodeledSideEffects(); 15547d523365SDimitry Andric } 15557d523365SDimitry Andric 1556f22ef01cSRoman Divacky /// allDefsAreDead - Return true if all the defs of this instruction are dead. 1557f22ef01cSRoman Divacky /// 1558f22ef01cSRoman Divacky bool MachineInstr::allDefsAreDead() const { 1559ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 1560f22ef01cSRoman Divacky if (!MO.isReg() || MO.isUse()) 1561f22ef01cSRoman Divacky continue; 1562f22ef01cSRoman Divacky if (!MO.isDead()) 1563f22ef01cSRoman Divacky return false; 1564f22ef01cSRoman Divacky } 1565f22ef01cSRoman Divacky return true; 1566f22ef01cSRoman Divacky } 1567f22ef01cSRoman Divacky 15682754fe60SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified 15692754fe60SDimitry Andric /// instruction to this instruction. 1570139f7f9bSDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF, 1571139f7f9bSDimitry Andric const MachineInstr *MI) { 15722754fe60SDimitry Andric for (unsigned i = MI->getDesc().getNumOperands(), e = MI->getNumOperands(); 15732754fe60SDimitry Andric i != e; ++i) { 15742754fe60SDimitry Andric const MachineOperand &MO = MI->getOperand(i); 157591bc56edSDimitry Andric if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask()) 1576139f7f9bSDimitry Andric addOperand(MF, MO); 15772754fe60SDimitry Andric } 15782754fe60SDimitry Andric } 15792754fe60SDimitry Andric 1580f22ef01cSRoman Divacky void MachineInstr::dump() const { 15813861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1582f22ef01cSRoman Divacky dbgs() << " " << *this; 15833861d79fSDimitry Andric #endif 1584f22ef01cSRoman Divacky } 1585f22ef01cSRoman Divacky 1586ff0cc061SDimitry Andric void MachineInstr::print(raw_ostream &OS, bool SkipOpers) const { 15873dac3a9bSDimitry Andric const Module *M = nullptr; 15883dac3a9bSDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 15893dac3a9bSDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 15903dac3a9bSDimitry Andric M = MF->getFunction()->getParent(); 15913dac3a9bSDimitry Andric 15923dac3a9bSDimitry Andric ModuleSlotTracker MST(M); 15933dac3a9bSDimitry Andric print(OS, MST, SkipOpers); 15943dac3a9bSDimitry Andric } 15953dac3a9bSDimitry Andric 15963dac3a9bSDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, 15973dac3a9bSDimitry Andric bool SkipOpers) const { 1598ff0cc061SDimitry Andric // We can be a bit tidier if we know the MachineFunction. 159991bc56edSDimitry Andric const MachineFunction *MF = nullptr; 1600ff0cc061SDimitry Andric const TargetRegisterInfo *TRI = nullptr; 160191bc56edSDimitry Andric const MachineRegisterInfo *MRI = nullptr; 1602ff0cc061SDimitry Andric const TargetInstrInfo *TII = nullptr; 1603f22ef01cSRoman Divacky if (const MachineBasicBlock *MBB = getParent()) { 1604f22ef01cSRoman Divacky MF = MBB->getParent(); 1605ff0cc061SDimitry Andric if (MF) { 1606e580952dSDimitry Andric MRI = &MF->getRegInfo(); 1607ff0cc061SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo(); 1608ff0cc061SDimitry Andric TII = MF->getSubtarget().getInstrInfo(); 1609ff0cc061SDimitry Andric } 1610f22ef01cSRoman Divacky } 1611f22ef01cSRoman Divacky 1612e580952dSDimitry Andric // Save a list of virtual registers. 1613e580952dSDimitry Andric SmallVector<unsigned, 8> VirtRegs; 1614e580952dSDimitry Andric 1615f22ef01cSRoman Divacky // Print explicitly defined operands on the left of an assignment syntax. 1616f22ef01cSRoman Divacky unsigned StartOp = 0, e = getNumOperands(); 1617f22ef01cSRoman Divacky for (; StartOp < e && getOperand(StartOp).isReg() && 1618f22ef01cSRoman Divacky getOperand(StartOp).isDef() && 1619f22ef01cSRoman Divacky !getOperand(StartOp).isImplicit(); 1620f22ef01cSRoman Divacky ++StartOp) { 1621f22ef01cSRoman Divacky if (StartOp != 0) OS << ", "; 16223dac3a9bSDimitry Andric getOperand(StartOp).print(OS, MST, TRI); 1623e580952dSDimitry Andric unsigned Reg = getOperand(StartOp).getReg(); 16242754fe60SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(Reg)) 1625e580952dSDimitry Andric VirtRegs.push_back(Reg); 1626f22ef01cSRoman Divacky } 1627f22ef01cSRoman Divacky 1628f22ef01cSRoman Divacky if (StartOp != 0) 1629f22ef01cSRoman Divacky OS << " = "; 1630f22ef01cSRoman Divacky 1631f22ef01cSRoman Divacky // Print the opcode name. 1632ff0cc061SDimitry Andric if (TII) 1633ff0cc061SDimitry Andric OS << TII->getName(getOpcode()); 1634dff0c46cSDimitry Andric else 1635dff0c46cSDimitry Andric OS << "UNKNOWN"; 1636f22ef01cSRoman Divacky 1637139f7f9bSDimitry Andric if (SkipOpers) 1638139f7f9bSDimitry Andric return; 1639139f7f9bSDimitry Andric 1640f22ef01cSRoman Divacky // Print the rest of the operands. 1641f22ef01cSRoman Divacky bool OmittedAnyCallClobbers = false; 1642f22ef01cSRoman Divacky bool FirstOp = true; 164317a519f9SDimitry Andric unsigned AsmDescOp = ~0u; 164417a519f9SDimitry Andric unsigned AsmOpCount = 0; 16452754fe60SDimitry Andric 16466122f3e6SDimitry Andric if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { 16472754fe60SDimitry Andric // Print asm string. 16482754fe60SDimitry Andric OS << " "; 16493dac3a9bSDimitry Andric getOperand(InlineAsm::MIOp_AsmString).print(OS, MST, TRI); 16502754fe60SDimitry Andric 1651139f7f9bSDimitry Andric // Print HasSideEffects, MayLoad, MayStore, IsAlignStack 16522754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 16532754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 16542754fe60SDimitry Andric OS << " [sideeffect]"; 1655139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayLoad) 1656139f7f9bSDimitry Andric OS << " [mayload]"; 1657139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayStore) 1658139f7f9bSDimitry Andric OS << " [maystore]"; 16592754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 16602754fe60SDimitry Andric OS << " [alignstack]"; 16613861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_ATT) 16623861d79fSDimitry Andric OS << " [attdialect]"; 16633861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_Intel) 16643861d79fSDimitry Andric OS << " [inteldialect]"; 16652754fe60SDimitry Andric 166617a519f9SDimitry Andric StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand; 16672754fe60SDimitry Andric FirstOp = false; 16682754fe60SDimitry Andric } 16692754fe60SDimitry Andric 1670f22ef01cSRoman Divacky for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 1671f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1672f22ef01cSRoman Divacky 16732754fe60SDimitry Andric if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) 1674e580952dSDimitry Andric VirtRegs.push_back(MO.getReg()); 1675e580952dSDimitry Andric 1676f22ef01cSRoman Divacky // Omit call-clobbered registers which aren't used anywhere. This makes 1677f22ef01cSRoman Divacky // call instructions much less noisy on targets where calls clobber lots 1678f22ef01cSRoman Divacky // of registers. Don't rely on MO.isDead() because we may be called before 1679f22ef01cSRoman Divacky // LiveVariables is run, or we may be looking at a non-allocatable reg. 168039d628a0SDimitry Andric if (MRI && isCall() && 1681f22ef01cSRoman Divacky MO.isReg() && MO.isImplicit() && MO.isDef()) { 1682f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 16832754fe60SDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 168439d628a0SDimitry Andric if (MRI->use_empty(Reg)) { 1685f22ef01cSRoman Divacky bool HasAliasLive = false; 1686ff0cc061SDimitry Andric for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { 16877ae0e2c9SDimitry Andric unsigned AliasReg = *AI; 168839d628a0SDimitry Andric if (!MRI->use_empty(AliasReg)) { 1689f22ef01cSRoman Divacky HasAliasLive = true; 1690f22ef01cSRoman Divacky break; 1691f22ef01cSRoman Divacky } 16927ae0e2c9SDimitry Andric } 1693f22ef01cSRoman Divacky if (!HasAliasLive) { 1694f22ef01cSRoman Divacky OmittedAnyCallClobbers = true; 1695f22ef01cSRoman Divacky continue; 1696f22ef01cSRoman Divacky } 1697f22ef01cSRoman Divacky } 1698f22ef01cSRoman Divacky } 1699f22ef01cSRoman Divacky } 1700f22ef01cSRoman Divacky 1701f22ef01cSRoman Divacky if (FirstOp) FirstOp = false; else OS << ","; 1702f22ef01cSRoman Divacky OS << " "; 1703f22ef01cSRoman Divacky if (i < getDesc().NumOperands) { 170417a519f9SDimitry Andric const MCOperandInfo &MCOI = getDesc().OpInfo[i]; 170517a519f9SDimitry Andric if (MCOI.isPredicate()) 1706f22ef01cSRoman Divacky OS << "pred:"; 170717a519f9SDimitry Andric if (MCOI.isOptionalDef()) 1708f22ef01cSRoman Divacky OS << "opt:"; 1709f22ef01cSRoman Divacky } 1710f22ef01cSRoman Divacky if (isDebugValue() && MO.isMetadata()) { 1711f22ef01cSRoman Divacky // Pretty print DBG_VALUE instructions. 1712ff0cc061SDimitry Andric auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata()); 1713ff0cc061SDimitry Andric if (DIV && !DIV->getName().empty()) 1714ff0cc061SDimitry Andric OS << "!\"" << DIV->getName() << '\"'; 1715f22ef01cSRoman Divacky else 17163dac3a9bSDimitry Andric MO.print(OS, MST, TRI); 1717ff0cc061SDimitry Andric } else if (TRI && (isInsertSubreg() || isRegSequence()) && MO.isImm()) { 1718ff0cc061SDimitry Andric OS << TRI->getSubRegIndexName(MO.getImm()); 171917a519f9SDimitry Andric } else if (i == AsmDescOp && MO.isImm()) { 172017a519f9SDimitry Andric // Pretty print the inline asm operand descriptor. 172117a519f9SDimitry Andric OS << '$' << AsmOpCount++; 172217a519f9SDimitry Andric unsigned Flag = MO.getImm(); 172317a519f9SDimitry Andric switch (InlineAsm::getKind(Flag)) { 17246122f3e6SDimitry Andric case InlineAsm::Kind_RegUse: OS << ":[reguse"; break; 17256122f3e6SDimitry Andric case InlineAsm::Kind_RegDef: OS << ":[regdef"; break; 17266122f3e6SDimitry Andric case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec"; break; 17276122f3e6SDimitry Andric case InlineAsm::Kind_Clobber: OS << ":[clobber"; break; 17286122f3e6SDimitry Andric case InlineAsm::Kind_Imm: OS << ":[imm"; break; 17296122f3e6SDimitry Andric case InlineAsm::Kind_Mem: OS << ":[mem"; break; 17306122f3e6SDimitry Andric default: OS << ":[??" << InlineAsm::getKind(Flag); break; 17316122f3e6SDimitry Andric } 17326122f3e6SDimitry Andric 17336122f3e6SDimitry Andric unsigned RCID = 0; 17346122f3e6SDimitry Andric if (InlineAsm::hasRegClassConstraint(Flag, RCID)) { 1735ff0cc061SDimitry Andric if (TRI) { 1736ff0cc061SDimitry Andric OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID)); 173739d628a0SDimitry Andric } else 17386122f3e6SDimitry Andric OS << ":RC" << RCID; 173917a519f9SDimitry Andric } 174017a519f9SDimitry Andric 174117a519f9SDimitry Andric unsigned TiedTo = 0; 174217a519f9SDimitry Andric if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo)) 17436122f3e6SDimitry Andric OS << " tiedto:$" << TiedTo; 17446122f3e6SDimitry Andric 17456122f3e6SDimitry Andric OS << ']'; 174617a519f9SDimitry Andric 174717a519f9SDimitry Andric // Compute the index of the next operand descriptor. 174817a519f9SDimitry Andric AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); 1749f22ef01cSRoman Divacky } else 17503dac3a9bSDimitry Andric MO.print(OS, MST, TRI); 1751f22ef01cSRoman Divacky } 1752f22ef01cSRoman Divacky 1753f22ef01cSRoman Divacky // Briefly indicate whether any call clobbers were omitted. 1754f22ef01cSRoman Divacky if (OmittedAnyCallClobbers) { 1755f22ef01cSRoman Divacky if (!FirstOp) OS << ","; 1756f22ef01cSRoman Divacky OS << " ..."; 1757f22ef01cSRoman Divacky } 1758f22ef01cSRoman Divacky 1759f22ef01cSRoman Divacky bool HaveSemi = false; 17607d523365SDimitry Andric const unsigned PrintableFlags = FrameSetup | FrameDestroy; 1761139f7f9bSDimitry Andric if (Flags & PrintableFlags) { 17624d0b32cdSDimitry Andric if (!HaveSemi) { 17634d0b32cdSDimitry Andric OS << ";"; 17644d0b32cdSDimitry Andric HaveSemi = true; 17654d0b32cdSDimitry Andric } 17663b0f4066SDimitry Andric OS << " flags: "; 17673b0f4066SDimitry Andric 17683b0f4066SDimitry Andric if (Flags & FrameSetup) 17693b0f4066SDimitry Andric OS << "FrameSetup"; 17707d523365SDimitry Andric 17717d523365SDimitry Andric if (Flags & FrameDestroy) 17727d523365SDimitry Andric OS << "FrameDestroy"; 17733b0f4066SDimitry Andric } 17743b0f4066SDimitry Andric 1775f22ef01cSRoman Divacky if (!memoperands_empty()) { 17764d0b32cdSDimitry Andric if (!HaveSemi) { 17774d0b32cdSDimitry Andric OS << ";"; 17784d0b32cdSDimitry Andric HaveSemi = true; 17794d0b32cdSDimitry Andric } 1780f22ef01cSRoman Divacky 1781f22ef01cSRoman Divacky OS << " mem:"; 1782f22ef01cSRoman Divacky for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); 1783f22ef01cSRoman Divacky i != e; ++i) { 17843dac3a9bSDimitry Andric (*i)->print(OS, MST); 178591bc56edSDimitry Andric if (std::next(i) != e) 1786f22ef01cSRoman Divacky OS << " "; 1787f22ef01cSRoman Divacky } 1788f22ef01cSRoman Divacky } 1789f22ef01cSRoman Divacky 1790e580952dSDimitry Andric // Print the regclass of any virtual registers encountered. 1791e580952dSDimitry Andric if (MRI && !VirtRegs.empty()) { 17924d0b32cdSDimitry Andric if (!HaveSemi) { 17934d0b32cdSDimitry Andric OS << ";"; 17944d0b32cdSDimitry Andric HaveSemi = true; 17954d0b32cdSDimitry Andric } 1796e580952dSDimitry Andric for (unsigned i = 0; i != VirtRegs.size(); ++i) { 1797e580952dSDimitry Andric const TargetRegisterClass *RC = MRI->getRegClass(VirtRegs[i]); 1798ff0cc061SDimitry Andric OS << " " << TRI->getRegClassName(RC) 179939d628a0SDimitry Andric << ':' << PrintReg(VirtRegs[i]); 1800e580952dSDimitry Andric for (unsigned j = i+1; j != VirtRegs.size();) { 1801e580952dSDimitry Andric if (MRI->getRegClass(VirtRegs[j]) != RC) { 1802e580952dSDimitry Andric ++j; 1803e580952dSDimitry Andric continue; 1804e580952dSDimitry Andric } 1805e580952dSDimitry Andric if (VirtRegs[i] != VirtRegs[j]) 18062754fe60SDimitry Andric OS << "," << PrintReg(VirtRegs[j]); 1807e580952dSDimitry Andric VirtRegs.erase(VirtRegs.begin()+j); 1808e580952dSDimitry Andric } 1809e580952dSDimitry Andric } 1810e580952dSDimitry Andric } 1811e580952dSDimitry Andric 18123b0f4066SDimitry Andric // Print debug location information. 1813ff0cc061SDimitry Andric if (isDebugValue() && getOperand(e - 2).isMetadata()) { 18144d0b32cdSDimitry Andric if (!HaveSemi) 18154d0b32cdSDimitry Andric OS << ";"; 1816ff0cc061SDimitry Andric auto *DV = cast<DILocalVariable>(getOperand(e - 2).getMetadata()); 1817ff0cc061SDimitry Andric OS << " line no:" << DV->getLine(); 1818ff0cc061SDimitry Andric if (auto *InlinedAt = debugLoc->getInlinedAt()) { 1819ff0cc061SDimitry Andric DebugLoc InlinedAtDL(InlinedAt); 1820ff0cc061SDimitry Andric if (InlinedAtDL && MF) { 18216122f3e6SDimitry Andric OS << " inlined @[ "; 1822ff0cc061SDimitry Andric InlinedAtDL.print(OS); 18236122f3e6SDimitry Andric OS << " ]"; 18246122f3e6SDimitry Andric } 18256122f3e6SDimitry Andric } 182639d628a0SDimitry Andric if (isIndirectDebugValue()) 182739d628a0SDimitry Andric OS << " indirect"; 1828ff0cc061SDimitry Andric } else if (debugLoc && MF) { 18294d0b32cdSDimitry Andric if (!HaveSemi) 18304d0b32cdSDimitry Andric OS << ";"; 1831f22ef01cSRoman Divacky OS << " dbg:"; 1832ff0cc061SDimitry Andric debugLoc.print(OS); 1833f22ef01cSRoman Divacky } 1834f22ef01cSRoman Divacky 18353b0f4066SDimitry Andric OS << '\n'; 1836f22ef01cSRoman Divacky } 1837f22ef01cSRoman Divacky 1838f22ef01cSRoman Divacky bool MachineInstr::addRegisterKilled(unsigned IncomingReg, 1839f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 1840f22ef01cSRoman Divacky bool AddIfNotFound) { 1841f22ef01cSRoman Divacky bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); 18427ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 18437ae0e2c9SDimitry Andric MCRegAliasIterator(IncomingReg, RegInfo, false).isValid(); 1844f22ef01cSRoman Divacky bool Found = false; 1845f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 1846f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1847f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1848f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse() || MO.isUndef()) 1849f22ef01cSRoman Divacky continue; 1850f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 1851f22ef01cSRoman Divacky if (!Reg) 1852f22ef01cSRoman Divacky continue; 1853f22ef01cSRoman Divacky 1854f22ef01cSRoman Divacky if (Reg == IncomingReg) { 1855f22ef01cSRoman Divacky if (!Found) { 1856f22ef01cSRoman Divacky if (MO.isKill()) 1857f22ef01cSRoman Divacky // The register is already marked kill. 1858f22ef01cSRoman Divacky return true; 1859f22ef01cSRoman Divacky if (isPhysReg && isRegTiedToDefOperand(i)) 1860f22ef01cSRoman Divacky // Two-address uses of physregs must not be marked kill. 1861f22ef01cSRoman Divacky return true; 1862f22ef01cSRoman Divacky MO.setIsKill(); 1863f22ef01cSRoman Divacky Found = true; 1864f22ef01cSRoman Divacky } 1865f22ef01cSRoman Divacky } else if (hasAliases && MO.isKill() && 1866f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg)) { 1867f22ef01cSRoman Divacky // A super-register kill already exists. 1868f22ef01cSRoman Divacky if (RegInfo->isSuperRegister(IncomingReg, Reg)) 1869f22ef01cSRoman Divacky return true; 1870f22ef01cSRoman Divacky if (RegInfo->isSubRegister(IncomingReg, Reg)) 1871f22ef01cSRoman Divacky DeadOps.push_back(i); 1872f22ef01cSRoman Divacky } 1873f22ef01cSRoman Divacky } 1874f22ef01cSRoman Divacky 1875f22ef01cSRoman Divacky // Trim unneeded kill operands. 1876f22ef01cSRoman Divacky while (!DeadOps.empty()) { 1877f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 1878f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 1879f22ef01cSRoman Divacky RemoveOperand(OpIdx); 1880f22ef01cSRoman Divacky else 1881f22ef01cSRoman Divacky getOperand(OpIdx).setIsKill(false); 1882f22ef01cSRoman Divacky DeadOps.pop_back(); 1883f22ef01cSRoman Divacky } 1884f22ef01cSRoman Divacky 1885f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is killed. Add a 1886f22ef01cSRoman Divacky // new implicit operand if required. 1887f22ef01cSRoman Divacky if (!Found && AddIfNotFound) { 1888f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(IncomingReg, 1889f22ef01cSRoman Divacky false /*IsDef*/, 1890f22ef01cSRoman Divacky true /*IsImp*/, 1891f22ef01cSRoman Divacky true /*IsKill*/)); 1892f22ef01cSRoman Divacky return true; 1893f22ef01cSRoman Divacky } 1894f22ef01cSRoman Divacky return Found; 1895f22ef01cSRoman Divacky } 1896f22ef01cSRoman Divacky 1897dff0c46cSDimitry Andric void MachineInstr::clearRegisterKills(unsigned Reg, 1898dff0c46cSDimitry Andric const TargetRegisterInfo *RegInfo) { 1899dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) 190091bc56edSDimitry Andric RegInfo = nullptr; 1901ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1902dff0c46cSDimitry Andric if (!MO.isReg() || !MO.isUse() || !MO.isKill()) 1903dff0c46cSDimitry Andric continue; 1904dff0c46cSDimitry Andric unsigned OpReg = MO.getReg(); 1905dff0c46cSDimitry Andric if (OpReg == Reg || (RegInfo && RegInfo->isSuperRegister(Reg, OpReg))) 1906dff0c46cSDimitry Andric MO.setIsKill(false); 1907dff0c46cSDimitry Andric } 1908dff0c46cSDimitry Andric } 1909dff0c46cSDimitry Andric 1910f785676fSDimitry Andric bool MachineInstr::addRegisterDead(unsigned Reg, 1911f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 1912f22ef01cSRoman Divacky bool AddIfNotFound) { 1913f785676fSDimitry Andric bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(Reg); 19147ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 1915f785676fSDimitry Andric MCRegAliasIterator(Reg, RegInfo, false).isValid(); 1916f22ef01cSRoman Divacky bool Found = false; 1917f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 1918f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1919f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1920f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 1921f22ef01cSRoman Divacky continue; 1922f785676fSDimitry Andric unsigned MOReg = MO.getReg(); 1923f785676fSDimitry Andric if (!MOReg) 1924f22ef01cSRoman Divacky continue; 1925f22ef01cSRoman Divacky 1926f785676fSDimitry Andric if (MOReg == Reg) { 1927f22ef01cSRoman Divacky MO.setIsDead(); 1928f22ef01cSRoman Divacky Found = true; 1929f22ef01cSRoman Divacky } else if (hasAliases && MO.isDead() && 1930f785676fSDimitry Andric TargetRegisterInfo::isPhysicalRegister(MOReg)) { 1931f22ef01cSRoman Divacky // There exists a super-register that's marked dead. 1932f785676fSDimitry Andric if (RegInfo->isSuperRegister(Reg, MOReg)) 1933f22ef01cSRoman Divacky return true; 1934f785676fSDimitry Andric if (RegInfo->isSubRegister(Reg, MOReg)) 1935f22ef01cSRoman Divacky DeadOps.push_back(i); 1936f22ef01cSRoman Divacky } 1937f22ef01cSRoman Divacky } 1938f22ef01cSRoman Divacky 1939f22ef01cSRoman Divacky // Trim unneeded dead operands. 1940f22ef01cSRoman Divacky while (!DeadOps.empty()) { 1941f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 1942f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 1943f22ef01cSRoman Divacky RemoveOperand(OpIdx); 1944f22ef01cSRoman Divacky else 1945f22ef01cSRoman Divacky getOperand(OpIdx).setIsDead(false); 1946f22ef01cSRoman Divacky DeadOps.pop_back(); 1947f22ef01cSRoman Divacky } 1948f22ef01cSRoman Divacky 1949f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is dead. Add a 1950f22ef01cSRoman Divacky // new implicit operand if required. 1951f22ef01cSRoman Divacky if (Found || !AddIfNotFound) 1952f22ef01cSRoman Divacky return Found; 1953f22ef01cSRoman Divacky 1954f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 1955f22ef01cSRoman Divacky true /*IsDef*/, 1956f22ef01cSRoman Divacky true /*IsImp*/, 1957f22ef01cSRoman Divacky false /*IsKill*/, 1958f22ef01cSRoman Divacky true /*IsDead*/)); 1959f22ef01cSRoman Divacky return true; 1960f22ef01cSRoman Divacky } 1961f22ef01cSRoman Divacky 1962ff0cc061SDimitry Andric void MachineInstr::clearRegisterDeads(unsigned Reg) { 1963ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1964ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg) 1965ff0cc061SDimitry Andric continue; 1966ff0cc061SDimitry Andric MO.setIsDead(false); 1967ff0cc061SDimitry Andric } 1968ff0cc061SDimitry Andric } 1969ff0cc061SDimitry Andric 19707d523365SDimitry Andric void MachineInstr::setRegisterDefReadUndef(unsigned Reg, bool IsUndef) { 1971ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1972ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0) 1973ff0cc061SDimitry Andric continue; 19747d523365SDimitry Andric MO.setIsUndef(IsUndef); 1975ff0cc061SDimitry Andric } 1976ff0cc061SDimitry Andric } 1977ff0cc061SDimitry Andric 1978f785676fSDimitry Andric void MachineInstr::addRegisterDefined(unsigned Reg, 1979f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo) { 1980f785676fSDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 1981f785676fSDimitry Andric MachineOperand *MO = findRegisterDefOperand(Reg, false, RegInfo); 1982f22ef01cSRoman Divacky if (MO) 1983f22ef01cSRoman Divacky return; 1984f22ef01cSRoman Divacky } else { 1985ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 1986f785676fSDimitry Andric if (MO.isReg() && MO.getReg() == Reg && MO.isDef() && 1987f22ef01cSRoman Divacky MO.getSubReg() == 0) 1988f22ef01cSRoman Divacky return; 1989f22ef01cSRoman Divacky } 1990f22ef01cSRoman Divacky } 1991f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 1992f22ef01cSRoman Divacky true /*IsDef*/, 1993f22ef01cSRoman Divacky true /*IsImp*/)); 1994f22ef01cSRoman Divacky } 1995f22ef01cSRoman Divacky 1996dff0c46cSDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs, 1997ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 1998dff0c46cSDimitry Andric bool HasRegMask = false; 1999ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 2000dff0c46cSDimitry Andric if (MO.isRegMask()) { 2001dff0c46cSDimitry Andric HasRegMask = true; 2002dff0c46cSDimitry Andric continue; 2003dff0c46cSDimitry Andric } 2004ffd1746dSEd Schouten if (!MO.isReg() || !MO.isDef()) continue; 2005ffd1746dSEd Schouten unsigned Reg = MO.getReg(); 2006dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; 2007ffd1746dSEd Schouten // If there are no uses, including partial uses, the def is dead. 2008ff0cc061SDimitry Andric if (std::none_of(UsedRegs.begin(), UsedRegs.end(), 2009ff0cc061SDimitry Andric [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); })) 2010ff0cc061SDimitry Andric MO.setIsDead(); 2011ffd1746dSEd Schouten } 2012dff0c46cSDimitry Andric 2013dff0c46cSDimitry Andric // This is a call with a register mask operand. 2014dff0c46cSDimitry Andric // Mask clobbers are always dead, so add defs for the non-dead defines. 2015dff0c46cSDimitry Andric if (HasRegMask) 2016dff0c46cSDimitry Andric for (ArrayRef<unsigned>::iterator I = UsedRegs.begin(), E = UsedRegs.end(); 2017dff0c46cSDimitry Andric I != E; ++I) 2018dff0c46cSDimitry Andric addRegisterDefined(*I, &TRI); 2019ffd1746dSEd Schouten } 2020ffd1746dSEd Schouten 2021f22ef01cSRoman Divacky unsigned 2022f22ef01cSRoman Divacky MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { 2023dff0c46cSDimitry Andric // Build up a buffer of hash code components. 2024dff0c46cSDimitry Andric SmallVector<size_t, 8> HashComponents; 2025dff0c46cSDimitry Andric HashComponents.reserve(MI->getNumOperands() + 1); 2026dff0c46cSDimitry Andric HashComponents.push_back(MI->getOpcode()); 2027ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 20287ae0e2c9SDimitry Andric if (MO.isReg() && MO.isDef() && 20297ae0e2c9SDimitry Andric TargetRegisterInfo::isVirtualRegister(MO.getReg())) 2030f22ef01cSRoman Divacky continue; // Skip virtual register defs. 20317ae0e2c9SDimitry Andric 20327ae0e2c9SDimitry Andric HashComponents.push_back(hash_value(MO)); 2033f22ef01cSRoman Divacky } 2034dff0c46cSDimitry Andric return hash_combine_range(HashComponents.begin(), HashComponents.end()); 2035f22ef01cSRoman Divacky } 203617a519f9SDimitry Andric 203717a519f9SDimitry Andric void MachineInstr::emitError(StringRef Msg) const { 203817a519f9SDimitry Andric // Find the source location cookie. 203917a519f9SDimitry Andric unsigned LocCookie = 0; 204091bc56edSDimitry Andric const MDNode *LocMD = nullptr; 204117a519f9SDimitry Andric for (unsigned i = getNumOperands(); i != 0; --i) { 204217a519f9SDimitry Andric if (getOperand(i-1).isMetadata() && 204317a519f9SDimitry Andric (LocMD = getOperand(i-1).getMetadata()) && 204417a519f9SDimitry Andric LocMD->getNumOperands() != 0) { 204539d628a0SDimitry Andric if (const ConstantInt *CI = 204639d628a0SDimitry Andric mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) { 204717a519f9SDimitry Andric LocCookie = CI->getZExtValue(); 204817a519f9SDimitry Andric break; 204917a519f9SDimitry Andric } 205017a519f9SDimitry Andric } 205117a519f9SDimitry Andric } 205217a519f9SDimitry Andric 205317a519f9SDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 205417a519f9SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 205517a519f9SDimitry Andric return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg); 205617a519f9SDimitry Andric report_fatal_error(Msg); 205717a519f9SDimitry Andric } 2058