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" 31139f7f9bSDimitry Andric #include "llvm/IR/Type.h" 32139f7f9bSDimitry Andric #include "llvm/IR/Value.h" 3317a519f9SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 34f22ef01cSRoman Divacky #include "llvm/MC/MCSymbol.h" 35f22ef01cSRoman Divacky #include "llvm/Support/Debug.h" 36f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 37f22ef01cSRoman Divacky #include "llvm/Support/MathExtras.h" 38f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 39139f7f9bSDimitry Andric #include "llvm/Target/TargetInstrInfo.h" 40139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h" 41139f7f9bSDimitry Andric #include "llvm/Target/TargetRegisterInfo.h" 42f22ef01cSRoman Divacky using namespace llvm; 43f22ef01cSRoman Divacky 44f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 45f22ef01cSRoman Divacky // MachineOperand Implementation 46f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 47f22ef01cSRoman Divacky 48f22ef01cSRoman Divacky void MachineOperand::setReg(unsigned Reg) { 49f22ef01cSRoman Divacky if (getReg() == Reg) return; // No change. 50f22ef01cSRoman Divacky 51f22ef01cSRoman Divacky // Otherwise, we have to change the register. If this operand is embedded 52f22ef01cSRoman Divacky // into a machine function, we need to update the old and new register's 53f22ef01cSRoman Divacky // use/def lists. 54f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 55f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 56f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) { 577ae0e2c9SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 587ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(this); 592754fe60SDimitry Andric SmallContents.RegNo = Reg; 607ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(this); 61f22ef01cSRoman Divacky return; 62f22ef01cSRoman Divacky } 63f22ef01cSRoman Divacky 64f22ef01cSRoman Divacky // Otherwise, just change the register, no problem. :) 652754fe60SDimitry Andric SmallContents.RegNo = Reg; 66f22ef01cSRoman Divacky } 67f22ef01cSRoman Divacky 68ffd1746dSEd Schouten void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, 69ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 70ffd1746dSEd Schouten assert(TargetRegisterInfo::isVirtualRegister(Reg)); 71ffd1746dSEd Schouten if (SubIdx && getSubReg()) 72ffd1746dSEd Schouten SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); 73ffd1746dSEd Schouten setReg(Reg); 74ffd1746dSEd Schouten if (SubIdx) 75ffd1746dSEd Schouten setSubReg(SubIdx); 76ffd1746dSEd Schouten } 77ffd1746dSEd Schouten 78ffd1746dSEd Schouten void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { 79ffd1746dSEd Schouten assert(TargetRegisterInfo::isPhysicalRegister(Reg)); 80ffd1746dSEd Schouten if (getSubReg()) { 81ffd1746dSEd Schouten Reg = TRI.getSubReg(Reg, getSubReg()); 82bd5abe19SDimitry Andric // Note that getSubReg() may return 0 if the sub-register doesn't exist. 83bd5abe19SDimitry Andric // That won't happen in legal code. 84ffd1746dSEd Schouten setSubReg(0); 85ffd1746dSEd Schouten } 86ffd1746dSEd Schouten setReg(Reg); 87ffd1746dSEd Schouten } 88ffd1746dSEd Schouten 897ae0e2c9SDimitry Andric /// Change a def to a use, or a use to a def. 907ae0e2c9SDimitry Andric void MachineOperand::setIsDef(bool Val) { 917ae0e2c9SDimitry Andric assert(isReg() && "Wrong MachineOperand accessor"); 927ae0e2c9SDimitry Andric assert((!Val || !isDebug()) && "Marking a debug operation as def"); 937ae0e2c9SDimitry Andric if (IsDef == Val) 947ae0e2c9SDimitry Andric return; 957ae0e2c9SDimitry Andric // MRI may keep uses and defs in different list positions. 967ae0e2c9SDimitry Andric if (MachineInstr *MI = getParent()) 977ae0e2c9SDimitry Andric if (MachineBasicBlock *MBB = MI->getParent()) 987ae0e2c9SDimitry Andric if (MachineFunction *MF = MBB->getParent()) { 997ae0e2c9SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 1007ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(this); 1017ae0e2c9SDimitry Andric IsDef = Val; 1027ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(this); 1037ae0e2c9SDimitry Andric return; 1047ae0e2c9SDimitry Andric } 1057ae0e2c9SDimitry Andric IsDef = Val; 1067ae0e2c9SDimitry Andric } 1077ae0e2c9SDimitry Andric 108f22ef01cSRoman Divacky /// ChangeToImmediate - Replace this operand with a new immediate operand of 109f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an immediate already, 110f22ef01cSRoman Divacky /// the setImm method should be used. 111f22ef01cSRoman Divacky void MachineOperand::ChangeToImmediate(int64_t ImmVal) { 1123861d79fSDimitry Andric assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); 113f22ef01cSRoman Divacky // If this operand is currently a register operand, and if this is in a 114f22ef01cSRoman Divacky // function, deregister the operand from the register's use/def list. 1157ae0e2c9SDimitry Andric if (isReg() && isOnRegUseList()) 1167ae0e2c9SDimitry Andric if (MachineInstr *MI = getParent()) 1177ae0e2c9SDimitry Andric if (MachineBasicBlock *MBB = MI->getParent()) 1187ae0e2c9SDimitry Andric if (MachineFunction *MF = MBB->getParent()) 1197ae0e2c9SDimitry Andric MF->getRegInfo().removeRegOperandFromUseList(this); 120f22ef01cSRoman Divacky 121f22ef01cSRoman Divacky OpKind = MO_Immediate; 122f22ef01cSRoman Divacky Contents.ImmVal = ImmVal; 123f22ef01cSRoman Divacky } 124f22ef01cSRoman Divacky 125f22ef01cSRoman Divacky /// ChangeToRegister - Replace this operand with a new register operand of 126f22ef01cSRoman Divacky /// the specified value. If an operand is known to be an register already, 127f22ef01cSRoman Divacky /// the setReg method should be used. 128f22ef01cSRoman Divacky void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, 129f22ef01cSRoman Divacky bool isKill, bool isDead, bool isUndef, 130f22ef01cSRoman Divacky bool isDebug) { 13191bc56edSDimitry Andric MachineRegisterInfo *RegInfo = nullptr; 132f22ef01cSRoman Divacky if (MachineInstr *MI = getParent()) 133f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = MI->getParent()) 134f22ef01cSRoman Divacky if (MachineFunction *MF = MBB->getParent()) 1357ae0e2c9SDimitry Andric RegInfo = &MF->getRegInfo(); 1367ae0e2c9SDimitry Andric // If this operand is already a register operand, remove it from the 1377ae0e2c9SDimitry Andric // register's use/def lists. 1383861d79fSDimitry Andric bool WasReg = isReg(); 1393861d79fSDimitry Andric if (RegInfo && WasReg) 1407ae0e2c9SDimitry Andric RegInfo->removeRegOperandFromUseList(this); 141f22ef01cSRoman Divacky 1427ae0e2c9SDimitry Andric // Change this to a register and set the reg#. 1437ae0e2c9SDimitry Andric OpKind = MO_Register; 1447ae0e2c9SDimitry Andric SmallContents.RegNo = Reg; 145139f7f9bSDimitry Andric SubReg_TargetFlags = 0; 146f22ef01cSRoman Divacky IsDef = isDef; 147f22ef01cSRoman Divacky IsImp = isImp; 148f22ef01cSRoman Divacky IsKill = isKill; 149f22ef01cSRoman Divacky IsDead = isDead; 150f22ef01cSRoman Divacky IsUndef = isUndef; 151dff0c46cSDimitry Andric IsInternalRead = false; 152f22ef01cSRoman Divacky IsEarlyClobber = false; 153f22ef01cSRoman Divacky IsDebug = isDebug; 1547ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false. 15591bc56edSDimitry Andric Contents.Reg.Prev = nullptr; 1563861d79fSDimitry Andric // Preserve the tie when the operand was already a register. 1573861d79fSDimitry Andric if (!WasReg) 1583861d79fSDimitry Andric TiedTo = 0; 1597ae0e2c9SDimitry Andric 1607ae0e2c9SDimitry Andric // If this operand is embedded in a function, add the operand to the 1617ae0e2c9SDimitry Andric // register's use/def list. 1627ae0e2c9SDimitry Andric if (RegInfo) 1637ae0e2c9SDimitry Andric RegInfo->addRegOperandToUseList(this); 164f22ef01cSRoman Divacky } 165f22ef01cSRoman Divacky 166f22ef01cSRoman Divacky /// isIdenticalTo - Return true if this operand is identical to the specified 1677ae0e2c9SDimitry Andric /// operand. Note that this should stay in sync with the hash_value overload 1687ae0e2c9SDimitry Andric /// below. 169f22ef01cSRoman Divacky bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const { 170f22ef01cSRoman Divacky if (getType() != Other.getType() || 171f22ef01cSRoman Divacky getTargetFlags() != Other.getTargetFlags()) 172f22ef01cSRoman Divacky return false; 173f22ef01cSRoman Divacky 174f22ef01cSRoman Divacky switch (getType()) { 175f22ef01cSRoman Divacky case MachineOperand::MO_Register: 176f22ef01cSRoman Divacky return getReg() == Other.getReg() && isDef() == Other.isDef() && 177f22ef01cSRoman Divacky getSubReg() == Other.getSubReg(); 178f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 179f22ef01cSRoman Divacky return getImm() == Other.getImm(); 18017a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 18117a519f9SDimitry Andric return getCImm() == Other.getCImm(); 182f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 183f22ef01cSRoman Divacky return getFPImm() == Other.getFPImm(); 184f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 185f22ef01cSRoman Divacky return getMBB() == Other.getMBB(); 186f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 187f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 188f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 1897ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 190f22ef01cSRoman Divacky return getIndex() == Other.getIndex() && getOffset() == Other.getOffset(); 191f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 192f22ef01cSRoman Divacky return getIndex() == Other.getIndex(); 193f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 194f22ef01cSRoman Divacky return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); 195f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 196f22ef01cSRoman Divacky return !strcmp(getSymbolName(), Other.getSymbolName()) && 197f22ef01cSRoman Divacky getOffset() == Other.getOffset(); 198f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 1993861d79fSDimitry Andric return getBlockAddress() == Other.getBlockAddress() && 2003861d79fSDimitry Andric getOffset() == Other.getOffset(); 20191bc56edSDimitry Andric case MachineOperand::MO_RegisterMask: 20291bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 203dff0c46cSDimitry Andric return getRegMask() == Other.getRegMask(); 204f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 205f22ef01cSRoman Divacky return getMCSymbol() == Other.getMCSymbol(); 20691bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 20791bc56edSDimitry Andric return getCFIIndex() == Other.getCFIIndex(); 208f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 209f22ef01cSRoman Divacky return getMetadata() == Other.getMetadata(); 210f22ef01cSRoman Divacky } 211dff0c46cSDimitry Andric llvm_unreachable("Invalid machine operand type"); 212f22ef01cSRoman Divacky } 213f22ef01cSRoman Divacky 2147ae0e2c9SDimitry Andric // Note: this must stay exactly in sync with isIdenticalTo above. 2157ae0e2c9SDimitry Andric hash_code llvm::hash_value(const MachineOperand &MO) { 2167ae0e2c9SDimitry Andric switch (MO.getType()) { 2177ae0e2c9SDimitry Andric case MachineOperand::MO_Register: 2183861d79fSDimitry Andric // Register operands don't have target flags. 2193861d79fSDimitry Andric return hash_combine(MO.getType(), MO.getReg(), MO.getSubReg(), MO.isDef()); 2207ae0e2c9SDimitry Andric case MachineOperand::MO_Immediate: 2217ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); 2227ae0e2c9SDimitry Andric case MachineOperand::MO_CImmediate: 2237ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); 2247ae0e2c9SDimitry Andric case MachineOperand::MO_FPImmediate: 2257ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); 2267ae0e2c9SDimitry Andric case MachineOperand::MO_MachineBasicBlock: 2277ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); 2287ae0e2c9SDimitry Andric case MachineOperand::MO_FrameIndex: 2297ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 2307ae0e2c9SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 2317ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 2327ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), 2337ae0e2c9SDimitry Andric MO.getOffset()); 2347ae0e2c9SDimitry Andric case MachineOperand::MO_JumpTableIndex: 2357ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); 2367ae0e2c9SDimitry Andric case MachineOperand::MO_ExternalSymbol: 2377ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), 2387ae0e2c9SDimitry Andric MO.getSymbolName()); 2397ae0e2c9SDimitry Andric case MachineOperand::MO_GlobalAddress: 2407ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), 2417ae0e2c9SDimitry Andric MO.getOffset()); 2427ae0e2c9SDimitry Andric case MachineOperand::MO_BlockAddress: 2437ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), 2443861d79fSDimitry Andric MO.getBlockAddress(), MO.getOffset()); 2457ae0e2c9SDimitry Andric case MachineOperand::MO_RegisterMask: 24691bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 2477ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); 2487ae0e2c9SDimitry Andric case MachineOperand::MO_Metadata: 2497ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); 2507ae0e2c9SDimitry Andric case MachineOperand::MO_MCSymbol: 2517ae0e2c9SDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); 25291bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 25391bc56edSDimitry Andric return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); 2547ae0e2c9SDimitry Andric } 2557ae0e2c9SDimitry Andric llvm_unreachable("Invalid machine operand type"); 2567ae0e2c9SDimitry Andric } 2577ae0e2c9SDimitry Andric 258f22ef01cSRoman Divacky /// print - Print the specified machine operand. 259f22ef01cSRoman Divacky /// 260f22ef01cSRoman Divacky void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { 261f22ef01cSRoman Divacky // If the instruction is embedded into a basic block, we can find the 262f22ef01cSRoman Divacky // target info for the instruction. 263f22ef01cSRoman Divacky if (!TM) 264f22ef01cSRoman Divacky if (const MachineInstr *MI = getParent()) 265f22ef01cSRoman Divacky if (const MachineBasicBlock *MBB = MI->getParent()) 266f22ef01cSRoman Divacky if (const MachineFunction *MF = MBB->getParent()) 267f22ef01cSRoman Divacky TM = &MF->getTarget(); 26891bc56edSDimitry Andric const TargetRegisterInfo *TRI = TM ? TM->getRegisterInfo() : nullptr; 269f22ef01cSRoman Divacky 270f22ef01cSRoman Divacky switch (getType()) { 271f22ef01cSRoman Divacky case MachineOperand::MO_Register: 2722754fe60SDimitry Andric OS << PrintReg(getReg(), TRI, getSubReg()); 273f22ef01cSRoman Divacky 274f22ef01cSRoman Divacky if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || 2753861d79fSDimitry Andric isInternalRead() || isEarlyClobber() || isTied()) { 276f22ef01cSRoman Divacky OS << '<'; 277f22ef01cSRoman Divacky bool NeedComma = false; 278f22ef01cSRoman Divacky if (isDef()) { 279f22ef01cSRoman Divacky if (NeedComma) OS << ','; 280f22ef01cSRoman Divacky if (isEarlyClobber()) 281f22ef01cSRoman Divacky OS << "earlyclobber,"; 282f22ef01cSRoman Divacky if (isImplicit()) 283f22ef01cSRoman Divacky OS << "imp-"; 284f22ef01cSRoman Divacky OS << "def"; 285f22ef01cSRoman Divacky NeedComma = true; 2867ae0e2c9SDimitry Andric // <def,read-undef> only makes sense when getSubReg() is set. 2877ae0e2c9SDimitry Andric // Don't clutter the output otherwise. 2887ae0e2c9SDimitry Andric if (isUndef() && getSubReg()) 2897ae0e2c9SDimitry Andric OS << ",read-undef"; 290f22ef01cSRoman Divacky } else if (isImplicit()) { 291f22ef01cSRoman Divacky OS << "imp-use"; 292f22ef01cSRoman Divacky NeedComma = true; 293f22ef01cSRoman Divacky } 294f22ef01cSRoman Divacky 295dff0c46cSDimitry Andric if (isKill()) { 2963861d79fSDimitry Andric if (NeedComma) OS << ','; 297dff0c46cSDimitry Andric OS << "kill"; 298dff0c46cSDimitry Andric NeedComma = true; 299dff0c46cSDimitry Andric } 300dff0c46cSDimitry Andric if (isDead()) { 3013861d79fSDimitry Andric if (NeedComma) OS << ','; 302dff0c46cSDimitry Andric OS << "dead"; 303dff0c46cSDimitry Andric NeedComma = true; 304dff0c46cSDimitry Andric } 3057ae0e2c9SDimitry Andric if (isUndef() && isUse()) { 306dff0c46cSDimitry Andric if (NeedComma) OS << ','; 307f22ef01cSRoman Divacky OS << "undef"; 308dff0c46cSDimitry Andric NeedComma = true; 309dff0c46cSDimitry Andric } 310dff0c46cSDimitry Andric if (isInternalRead()) { 311dff0c46cSDimitry Andric if (NeedComma) OS << ','; 312dff0c46cSDimitry Andric OS << "internal"; 313dff0c46cSDimitry Andric NeedComma = true; 314f22ef01cSRoman Divacky } 3153861d79fSDimitry Andric if (isTied()) { 3163861d79fSDimitry Andric if (NeedComma) OS << ','; 3173861d79fSDimitry Andric OS << "tied"; 3183861d79fSDimitry Andric if (TiedTo != 15) 3193861d79fSDimitry Andric OS << unsigned(TiedTo - 1); 320f22ef01cSRoman Divacky } 321f22ef01cSRoman Divacky OS << '>'; 322f22ef01cSRoman Divacky } 323f22ef01cSRoman Divacky break; 324f22ef01cSRoman Divacky case MachineOperand::MO_Immediate: 325f22ef01cSRoman Divacky OS << getImm(); 326f22ef01cSRoman Divacky break; 32717a519f9SDimitry Andric case MachineOperand::MO_CImmediate: 32817a519f9SDimitry Andric getCImm()->getValue().print(OS, false); 32917a519f9SDimitry Andric break; 330f22ef01cSRoman Divacky case MachineOperand::MO_FPImmediate: 331f22ef01cSRoman Divacky if (getFPImm()->getType()->isFloatTy()) 332f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToFloat(); 333f22ef01cSRoman Divacky else 334f22ef01cSRoman Divacky OS << getFPImm()->getValueAPF().convertToDouble(); 335f22ef01cSRoman Divacky break; 336f22ef01cSRoman Divacky case MachineOperand::MO_MachineBasicBlock: 337f22ef01cSRoman Divacky OS << "<BB#" << getMBB()->getNumber() << ">"; 338f22ef01cSRoman Divacky break; 339f22ef01cSRoman Divacky case MachineOperand::MO_FrameIndex: 340f22ef01cSRoman Divacky OS << "<fi#" << getIndex() << '>'; 341f22ef01cSRoman Divacky break; 342f22ef01cSRoman Divacky case MachineOperand::MO_ConstantPoolIndex: 343f22ef01cSRoman Divacky OS << "<cp#" << getIndex(); 344f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 345f22ef01cSRoman Divacky OS << '>'; 346f22ef01cSRoman Divacky break; 3477ae0e2c9SDimitry Andric case MachineOperand::MO_TargetIndex: 3487ae0e2c9SDimitry Andric OS << "<ti#" << getIndex(); 3497ae0e2c9SDimitry Andric if (getOffset()) OS << "+" << getOffset(); 3507ae0e2c9SDimitry Andric OS << '>'; 3517ae0e2c9SDimitry Andric break; 352f22ef01cSRoman Divacky case MachineOperand::MO_JumpTableIndex: 353f22ef01cSRoman Divacky OS << "<jt#" << getIndex() << '>'; 354f22ef01cSRoman Divacky break; 355f22ef01cSRoman Divacky case MachineOperand::MO_GlobalAddress: 356f22ef01cSRoman Divacky OS << "<ga:"; 35791bc56edSDimitry Andric getGlobal()->printAsOperand(OS, /*PrintType=*/false); 358f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 359f22ef01cSRoman Divacky OS << '>'; 360f22ef01cSRoman Divacky break; 361f22ef01cSRoman Divacky case MachineOperand::MO_ExternalSymbol: 362f22ef01cSRoman Divacky OS << "<es:" << getSymbolName(); 363f22ef01cSRoman Divacky if (getOffset()) OS << "+" << getOffset(); 364f22ef01cSRoman Divacky OS << '>'; 365f22ef01cSRoman Divacky break; 366f22ef01cSRoman Divacky case MachineOperand::MO_BlockAddress: 367f22ef01cSRoman Divacky OS << '<'; 36891bc56edSDimitry Andric getBlockAddress()->printAsOperand(OS, /*PrintType=*/false); 3693861d79fSDimitry Andric if (getOffset()) OS << "+" << getOffset(); 370f22ef01cSRoman Divacky OS << '>'; 371f22ef01cSRoman Divacky break; 372dff0c46cSDimitry Andric case MachineOperand::MO_RegisterMask: 373dff0c46cSDimitry Andric OS << "<regmask>"; 374dff0c46cSDimitry Andric break; 37591bc56edSDimitry Andric case MachineOperand::MO_RegisterLiveOut: 37691bc56edSDimitry Andric OS << "<regliveout>"; 37791bc56edSDimitry Andric break; 378f22ef01cSRoman Divacky case MachineOperand::MO_Metadata: 379f22ef01cSRoman Divacky OS << '<'; 38091bc56edSDimitry Andric getMetadata()->printAsOperand(OS, /*PrintType=*/false); 381f22ef01cSRoman Divacky OS << '>'; 382f22ef01cSRoman Divacky break; 383f22ef01cSRoman Divacky case MachineOperand::MO_MCSymbol: 384f22ef01cSRoman Divacky OS << "<MCSym=" << *getMCSymbol() << '>'; 385f22ef01cSRoman Divacky break; 38691bc56edSDimitry Andric case MachineOperand::MO_CFIIndex: 38791bc56edSDimitry Andric OS << "<call frame instruction>"; 38891bc56edSDimitry Andric break; 389f22ef01cSRoman Divacky } 390f22ef01cSRoman Divacky 391f22ef01cSRoman Divacky if (unsigned TF = getTargetFlags()) 392f22ef01cSRoman Divacky OS << "[TF=" << TF << ']'; 393f22ef01cSRoman Divacky } 394f22ef01cSRoman Divacky 395f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 396f22ef01cSRoman Divacky // MachineMemOperand Implementation 397f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 398f22ef01cSRoman Divacky 3992754fe60SDimitry Andric /// getAddrSpace - Return the LLVM IR address space number that this pointer 4002754fe60SDimitry Andric /// points into. 4012754fe60SDimitry Andric unsigned MachinePointerInfo::getAddrSpace() const { 40291bc56edSDimitry Andric if (V.isNull() || V.is<const PseudoSourceValue*>()) return 0; 40391bc56edSDimitry Andric return cast<PointerType>(V.get<const Value*>()->getType())->getAddressSpace(); 4042754fe60SDimitry Andric } 4052754fe60SDimitry Andric 4062754fe60SDimitry Andric /// getConstantPool - Return a MachinePointerInfo record that refers to the 4072754fe60SDimitry Andric /// constant pool. 4082754fe60SDimitry Andric MachinePointerInfo MachinePointerInfo::getConstantPool() { 4092754fe60SDimitry Andric return MachinePointerInfo(PseudoSourceValue::getConstantPool()); 4102754fe60SDimitry Andric } 4112754fe60SDimitry Andric 4122754fe60SDimitry Andric /// getFixedStack - Return a MachinePointerInfo record that refers to the 4132754fe60SDimitry Andric /// the specified FrameIndex. 4142754fe60SDimitry Andric MachinePointerInfo MachinePointerInfo::getFixedStack(int FI, int64_t offset) { 4152754fe60SDimitry Andric return MachinePointerInfo(PseudoSourceValue::getFixedStack(FI), offset); 4162754fe60SDimitry Andric } 4172754fe60SDimitry Andric 4182754fe60SDimitry Andric MachinePointerInfo MachinePointerInfo::getJumpTable() { 4192754fe60SDimitry Andric return MachinePointerInfo(PseudoSourceValue::getJumpTable()); 4202754fe60SDimitry Andric } 4212754fe60SDimitry Andric 4222754fe60SDimitry Andric MachinePointerInfo MachinePointerInfo::getGOT() { 4232754fe60SDimitry Andric return MachinePointerInfo(PseudoSourceValue::getGOT()); 4242754fe60SDimitry Andric } 4252754fe60SDimitry Andric 4262754fe60SDimitry Andric MachinePointerInfo MachinePointerInfo::getStack(int64_t Offset) { 4272754fe60SDimitry Andric return MachinePointerInfo(PseudoSourceValue::getStack(), Offset); 4282754fe60SDimitry Andric } 4292754fe60SDimitry Andric 4302754fe60SDimitry Andric MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, unsigned f, 4312754fe60SDimitry Andric uint64_t s, unsigned int a, 432dff0c46cSDimitry Andric const MDNode *TBAAInfo, 433dff0c46cSDimitry Andric const MDNode *Ranges) 4342754fe60SDimitry Andric : PtrInfo(ptrinfo), Size(s), 4352754fe60SDimitry Andric Flags((f & ((1 << MOMaxBits) - 1)) | ((Log2_32(a) + 1) << MOMaxBits)), 436dff0c46cSDimitry Andric TBAAInfo(TBAAInfo), Ranges(Ranges) { 43791bc56edSDimitry Andric assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue*>() || 43891bc56edSDimitry Andric isa<PointerType>(PtrInfo.V.get<const Value*>()->getType())) && 4392754fe60SDimitry Andric "invalid pointer value"); 440f22ef01cSRoman Divacky assert(getBaseAlignment() == a && "Alignment is not a power of 2!"); 441f22ef01cSRoman Divacky assert((isLoad() || isStore()) && "Not a load/store!"); 442f22ef01cSRoman Divacky } 443f22ef01cSRoman Divacky 444f22ef01cSRoman Divacky /// Profile - Gather unique data for the object. 445f22ef01cSRoman Divacky /// 446f22ef01cSRoman Divacky void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { 4472754fe60SDimitry Andric ID.AddInteger(getOffset()); 448f22ef01cSRoman Divacky ID.AddInteger(Size); 44991bc56edSDimitry Andric ID.AddPointer(getOpaqueValue()); 450f22ef01cSRoman Divacky ID.AddInteger(Flags); 451f22ef01cSRoman Divacky } 452f22ef01cSRoman Divacky 453f22ef01cSRoman Divacky void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { 454f22ef01cSRoman Divacky // The Value and Offset may differ due to CSE. But the flags and size 455f22ef01cSRoman Divacky // should be the same. 456f22ef01cSRoman Divacky assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); 457f22ef01cSRoman Divacky assert(MMO->getSize() == getSize() && "Size mismatch!"); 458f22ef01cSRoman Divacky 459f22ef01cSRoman Divacky if (MMO->getBaseAlignment() >= getBaseAlignment()) { 460f22ef01cSRoman Divacky // Update the alignment value. 461f22ef01cSRoman Divacky Flags = (Flags & ((1 << MOMaxBits) - 1)) | 462f22ef01cSRoman Divacky ((Log2_32(MMO->getBaseAlignment()) + 1) << MOMaxBits); 463f22ef01cSRoman Divacky // Also update the base and offset, because the new alignment may 464f22ef01cSRoman Divacky // not be applicable with the old ones. 4652754fe60SDimitry Andric PtrInfo = MMO->PtrInfo; 466f22ef01cSRoman Divacky } 467f22ef01cSRoman Divacky } 468f22ef01cSRoman Divacky 469f22ef01cSRoman Divacky /// getAlignment - Return the minimum known alignment in bytes of the 470f22ef01cSRoman Divacky /// actual memory reference. 471f22ef01cSRoman Divacky uint64_t MachineMemOperand::getAlignment() const { 472f22ef01cSRoman Divacky return MinAlign(getBaseAlignment(), getOffset()); 473f22ef01cSRoman Divacky } 474f22ef01cSRoman Divacky 475f22ef01cSRoman Divacky raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) { 476f22ef01cSRoman Divacky assert((MMO.isLoad() || MMO.isStore()) && 477f22ef01cSRoman Divacky "SV has to be a load, store or both."); 478f22ef01cSRoman Divacky 479f22ef01cSRoman Divacky if (MMO.isVolatile()) 480f22ef01cSRoman Divacky OS << "Volatile "; 481f22ef01cSRoman Divacky 482f22ef01cSRoman Divacky if (MMO.isLoad()) 483f22ef01cSRoman Divacky OS << "LD"; 484f22ef01cSRoman Divacky if (MMO.isStore()) 485f22ef01cSRoman Divacky OS << "ST"; 486f22ef01cSRoman Divacky OS << MMO.getSize(); 487f22ef01cSRoman Divacky 488f22ef01cSRoman Divacky // Print the address information. 489f22ef01cSRoman Divacky OS << "["; 49091bc56edSDimitry Andric if (const Value *V = MMO.getValue()) 49191bc56edSDimitry Andric V->printAsOperand(OS, /*PrintType=*/false); 49291bc56edSDimitry Andric else if (const PseudoSourceValue *PSV = MMO.getPseudoValue()) 49391bc56edSDimitry Andric PSV->printCustom(OS); 494f22ef01cSRoman Divacky else 49591bc56edSDimitry Andric OS << "<unknown>"; 49691bc56edSDimitry Andric 49791bc56edSDimitry Andric unsigned AS = MMO.getAddrSpace(); 49891bc56edSDimitry Andric if (AS != 0) 49991bc56edSDimitry Andric OS << "(addrspace=" << AS << ')'; 500f22ef01cSRoman Divacky 501f22ef01cSRoman Divacky // If the alignment of the memory reference itself differs from the alignment 502f22ef01cSRoman Divacky // of the base pointer, print the base alignment explicitly, next to the base 503f22ef01cSRoman Divacky // pointer. 504f22ef01cSRoman Divacky if (MMO.getBaseAlignment() != MMO.getAlignment()) 505f22ef01cSRoman Divacky OS << "(align=" << MMO.getBaseAlignment() << ")"; 506f22ef01cSRoman Divacky 507f22ef01cSRoman Divacky if (MMO.getOffset() != 0) 508f22ef01cSRoman Divacky OS << "+" << MMO.getOffset(); 509f22ef01cSRoman Divacky OS << "]"; 510f22ef01cSRoman Divacky 511f22ef01cSRoman Divacky // Print the alignment of the reference. 512f22ef01cSRoman Divacky if (MMO.getBaseAlignment() != MMO.getAlignment() || 513f22ef01cSRoman Divacky MMO.getBaseAlignment() != MMO.getSize()) 514f22ef01cSRoman Divacky OS << "(align=" << MMO.getAlignment() << ")"; 515f22ef01cSRoman Divacky 5162754fe60SDimitry Andric // Print TBAA info. 5172754fe60SDimitry Andric if (const MDNode *TBAAInfo = MMO.getTBAAInfo()) { 5182754fe60SDimitry Andric OS << "(tbaa="; 5192754fe60SDimitry Andric if (TBAAInfo->getNumOperands() > 0) 52091bc56edSDimitry Andric TBAAInfo->getOperand(0)->printAsOperand(OS, /*PrintType=*/false); 5212754fe60SDimitry Andric else 5222754fe60SDimitry Andric OS << "<unknown>"; 5232754fe60SDimitry Andric OS << ")"; 5242754fe60SDimitry Andric } 5252754fe60SDimitry Andric 5263b0f4066SDimitry Andric // Print nontemporal info. 5273b0f4066SDimitry Andric if (MMO.isNonTemporal()) 5283b0f4066SDimitry Andric OS << "(nontemporal)"; 5293b0f4066SDimitry Andric 530f22ef01cSRoman Divacky return OS; 531f22ef01cSRoman Divacky } 532f22ef01cSRoman Divacky 533f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 534f22ef01cSRoman Divacky // MachineInstr Implementation 535f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 536f22ef01cSRoman Divacky 537139f7f9bSDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { 53817a519f9SDimitry Andric if (MCID->ImplicitDefs) 539dff0c46cSDimitry Andric for (const uint16_t *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; ++ImpDefs) 540139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true)); 54117a519f9SDimitry Andric if (MCID->ImplicitUses) 542dff0c46cSDimitry Andric for (const uint16_t *ImpUses = MCID->getImplicitUses(); *ImpUses; ++ImpUses) 543139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true)); 544f22ef01cSRoman Divacky } 545f22ef01cSRoman Divacky 546f22ef01cSRoman Divacky /// MachineInstr ctor - This constructor creates a MachineInstr and adds the 547f22ef01cSRoman Divacky /// implicit operands. It reserves space for the number of operands specified by 54817a519f9SDimitry Andric /// the MCInstrDesc. 549139f7f9bSDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid, 550139f7f9bSDimitry Andric const DebugLoc dl, bool NoImp) 55191bc56edSDimitry Andric : MCID(&tid), Parent(nullptr), Operands(nullptr), NumOperands(0), 552139f7f9bSDimitry Andric Flags(0), AsmPrinterFlags(0), 55391bc56edSDimitry Andric NumMemRefs(0), MemRefs(nullptr), debugLoc(dl) { 554139f7f9bSDimitry Andric // Reserve space for the expected number of operands. 555139f7f9bSDimitry Andric if (unsigned NumOps = MCID->getNumOperands() + 556139f7f9bSDimitry Andric MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) { 557139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(NumOps); 558139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 559f22ef01cSRoman Divacky } 560f22ef01cSRoman Divacky 561139f7f9bSDimitry Andric if (!NoImp) 562139f7f9bSDimitry Andric addImplicitDefUseOperands(MF); 563f22ef01cSRoman Divacky } 564f22ef01cSRoman Divacky 565f22ef01cSRoman Divacky /// MachineInstr ctor - Copies MachineInstr arg exactly 566f22ef01cSRoman Divacky /// 567f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) 56891bc56edSDimitry Andric : MCID(&MI.getDesc()), Parent(nullptr), Operands(nullptr), NumOperands(0), 569139f7f9bSDimitry Andric Flags(0), AsmPrinterFlags(0), 570dff0c46cSDimitry Andric NumMemRefs(MI.NumMemRefs), MemRefs(MI.MemRefs), 571139f7f9bSDimitry Andric debugLoc(MI.getDebugLoc()) { 572139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(MI.getNumOperands()); 573139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 574f22ef01cSRoman Divacky 575139f7f9bSDimitry Andric // Copy operands. 576f22ef01cSRoman Divacky for (unsigned i = 0; i != MI.getNumOperands(); ++i) 577139f7f9bSDimitry Andric addOperand(MF, MI.getOperand(i)); 578f22ef01cSRoman Divacky 579139f7f9bSDimitry Andric // Copy all the sensible flags. 580139f7f9bSDimitry Andric setFlags(MI.Flags); 581f22ef01cSRoman Divacky } 582f22ef01cSRoman Divacky 583f22ef01cSRoman Divacky /// getRegInfo - If this instruction is embedded into a MachineFunction, 584f22ef01cSRoman Divacky /// return the MachineRegisterInfo object for the current function, otherwise 585f22ef01cSRoman Divacky /// return null. 586f22ef01cSRoman Divacky MachineRegisterInfo *MachineInstr::getRegInfo() { 587f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = getParent()) 588f22ef01cSRoman Divacky return &MBB->getParent()->getRegInfo(); 58991bc56edSDimitry Andric return nullptr; 590f22ef01cSRoman Divacky } 591f22ef01cSRoman Divacky 592f22ef01cSRoman Divacky /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in 593f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 594f22ef01cSRoman Divacky /// operands already be on their use lists. 5957ae0e2c9SDimitry Andric void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) { 596139f7f9bSDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 597f22ef01cSRoman Divacky if (Operands[i].isReg()) 5987ae0e2c9SDimitry Andric MRI.removeRegOperandFromUseList(&Operands[i]); 599f22ef01cSRoman Divacky } 600f22ef01cSRoman Divacky 601f22ef01cSRoman Divacky /// AddRegOperandsToUseLists - Add all of the register operands in 602f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 603f22ef01cSRoman Divacky /// operands not be on their use lists yet. 6047ae0e2c9SDimitry Andric void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) { 605139f7f9bSDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 606f22ef01cSRoman Divacky if (Operands[i].isReg()) 6077ae0e2c9SDimitry Andric MRI.addRegOperandToUseList(&Operands[i]); 608f22ef01cSRoman Divacky } 609f22ef01cSRoman Divacky 610139f7f9bSDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) { 611139f7f9bSDimitry Andric MachineBasicBlock *MBB = getParent(); 612139f7f9bSDimitry Andric assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs"); 613139f7f9bSDimitry Andric MachineFunction *MF = MBB->getParent(); 614139f7f9bSDimitry Andric assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs"); 615139f7f9bSDimitry Andric addOperand(*MF, Op); 616139f7f9bSDimitry Andric } 617139f7f9bSDimitry Andric 618139f7f9bSDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping 619139f7f9bSDimitry Andric /// ranges. If MRI is non-null also update use-def chains. 620139f7f9bSDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src, 621139f7f9bSDimitry Andric unsigned NumOps, MachineRegisterInfo *MRI) { 622139f7f9bSDimitry Andric if (MRI) 623139f7f9bSDimitry Andric return MRI->moveOperands(Dst, Src, NumOps); 624139f7f9bSDimitry Andric 625139f7f9bSDimitry Andric // Here it would be convenient to call memmove, so that isn't allowed because 626139f7f9bSDimitry Andric // MachineOperand has a constructor and so isn't a POD type. 627139f7f9bSDimitry Andric if (Dst < Src) 628139f7f9bSDimitry Andric for (unsigned i = 0; i != NumOps; ++i) 629139f7f9bSDimitry Andric new (Dst + i) MachineOperand(Src[i]); 630139f7f9bSDimitry Andric else 631139f7f9bSDimitry Andric for (unsigned i = NumOps; i ; --i) 632139f7f9bSDimitry Andric new (Dst + i - 1) MachineOperand(Src[i - 1]); 633139f7f9bSDimitry Andric } 634139f7f9bSDimitry Andric 635f22ef01cSRoman Divacky /// addOperand - Add the specified operand to the instruction. If it is an 636f22ef01cSRoman Divacky /// implicit operand, it is added to the end of the operand list. If it is 637f22ef01cSRoman Divacky /// an explicit operand it is added at the end of the explicit operand list 638f22ef01cSRoman Divacky /// (before the first implicit operand). 639139f7f9bSDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { 6406122f3e6SDimitry Andric assert(MCID && "Cannot add operands before providing an instr descriptor"); 641f22ef01cSRoman Divacky 642139f7f9bSDimitry Andric // Check if we're adding one of our existing operands. 643139f7f9bSDimitry Andric if (&Op >= Operands && &Op < Operands + NumOperands) { 644139f7f9bSDimitry Andric // This is unusual: MI->addOperand(MI->getOperand(i)). 645139f7f9bSDimitry Andric // If adding Op requires reallocating or moving existing operands around, 646139f7f9bSDimitry Andric // the Op reference could go stale. Support it by copying Op. 647139f7f9bSDimitry Andric MachineOperand CopyOp(Op); 648139f7f9bSDimitry Andric return addOperand(MF, CopyOp); 649139f7f9bSDimitry Andric } 650f22ef01cSRoman Divacky 6516122f3e6SDimitry Andric // Find the insert location for the new operand. Implicit registers go at 652139f7f9bSDimitry Andric // the end, everything else goes before the implicit regs. 653139f7f9bSDimitry Andric // 6546122f3e6SDimitry Andric // FIXME: Allow mixed explicit and implicit operands on inline asm. 6556122f3e6SDimitry Andric // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as 6566122f3e6SDimitry Andric // implicit-defs, but they must not be moved around. See the FIXME in 6576122f3e6SDimitry Andric // InstrEmitter.cpp. 658139f7f9bSDimitry Andric unsigned OpNo = getNumOperands(); 659139f7f9bSDimitry Andric bool isImpReg = Op.isReg() && Op.isImplicit(); 6606122f3e6SDimitry Andric if (!isImpReg && !isInlineAsm()) { 6616122f3e6SDimitry Andric while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) { 6626122f3e6SDimitry Andric --OpNo; 6633861d79fSDimitry Andric assert(!Operands[OpNo].isTied() && "Cannot move tied operands"); 664f22ef01cSRoman Divacky } 665f22ef01cSRoman Divacky } 666f22ef01cSRoman Divacky 667f785676fSDimitry Andric #ifndef NDEBUG 668f785676fSDimitry Andric bool isMetaDataOp = Op.getType() == MachineOperand::MO_Metadata; 6696122f3e6SDimitry Andric // OpNo now points as the desired insertion point. Unless this is a variadic 6706122f3e6SDimitry Andric // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). 6717ae0e2c9SDimitry Andric // RegMask operands go between the explicit and implicit operands. 6727ae0e2c9SDimitry Andric assert((isImpReg || Op.isRegMask() || MCID->isVariadic() || 673f785676fSDimitry Andric OpNo < MCID->getNumOperands() || isMetaDataOp) && 6746122f3e6SDimitry Andric "Trying to add an operand to a machine instr that is already done!"); 675f785676fSDimitry Andric #endif 676f22ef01cSRoman Divacky 677139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 678f22ef01cSRoman Divacky 679139f7f9bSDimitry Andric // Determine if the Operands array needs to be reallocated. 680139f7f9bSDimitry Andric // Save the old capacity and operand array. 681139f7f9bSDimitry Andric OperandCapacity OldCap = CapOperands; 682139f7f9bSDimitry Andric MachineOperand *OldOperands = Operands; 683139f7f9bSDimitry Andric if (!OldOperands || OldCap.getSize() == getNumOperands()) { 684139f7f9bSDimitry Andric CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1); 685139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 686139f7f9bSDimitry Andric // Move the operands before the insertion point. 687139f7f9bSDimitry Andric if (OpNo) 688139f7f9bSDimitry Andric moveOperands(Operands, OldOperands, OpNo, MRI); 689139f7f9bSDimitry Andric } 690f22ef01cSRoman Divacky 691139f7f9bSDimitry Andric // Move the operands following the insertion point. 692139f7f9bSDimitry Andric if (OpNo != NumOperands) 693139f7f9bSDimitry Andric moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo, 694139f7f9bSDimitry Andric MRI); 695139f7f9bSDimitry Andric ++NumOperands; 6966122f3e6SDimitry Andric 697139f7f9bSDimitry Andric // Deallocate the old operand array. 698139f7f9bSDimitry Andric if (OldOperands != Operands && OldOperands) 699139f7f9bSDimitry Andric MF.deallocateOperandArray(OldCap, OldOperands); 700139f7f9bSDimitry Andric 701139f7f9bSDimitry Andric // Copy Op into place. It still needs to be inserted into the MRI use lists. 702139f7f9bSDimitry Andric MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op); 703139f7f9bSDimitry Andric NewMO->ParentMI = this; 704139f7f9bSDimitry Andric 705139f7f9bSDimitry Andric // When adding a register operand, tell MRI about it. 706139f7f9bSDimitry Andric if (NewMO->isReg()) { 7077ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false, regardless of Op's status. 70891bc56edSDimitry Andric NewMO->Contents.Reg.Prev = nullptr; 7093861d79fSDimitry Andric // Ignore existing ties. This is not a property that can be copied. 710139f7f9bSDimitry Andric NewMO->TiedTo = 0; 711139f7f9bSDimitry Andric // Add the new operand to MRI, but only for instructions in an MBB. 712139f7f9bSDimitry Andric if (MRI) 713139f7f9bSDimitry Andric MRI->addRegOperandToUseList(NewMO); 7143861d79fSDimitry Andric // The MCID operand information isn't accurate until we start adding 7153861d79fSDimitry Andric // explicit operands. The implicit operands are added first, then the 7163861d79fSDimitry Andric // explicits are inserted before them. 7173861d79fSDimitry Andric if (!isImpReg) { 7183861d79fSDimitry Andric // Tie uses to defs as indicated in MCInstrDesc. 719139f7f9bSDimitry Andric if (NewMO->isUse()) { 7203861d79fSDimitry Andric int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO); 7213861d79fSDimitry Andric if (DefIdx != -1) 7223861d79fSDimitry Andric tieOperands(DefIdx, OpNo); 7233861d79fSDimitry Andric } 7246122f3e6SDimitry Andric // If the register operand is flagged as early, mark the operand as such. 72517a519f9SDimitry Andric if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) 726139f7f9bSDimitry Andric NewMO->setIsEarlyClobber(true); 727f22ef01cSRoman Divacky } 728f22ef01cSRoman Divacky } 729f22ef01cSRoman Divacky } 730f22ef01cSRoman Divacky 731f22ef01cSRoman Divacky /// RemoveOperand - Erase an operand from an instruction, leaving it with one 732f22ef01cSRoman Divacky /// fewer operand than it started with. 733f22ef01cSRoman Divacky /// 734f22ef01cSRoman Divacky void MachineInstr::RemoveOperand(unsigned OpNo) { 735139f7f9bSDimitry Andric assert(OpNo < getNumOperands() && "Invalid operand number"); 7363861d79fSDimitry Andric untieRegOperand(OpNo); 737f22ef01cSRoman Divacky 7383861d79fSDimitry Andric #ifndef NDEBUG 7393861d79fSDimitry Andric // Moving tied operands would break the ties. 740139f7f9bSDimitry Andric for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i) 7413861d79fSDimitry Andric if (Operands[i].isReg()) 7423861d79fSDimitry Andric assert(!Operands[i].isTied() && "Cannot move tied operands"); 7433861d79fSDimitry Andric #endif 7443861d79fSDimitry Andric 745139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 746139f7f9bSDimitry Andric if (MRI && Operands[OpNo].isReg()) 747139f7f9bSDimitry Andric MRI->removeRegOperandFromUseList(Operands + OpNo); 748f22ef01cSRoman Divacky 749139f7f9bSDimitry Andric // Don't call the MachineOperand destructor. A lot of this code depends on 750139f7f9bSDimitry Andric // MachineOperand having a trivial destructor anyway, and adding a call here 751139f7f9bSDimitry Andric // wouldn't make it 'destructor-correct'. 752139f7f9bSDimitry Andric 753139f7f9bSDimitry Andric if (unsigned N = NumOperands - 1 - OpNo) 754139f7f9bSDimitry Andric moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI); 755139f7f9bSDimitry Andric --NumOperands; 756f22ef01cSRoman Divacky } 757f22ef01cSRoman Divacky 758f22ef01cSRoman Divacky /// addMemOperand - Add a MachineMemOperand to the machine instruction. 759f22ef01cSRoman Divacky /// This function should be used only occasionally. The setMemRefs function 760f22ef01cSRoman Divacky /// is the primary method for setting up a MachineInstr's MemRefs list. 761f22ef01cSRoman Divacky void MachineInstr::addMemOperand(MachineFunction &MF, 762f22ef01cSRoman Divacky MachineMemOperand *MO) { 763f22ef01cSRoman Divacky mmo_iterator OldMemRefs = MemRefs; 764139f7f9bSDimitry Andric unsigned OldNumMemRefs = NumMemRefs; 765f22ef01cSRoman Divacky 766139f7f9bSDimitry Andric unsigned NewNum = NumMemRefs + 1; 767f22ef01cSRoman Divacky mmo_iterator NewMemRefs = MF.allocateMemRefsArray(NewNum); 768f22ef01cSRoman Divacky 769dff0c46cSDimitry Andric std::copy(OldMemRefs, OldMemRefs + OldNumMemRefs, NewMemRefs); 770f22ef01cSRoman Divacky NewMemRefs[NewNum - 1] = MO; 771139f7f9bSDimitry Andric setMemRefs(NewMemRefs, NewMemRefs + NewNum); 772dff0c46cSDimitry Andric } 773dff0c46cSDimitry Andric 774dff0c46cSDimitry Andric bool MachineInstr::hasPropertyInBundle(unsigned Mask, QueryType Type) const { 775139f7f9bSDimitry Andric assert(!isBundledWithPred() && "Must be called on bundle header"); 776139f7f9bSDimitry Andric for (MachineBasicBlock::const_instr_iterator MII = this;; ++MII) { 777dff0c46cSDimitry Andric if (MII->getDesc().getFlags() & Mask) { 778dff0c46cSDimitry Andric if (Type == AnyInBundle) 779dff0c46cSDimitry Andric return true; 780dff0c46cSDimitry Andric } else { 781139f7f9bSDimitry Andric if (Type == AllInBundle && !MII->isBundle()) 782dff0c46cSDimitry Andric return false; 783dff0c46cSDimitry Andric } 784139f7f9bSDimitry Andric // This was the last instruction in the bundle. 785139f7f9bSDimitry Andric if (!MII->isBundledWithSucc()) 786dff0c46cSDimitry Andric return Type == AllInBundle; 787f22ef01cSRoman Divacky } 788139f7f9bSDimitry Andric } 789f22ef01cSRoman Divacky 790f22ef01cSRoman Divacky bool MachineInstr::isIdenticalTo(const MachineInstr *Other, 791f22ef01cSRoman Divacky MICheckType Check) const { 792f22ef01cSRoman Divacky // If opcodes or number of operands are not the same then the two 793f22ef01cSRoman Divacky // instructions are obviously not identical. 794f22ef01cSRoman Divacky if (Other->getOpcode() != getOpcode() || 795f22ef01cSRoman Divacky Other->getNumOperands() != getNumOperands()) 796f22ef01cSRoman Divacky return false; 797f22ef01cSRoman Divacky 798dff0c46cSDimitry Andric if (isBundle()) { 799dff0c46cSDimitry Andric // Both instructions are bundles, compare MIs inside the bundle. 800dff0c46cSDimitry Andric MachineBasicBlock::const_instr_iterator I1 = *this; 801dff0c46cSDimitry Andric MachineBasicBlock::const_instr_iterator E1 = getParent()->instr_end(); 802dff0c46cSDimitry Andric MachineBasicBlock::const_instr_iterator I2 = *Other; 803dff0c46cSDimitry Andric MachineBasicBlock::const_instr_iterator E2= Other->getParent()->instr_end(); 804dff0c46cSDimitry Andric while (++I1 != E1 && I1->isInsideBundle()) { 805dff0c46cSDimitry Andric ++I2; 806dff0c46cSDimitry Andric if (I2 == E2 || !I2->isInsideBundle() || !I1->isIdenticalTo(I2, Check)) 807dff0c46cSDimitry Andric return false; 808dff0c46cSDimitry Andric } 809dff0c46cSDimitry Andric } 810dff0c46cSDimitry Andric 811f22ef01cSRoman Divacky // Check operands to make sure they match. 812f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 813f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 814f22ef01cSRoman Divacky const MachineOperand &OMO = Other->getOperand(i); 815bd5abe19SDimitry Andric if (!MO.isReg()) { 816bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 817bd5abe19SDimitry Andric return false; 818bd5abe19SDimitry Andric continue; 819bd5abe19SDimitry Andric } 820bd5abe19SDimitry Andric 821f22ef01cSRoman Divacky // Clients may or may not want to ignore defs when testing for equality. 822f22ef01cSRoman Divacky // For example, machine CSE pass only cares about finding common 823f22ef01cSRoman Divacky // subexpressions, so it's safe to ignore virtual register defs. 824bd5abe19SDimitry Andric if (MO.isDef()) { 825f22ef01cSRoman Divacky if (Check == IgnoreDefs) 826f22ef01cSRoman Divacky continue; 827bd5abe19SDimitry Andric else if (Check == IgnoreVRegDefs) { 828f22ef01cSRoman Divacky if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) || 829f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(OMO.getReg())) 830f22ef01cSRoman Divacky if (MO.getReg() != OMO.getReg()) 831f22ef01cSRoman Divacky return false; 832bd5abe19SDimitry Andric } else { 833bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 834f22ef01cSRoman Divacky return false; 835bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isDead() != OMO.isDead()) 836bd5abe19SDimitry Andric return false; 837bd5abe19SDimitry Andric } 838bd5abe19SDimitry Andric } else { 839bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 840bd5abe19SDimitry Andric return false; 841bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isKill() != OMO.isKill()) 842bd5abe19SDimitry Andric return false; 843bd5abe19SDimitry Andric } 844f22ef01cSRoman Divacky } 84517a519f9SDimitry Andric // If DebugLoc does not match then two dbg.values are not identical. 84617a519f9SDimitry Andric if (isDebugValue()) 84717a519f9SDimitry Andric if (!getDebugLoc().isUnknown() && !Other->getDebugLoc().isUnknown() 84817a519f9SDimitry Andric && getDebugLoc() != Other->getDebugLoc()) 84917a519f9SDimitry Andric return false; 850f22ef01cSRoman Divacky return true; 851f22ef01cSRoman Divacky } 852f22ef01cSRoman Divacky 853f22ef01cSRoman Divacky MachineInstr *MachineInstr::removeFromParent() { 854f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 855139f7f9bSDimitry Andric return getParent()->remove(this); 856f22ef01cSRoman Divacky } 857f22ef01cSRoman Divacky 858139f7f9bSDimitry Andric MachineInstr *MachineInstr::removeFromBundle() { 859139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 860139f7f9bSDimitry Andric return getParent()->remove_instr(this); 861139f7f9bSDimitry Andric } 862f22ef01cSRoman Divacky 863f22ef01cSRoman Divacky void MachineInstr::eraseFromParent() { 864f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 865139f7f9bSDimitry Andric getParent()->erase(this); 866f22ef01cSRoman Divacky } 867f22ef01cSRoman Divacky 868139f7f9bSDimitry Andric void MachineInstr::eraseFromBundle() { 869139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 870139f7f9bSDimitry Andric getParent()->erase_instr(this); 871139f7f9bSDimitry Andric } 872f22ef01cSRoman Divacky 873f22ef01cSRoman Divacky /// getNumExplicitOperands - Returns the number of non-implicit operands. 874f22ef01cSRoman Divacky /// 875f22ef01cSRoman Divacky unsigned MachineInstr::getNumExplicitOperands() const { 87617a519f9SDimitry Andric unsigned NumOperands = MCID->getNumOperands(); 87717a519f9SDimitry Andric if (!MCID->isVariadic()) 878f22ef01cSRoman Divacky return NumOperands; 879f22ef01cSRoman Divacky 880f22ef01cSRoman Divacky for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) { 881f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 882f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isImplicit()) 883f22ef01cSRoman Divacky NumOperands++; 884f22ef01cSRoman Divacky } 885f22ef01cSRoman Divacky return NumOperands; 886f22ef01cSRoman Divacky } 887f22ef01cSRoman Divacky 888139f7f9bSDimitry Andric void MachineInstr::bundleWithPred() { 889139f7f9bSDimitry Andric assert(!isBundledWithPred() && "MI is already bundled with its predecessor"); 890139f7f9bSDimitry Andric setFlag(BundledPred); 891139f7f9bSDimitry Andric MachineBasicBlock::instr_iterator Pred = this; 892139f7f9bSDimitry Andric --Pred; 893139f7f9bSDimitry Andric assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 894139f7f9bSDimitry Andric Pred->setFlag(BundledSucc); 895139f7f9bSDimitry Andric } 896139f7f9bSDimitry Andric 897139f7f9bSDimitry Andric void MachineInstr::bundleWithSucc() { 898139f7f9bSDimitry Andric assert(!isBundledWithSucc() && "MI is already bundled with its successor"); 899139f7f9bSDimitry Andric setFlag(BundledSucc); 900139f7f9bSDimitry Andric MachineBasicBlock::instr_iterator Succ = this; 901139f7f9bSDimitry Andric ++Succ; 902139f7f9bSDimitry Andric assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags"); 903139f7f9bSDimitry Andric Succ->setFlag(BundledPred); 904139f7f9bSDimitry Andric } 905139f7f9bSDimitry Andric 906139f7f9bSDimitry Andric void MachineInstr::unbundleFromPred() { 907139f7f9bSDimitry Andric assert(isBundledWithPred() && "MI isn't bundled with its predecessor"); 908139f7f9bSDimitry Andric clearFlag(BundledPred); 909139f7f9bSDimitry Andric MachineBasicBlock::instr_iterator Pred = this; 910139f7f9bSDimitry Andric --Pred; 911139f7f9bSDimitry Andric assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 912139f7f9bSDimitry Andric Pred->clearFlag(BundledSucc); 913139f7f9bSDimitry Andric } 914139f7f9bSDimitry Andric 915139f7f9bSDimitry Andric void MachineInstr::unbundleFromSucc() { 916139f7f9bSDimitry Andric assert(isBundledWithSucc() && "MI isn't bundled with its successor"); 917139f7f9bSDimitry Andric clearFlag(BundledSucc); 918139f7f9bSDimitry Andric MachineBasicBlock::instr_iterator Succ = this; 919139f7f9bSDimitry Andric ++Succ; 920139f7f9bSDimitry Andric assert(Succ->isBundledWithPred() && "Inconsistent bundle flags"); 921139f7f9bSDimitry Andric Succ->clearFlag(BundledPred); 922dff0c46cSDimitry Andric } 923dff0c46cSDimitry Andric 9242754fe60SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const { 9252754fe60SDimitry Andric if (isInlineAsm()) { 9262754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 9272754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 9282754fe60SDimitry Andric return true; 9292754fe60SDimitry Andric } 9302754fe60SDimitry Andric return false; 9312754fe60SDimitry Andric } 932f22ef01cSRoman Divacky 9333861d79fSDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const { 9343861d79fSDimitry Andric assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!"); 9353861d79fSDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 9363861d79fSDimitry Andric return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0); 9373861d79fSDimitry Andric } 9383861d79fSDimitry Andric 9396122f3e6SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx, 9406122f3e6SDimitry Andric unsigned *GroupNo) const { 9416122f3e6SDimitry Andric assert(isInlineAsm() && "Expected an inline asm instruction"); 9426122f3e6SDimitry Andric assert(OpIdx < getNumOperands() && "OpIdx out of range"); 9436122f3e6SDimitry Andric 9446122f3e6SDimitry Andric // Ignore queries about the initial operands. 9456122f3e6SDimitry Andric if (OpIdx < InlineAsm::MIOp_FirstOperand) 9466122f3e6SDimitry Andric return -1; 9476122f3e6SDimitry Andric 9486122f3e6SDimitry Andric unsigned Group = 0; 9496122f3e6SDimitry Andric unsigned NumOps; 9506122f3e6SDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 9516122f3e6SDimitry Andric i += NumOps) { 9526122f3e6SDimitry Andric const MachineOperand &FlagMO = getOperand(i); 9536122f3e6SDimitry Andric // If we reach the implicit register operands, stop looking. 9546122f3e6SDimitry Andric if (!FlagMO.isImm()) 9556122f3e6SDimitry Andric return -1; 9566122f3e6SDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 9576122f3e6SDimitry Andric if (i + NumOps > OpIdx) { 9586122f3e6SDimitry Andric if (GroupNo) 9596122f3e6SDimitry Andric *GroupNo = Group; 9606122f3e6SDimitry Andric return i; 9616122f3e6SDimitry Andric } 9626122f3e6SDimitry Andric ++Group; 9636122f3e6SDimitry Andric } 9646122f3e6SDimitry Andric return -1; 9656122f3e6SDimitry Andric } 9666122f3e6SDimitry Andric 9676122f3e6SDimitry Andric const TargetRegisterClass* 9686122f3e6SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx, 9696122f3e6SDimitry Andric const TargetInstrInfo *TII, 9706122f3e6SDimitry Andric const TargetRegisterInfo *TRI) const { 9717ae0e2c9SDimitry Andric assert(getParent() && "Can't have an MBB reference here!"); 9727ae0e2c9SDimitry Andric assert(getParent()->getParent() && "Can't have an MF reference here!"); 9737ae0e2c9SDimitry Andric const MachineFunction &MF = *getParent()->getParent(); 9747ae0e2c9SDimitry Andric 9756122f3e6SDimitry Andric // Most opcodes have fixed constraints in their MCInstrDesc. 9766122f3e6SDimitry Andric if (!isInlineAsm()) 9777ae0e2c9SDimitry Andric return TII->getRegClass(getDesc(), OpIdx, TRI, MF); 9786122f3e6SDimitry Andric 9796122f3e6SDimitry Andric if (!getOperand(OpIdx).isReg()) 98091bc56edSDimitry Andric return nullptr; 9816122f3e6SDimitry Andric 9826122f3e6SDimitry Andric // For tied uses on inline asm, get the constraint from the def. 9836122f3e6SDimitry Andric unsigned DefIdx; 9846122f3e6SDimitry Andric if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx)) 9856122f3e6SDimitry Andric OpIdx = DefIdx; 9866122f3e6SDimitry Andric 9876122f3e6SDimitry Andric // Inline asm stores register class constraints in the flag word. 9886122f3e6SDimitry Andric int FlagIdx = findInlineAsmFlagIdx(OpIdx); 9896122f3e6SDimitry Andric if (FlagIdx < 0) 99091bc56edSDimitry Andric return nullptr; 9916122f3e6SDimitry Andric 9926122f3e6SDimitry Andric unsigned Flag = getOperand(FlagIdx).getImm(); 9936122f3e6SDimitry Andric unsigned RCID; 9946122f3e6SDimitry Andric if (InlineAsm::hasRegClassConstraint(Flag, RCID)) 9956122f3e6SDimitry Andric return TRI->getRegClass(RCID); 9966122f3e6SDimitry Andric 9976122f3e6SDimitry Andric // Assume that all registers in a memory operand are pointers. 9986122f3e6SDimitry Andric if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem) 9997ae0e2c9SDimitry Andric return TRI->getPointerRegClass(MF); 10006122f3e6SDimitry Andric 100191bc56edSDimitry Andric return nullptr; 100291bc56edSDimitry Andric } 100391bc56edSDimitry Andric 100491bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( 100591bc56edSDimitry Andric unsigned Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, 100691bc56edSDimitry Andric const TargetRegisterInfo *TRI, bool ExploreBundle) const { 100791bc56edSDimitry Andric // Check every operands inside the bundle if we have 100891bc56edSDimitry Andric // been asked to. 100991bc56edSDimitry Andric if (ExploreBundle) 101091bc56edSDimitry Andric for (ConstMIBundleOperands OpndIt(this); OpndIt.isValid() && CurRC; 101191bc56edSDimitry Andric ++OpndIt) 101291bc56edSDimitry Andric CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl( 101391bc56edSDimitry Andric OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); 101491bc56edSDimitry Andric else 101591bc56edSDimitry Andric // Otherwise, just check the current operands. 101691bc56edSDimitry Andric for (ConstMIOperands OpndIt(this); OpndIt.isValid() && CurRC; ++OpndIt) 101791bc56edSDimitry Andric CurRC = getRegClassConstraintEffectForVRegImpl(OpndIt.getOperandNo(), Reg, 101891bc56edSDimitry Andric CurRC, TII, TRI); 101991bc56edSDimitry Andric return CurRC; 102091bc56edSDimitry Andric } 102191bc56edSDimitry Andric 102291bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl( 102391bc56edSDimitry Andric unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC, 102491bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 102591bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 102691bc56edSDimitry Andric // Check if Reg is constrained by some of its use/def from MI. 102791bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 102891bc56edSDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 102991bc56edSDimitry Andric return CurRC; 103091bc56edSDimitry Andric // If yes, accumulate the constraints through the operand. 103191bc56edSDimitry Andric return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI); 103291bc56edSDimitry Andric } 103391bc56edSDimitry Andric 103491bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( 103591bc56edSDimitry Andric unsigned OpIdx, const TargetRegisterClass *CurRC, 103691bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 103791bc56edSDimitry Andric const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI); 103891bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 103991bc56edSDimitry Andric assert(MO.isReg() && 104091bc56edSDimitry Andric "Cannot get register constraints for non-register operand"); 104191bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 104291bc56edSDimitry Andric if (unsigned SubIdx = MO.getSubReg()) { 104391bc56edSDimitry Andric if (OpRC) 104491bc56edSDimitry Andric CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx); 104591bc56edSDimitry Andric else 104691bc56edSDimitry Andric CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx); 104791bc56edSDimitry Andric } else if (OpRC) 104891bc56edSDimitry Andric CurRC = TRI->getCommonSubClass(CurRC, OpRC); 104991bc56edSDimitry Andric return CurRC; 10506122f3e6SDimitry Andric } 10516122f3e6SDimitry Andric 1052139f7f9bSDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the 1053139f7f9bSDimitry Andric /// header instruction. 1054dff0c46cSDimitry Andric unsigned MachineInstr::getBundleSize() const { 1055139f7f9bSDimitry Andric MachineBasicBlock::const_instr_iterator I = this; 1056dff0c46cSDimitry Andric unsigned Size = 0; 1057139f7f9bSDimitry Andric while (I->isBundledWithSucc()) 1058139f7f9bSDimitry Andric ++Size, ++I; 1059dff0c46cSDimitry Andric return Size; 1060dff0c46cSDimitry Andric } 1061dff0c46cSDimitry Andric 1062f22ef01cSRoman Divacky /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of 1063f22ef01cSRoman Divacky /// the specific register or -1 if it is not found. It further tightens 1064f22ef01cSRoman Divacky /// the search criteria to a use that kills the register if isKill is true. 1065f22ef01cSRoman Divacky int MachineInstr::findRegisterUseOperandIdx(unsigned Reg, bool isKill, 1066f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 1067f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1068f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1069f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse()) 1070f22ef01cSRoman Divacky continue; 1071f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1072f22ef01cSRoman Divacky if (!MOReg) 1073f22ef01cSRoman Divacky continue; 1074f22ef01cSRoman Divacky if (MOReg == Reg || 1075f22ef01cSRoman Divacky (TRI && 1076f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg) && 1077f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg) && 1078f22ef01cSRoman Divacky TRI->isSubRegister(MOReg, Reg))) 1079f22ef01cSRoman Divacky if (!isKill || MO.isKill()) 1080f22ef01cSRoman Divacky return i; 1081f22ef01cSRoman Divacky } 1082f22ef01cSRoman Divacky return -1; 1083f22ef01cSRoman Divacky } 1084f22ef01cSRoman Divacky 1085f22ef01cSRoman Divacky /// readsWritesVirtualRegister - Return a pair of bools (reads, writes) 1086f22ef01cSRoman Divacky /// indicating if this instruction reads or writes Reg. This also considers 1087f22ef01cSRoman Divacky /// partial defines. 1088f22ef01cSRoman Divacky std::pair<bool,bool> 1089f22ef01cSRoman Divacky MachineInstr::readsWritesVirtualRegister(unsigned Reg, 1090f22ef01cSRoman Divacky SmallVectorImpl<unsigned> *Ops) const { 1091f22ef01cSRoman Divacky bool PartDef = false; // Partial redefine. 1092f22ef01cSRoman Divacky bool FullDef = false; // Full define. 1093f22ef01cSRoman Divacky bool Use = false; 1094f22ef01cSRoman Divacky 1095f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1096f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1097f22ef01cSRoman Divacky if (!MO.isReg() || MO.getReg() != Reg) 1098f22ef01cSRoman Divacky continue; 1099f22ef01cSRoman Divacky if (Ops) 1100f22ef01cSRoman Divacky Ops->push_back(i); 1101f22ef01cSRoman Divacky if (MO.isUse()) 1102f22ef01cSRoman Divacky Use |= !MO.isUndef(); 11036122f3e6SDimitry Andric else if (MO.getSubReg() && !MO.isUndef()) 11046122f3e6SDimitry Andric // A partial <def,undef> doesn't count as reading the register. 1105f22ef01cSRoman Divacky PartDef = true; 1106f22ef01cSRoman Divacky else 1107f22ef01cSRoman Divacky FullDef = true; 1108f22ef01cSRoman Divacky } 1109f22ef01cSRoman Divacky // A partial redefine uses Reg unless there is also a full define. 1110f22ef01cSRoman Divacky return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef); 1111f22ef01cSRoman Divacky } 1112f22ef01cSRoman Divacky 1113f22ef01cSRoman Divacky /// findRegisterDefOperandIdx() - Returns the operand index that is a def of 1114f22ef01cSRoman Divacky /// the specified register or -1 if it is not found. If isDead is true, defs 1115f22ef01cSRoman Divacky /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it 1116f22ef01cSRoman Divacky /// also checks if there is a def of a super-register. 1117f22ef01cSRoman Divacky int 1118f22ef01cSRoman Divacky MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap, 1119f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 1120f22ef01cSRoman Divacky bool isPhys = TargetRegisterInfo::isPhysicalRegister(Reg); 1121f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1122f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1123dff0c46cSDimitry Andric // Accept regmask operands when Overlap is set. 1124dff0c46cSDimitry Andric // Ignore them when looking for a specific def operand (Overlap == false). 1125dff0c46cSDimitry Andric if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg)) 1126dff0c46cSDimitry Andric return i; 1127f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 1128f22ef01cSRoman Divacky continue; 1129f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 1130f22ef01cSRoman Divacky bool Found = (MOReg == Reg); 1131f22ef01cSRoman Divacky if (!Found && TRI && isPhys && 1132f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg)) { 1133f22ef01cSRoman Divacky if (Overlap) 1134f22ef01cSRoman Divacky Found = TRI->regsOverlap(MOReg, Reg); 1135f22ef01cSRoman Divacky else 1136f22ef01cSRoman Divacky Found = TRI->isSubRegister(MOReg, Reg); 1137f22ef01cSRoman Divacky } 1138f22ef01cSRoman Divacky if (Found && (!isDead || MO.isDead())) 1139f22ef01cSRoman Divacky return i; 1140f22ef01cSRoman Divacky } 1141f22ef01cSRoman Divacky return -1; 1142f22ef01cSRoman Divacky } 1143f22ef01cSRoman Divacky 1144f22ef01cSRoman Divacky /// findFirstPredOperandIdx() - Find the index of the first operand in the 1145f22ef01cSRoman Divacky /// operand list that is used to represent the predicate. It returns -1 if 1146f22ef01cSRoman Divacky /// none is found. 1147f22ef01cSRoman Divacky int MachineInstr::findFirstPredOperandIdx() const { 11486122f3e6SDimitry Andric // Don't call MCID.findFirstPredOperandIdx() because this variant 11496122f3e6SDimitry Andric // is sometimes called on an instruction that's not yet complete, and 11506122f3e6SDimitry Andric // so the number of operands is less than the MCID indicates. In 11516122f3e6SDimitry Andric // particular, the PTX target does this. 115217a519f9SDimitry Andric const MCInstrDesc &MCID = getDesc(); 115317a519f9SDimitry Andric if (MCID.isPredicable()) { 1154f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 115517a519f9SDimitry Andric if (MCID.OpInfo[i].isPredicate()) 1156f22ef01cSRoman Divacky return i; 1157f22ef01cSRoman Divacky } 1158f22ef01cSRoman Divacky 1159f22ef01cSRoman Divacky return -1; 1160f22ef01cSRoman Divacky } 1161f22ef01cSRoman Divacky 11623861d79fSDimitry Andric // MachineOperand::TiedTo is 4 bits wide. 11633861d79fSDimitry Andric const unsigned TiedMax = 15; 11646122f3e6SDimitry Andric 11653861d79fSDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other. 11663861d79fSDimitry Andric /// 11673861d79fSDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo 11683861d79fSDimitry Andric /// field. TiedTo can have these values: 11693861d79fSDimitry Andric /// 11703861d79fSDimitry Andric /// 0: Operand is not tied to anything. 11713861d79fSDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1). 11723861d79fSDimitry Andric /// TiedMax: Tied to an operand >= TiedMax-1. 11733861d79fSDimitry Andric /// 11743861d79fSDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal 11753861d79fSDimitry Andric /// instruction. INLINEASM instructions allow more tied defs. 11763861d79fSDimitry Andric /// 11773861d79fSDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) { 11783861d79fSDimitry Andric MachineOperand &DefMO = getOperand(DefIdx); 11793861d79fSDimitry Andric MachineOperand &UseMO = getOperand(UseIdx); 11803861d79fSDimitry Andric assert(DefMO.isDef() && "DefIdx must be a def operand"); 11813861d79fSDimitry Andric assert(UseMO.isUse() && "UseIdx must be a use operand"); 11823861d79fSDimitry Andric assert(!DefMO.isTied() && "Def is already tied to another use"); 11833861d79fSDimitry Andric assert(!UseMO.isTied() && "Use is already tied to another def"); 11846122f3e6SDimitry Andric 11853861d79fSDimitry Andric if (DefIdx < TiedMax) 11863861d79fSDimitry Andric UseMO.TiedTo = DefIdx + 1; 11873861d79fSDimitry Andric else { 11883861d79fSDimitry Andric // Inline asm can use the group descriptors to find tied operands, but on 11893861d79fSDimitry Andric // normal instruction, the tied def must be within the first TiedMax 11903861d79fSDimitry Andric // operands. 11913861d79fSDimitry Andric assert(isInlineAsm() && "DefIdx out of range"); 11923861d79fSDimitry Andric UseMO.TiedTo = TiedMax; 11933861d79fSDimitry Andric } 11943861d79fSDimitry Andric 11953861d79fSDimitry Andric // UseIdx can be out of range, we'll search for it in findTiedOperandIdx(). 11963861d79fSDimitry Andric DefMO.TiedTo = std::min(UseIdx + 1, TiedMax); 11973861d79fSDimitry Andric } 11983861d79fSDimitry Andric 11993861d79fSDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to. 12003861d79fSDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand 12013861d79fSDimitry Andric /// which must exist. 12023861d79fSDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const { 12033861d79fSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 12043861d79fSDimitry Andric assert(MO.isTied() && "Operand isn't tied"); 12053861d79fSDimitry Andric 12063861d79fSDimitry Andric // Normally TiedTo is in range. 12073861d79fSDimitry Andric if (MO.TiedTo < TiedMax) 12083861d79fSDimitry Andric return MO.TiedTo - 1; 12093861d79fSDimitry Andric 12103861d79fSDimitry Andric // Uses on normal instructions can be out of range. 12113861d79fSDimitry Andric if (!isInlineAsm()) { 12123861d79fSDimitry Andric // Normal tied defs must be in the 0..TiedMax-1 range. 12133861d79fSDimitry Andric if (MO.isUse()) 12143861d79fSDimitry Andric return TiedMax - 1; 12153861d79fSDimitry Andric // MO is a def. Search for the tied use. 12163861d79fSDimitry Andric for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) { 12173861d79fSDimitry Andric const MachineOperand &UseMO = getOperand(i); 12183861d79fSDimitry Andric if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1) 12193861d79fSDimitry Andric return i; 12203861d79fSDimitry Andric } 12213861d79fSDimitry Andric llvm_unreachable("Can't find tied use"); 12223861d79fSDimitry Andric } 12233861d79fSDimitry Andric 12243861d79fSDimitry Andric // Now deal with inline asm by parsing the operand group descriptor flags. 12253861d79fSDimitry Andric // Find the beginning of each operand group. 12263861d79fSDimitry Andric SmallVector<unsigned, 8> GroupIdx; 12273861d79fSDimitry Andric unsigned OpIdxGroup = ~0u; 12283861d79fSDimitry Andric unsigned NumOps; 12293861d79fSDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 12303861d79fSDimitry Andric i += NumOps) { 12313861d79fSDimitry Andric const MachineOperand &FlagMO = getOperand(i); 12323861d79fSDimitry Andric assert(FlagMO.isImm() && "Invalid tied operand on inline asm"); 12333861d79fSDimitry Andric unsigned CurGroup = GroupIdx.size(); 12343861d79fSDimitry Andric GroupIdx.push_back(i); 12353861d79fSDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 12363861d79fSDimitry Andric // OpIdx belongs to this operand group. 12373861d79fSDimitry Andric if (OpIdx > i && OpIdx < i + NumOps) 12383861d79fSDimitry Andric OpIdxGroup = CurGroup; 12393861d79fSDimitry Andric unsigned TiedGroup; 12403861d79fSDimitry Andric if (!InlineAsm::isUseOperandTiedToDef(FlagMO.getImm(), TiedGroup)) 1241f22ef01cSRoman Divacky continue; 12423861d79fSDimitry Andric // Operands in this group are tied to operands in TiedGroup which must be 12433861d79fSDimitry Andric // earlier. Find the number of operands between the two groups. 12443861d79fSDimitry Andric unsigned Delta = i - GroupIdx[TiedGroup]; 1245f22ef01cSRoman Divacky 12463861d79fSDimitry Andric // OpIdx is a use tied to TiedGroup. 12473861d79fSDimitry Andric if (OpIdxGroup == CurGroup) 12483861d79fSDimitry Andric return OpIdx - Delta; 1249f22ef01cSRoman Divacky 12503861d79fSDimitry Andric // OpIdx is a def tied to this use group. 12513861d79fSDimitry Andric if (OpIdxGroup == TiedGroup) 12523861d79fSDimitry Andric return OpIdx + Delta; 1253f22ef01cSRoman Divacky } 12543861d79fSDimitry Andric llvm_unreachable("Invalid tied operand on inline asm"); 1255f22ef01cSRoman Divacky } 1256f22ef01cSRoman Divacky 1257f22ef01cSRoman Divacky /// clearKillInfo - Clears kill flags on all operands. 1258f22ef01cSRoman Divacky /// 1259f22ef01cSRoman Divacky void MachineInstr::clearKillInfo() { 1260f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1261f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1262f22ef01cSRoman Divacky if (MO.isReg() && MO.isUse()) 1263f22ef01cSRoman Divacky MO.setIsKill(false); 1264f22ef01cSRoman Divacky } 1265f22ef01cSRoman Divacky } 1266f22ef01cSRoman Divacky 1267ffd1746dSEd Schouten void MachineInstr::substituteRegister(unsigned FromReg, 1268ffd1746dSEd Schouten unsigned ToReg, 1269ffd1746dSEd Schouten unsigned SubIdx, 1270ffd1746dSEd Schouten const TargetRegisterInfo &RegInfo) { 1271ffd1746dSEd Schouten if (TargetRegisterInfo::isPhysicalRegister(ToReg)) { 1272ffd1746dSEd Schouten if (SubIdx) 1273ffd1746dSEd Schouten ToReg = RegInfo.getSubReg(ToReg, SubIdx); 1274ffd1746dSEd Schouten for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1275ffd1746dSEd Schouten MachineOperand &MO = getOperand(i); 1276ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1277ffd1746dSEd Schouten continue; 1278ffd1746dSEd Schouten MO.substPhysReg(ToReg, RegInfo); 1279ffd1746dSEd Schouten } 1280ffd1746dSEd Schouten } else { 1281ffd1746dSEd Schouten for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1282ffd1746dSEd Schouten MachineOperand &MO = getOperand(i); 1283ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 1284ffd1746dSEd Schouten continue; 1285ffd1746dSEd Schouten MO.substVirtReg(ToReg, SubIdx, RegInfo); 1286ffd1746dSEd Schouten } 1287ffd1746dSEd Schouten } 1288ffd1746dSEd Schouten } 1289ffd1746dSEd Schouten 1290f22ef01cSRoman Divacky /// isSafeToMove - Return true if it is safe to move this instruction. If 1291f22ef01cSRoman Divacky /// SawStore is set to true, it means that there is a store (or call) between 1292f22ef01cSRoman Divacky /// the instruction's location and its intended destination. 1293f22ef01cSRoman Divacky bool MachineInstr::isSafeToMove(const TargetInstrInfo *TII, 1294f22ef01cSRoman Divacky AliasAnalysis *AA, 1295f22ef01cSRoman Divacky bool &SawStore) const { 1296f22ef01cSRoman Divacky // Ignore stuff that we obviously can't move. 12973861d79fSDimitry Andric // 12983861d79fSDimitry Andric // Treat volatile loads as stores. This is not strictly necessary for 12993861d79fSDimitry Andric // volatiles, but it is required for atomic loads. It is not allowed to move 13003861d79fSDimitry Andric // a load across an atomic load with Ordering > Monotonic. 13013861d79fSDimitry Andric if (mayStore() || isCall() || 13023861d79fSDimitry Andric (mayLoad() && hasOrderedMemoryRef())) { 1303f22ef01cSRoman Divacky SawStore = true; 1304f22ef01cSRoman Divacky return false; 1305f22ef01cSRoman Divacky } 13062754fe60SDimitry Andric 130791bc56edSDimitry Andric if (isPosition() || isDebugValue() || isTerminator() || 130891bc56edSDimitry Andric hasUnmodeledSideEffects()) 1309f22ef01cSRoman Divacky return false; 1310f22ef01cSRoman Divacky 1311f22ef01cSRoman Divacky // See if this instruction does a load. If so, we have to guarantee that the 1312f22ef01cSRoman Divacky // loaded value doesn't change between the load and the its intended 1313f22ef01cSRoman Divacky // destination. The check for isInvariantLoad gives the targe the chance to 1314f22ef01cSRoman Divacky // classify the load as always returning a constant, e.g. a constant pool 1315f22ef01cSRoman Divacky // load. 1316dff0c46cSDimitry Andric if (mayLoad() && !isInvariantLoad(AA)) 1317f22ef01cSRoman Divacky // Otherwise, this is a real load. If there is a store between the load and 13183861d79fSDimitry Andric // end of block, we can't move it. 13193861d79fSDimitry Andric return !SawStore; 1320f22ef01cSRoman Divacky 1321f22ef01cSRoman Divacky return true; 1322f22ef01cSRoman Divacky } 1323f22ef01cSRoman Divacky 13243861d79fSDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered 13253861d79fSDimitry Andric /// or volatile memory reference, or if the information describing the memory 13263861d79fSDimitry Andric /// reference is not available. Return false if it is known to have no ordered 13273861d79fSDimitry Andric /// memory references. 13283861d79fSDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const { 1329f22ef01cSRoman Divacky // An instruction known never to access memory won't have a volatile access. 1330dff0c46cSDimitry Andric if (!mayStore() && 1331dff0c46cSDimitry Andric !mayLoad() && 1332dff0c46cSDimitry Andric !isCall() && 13332754fe60SDimitry Andric !hasUnmodeledSideEffects()) 1334f22ef01cSRoman Divacky return false; 1335f22ef01cSRoman Divacky 1336f22ef01cSRoman Divacky // Otherwise, if the instruction has no memory reference information, 1337f22ef01cSRoman Divacky // conservatively assume it wasn't preserved. 1338f22ef01cSRoman Divacky if (memoperands_empty()) 1339f22ef01cSRoman Divacky return true; 1340f22ef01cSRoman Divacky 13413861d79fSDimitry Andric // Check the memory reference information for ordered references. 1342f22ef01cSRoman Divacky for (mmo_iterator I = memoperands_begin(), E = memoperands_end(); I != E; ++I) 13433861d79fSDimitry Andric if (!(*I)->isUnordered()) 1344f22ef01cSRoman Divacky return true; 1345f22ef01cSRoman Divacky 1346f22ef01cSRoman Divacky return false; 1347f22ef01cSRoman Divacky } 1348f22ef01cSRoman Divacky 1349f22ef01cSRoman Divacky /// isInvariantLoad - Return true if this instruction is loading from a 1350f22ef01cSRoman Divacky /// location whose value is invariant across the function. For example, 1351f22ef01cSRoman Divacky /// loading a value from the constant pool or from the argument area 1352f22ef01cSRoman Divacky /// of a function if it does not change. This should only return true of 1353f22ef01cSRoman Divacky /// *all* loads the instruction does are invariant (if it does multiple loads). 1354f22ef01cSRoman Divacky bool MachineInstr::isInvariantLoad(AliasAnalysis *AA) const { 1355f22ef01cSRoman Divacky // If the instruction doesn't load at all, it isn't an invariant load. 1356dff0c46cSDimitry Andric if (!mayLoad()) 1357f22ef01cSRoman Divacky return false; 1358f22ef01cSRoman Divacky 1359f22ef01cSRoman Divacky // If the instruction has lost its memoperands, conservatively assume that 1360f22ef01cSRoman Divacky // it may not be an invariant load. 1361f22ef01cSRoman Divacky if (memoperands_empty()) 1362f22ef01cSRoman Divacky return false; 1363f22ef01cSRoman Divacky 1364f22ef01cSRoman Divacky const MachineFrameInfo *MFI = getParent()->getParent()->getFrameInfo(); 1365f22ef01cSRoman Divacky 1366f22ef01cSRoman Divacky for (mmo_iterator I = memoperands_begin(), 1367f22ef01cSRoman Divacky E = memoperands_end(); I != E; ++I) { 1368f22ef01cSRoman Divacky if ((*I)->isVolatile()) return false; 1369f22ef01cSRoman Divacky if ((*I)->isStore()) return false; 1370dff0c46cSDimitry Andric if ((*I)->isInvariant()) return true; 1371f22ef01cSRoman Divacky 137291bc56edSDimitry Andric 1373f22ef01cSRoman Divacky // A load from a constant PseudoSourceValue is invariant. 137491bc56edSDimitry Andric if (const PseudoSourceValue *PSV = (*I)->getPseudoValue()) 1375f22ef01cSRoman Divacky if (PSV->isConstant(MFI)) 1376f22ef01cSRoman Divacky continue; 137791bc56edSDimitry Andric 137891bc56edSDimitry Andric if (const Value *V = (*I)->getValue()) { 1379f22ef01cSRoman Divacky // If we have an AliasAnalysis, ask it whether the memory is constant. 13802754fe60SDimitry Andric if (AA && AA->pointsToConstantMemory( 13812754fe60SDimitry Andric AliasAnalysis::Location(V, (*I)->getSize(), 13822754fe60SDimitry Andric (*I)->getTBAAInfo()))) 1383f22ef01cSRoman Divacky continue; 1384f22ef01cSRoman Divacky } 1385f22ef01cSRoman Divacky 1386f22ef01cSRoman Divacky // Otherwise assume conservatively. 1387f22ef01cSRoman Divacky return false; 1388f22ef01cSRoman Divacky } 1389f22ef01cSRoman Divacky 1390f22ef01cSRoman Divacky // Everything checks out. 1391f22ef01cSRoman Divacky return true; 1392f22ef01cSRoman Divacky } 1393f22ef01cSRoman Divacky 1394f22ef01cSRoman Divacky /// isConstantValuePHI - If the specified instruction is a PHI that always 1395f22ef01cSRoman Divacky /// merges together the same virtual register, return the register, otherwise 1396f22ef01cSRoman Divacky /// return 0. 1397f22ef01cSRoman Divacky unsigned MachineInstr::isConstantValuePHI() const { 1398f22ef01cSRoman Divacky if (!isPHI()) 1399f22ef01cSRoman Divacky return 0; 1400f22ef01cSRoman Divacky assert(getNumOperands() >= 3 && 1401f22ef01cSRoman Divacky "It's illegal to have a PHI without source operands"); 1402f22ef01cSRoman Divacky 1403f22ef01cSRoman Divacky unsigned Reg = getOperand(1).getReg(); 1404f22ef01cSRoman Divacky for (unsigned i = 3, e = getNumOperands(); i < e; i += 2) 1405f22ef01cSRoman Divacky if (getOperand(i).getReg() != Reg) 1406f22ef01cSRoman Divacky return 0; 1407f22ef01cSRoman Divacky return Reg; 1408f22ef01cSRoman Divacky } 1409f22ef01cSRoman Divacky 14102754fe60SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const { 1411dff0c46cSDimitry Andric if (hasProperty(MCID::UnmodeledSideEffects)) 14122754fe60SDimitry Andric return true; 14132754fe60SDimitry Andric if (isInlineAsm()) { 14142754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 14152754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 14162754fe60SDimitry Andric return true; 14172754fe60SDimitry Andric } 14182754fe60SDimitry Andric 14192754fe60SDimitry Andric return false; 14202754fe60SDimitry Andric } 14212754fe60SDimitry Andric 1422f22ef01cSRoman Divacky /// allDefsAreDead - Return true if all the defs of this instruction are dead. 1423f22ef01cSRoman Divacky /// 1424f22ef01cSRoman Divacky bool MachineInstr::allDefsAreDead() const { 1425f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i < e; ++i) { 1426f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1427f22ef01cSRoman Divacky if (!MO.isReg() || MO.isUse()) 1428f22ef01cSRoman Divacky continue; 1429f22ef01cSRoman Divacky if (!MO.isDead()) 1430f22ef01cSRoman Divacky return false; 1431f22ef01cSRoman Divacky } 1432f22ef01cSRoman Divacky return true; 1433f22ef01cSRoman Divacky } 1434f22ef01cSRoman Divacky 14352754fe60SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified 14362754fe60SDimitry Andric /// instruction to this instruction. 1437139f7f9bSDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF, 1438139f7f9bSDimitry Andric const MachineInstr *MI) { 14392754fe60SDimitry Andric for (unsigned i = MI->getDesc().getNumOperands(), e = MI->getNumOperands(); 14402754fe60SDimitry Andric i != e; ++i) { 14412754fe60SDimitry Andric const MachineOperand &MO = MI->getOperand(i); 144291bc56edSDimitry Andric if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask()) 1443139f7f9bSDimitry Andric addOperand(MF, MO); 14442754fe60SDimitry Andric } 14452754fe60SDimitry Andric } 14462754fe60SDimitry Andric 1447f22ef01cSRoman Divacky void MachineInstr::dump() const { 14483861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1449f22ef01cSRoman Divacky dbgs() << " " << *this; 14503861d79fSDimitry Andric #endif 1451f22ef01cSRoman Divacky } 1452f22ef01cSRoman Divacky 1453ffd1746dSEd Schouten static void printDebugLoc(DebugLoc DL, const MachineFunction *MF, 1454ffd1746dSEd Schouten raw_ostream &CommentOS) { 1455ffd1746dSEd Schouten const LLVMContext &Ctx = MF->getFunction()->getContext(); 145691bc56edSDimitry Andric DL.print(Ctx, CommentOS); 1457ffd1746dSEd Schouten } 1458ffd1746dSEd Schouten 1459139f7f9bSDimitry Andric void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM, 1460139f7f9bSDimitry Andric bool SkipOpers) const { 1461f22ef01cSRoman Divacky // We can be a bit tidier if we know the TargetMachine and/or MachineFunction. 146291bc56edSDimitry Andric const MachineFunction *MF = nullptr; 146391bc56edSDimitry Andric const MachineRegisterInfo *MRI = nullptr; 1464f22ef01cSRoman Divacky if (const MachineBasicBlock *MBB = getParent()) { 1465f22ef01cSRoman Divacky MF = MBB->getParent(); 1466f22ef01cSRoman Divacky if (!TM && MF) 1467f22ef01cSRoman Divacky TM = &MF->getTarget(); 1468e580952dSDimitry Andric if (MF) 1469e580952dSDimitry Andric MRI = &MF->getRegInfo(); 1470f22ef01cSRoman Divacky } 1471f22ef01cSRoman Divacky 1472e580952dSDimitry Andric // Save a list of virtual registers. 1473e580952dSDimitry Andric SmallVector<unsigned, 8> VirtRegs; 1474e580952dSDimitry Andric 1475f22ef01cSRoman Divacky // Print explicitly defined operands on the left of an assignment syntax. 1476f22ef01cSRoman Divacky unsigned StartOp = 0, e = getNumOperands(); 1477f22ef01cSRoman Divacky for (; StartOp < e && getOperand(StartOp).isReg() && 1478f22ef01cSRoman Divacky getOperand(StartOp).isDef() && 1479f22ef01cSRoman Divacky !getOperand(StartOp).isImplicit(); 1480f22ef01cSRoman Divacky ++StartOp) { 1481f22ef01cSRoman Divacky if (StartOp != 0) OS << ", "; 1482f22ef01cSRoman Divacky getOperand(StartOp).print(OS, TM); 1483e580952dSDimitry Andric unsigned Reg = getOperand(StartOp).getReg(); 14842754fe60SDimitry Andric if (TargetRegisterInfo::isVirtualRegister(Reg)) 1485e580952dSDimitry Andric VirtRegs.push_back(Reg); 1486f22ef01cSRoman Divacky } 1487f22ef01cSRoman Divacky 1488f22ef01cSRoman Divacky if (StartOp != 0) 1489f22ef01cSRoman Divacky OS << " = "; 1490f22ef01cSRoman Divacky 1491f22ef01cSRoman Divacky // Print the opcode name. 1492dff0c46cSDimitry Andric if (TM && TM->getInstrInfo()) 1493dff0c46cSDimitry Andric OS << TM->getInstrInfo()->getName(getOpcode()); 1494dff0c46cSDimitry Andric else 1495dff0c46cSDimitry Andric OS << "UNKNOWN"; 1496f22ef01cSRoman Divacky 1497139f7f9bSDimitry Andric if (SkipOpers) 1498139f7f9bSDimitry Andric return; 1499139f7f9bSDimitry Andric 1500f22ef01cSRoman Divacky // Print the rest of the operands. 1501f22ef01cSRoman Divacky bool OmittedAnyCallClobbers = false; 1502f22ef01cSRoman Divacky bool FirstOp = true; 150317a519f9SDimitry Andric unsigned AsmDescOp = ~0u; 150417a519f9SDimitry Andric unsigned AsmOpCount = 0; 15052754fe60SDimitry Andric 15066122f3e6SDimitry Andric if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { 15072754fe60SDimitry Andric // Print asm string. 15082754fe60SDimitry Andric OS << " "; 15092754fe60SDimitry Andric getOperand(InlineAsm::MIOp_AsmString).print(OS, TM); 15102754fe60SDimitry Andric 1511139f7f9bSDimitry Andric // Print HasSideEffects, MayLoad, MayStore, IsAlignStack 15122754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 15132754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 15142754fe60SDimitry Andric OS << " [sideeffect]"; 1515139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayLoad) 1516139f7f9bSDimitry Andric OS << " [mayload]"; 1517139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayStore) 1518139f7f9bSDimitry Andric OS << " [maystore]"; 15192754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 15202754fe60SDimitry Andric OS << " [alignstack]"; 15213861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_ATT) 15223861d79fSDimitry Andric OS << " [attdialect]"; 15233861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_Intel) 15243861d79fSDimitry Andric OS << " [inteldialect]"; 15252754fe60SDimitry Andric 152617a519f9SDimitry Andric StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand; 15272754fe60SDimitry Andric FirstOp = false; 15282754fe60SDimitry Andric } 15292754fe60SDimitry Andric 15302754fe60SDimitry Andric 1531f22ef01cSRoman Divacky for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 1532f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1533f22ef01cSRoman Divacky 15342754fe60SDimitry Andric if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) 1535e580952dSDimitry Andric VirtRegs.push_back(MO.getReg()); 1536e580952dSDimitry Andric 1537f22ef01cSRoman Divacky // Omit call-clobbered registers which aren't used anywhere. This makes 1538f22ef01cSRoman Divacky // call instructions much less noisy on targets where calls clobber lots 1539f22ef01cSRoman Divacky // of registers. Don't rely on MO.isDead() because we may be called before 1540f22ef01cSRoman Divacky // LiveVariables is run, or we may be looking at a non-allocatable reg. 1541dff0c46cSDimitry Andric if (MF && isCall() && 1542f22ef01cSRoman Divacky MO.isReg() && MO.isImplicit() && MO.isDef()) { 1543f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 15442754fe60SDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 1545f22ef01cSRoman Divacky const MachineRegisterInfo &MRI = MF->getRegInfo(); 1546139f7f9bSDimitry Andric if (MRI.use_empty(Reg)) { 1547f22ef01cSRoman Divacky bool HasAliasLive = false; 15487ae0e2c9SDimitry Andric for (MCRegAliasIterator AI(Reg, TM->getRegisterInfo(), true); 15497ae0e2c9SDimitry Andric AI.isValid(); ++AI) { 15507ae0e2c9SDimitry Andric unsigned AliasReg = *AI; 1551139f7f9bSDimitry Andric if (!MRI.use_empty(AliasReg)) { 1552f22ef01cSRoman Divacky HasAliasLive = true; 1553f22ef01cSRoman Divacky break; 1554f22ef01cSRoman Divacky } 15557ae0e2c9SDimitry Andric } 1556f22ef01cSRoman Divacky if (!HasAliasLive) { 1557f22ef01cSRoman Divacky OmittedAnyCallClobbers = true; 1558f22ef01cSRoman Divacky continue; 1559f22ef01cSRoman Divacky } 1560f22ef01cSRoman Divacky } 1561f22ef01cSRoman Divacky } 1562f22ef01cSRoman Divacky } 1563f22ef01cSRoman Divacky 1564f22ef01cSRoman Divacky if (FirstOp) FirstOp = false; else OS << ","; 1565f22ef01cSRoman Divacky OS << " "; 1566f22ef01cSRoman Divacky if (i < getDesc().NumOperands) { 156717a519f9SDimitry Andric const MCOperandInfo &MCOI = getDesc().OpInfo[i]; 156817a519f9SDimitry Andric if (MCOI.isPredicate()) 1569f22ef01cSRoman Divacky OS << "pred:"; 157017a519f9SDimitry Andric if (MCOI.isOptionalDef()) 1571f22ef01cSRoman Divacky OS << "opt:"; 1572f22ef01cSRoman Divacky } 1573f22ef01cSRoman Divacky if (isDebugValue() && MO.isMetadata()) { 1574f22ef01cSRoman Divacky // Pretty print DBG_VALUE instructions. 1575f22ef01cSRoman Divacky const MDNode *MD = MO.getMetadata(); 1576f22ef01cSRoman Divacky if (const MDString *MDS = dyn_cast<MDString>(MD->getOperand(2))) 1577f22ef01cSRoman Divacky OS << "!\"" << MDS->getString() << '\"'; 1578f22ef01cSRoman Divacky else 1579f22ef01cSRoman Divacky MO.print(OS, TM); 1580ffd1746dSEd Schouten } else if (TM && (isInsertSubreg() || isRegSequence()) && MO.isImm()) { 1581ffd1746dSEd Schouten OS << TM->getRegisterInfo()->getSubRegIndexName(MO.getImm()); 158217a519f9SDimitry Andric } else if (i == AsmDescOp && MO.isImm()) { 158317a519f9SDimitry Andric // Pretty print the inline asm operand descriptor. 158417a519f9SDimitry Andric OS << '$' << AsmOpCount++; 158517a519f9SDimitry Andric unsigned Flag = MO.getImm(); 158617a519f9SDimitry Andric switch (InlineAsm::getKind(Flag)) { 15876122f3e6SDimitry Andric case InlineAsm::Kind_RegUse: OS << ":[reguse"; break; 15886122f3e6SDimitry Andric case InlineAsm::Kind_RegDef: OS << ":[regdef"; break; 15896122f3e6SDimitry Andric case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec"; break; 15906122f3e6SDimitry Andric case InlineAsm::Kind_Clobber: OS << ":[clobber"; break; 15916122f3e6SDimitry Andric case InlineAsm::Kind_Imm: OS << ":[imm"; break; 15926122f3e6SDimitry Andric case InlineAsm::Kind_Mem: OS << ":[mem"; break; 15936122f3e6SDimitry Andric default: OS << ":[??" << InlineAsm::getKind(Flag); break; 15946122f3e6SDimitry Andric } 15956122f3e6SDimitry Andric 15966122f3e6SDimitry Andric unsigned RCID = 0; 15976122f3e6SDimitry Andric if (InlineAsm::hasRegClassConstraint(Flag, RCID)) { 15986122f3e6SDimitry Andric if (TM) 15996122f3e6SDimitry Andric OS << ':' << TM->getRegisterInfo()->getRegClass(RCID)->getName(); 16006122f3e6SDimitry Andric else 16016122f3e6SDimitry Andric OS << ":RC" << RCID; 160217a519f9SDimitry Andric } 160317a519f9SDimitry Andric 160417a519f9SDimitry Andric unsigned TiedTo = 0; 160517a519f9SDimitry Andric if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo)) 16066122f3e6SDimitry Andric OS << " tiedto:$" << TiedTo; 16076122f3e6SDimitry Andric 16086122f3e6SDimitry Andric OS << ']'; 160917a519f9SDimitry Andric 161017a519f9SDimitry Andric // Compute the index of the next operand descriptor. 161117a519f9SDimitry Andric AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); 1612f22ef01cSRoman Divacky } else 1613f22ef01cSRoman Divacky MO.print(OS, TM); 1614f22ef01cSRoman Divacky } 1615f22ef01cSRoman Divacky 1616f22ef01cSRoman Divacky // Briefly indicate whether any call clobbers were omitted. 1617f22ef01cSRoman Divacky if (OmittedAnyCallClobbers) { 1618f22ef01cSRoman Divacky if (!FirstOp) OS << ","; 1619f22ef01cSRoman Divacky OS << " ..."; 1620f22ef01cSRoman Divacky } 1621f22ef01cSRoman Divacky 1622f22ef01cSRoman Divacky bool HaveSemi = false; 1623139f7f9bSDimitry Andric const unsigned PrintableFlags = FrameSetup; 1624139f7f9bSDimitry Andric if (Flags & PrintableFlags) { 16253b0f4066SDimitry Andric if (!HaveSemi) OS << ";"; HaveSemi = true; 16263b0f4066SDimitry Andric OS << " flags: "; 16273b0f4066SDimitry Andric 16283b0f4066SDimitry Andric if (Flags & FrameSetup) 16293b0f4066SDimitry Andric OS << "FrameSetup"; 16303b0f4066SDimitry Andric } 16313b0f4066SDimitry Andric 1632f22ef01cSRoman Divacky if (!memoperands_empty()) { 1633f22ef01cSRoman Divacky if (!HaveSemi) OS << ";"; HaveSemi = true; 1634f22ef01cSRoman Divacky 1635f22ef01cSRoman Divacky OS << " mem:"; 1636f22ef01cSRoman Divacky for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); 1637f22ef01cSRoman Divacky i != e; ++i) { 1638f22ef01cSRoman Divacky OS << **i; 163991bc56edSDimitry Andric if (std::next(i) != e) 1640f22ef01cSRoman Divacky OS << " "; 1641f22ef01cSRoman Divacky } 1642f22ef01cSRoman Divacky } 1643f22ef01cSRoman Divacky 1644e580952dSDimitry Andric // Print the regclass of any virtual registers encountered. 1645e580952dSDimitry Andric if (MRI && !VirtRegs.empty()) { 1646e580952dSDimitry Andric if (!HaveSemi) OS << ";"; HaveSemi = true; 1647e580952dSDimitry Andric for (unsigned i = 0; i != VirtRegs.size(); ++i) { 1648e580952dSDimitry Andric const TargetRegisterClass *RC = MRI->getRegClass(VirtRegs[i]); 16492754fe60SDimitry Andric OS << " " << RC->getName() << ':' << PrintReg(VirtRegs[i]); 1650e580952dSDimitry Andric for (unsigned j = i+1; j != VirtRegs.size();) { 1651e580952dSDimitry Andric if (MRI->getRegClass(VirtRegs[j]) != RC) { 1652e580952dSDimitry Andric ++j; 1653e580952dSDimitry Andric continue; 1654e580952dSDimitry Andric } 1655e580952dSDimitry Andric if (VirtRegs[i] != VirtRegs[j]) 16562754fe60SDimitry Andric OS << "," << PrintReg(VirtRegs[j]); 1657e580952dSDimitry Andric VirtRegs.erase(VirtRegs.begin()+j); 1658e580952dSDimitry Andric } 1659e580952dSDimitry Andric } 1660e580952dSDimitry Andric } 1661e580952dSDimitry Andric 16623b0f4066SDimitry Andric // Print debug location information. 16636122f3e6SDimitry Andric if (isDebugValue() && getOperand(e - 1).isMetadata()) { 166491bc56edSDimitry Andric if (!HaveSemi) OS << ";"; 16656122f3e6SDimitry Andric DIVariable DV(getOperand(e - 1).getMetadata()); 16666122f3e6SDimitry Andric OS << " line no:" << DV.getLineNumber(); 16676122f3e6SDimitry Andric if (MDNode *InlinedAt = DV.getInlinedAt()) { 16686122f3e6SDimitry Andric DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt); 166991bc56edSDimitry Andric if (!InlinedAtDL.isUnknown() && MF) { 16706122f3e6SDimitry Andric OS << " inlined @[ "; 16716122f3e6SDimitry Andric printDebugLoc(InlinedAtDL, MF, OS); 16726122f3e6SDimitry Andric OS << " ]"; 16736122f3e6SDimitry Andric } 16746122f3e6SDimitry Andric } 16756122f3e6SDimitry Andric } else if (!debugLoc.isUnknown() && MF) { 167691bc56edSDimitry Andric if (!HaveSemi) OS << ";"; 1677f22ef01cSRoman Divacky OS << " dbg:"; 1678ffd1746dSEd Schouten printDebugLoc(debugLoc, MF, OS); 1679f22ef01cSRoman Divacky } 1680f22ef01cSRoman Divacky 16813b0f4066SDimitry Andric OS << '\n'; 1682f22ef01cSRoman Divacky } 1683f22ef01cSRoman Divacky 1684f22ef01cSRoman Divacky bool MachineInstr::addRegisterKilled(unsigned IncomingReg, 1685f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 1686f22ef01cSRoman Divacky bool AddIfNotFound) { 1687f22ef01cSRoman Divacky bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); 16887ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 16897ae0e2c9SDimitry Andric MCRegAliasIterator(IncomingReg, RegInfo, false).isValid(); 1690f22ef01cSRoman Divacky bool Found = false; 1691f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 1692f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1693f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1694f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse() || MO.isUndef()) 1695f22ef01cSRoman Divacky continue; 1696f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 1697f22ef01cSRoman Divacky if (!Reg) 1698f22ef01cSRoman Divacky continue; 1699f22ef01cSRoman Divacky 1700f22ef01cSRoman Divacky if (Reg == IncomingReg) { 1701f22ef01cSRoman Divacky if (!Found) { 1702f22ef01cSRoman Divacky if (MO.isKill()) 1703f22ef01cSRoman Divacky // The register is already marked kill. 1704f22ef01cSRoman Divacky return true; 1705f22ef01cSRoman Divacky if (isPhysReg && isRegTiedToDefOperand(i)) 1706f22ef01cSRoman Divacky // Two-address uses of physregs must not be marked kill. 1707f22ef01cSRoman Divacky return true; 1708f22ef01cSRoman Divacky MO.setIsKill(); 1709f22ef01cSRoman Divacky Found = true; 1710f22ef01cSRoman Divacky } 1711f22ef01cSRoman Divacky } else if (hasAliases && MO.isKill() && 1712f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg)) { 1713f22ef01cSRoman Divacky // A super-register kill already exists. 1714f22ef01cSRoman Divacky if (RegInfo->isSuperRegister(IncomingReg, Reg)) 1715f22ef01cSRoman Divacky return true; 1716f22ef01cSRoman Divacky if (RegInfo->isSubRegister(IncomingReg, Reg)) 1717f22ef01cSRoman Divacky DeadOps.push_back(i); 1718f22ef01cSRoman Divacky } 1719f22ef01cSRoman Divacky } 1720f22ef01cSRoman Divacky 1721f22ef01cSRoman Divacky // Trim unneeded kill operands. 1722f22ef01cSRoman Divacky while (!DeadOps.empty()) { 1723f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 1724f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 1725f22ef01cSRoman Divacky RemoveOperand(OpIdx); 1726f22ef01cSRoman Divacky else 1727f22ef01cSRoman Divacky getOperand(OpIdx).setIsKill(false); 1728f22ef01cSRoman Divacky DeadOps.pop_back(); 1729f22ef01cSRoman Divacky } 1730f22ef01cSRoman Divacky 1731f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is killed. Add a 1732f22ef01cSRoman Divacky // new implicit operand if required. 1733f22ef01cSRoman Divacky if (!Found && AddIfNotFound) { 1734f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(IncomingReg, 1735f22ef01cSRoman Divacky false /*IsDef*/, 1736f22ef01cSRoman Divacky true /*IsImp*/, 1737f22ef01cSRoman Divacky true /*IsKill*/)); 1738f22ef01cSRoman Divacky return true; 1739f22ef01cSRoman Divacky } 1740f22ef01cSRoman Divacky return Found; 1741f22ef01cSRoman Divacky } 1742f22ef01cSRoman Divacky 1743dff0c46cSDimitry Andric void MachineInstr::clearRegisterKills(unsigned Reg, 1744dff0c46cSDimitry Andric const TargetRegisterInfo *RegInfo) { 1745dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) 174691bc56edSDimitry Andric RegInfo = nullptr; 1747dff0c46cSDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1748dff0c46cSDimitry Andric MachineOperand &MO = getOperand(i); 1749dff0c46cSDimitry Andric if (!MO.isReg() || !MO.isUse() || !MO.isKill()) 1750dff0c46cSDimitry Andric continue; 1751dff0c46cSDimitry Andric unsigned OpReg = MO.getReg(); 1752dff0c46cSDimitry Andric if (OpReg == Reg || (RegInfo && RegInfo->isSuperRegister(Reg, OpReg))) 1753dff0c46cSDimitry Andric MO.setIsKill(false); 1754dff0c46cSDimitry Andric } 1755dff0c46cSDimitry Andric } 1756dff0c46cSDimitry Andric 1757f785676fSDimitry Andric bool MachineInstr::addRegisterDead(unsigned Reg, 1758f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 1759f22ef01cSRoman Divacky bool AddIfNotFound) { 1760f785676fSDimitry Andric bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(Reg); 17617ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 1762f785676fSDimitry Andric MCRegAliasIterator(Reg, RegInfo, false).isValid(); 1763f22ef01cSRoman Divacky bool Found = false; 1764f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 1765f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1766f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1767f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 1768f22ef01cSRoman Divacky continue; 1769f785676fSDimitry Andric unsigned MOReg = MO.getReg(); 1770f785676fSDimitry Andric if (!MOReg) 1771f22ef01cSRoman Divacky continue; 1772f22ef01cSRoman Divacky 1773f785676fSDimitry Andric if (MOReg == Reg) { 1774f22ef01cSRoman Divacky MO.setIsDead(); 1775f22ef01cSRoman Divacky Found = true; 1776f22ef01cSRoman Divacky } else if (hasAliases && MO.isDead() && 1777f785676fSDimitry Andric TargetRegisterInfo::isPhysicalRegister(MOReg)) { 1778f22ef01cSRoman Divacky // There exists a super-register that's marked dead. 1779f785676fSDimitry Andric if (RegInfo->isSuperRegister(Reg, MOReg)) 1780f22ef01cSRoman Divacky return true; 1781f785676fSDimitry Andric if (RegInfo->isSubRegister(Reg, MOReg)) 1782f22ef01cSRoman Divacky DeadOps.push_back(i); 1783f22ef01cSRoman Divacky } 1784f22ef01cSRoman Divacky } 1785f22ef01cSRoman Divacky 1786f22ef01cSRoman Divacky // Trim unneeded dead operands. 1787f22ef01cSRoman Divacky while (!DeadOps.empty()) { 1788f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 1789f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 1790f22ef01cSRoman Divacky RemoveOperand(OpIdx); 1791f22ef01cSRoman Divacky else 1792f22ef01cSRoman Divacky getOperand(OpIdx).setIsDead(false); 1793f22ef01cSRoman Divacky DeadOps.pop_back(); 1794f22ef01cSRoman Divacky } 1795f22ef01cSRoman Divacky 1796f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is dead. Add a 1797f22ef01cSRoman Divacky // new implicit operand if required. 1798f22ef01cSRoman Divacky if (Found || !AddIfNotFound) 1799f22ef01cSRoman Divacky return Found; 1800f22ef01cSRoman Divacky 1801f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 1802f22ef01cSRoman Divacky true /*IsDef*/, 1803f22ef01cSRoman Divacky true /*IsImp*/, 1804f22ef01cSRoman Divacky false /*IsKill*/, 1805f22ef01cSRoman Divacky true /*IsDead*/)); 1806f22ef01cSRoman Divacky return true; 1807f22ef01cSRoman Divacky } 1808f22ef01cSRoman Divacky 1809f785676fSDimitry Andric void MachineInstr::addRegisterDefined(unsigned Reg, 1810f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo) { 1811f785676fSDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 1812f785676fSDimitry Andric MachineOperand *MO = findRegisterDefOperand(Reg, false, RegInfo); 1813f22ef01cSRoman Divacky if (MO) 1814f22ef01cSRoman Divacky return; 1815f22ef01cSRoman Divacky } else { 1816f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1817f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1818f785676fSDimitry Andric if (MO.isReg() && MO.getReg() == Reg && MO.isDef() && 1819f22ef01cSRoman Divacky MO.getSubReg() == 0) 1820f22ef01cSRoman Divacky return; 1821f22ef01cSRoman Divacky } 1822f22ef01cSRoman Divacky } 1823f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 1824f22ef01cSRoman Divacky true /*IsDef*/, 1825f22ef01cSRoman Divacky true /*IsImp*/)); 1826f22ef01cSRoman Divacky } 1827f22ef01cSRoman Divacky 1828dff0c46cSDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs, 1829ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 1830dff0c46cSDimitry Andric bool HasRegMask = false; 1831ffd1746dSEd Schouten for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1832ffd1746dSEd Schouten MachineOperand &MO = getOperand(i); 1833dff0c46cSDimitry Andric if (MO.isRegMask()) { 1834dff0c46cSDimitry Andric HasRegMask = true; 1835dff0c46cSDimitry Andric continue; 1836dff0c46cSDimitry Andric } 1837ffd1746dSEd Schouten if (!MO.isReg() || !MO.isDef()) continue; 1838ffd1746dSEd Schouten unsigned Reg = MO.getReg(); 1839dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; 1840ffd1746dSEd Schouten bool Dead = true; 1841dff0c46cSDimitry Andric for (ArrayRef<unsigned>::iterator I = UsedRegs.begin(), E = UsedRegs.end(); 1842dff0c46cSDimitry Andric I != E; ++I) 1843ffd1746dSEd Schouten if (TRI.regsOverlap(*I, Reg)) { 1844ffd1746dSEd Schouten Dead = false; 1845ffd1746dSEd Schouten break; 1846ffd1746dSEd Schouten } 1847ffd1746dSEd Schouten // If there are no uses, including partial uses, the def is dead. 1848ffd1746dSEd Schouten if (Dead) MO.setIsDead(); 1849ffd1746dSEd Schouten } 1850dff0c46cSDimitry Andric 1851dff0c46cSDimitry Andric // This is a call with a register mask operand. 1852dff0c46cSDimitry Andric // Mask clobbers are always dead, so add defs for the non-dead defines. 1853dff0c46cSDimitry Andric if (HasRegMask) 1854dff0c46cSDimitry Andric for (ArrayRef<unsigned>::iterator I = UsedRegs.begin(), E = UsedRegs.end(); 1855dff0c46cSDimitry Andric I != E; ++I) 1856dff0c46cSDimitry Andric addRegisterDefined(*I, &TRI); 1857ffd1746dSEd Schouten } 1858ffd1746dSEd Schouten 1859f22ef01cSRoman Divacky unsigned 1860f22ef01cSRoman Divacky MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { 1861dff0c46cSDimitry Andric // Build up a buffer of hash code components. 1862dff0c46cSDimitry Andric SmallVector<size_t, 8> HashComponents; 1863dff0c46cSDimitry Andric HashComponents.reserve(MI->getNumOperands() + 1); 1864dff0c46cSDimitry Andric HashComponents.push_back(MI->getOpcode()); 1865f22ef01cSRoman Divacky for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 1866f22ef01cSRoman Divacky const MachineOperand &MO = MI->getOperand(i); 18677ae0e2c9SDimitry Andric if (MO.isReg() && MO.isDef() && 18687ae0e2c9SDimitry Andric TargetRegisterInfo::isVirtualRegister(MO.getReg())) 1869f22ef01cSRoman Divacky continue; // Skip virtual register defs. 18707ae0e2c9SDimitry Andric 18717ae0e2c9SDimitry Andric HashComponents.push_back(hash_value(MO)); 1872f22ef01cSRoman Divacky } 1873dff0c46cSDimitry Andric return hash_combine_range(HashComponents.begin(), HashComponents.end()); 1874f22ef01cSRoman Divacky } 187517a519f9SDimitry Andric 187617a519f9SDimitry Andric void MachineInstr::emitError(StringRef Msg) const { 187717a519f9SDimitry Andric // Find the source location cookie. 187817a519f9SDimitry Andric unsigned LocCookie = 0; 187991bc56edSDimitry Andric const MDNode *LocMD = nullptr; 188017a519f9SDimitry Andric for (unsigned i = getNumOperands(); i != 0; --i) { 188117a519f9SDimitry Andric if (getOperand(i-1).isMetadata() && 188217a519f9SDimitry Andric (LocMD = getOperand(i-1).getMetadata()) && 188317a519f9SDimitry Andric LocMD->getNumOperands() != 0) { 188417a519f9SDimitry Andric if (const ConstantInt *CI = dyn_cast<ConstantInt>(LocMD->getOperand(0))) { 188517a519f9SDimitry Andric LocCookie = CI->getZExtValue(); 188617a519f9SDimitry Andric break; 188717a519f9SDimitry Andric } 188817a519f9SDimitry Andric } 188917a519f9SDimitry Andric } 189017a519f9SDimitry Andric 189117a519f9SDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 189217a519f9SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 189317a519f9SDimitry Andric return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg); 189417a519f9SDimitry Andric report_fatal_error(Msg); 189517a519f9SDimitry Andric } 1896