1f9448bf3SDimitry Andric //===- 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 14db17bf38SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 15f9448bf3SDimitry Andric #include "llvm/ADT/APFloat.h" 16f9448bf3SDimitry Andric #include "llvm/ADT/ArrayRef.h" 17139f7f9bSDimitry Andric #include "llvm/ADT/FoldingSet.h" 18139f7f9bSDimitry Andric #include "llvm/ADT/Hashing.h" 19f9448bf3SDimitry Andric #include "llvm/ADT/None.h" 20db17bf38SDimitry Andric #include "llvm/ADT/STLExtras.h" 212cab237bSDimitry Andric #include "llvm/ADT/SmallBitVector.h" 22f9448bf3SDimitry Andric #include "llvm/ADT/SmallString.h" 23f9448bf3SDimitry Andric #include "llvm/ADT/SmallVector.h" 24139f7f9bSDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 25edd7eaddSDimitry Andric #include "llvm/Analysis/Loads.h" 26f9448bf3SDimitry Andric #include "llvm/Analysis/MemoryLocation.h" 27f9448bf3SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 28f9448bf3SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 29f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunction.h" 303ca95b02SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 31f9448bf3SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h" 32f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineMemOperand.h" 3317a519f9SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 34f9448bf3SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 35f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h" 36f22ef01cSRoman Divacky #include "llvm/CodeGen/PseudoSourceValue.h" 372cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 382cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 392cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 40139f7f9bSDimitry Andric #include "llvm/IR/Constants.h" 41f9448bf3SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 42f9448bf3SDimitry Andric #include "llvm/IR/DebugLoc.h" 43f9448bf3SDimitry Andric #include "llvm/IR/DerivedTypes.h" 44139f7f9bSDimitry Andric #include "llvm/IR/Function.h" 45139f7f9bSDimitry Andric #include "llvm/IR/InlineAsm.h" 46f9448bf3SDimitry Andric #include "llvm/IR/InstrTypes.h" 47d88c1a5aSDimitry Andric #include "llvm/IR/Intrinsics.h" 48139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h" 49139f7f9bSDimitry Andric #include "llvm/IR/Metadata.h" 50139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 513dac3a9bSDimitry Andric #include "llvm/IR/ModuleSlotTracker.h" 52139f7f9bSDimitry Andric #include "llvm/IR/Type.h" 53139f7f9bSDimitry Andric #include "llvm/IR/Value.h" 5417a519f9SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 55f9448bf3SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 56db17bf38SDimitry Andric #include "llvm/MC/MCSymbol.h" 57f9448bf3SDimitry Andric #include "llvm/Support/Casting.h" 587d523365SDimitry Andric #include "llvm/Support/CommandLine.h" 59f9448bf3SDimitry Andric #include "llvm/Support/Compiler.h" 60f22ef01cSRoman Divacky #include "llvm/Support/Debug.h" 61f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 62f9448bf3SDimitry Andric #include "llvm/Support/LowLevelTypeImpl.h" 63f22ef01cSRoman Divacky #include "llvm/Support/MathExtras.h" 64f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 65d88c1a5aSDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h" 66139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h" 67f9448bf3SDimitry Andric #include <algorithm> 68f9448bf3SDimitry Andric #include <cassert> 69f9448bf3SDimitry Andric #include <cstddef> 70f9448bf3SDimitry Andric #include <cstdint> 71f9448bf3SDimitry Andric #include <cstring> 72f9448bf3SDimitry Andric #include <iterator> 73f9448bf3SDimitry Andric #include <utility> 74f9448bf3SDimitry Andric 75f22ef01cSRoman Divacky using namespace llvm; 76f22ef01cSRoman Divacky 77139f7f9bSDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { 7817a519f9SDimitry Andric if (MCID->ImplicitDefs) 797d523365SDimitry Andric for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; 807d523365SDimitry Andric ++ImpDefs) 81139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true)); 8217a519f9SDimitry Andric if (MCID->ImplicitUses) 837d523365SDimitry Andric for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses; 847d523365SDimitry Andric ++ImpUses) 85139f7f9bSDimitry Andric addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true)); 86f22ef01cSRoman Divacky } 87f22ef01cSRoman Divacky 88f22ef01cSRoman Divacky /// MachineInstr ctor - This constructor creates a MachineInstr and adds the 89f22ef01cSRoman Divacky /// implicit operands. It reserves space for the number of operands specified by 9017a519f9SDimitry Andric /// the MCInstrDesc. 91139f7f9bSDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid, 92ff0cc061SDimitry Andric DebugLoc dl, bool NoImp) 93f9448bf3SDimitry Andric : MCID(&tid), debugLoc(std::move(dl)) { 9439d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 9539d628a0SDimitry Andric 96139f7f9bSDimitry Andric // Reserve space for the expected number of operands. 97139f7f9bSDimitry Andric if (unsigned NumOps = MCID->getNumOperands() + 98139f7f9bSDimitry Andric MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) { 99139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(NumOps); 100139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 101f22ef01cSRoman Divacky } 102f22ef01cSRoman Divacky 103139f7f9bSDimitry Andric if (!NoImp) 104139f7f9bSDimitry Andric addImplicitDefUseOperands(MF); 105f22ef01cSRoman Divacky } 106f22ef01cSRoman Divacky 107f22ef01cSRoman Divacky /// MachineInstr ctor - Copies MachineInstr arg exactly 108f22ef01cSRoman Divacky /// 109f22ef01cSRoman Divacky MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) 110f9448bf3SDimitry Andric : MCID(&MI.getDesc()), NumMemRefs(MI.NumMemRefs), MemRefs(MI.MemRefs), 111f9448bf3SDimitry Andric debugLoc(MI.getDebugLoc()) { 11239d628a0SDimitry Andric assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor"); 11339d628a0SDimitry Andric 114139f7f9bSDimitry Andric CapOperands = OperandCapacity::get(MI.getNumOperands()); 115139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 116f22ef01cSRoman Divacky 117139f7f9bSDimitry Andric // Copy operands. 118ff0cc061SDimitry Andric for (const MachineOperand &MO : MI.operands()) 119ff0cc061SDimitry Andric addOperand(MF, MO); 120f22ef01cSRoman Divacky 121139f7f9bSDimitry Andric // Copy all the sensible flags. 122139f7f9bSDimitry Andric setFlags(MI.Flags); 123f22ef01cSRoman Divacky } 124f22ef01cSRoman Divacky 125f22ef01cSRoman Divacky /// getRegInfo - If this instruction is embedded into a MachineFunction, 126f22ef01cSRoman Divacky /// return the MachineRegisterInfo object for the current function, otherwise 127f22ef01cSRoman Divacky /// return null. 128f22ef01cSRoman Divacky MachineRegisterInfo *MachineInstr::getRegInfo() { 129f22ef01cSRoman Divacky if (MachineBasicBlock *MBB = getParent()) 130f22ef01cSRoman Divacky return &MBB->getParent()->getRegInfo(); 13191bc56edSDimitry Andric return nullptr; 132f22ef01cSRoman Divacky } 133f22ef01cSRoman Divacky 134f22ef01cSRoman Divacky /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in 135f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 136f22ef01cSRoman Divacky /// operands already be on their use lists. 1377ae0e2c9SDimitry Andric void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) { 138ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 139ff0cc061SDimitry Andric if (MO.isReg()) 140ff0cc061SDimitry Andric MRI.removeRegOperandFromUseList(&MO); 141f22ef01cSRoman Divacky } 142f22ef01cSRoman Divacky 143f22ef01cSRoman Divacky /// AddRegOperandsToUseLists - Add all of the register operands in 144f22ef01cSRoman Divacky /// this instruction from their respective use lists. This requires that the 145f22ef01cSRoman Divacky /// operands not be on their use lists yet. 1467ae0e2c9SDimitry Andric void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) { 147ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) 148ff0cc061SDimitry Andric if (MO.isReg()) 149ff0cc061SDimitry Andric MRI.addRegOperandToUseList(&MO); 150f22ef01cSRoman Divacky } 151f22ef01cSRoman Divacky 152139f7f9bSDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) { 153139f7f9bSDimitry Andric MachineBasicBlock *MBB = getParent(); 154139f7f9bSDimitry Andric assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs"); 155139f7f9bSDimitry Andric MachineFunction *MF = MBB->getParent(); 156139f7f9bSDimitry Andric assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs"); 157139f7f9bSDimitry Andric addOperand(*MF, Op); 158139f7f9bSDimitry Andric } 159139f7f9bSDimitry Andric 160139f7f9bSDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping 161139f7f9bSDimitry Andric /// ranges. If MRI is non-null also update use-def chains. 162139f7f9bSDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src, 163139f7f9bSDimitry Andric unsigned NumOps, MachineRegisterInfo *MRI) { 164139f7f9bSDimitry Andric if (MRI) 165139f7f9bSDimitry Andric return MRI->moveOperands(Dst, Src, NumOps); 166139f7f9bSDimitry Andric 167ff0cc061SDimitry Andric // MachineOperand is a trivially copyable type so we can just use memmove. 168ff0cc061SDimitry Andric std::memmove(Dst, Src, NumOps * sizeof(MachineOperand)); 169139f7f9bSDimitry Andric } 170139f7f9bSDimitry Andric 171f22ef01cSRoman Divacky /// addOperand - Add the specified operand to the instruction. If it is an 172f22ef01cSRoman Divacky /// implicit operand, it is added to the end of the operand list. If it is 173f22ef01cSRoman Divacky /// an explicit operand it is added at the end of the explicit operand list 174f22ef01cSRoman Divacky /// (before the first implicit operand). 175139f7f9bSDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { 1766122f3e6SDimitry Andric assert(MCID && "Cannot add operands before providing an instr descriptor"); 177f22ef01cSRoman Divacky 178139f7f9bSDimitry Andric // Check if we're adding one of our existing operands. 179139f7f9bSDimitry Andric if (&Op >= Operands && &Op < Operands + NumOperands) { 180139f7f9bSDimitry Andric // This is unusual: MI->addOperand(MI->getOperand(i)). 181139f7f9bSDimitry Andric // If adding Op requires reallocating or moving existing operands around, 182139f7f9bSDimitry Andric // the Op reference could go stale. Support it by copying Op. 183139f7f9bSDimitry Andric MachineOperand CopyOp(Op); 184139f7f9bSDimitry Andric return addOperand(MF, CopyOp); 185139f7f9bSDimitry Andric } 186f22ef01cSRoman Divacky 1876122f3e6SDimitry Andric // Find the insert location for the new operand. Implicit registers go at 188139f7f9bSDimitry Andric // the end, everything else goes before the implicit regs. 189139f7f9bSDimitry Andric // 1906122f3e6SDimitry Andric // FIXME: Allow mixed explicit and implicit operands on inline asm. 1916122f3e6SDimitry Andric // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as 1926122f3e6SDimitry Andric // implicit-defs, but they must not be moved around. See the FIXME in 1936122f3e6SDimitry Andric // InstrEmitter.cpp. 194139f7f9bSDimitry Andric unsigned OpNo = getNumOperands(); 195139f7f9bSDimitry Andric bool isImpReg = Op.isReg() && Op.isImplicit(); 1966122f3e6SDimitry Andric if (!isImpReg && !isInlineAsm()) { 1976122f3e6SDimitry Andric while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) { 1986122f3e6SDimitry Andric --OpNo; 1993861d79fSDimitry Andric assert(!Operands[OpNo].isTied() && "Cannot move tied operands"); 200f22ef01cSRoman Divacky } 201f22ef01cSRoman Divacky } 202f22ef01cSRoman Divacky 203f785676fSDimitry Andric #ifndef NDEBUG 204f785676fSDimitry Andric bool isMetaDataOp = Op.getType() == MachineOperand::MO_Metadata; 2056122f3e6SDimitry Andric // OpNo now points as the desired insertion point. Unless this is a variadic 2066122f3e6SDimitry Andric // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). 2077ae0e2c9SDimitry Andric // RegMask operands go between the explicit and implicit operands. 2087ae0e2c9SDimitry Andric assert((isImpReg || Op.isRegMask() || MCID->isVariadic() || 209f785676fSDimitry Andric OpNo < MCID->getNumOperands() || isMetaDataOp) && 2106122f3e6SDimitry Andric "Trying to add an operand to a machine instr that is already done!"); 211f785676fSDimitry Andric #endif 212f22ef01cSRoman Divacky 213139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 214f22ef01cSRoman Divacky 215139f7f9bSDimitry Andric // Determine if the Operands array needs to be reallocated. 216139f7f9bSDimitry Andric // Save the old capacity and operand array. 217139f7f9bSDimitry Andric OperandCapacity OldCap = CapOperands; 218139f7f9bSDimitry Andric MachineOperand *OldOperands = Operands; 219139f7f9bSDimitry Andric if (!OldOperands || OldCap.getSize() == getNumOperands()) { 220139f7f9bSDimitry Andric CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1); 221139f7f9bSDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 222139f7f9bSDimitry Andric // Move the operands before the insertion point. 223139f7f9bSDimitry Andric if (OpNo) 224139f7f9bSDimitry Andric moveOperands(Operands, OldOperands, OpNo, MRI); 225139f7f9bSDimitry Andric } 226f22ef01cSRoman Divacky 227139f7f9bSDimitry Andric // Move the operands following the insertion point. 228139f7f9bSDimitry Andric if (OpNo != NumOperands) 229139f7f9bSDimitry Andric moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo, 230139f7f9bSDimitry Andric MRI); 231139f7f9bSDimitry Andric ++NumOperands; 2326122f3e6SDimitry Andric 233139f7f9bSDimitry Andric // Deallocate the old operand array. 234139f7f9bSDimitry Andric if (OldOperands != Operands && OldOperands) 235139f7f9bSDimitry Andric MF.deallocateOperandArray(OldCap, OldOperands); 236139f7f9bSDimitry Andric 237139f7f9bSDimitry Andric // Copy Op into place. It still needs to be inserted into the MRI use lists. 238139f7f9bSDimitry Andric MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op); 239139f7f9bSDimitry Andric NewMO->ParentMI = this; 240139f7f9bSDimitry Andric 241139f7f9bSDimitry Andric // When adding a register operand, tell MRI about it. 242139f7f9bSDimitry Andric if (NewMO->isReg()) { 2437ae0e2c9SDimitry Andric // Ensure isOnRegUseList() returns false, regardless of Op's status. 24491bc56edSDimitry Andric NewMO->Contents.Reg.Prev = nullptr; 2453861d79fSDimitry Andric // Ignore existing ties. This is not a property that can be copied. 246139f7f9bSDimitry Andric NewMO->TiedTo = 0; 247139f7f9bSDimitry Andric // Add the new operand to MRI, but only for instructions in an MBB. 248139f7f9bSDimitry Andric if (MRI) 249139f7f9bSDimitry Andric MRI->addRegOperandToUseList(NewMO); 2503861d79fSDimitry Andric // The MCID operand information isn't accurate until we start adding 2513861d79fSDimitry Andric // explicit operands. The implicit operands are added first, then the 2523861d79fSDimitry Andric // explicits are inserted before them. 2533861d79fSDimitry Andric if (!isImpReg) { 2543861d79fSDimitry Andric // Tie uses to defs as indicated in MCInstrDesc. 255139f7f9bSDimitry Andric if (NewMO->isUse()) { 2563861d79fSDimitry Andric int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO); 2573861d79fSDimitry Andric if (DefIdx != -1) 2583861d79fSDimitry Andric tieOperands(DefIdx, OpNo); 2593861d79fSDimitry Andric } 2606122f3e6SDimitry Andric // If the register operand is flagged as early, mark the operand as such. 26117a519f9SDimitry Andric if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) 262139f7f9bSDimitry Andric NewMO->setIsEarlyClobber(true); 263f22ef01cSRoman Divacky } 264f22ef01cSRoman Divacky } 265f22ef01cSRoman Divacky } 266f22ef01cSRoman Divacky 267f22ef01cSRoman Divacky /// RemoveOperand - Erase an operand from an instruction, leaving it with one 268f22ef01cSRoman Divacky /// fewer operand than it started with. 269f22ef01cSRoman Divacky /// 270f22ef01cSRoman Divacky void MachineInstr::RemoveOperand(unsigned OpNo) { 271139f7f9bSDimitry Andric assert(OpNo < getNumOperands() && "Invalid operand number"); 2723861d79fSDimitry Andric untieRegOperand(OpNo); 273f22ef01cSRoman Divacky 2743861d79fSDimitry Andric #ifndef NDEBUG 2753861d79fSDimitry Andric // Moving tied operands would break the ties. 276139f7f9bSDimitry Andric for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i) 2773861d79fSDimitry Andric if (Operands[i].isReg()) 2783861d79fSDimitry Andric assert(!Operands[i].isTied() && "Cannot move tied operands"); 2793861d79fSDimitry Andric #endif 2803861d79fSDimitry Andric 281139f7f9bSDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 282139f7f9bSDimitry Andric if (MRI && Operands[OpNo].isReg()) 283139f7f9bSDimitry Andric MRI->removeRegOperandFromUseList(Operands + OpNo); 284f22ef01cSRoman Divacky 285139f7f9bSDimitry Andric // Don't call the MachineOperand destructor. A lot of this code depends on 286139f7f9bSDimitry Andric // MachineOperand having a trivial destructor anyway, and adding a call here 287139f7f9bSDimitry Andric // wouldn't make it 'destructor-correct'. 288139f7f9bSDimitry Andric 289139f7f9bSDimitry Andric if (unsigned N = NumOperands - 1 - OpNo) 290139f7f9bSDimitry Andric moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI); 291139f7f9bSDimitry Andric --NumOperands; 292f22ef01cSRoman Divacky } 293f22ef01cSRoman Divacky 294f22ef01cSRoman Divacky /// addMemOperand - Add a MachineMemOperand to the machine instruction. 295f22ef01cSRoman Divacky /// This function should be used only occasionally. The setMemRefs function 296f22ef01cSRoman Divacky /// is the primary method for setting up a MachineInstr's MemRefs list. 297f22ef01cSRoman Divacky void MachineInstr::addMemOperand(MachineFunction &MF, 298f22ef01cSRoman Divacky MachineMemOperand *MO) { 299f22ef01cSRoman Divacky mmo_iterator OldMemRefs = MemRefs; 300139f7f9bSDimitry Andric unsigned OldNumMemRefs = NumMemRefs; 301f22ef01cSRoman Divacky 302139f7f9bSDimitry Andric unsigned NewNum = NumMemRefs + 1; 303f22ef01cSRoman Divacky mmo_iterator NewMemRefs = MF.allocateMemRefsArray(NewNum); 304f22ef01cSRoman Divacky 305dff0c46cSDimitry Andric std::copy(OldMemRefs, OldMemRefs + OldNumMemRefs, NewMemRefs); 306f22ef01cSRoman Divacky NewMemRefs[NewNum - 1] = MO; 307139f7f9bSDimitry Andric setMemRefs(NewMemRefs, NewMemRefs + NewNum); 308dff0c46cSDimitry Andric } 309dff0c46cSDimitry Andric 310444ed5c5SDimitry Andric /// Check to see if the MMOs pointed to by the two MemRefs arrays are 311444ed5c5SDimitry Andric /// identical. 312444ed5c5SDimitry Andric static bool hasIdenticalMMOs(const MachineInstr &MI1, const MachineInstr &MI2) { 313444ed5c5SDimitry Andric auto I1 = MI1.memoperands_begin(), E1 = MI1.memoperands_end(); 314444ed5c5SDimitry Andric auto I2 = MI2.memoperands_begin(), E2 = MI2.memoperands_end(); 315444ed5c5SDimitry Andric if ((E1 - I1) != (E2 - I2)) 316444ed5c5SDimitry Andric return false; 317444ed5c5SDimitry Andric for (; I1 != E1; ++I1, ++I2) { 318444ed5c5SDimitry Andric if (**I1 != **I2) 319444ed5c5SDimitry Andric return false; 320444ed5c5SDimitry Andric } 321444ed5c5SDimitry Andric return true; 322444ed5c5SDimitry Andric } 323444ed5c5SDimitry Andric 3244d0b32cdSDimitry Andric std::pair<MachineInstr::mmo_iterator, unsigned> 3254d0b32cdSDimitry Andric MachineInstr::mergeMemRefsWith(const MachineInstr& Other) { 326444ed5c5SDimitry Andric 327444ed5c5SDimitry Andric // If either of the incoming memrefs are empty, we must be conservative and 328444ed5c5SDimitry Andric // treat this as if we've exhausted our space for memrefs and dropped them. 329444ed5c5SDimitry Andric if (memoperands_empty() || Other.memoperands_empty()) 330444ed5c5SDimitry Andric return std::make_pair(nullptr, 0); 331444ed5c5SDimitry Andric 332444ed5c5SDimitry Andric // If both instructions have identical memrefs, we don't need to merge them. 333444ed5c5SDimitry Andric // Since many instructions have a single memref, and we tend to merge things 334444ed5c5SDimitry Andric // like pairs of loads from the same location, this catches a large number of 335444ed5c5SDimitry Andric // cases in practice. 336444ed5c5SDimitry Andric if (hasIdenticalMMOs(*this, Other)) 337444ed5c5SDimitry Andric return std::make_pair(MemRefs, NumMemRefs); 338444ed5c5SDimitry Andric 3394d0b32cdSDimitry Andric // TODO: consider uniquing elements within the operand lists to reduce 3404d0b32cdSDimitry Andric // space usage and fall back to conservative information less often. 341444ed5c5SDimitry Andric size_t CombinedNumMemRefs = NumMemRefs + Other.NumMemRefs; 342444ed5c5SDimitry Andric 343444ed5c5SDimitry Andric // If we don't have enough room to store this many memrefs, be conservative 344444ed5c5SDimitry Andric // and drop them. Otherwise, we'd fail asserts when trying to add them to 345444ed5c5SDimitry Andric // the new instruction. 346444ed5c5SDimitry Andric if (CombinedNumMemRefs != uint8_t(CombinedNumMemRefs)) 347444ed5c5SDimitry Andric return std::make_pair(nullptr, 0); 3484d0b32cdSDimitry Andric 3492cab237bSDimitry Andric MachineFunction *MF = getMF(); 3504d0b32cdSDimitry Andric mmo_iterator MemBegin = MF->allocateMemRefsArray(CombinedNumMemRefs); 3514d0b32cdSDimitry Andric mmo_iterator MemEnd = std::copy(memoperands_begin(), memoperands_end(), 3524d0b32cdSDimitry Andric MemBegin); 3534d0b32cdSDimitry Andric MemEnd = std::copy(Other.memoperands_begin(), Other.memoperands_end(), 3544d0b32cdSDimitry Andric MemEnd); 3554d0b32cdSDimitry Andric assert(MemEnd - MemBegin == (ptrdiff_t)CombinedNumMemRefs && 3564d0b32cdSDimitry Andric "missing memrefs"); 3574d0b32cdSDimitry Andric 3584d0b32cdSDimitry Andric return std::make_pair(MemBegin, CombinedNumMemRefs); 3594d0b32cdSDimitry Andric } 3604d0b32cdSDimitry Andric 361dff0c46cSDimitry Andric bool MachineInstr::hasPropertyInBundle(unsigned Mask, QueryType Type) const { 362139f7f9bSDimitry Andric assert(!isBundledWithPred() && "Must be called on bundle header"); 3637d523365SDimitry Andric for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) { 364dff0c46cSDimitry Andric if (MII->getDesc().getFlags() & Mask) { 365dff0c46cSDimitry Andric if (Type == AnyInBundle) 366dff0c46cSDimitry Andric return true; 367dff0c46cSDimitry Andric } else { 368139f7f9bSDimitry Andric if (Type == AllInBundle && !MII->isBundle()) 369dff0c46cSDimitry Andric return false; 370dff0c46cSDimitry Andric } 371139f7f9bSDimitry Andric // This was the last instruction in the bundle. 372139f7f9bSDimitry Andric if (!MII->isBundledWithSucc()) 373dff0c46cSDimitry Andric return Type == AllInBundle; 374f22ef01cSRoman Divacky } 375139f7f9bSDimitry Andric } 376f22ef01cSRoman Divacky 3773ca95b02SDimitry Andric bool MachineInstr::isIdenticalTo(const MachineInstr &Other, 378f22ef01cSRoman Divacky MICheckType Check) const { 379f22ef01cSRoman Divacky // If opcodes or number of operands are not the same then the two 380f22ef01cSRoman Divacky // instructions are obviously not identical. 3813ca95b02SDimitry Andric if (Other.getOpcode() != getOpcode() || 3823ca95b02SDimitry Andric Other.getNumOperands() != getNumOperands()) 383f22ef01cSRoman Divacky return false; 384f22ef01cSRoman Divacky 385dff0c46cSDimitry Andric if (isBundle()) { 386d88c1a5aSDimitry Andric // We have passed the test above that both instructions have the same 387d88c1a5aSDimitry Andric // opcode, so we know that both instructions are bundles here. Let's compare 388d88c1a5aSDimitry Andric // MIs inside the bundle. 389d88c1a5aSDimitry Andric assert(Other.isBundle() && "Expected that both instructions are bundles."); 3907d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I1 = getIterator(); 3913ca95b02SDimitry Andric MachineBasicBlock::const_instr_iterator I2 = Other.getIterator(); 392d88c1a5aSDimitry Andric // Loop until we analysed the last intruction inside at least one of the 393d88c1a5aSDimitry Andric // bundles. 394d88c1a5aSDimitry Andric while (I1->isBundledWithSucc() && I2->isBundledWithSucc()) { 395d88c1a5aSDimitry Andric ++I1; 396dff0c46cSDimitry Andric ++I2; 397d88c1a5aSDimitry Andric if (!I1->isIdenticalTo(*I2, Check)) 398dff0c46cSDimitry Andric return false; 399dff0c46cSDimitry Andric } 400d88c1a5aSDimitry Andric // If we've reached the end of just one of the two bundles, but not both, 401d88c1a5aSDimitry Andric // the instructions are not identical. 402d88c1a5aSDimitry Andric if (I1->isBundledWithSucc() || I2->isBundledWithSucc()) 403d88c1a5aSDimitry Andric return false; 404dff0c46cSDimitry Andric } 405dff0c46cSDimitry Andric 406f22ef01cSRoman Divacky // Check operands to make sure they match. 407f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 408f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 4093ca95b02SDimitry Andric const MachineOperand &OMO = Other.getOperand(i); 410bd5abe19SDimitry Andric if (!MO.isReg()) { 411bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 412bd5abe19SDimitry Andric return false; 413bd5abe19SDimitry Andric continue; 414bd5abe19SDimitry Andric } 415bd5abe19SDimitry Andric 416f22ef01cSRoman Divacky // Clients may or may not want to ignore defs when testing for equality. 417f22ef01cSRoman Divacky // For example, machine CSE pass only cares about finding common 418f22ef01cSRoman Divacky // subexpressions, so it's safe to ignore virtual register defs. 419bd5abe19SDimitry Andric if (MO.isDef()) { 420f22ef01cSRoman Divacky if (Check == IgnoreDefs) 421f22ef01cSRoman Divacky continue; 422bd5abe19SDimitry Andric else if (Check == IgnoreVRegDefs) { 4232cab237bSDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(MO.getReg()) || 4242cab237bSDimitry Andric !TargetRegisterInfo::isVirtualRegister(OMO.getReg())) 4252cab237bSDimitry Andric if (!MO.isIdenticalTo(OMO)) 426f22ef01cSRoman Divacky return false; 427bd5abe19SDimitry Andric } else { 428bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 429f22ef01cSRoman Divacky return false; 430bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isDead() != OMO.isDead()) 431bd5abe19SDimitry Andric return false; 432bd5abe19SDimitry Andric } 433bd5abe19SDimitry Andric } else { 434bd5abe19SDimitry Andric if (!MO.isIdenticalTo(OMO)) 435bd5abe19SDimitry Andric return false; 436bd5abe19SDimitry Andric if (Check == CheckKillDead && MO.isKill() != OMO.isKill()) 437bd5abe19SDimitry Andric return false; 438bd5abe19SDimitry Andric } 439f22ef01cSRoman Divacky } 44017a519f9SDimitry Andric // If DebugLoc does not match then two dbg.values are not identical. 44117a519f9SDimitry Andric if (isDebugValue()) 4423ca95b02SDimitry Andric if (getDebugLoc() && Other.getDebugLoc() && 4433ca95b02SDimitry Andric getDebugLoc() != Other.getDebugLoc()) 44417a519f9SDimitry Andric return false; 445f22ef01cSRoman Divacky return true; 446f22ef01cSRoman Divacky } 447f22ef01cSRoman Divacky 4482cab237bSDimitry Andric const MachineFunction *MachineInstr::getMF() const { 4492cab237bSDimitry Andric return getParent()->getParent(); 4502cab237bSDimitry Andric } 4512cab237bSDimitry Andric 452f22ef01cSRoman Divacky MachineInstr *MachineInstr::removeFromParent() { 453f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 454139f7f9bSDimitry Andric return getParent()->remove(this); 455f22ef01cSRoman Divacky } 456f22ef01cSRoman Divacky 457139f7f9bSDimitry Andric MachineInstr *MachineInstr::removeFromBundle() { 458139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 459139f7f9bSDimitry Andric return getParent()->remove_instr(this); 460139f7f9bSDimitry Andric } 461f22ef01cSRoman Divacky 462f22ef01cSRoman Divacky void MachineInstr::eraseFromParent() { 463f22ef01cSRoman Divacky assert(getParent() && "Not embedded in a basic block!"); 464139f7f9bSDimitry Andric getParent()->erase(this); 465f22ef01cSRoman Divacky } 466f22ef01cSRoman Divacky 46739d628a0SDimitry Andric void MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval() { 46839d628a0SDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 46939d628a0SDimitry Andric MachineBasicBlock *MBB = getParent(); 47039d628a0SDimitry Andric MachineFunction *MF = MBB->getParent(); 47139d628a0SDimitry Andric assert(MF && "Not embedded in a function!"); 47239d628a0SDimitry Andric 47339d628a0SDimitry Andric MachineInstr *MI = (MachineInstr *)this; 47439d628a0SDimitry Andric MachineRegisterInfo &MRI = MF->getRegInfo(); 47539d628a0SDimitry Andric 476ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 47739d628a0SDimitry Andric if (!MO.isReg() || !MO.isDef()) 47839d628a0SDimitry Andric continue; 47939d628a0SDimitry Andric unsigned Reg = MO.getReg(); 48039d628a0SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg)) 48139d628a0SDimitry Andric continue; 48239d628a0SDimitry Andric MRI.markUsesInDebugValueAsUndef(Reg); 48339d628a0SDimitry Andric } 48439d628a0SDimitry Andric MI->eraseFromParent(); 48539d628a0SDimitry Andric } 48639d628a0SDimitry Andric 487139f7f9bSDimitry Andric void MachineInstr::eraseFromBundle() { 488139f7f9bSDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 489139f7f9bSDimitry Andric getParent()->erase_instr(this); 490139f7f9bSDimitry Andric } 491f22ef01cSRoman Divacky 492f22ef01cSRoman Divacky /// getNumExplicitOperands - Returns the number of non-implicit operands. 493f22ef01cSRoman Divacky /// 494f22ef01cSRoman Divacky unsigned MachineInstr::getNumExplicitOperands() const { 49517a519f9SDimitry Andric unsigned NumOperands = MCID->getNumOperands(); 49617a519f9SDimitry Andric if (!MCID->isVariadic()) 497f22ef01cSRoman Divacky return NumOperands; 498f22ef01cSRoman Divacky 499f22ef01cSRoman Divacky for (unsigned i = NumOperands, e = getNumOperands(); i != e; ++i) { 500f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 501f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isImplicit()) 502f22ef01cSRoman Divacky NumOperands++; 503f22ef01cSRoman Divacky } 504f22ef01cSRoman Divacky return NumOperands; 505f22ef01cSRoman Divacky } 506f22ef01cSRoman Divacky 507139f7f9bSDimitry Andric void MachineInstr::bundleWithPred() { 508139f7f9bSDimitry Andric assert(!isBundledWithPred() && "MI is already bundled with its predecessor"); 509139f7f9bSDimitry Andric setFlag(BundledPred); 5107d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 511139f7f9bSDimitry Andric --Pred; 512139f7f9bSDimitry Andric assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 513139f7f9bSDimitry Andric Pred->setFlag(BundledSucc); 514139f7f9bSDimitry Andric } 515139f7f9bSDimitry Andric 516139f7f9bSDimitry Andric void MachineInstr::bundleWithSucc() { 517139f7f9bSDimitry Andric assert(!isBundledWithSucc() && "MI is already bundled with its successor"); 518139f7f9bSDimitry Andric setFlag(BundledSucc); 5197d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 520139f7f9bSDimitry Andric ++Succ; 521139f7f9bSDimitry Andric assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags"); 522139f7f9bSDimitry Andric Succ->setFlag(BundledPred); 523139f7f9bSDimitry Andric } 524139f7f9bSDimitry Andric 525139f7f9bSDimitry Andric void MachineInstr::unbundleFromPred() { 526139f7f9bSDimitry Andric assert(isBundledWithPred() && "MI isn't bundled with its predecessor"); 527139f7f9bSDimitry Andric clearFlag(BundledPred); 5287d523365SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 529139f7f9bSDimitry Andric --Pred; 530139f7f9bSDimitry Andric assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 531139f7f9bSDimitry Andric Pred->clearFlag(BundledSucc); 532139f7f9bSDimitry Andric } 533139f7f9bSDimitry Andric 534139f7f9bSDimitry Andric void MachineInstr::unbundleFromSucc() { 535139f7f9bSDimitry Andric assert(isBundledWithSucc() && "MI isn't bundled with its successor"); 536139f7f9bSDimitry Andric clearFlag(BundledSucc); 5377d523365SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 538139f7f9bSDimitry Andric ++Succ; 539139f7f9bSDimitry Andric assert(Succ->isBundledWithPred() && "Inconsistent bundle flags"); 540139f7f9bSDimitry Andric Succ->clearFlag(BundledPred); 541dff0c46cSDimitry Andric } 542dff0c46cSDimitry Andric 5432754fe60SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const { 5442754fe60SDimitry Andric if (isInlineAsm()) { 5452754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 5462754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 5472754fe60SDimitry Andric return true; 5482754fe60SDimitry Andric } 5492754fe60SDimitry Andric return false; 5502754fe60SDimitry Andric } 551f22ef01cSRoman Divacky 5523861d79fSDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const { 5533861d79fSDimitry Andric assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!"); 5543861d79fSDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 5553861d79fSDimitry Andric return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0); 5563861d79fSDimitry Andric } 5573861d79fSDimitry Andric 5586122f3e6SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx, 5596122f3e6SDimitry Andric unsigned *GroupNo) const { 5606122f3e6SDimitry Andric assert(isInlineAsm() && "Expected an inline asm instruction"); 5616122f3e6SDimitry Andric assert(OpIdx < getNumOperands() && "OpIdx out of range"); 5626122f3e6SDimitry Andric 5636122f3e6SDimitry Andric // Ignore queries about the initial operands. 5646122f3e6SDimitry Andric if (OpIdx < InlineAsm::MIOp_FirstOperand) 5656122f3e6SDimitry Andric return -1; 5666122f3e6SDimitry Andric 5676122f3e6SDimitry Andric unsigned Group = 0; 5686122f3e6SDimitry Andric unsigned NumOps; 5696122f3e6SDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 5706122f3e6SDimitry Andric i += NumOps) { 5716122f3e6SDimitry Andric const MachineOperand &FlagMO = getOperand(i); 5726122f3e6SDimitry Andric // If we reach the implicit register operands, stop looking. 5736122f3e6SDimitry Andric if (!FlagMO.isImm()) 5746122f3e6SDimitry Andric return -1; 5756122f3e6SDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 5766122f3e6SDimitry Andric if (i + NumOps > OpIdx) { 5776122f3e6SDimitry Andric if (GroupNo) 5786122f3e6SDimitry Andric *GroupNo = Group; 5796122f3e6SDimitry Andric return i; 5806122f3e6SDimitry Andric } 5816122f3e6SDimitry Andric ++Group; 5826122f3e6SDimitry Andric } 5836122f3e6SDimitry Andric return -1; 5846122f3e6SDimitry Andric } 5856122f3e6SDimitry Andric 5863ca95b02SDimitry Andric const DILocalVariable *MachineInstr::getDebugVariable() const { 5873ca95b02SDimitry Andric assert(isDebugValue() && "not a DBG_VALUE"); 5883ca95b02SDimitry Andric return cast<DILocalVariable>(getOperand(2).getMetadata()); 5893ca95b02SDimitry Andric } 5903ca95b02SDimitry Andric 5913ca95b02SDimitry Andric const DIExpression *MachineInstr::getDebugExpression() const { 5923ca95b02SDimitry Andric assert(isDebugValue() && "not a DBG_VALUE"); 5933ca95b02SDimitry Andric return cast<DIExpression>(getOperand(3).getMetadata()); 5943ca95b02SDimitry Andric } 5953ca95b02SDimitry Andric 5966122f3e6SDimitry Andric const TargetRegisterClass* 5976122f3e6SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx, 5986122f3e6SDimitry Andric const TargetInstrInfo *TII, 5996122f3e6SDimitry Andric const TargetRegisterInfo *TRI) const { 6007ae0e2c9SDimitry Andric assert(getParent() && "Can't have an MBB reference here!"); 6012cab237bSDimitry Andric assert(getMF() && "Can't have an MF reference here!"); 6022cab237bSDimitry Andric const MachineFunction &MF = *getMF(); 6037ae0e2c9SDimitry Andric 6046122f3e6SDimitry Andric // Most opcodes have fixed constraints in their MCInstrDesc. 6056122f3e6SDimitry Andric if (!isInlineAsm()) 6067ae0e2c9SDimitry Andric return TII->getRegClass(getDesc(), OpIdx, TRI, MF); 6076122f3e6SDimitry Andric 6086122f3e6SDimitry Andric if (!getOperand(OpIdx).isReg()) 60991bc56edSDimitry Andric return nullptr; 6106122f3e6SDimitry Andric 6116122f3e6SDimitry Andric // For tied uses on inline asm, get the constraint from the def. 6126122f3e6SDimitry Andric unsigned DefIdx; 6136122f3e6SDimitry Andric if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx)) 6146122f3e6SDimitry Andric OpIdx = DefIdx; 6156122f3e6SDimitry Andric 6166122f3e6SDimitry Andric // Inline asm stores register class constraints in the flag word. 6176122f3e6SDimitry Andric int FlagIdx = findInlineAsmFlagIdx(OpIdx); 6186122f3e6SDimitry Andric if (FlagIdx < 0) 61991bc56edSDimitry Andric return nullptr; 6206122f3e6SDimitry Andric 6216122f3e6SDimitry Andric unsigned Flag = getOperand(FlagIdx).getImm(); 6226122f3e6SDimitry Andric unsigned RCID; 6233ca95b02SDimitry Andric if ((InlineAsm::getKind(Flag) == InlineAsm::Kind_RegUse || 6243ca95b02SDimitry Andric InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDef || 6253ca95b02SDimitry Andric InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDefEarlyClobber) && 6263ca95b02SDimitry Andric InlineAsm::hasRegClassConstraint(Flag, RCID)) 6276122f3e6SDimitry Andric return TRI->getRegClass(RCID); 6286122f3e6SDimitry Andric 6296122f3e6SDimitry Andric // Assume that all registers in a memory operand are pointers. 6306122f3e6SDimitry Andric if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem) 6317ae0e2c9SDimitry Andric return TRI->getPointerRegClass(MF); 6326122f3e6SDimitry Andric 63391bc56edSDimitry Andric return nullptr; 63491bc56edSDimitry Andric } 63591bc56edSDimitry Andric 63691bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( 63791bc56edSDimitry Andric unsigned Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, 63891bc56edSDimitry Andric const TargetRegisterInfo *TRI, bool ExploreBundle) const { 63991bc56edSDimitry Andric // Check every operands inside the bundle if we have 64091bc56edSDimitry Andric // been asked to. 64191bc56edSDimitry Andric if (ExploreBundle) 6423ca95b02SDimitry Andric for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC; 64391bc56edSDimitry Andric ++OpndIt) 64491bc56edSDimitry Andric CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl( 64591bc56edSDimitry Andric OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); 64691bc56edSDimitry Andric else 64791bc56edSDimitry Andric // Otherwise, just check the current operands. 64897bc6c73SDimitry Andric for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) 64997bc6c73SDimitry Andric CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); 65091bc56edSDimitry Andric return CurRC; 65191bc56edSDimitry Andric } 65291bc56edSDimitry Andric 65391bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl( 65491bc56edSDimitry Andric unsigned OpIdx, unsigned Reg, const TargetRegisterClass *CurRC, 65591bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 65691bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 65791bc56edSDimitry Andric // Check if Reg is constrained by some of its use/def from MI. 65891bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 65991bc56edSDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 66091bc56edSDimitry Andric return CurRC; 66191bc56edSDimitry Andric // If yes, accumulate the constraints through the operand. 66291bc56edSDimitry Andric return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI); 66391bc56edSDimitry Andric } 66491bc56edSDimitry Andric 66591bc56edSDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( 66691bc56edSDimitry Andric unsigned OpIdx, const TargetRegisterClass *CurRC, 66791bc56edSDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 66891bc56edSDimitry Andric const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI); 66991bc56edSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 67091bc56edSDimitry Andric assert(MO.isReg() && 67191bc56edSDimitry Andric "Cannot get register constraints for non-register operand"); 67291bc56edSDimitry Andric assert(CurRC && "Invalid initial register class"); 67391bc56edSDimitry Andric if (unsigned SubIdx = MO.getSubReg()) { 67491bc56edSDimitry Andric if (OpRC) 67591bc56edSDimitry Andric CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx); 67691bc56edSDimitry Andric else 67791bc56edSDimitry Andric CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx); 67891bc56edSDimitry Andric } else if (OpRC) 67991bc56edSDimitry Andric CurRC = TRI->getCommonSubClass(CurRC, OpRC); 68091bc56edSDimitry Andric return CurRC; 6816122f3e6SDimitry Andric } 6826122f3e6SDimitry Andric 683139f7f9bSDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the 684139f7f9bSDimitry Andric /// header instruction. 685dff0c46cSDimitry Andric unsigned MachineInstr::getBundleSize() const { 6867d523365SDimitry Andric MachineBasicBlock::const_instr_iterator I = getIterator(); 687dff0c46cSDimitry Andric unsigned Size = 0; 6883ca95b02SDimitry Andric while (I->isBundledWithSucc()) { 6893ca95b02SDimitry Andric ++Size; 6903ca95b02SDimitry Andric ++I; 6913ca95b02SDimitry Andric } 692dff0c46cSDimitry Andric return Size; 693dff0c46cSDimitry Andric } 694dff0c46cSDimitry Andric 6953ca95b02SDimitry Andric /// Returns true if the MachineInstr has an implicit-use operand of exactly 6963ca95b02SDimitry Andric /// the given register (not considering sub/super-registers). 6973ca95b02SDimitry Andric bool MachineInstr::hasRegisterImplicitUseOperand(unsigned Reg) const { 6983ca95b02SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 6993ca95b02SDimitry Andric const MachineOperand &MO = getOperand(i); 7003ca95b02SDimitry Andric if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == Reg) 7013ca95b02SDimitry Andric return true; 7023ca95b02SDimitry Andric } 7033ca95b02SDimitry Andric return false; 7043ca95b02SDimitry Andric } 7053ca95b02SDimitry Andric 706f22ef01cSRoman Divacky /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of 707f22ef01cSRoman Divacky /// the specific register or -1 if it is not found. It further tightens 708f22ef01cSRoman Divacky /// the search criteria to a use that kills the register if isKill is true. 709d88c1a5aSDimitry Andric int MachineInstr::findRegisterUseOperandIdx( 710d88c1a5aSDimitry Andric unsigned Reg, bool isKill, const TargetRegisterInfo *TRI) const { 711f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 712f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 713f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse()) 714f22ef01cSRoman Divacky continue; 715f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 716f22ef01cSRoman Divacky if (!MOReg) 717f22ef01cSRoman Divacky continue; 718d88c1a5aSDimitry Andric if (MOReg == Reg || (TRI && TargetRegisterInfo::isPhysicalRegister(MOReg) && 719f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg) && 720f22ef01cSRoman Divacky TRI->isSubRegister(MOReg, Reg))) 721f22ef01cSRoman Divacky if (!isKill || MO.isKill()) 722f22ef01cSRoman Divacky return i; 723f22ef01cSRoman Divacky } 724f22ef01cSRoman Divacky return -1; 725f22ef01cSRoman Divacky } 726f22ef01cSRoman Divacky 727f22ef01cSRoman Divacky /// readsWritesVirtualRegister - Return a pair of bools (reads, writes) 728f22ef01cSRoman Divacky /// indicating if this instruction reads or writes Reg. This also considers 729f22ef01cSRoman Divacky /// partial defines. 730f22ef01cSRoman Divacky std::pair<bool,bool> 731f22ef01cSRoman Divacky MachineInstr::readsWritesVirtualRegister(unsigned Reg, 732f22ef01cSRoman Divacky SmallVectorImpl<unsigned> *Ops) const { 733f22ef01cSRoman Divacky bool PartDef = false; // Partial redefine. 734f22ef01cSRoman Divacky bool FullDef = false; // Full define. 735f22ef01cSRoman Divacky bool Use = false; 736f22ef01cSRoman Divacky 737f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 738f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 739f22ef01cSRoman Divacky if (!MO.isReg() || MO.getReg() != Reg) 740f22ef01cSRoman Divacky continue; 741f22ef01cSRoman Divacky if (Ops) 742f22ef01cSRoman Divacky Ops->push_back(i); 743f22ef01cSRoman Divacky if (MO.isUse()) 744f22ef01cSRoman Divacky Use |= !MO.isUndef(); 7456122f3e6SDimitry Andric else if (MO.getSubReg() && !MO.isUndef()) 7462cab237bSDimitry Andric // A partial def undef doesn't count as reading the register. 747f22ef01cSRoman Divacky PartDef = true; 748f22ef01cSRoman Divacky else 749f22ef01cSRoman Divacky FullDef = true; 750f22ef01cSRoman Divacky } 751f22ef01cSRoman Divacky // A partial redefine uses Reg unless there is also a full define. 752f22ef01cSRoman Divacky return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef); 753f22ef01cSRoman Divacky } 754f22ef01cSRoman Divacky 755f22ef01cSRoman Divacky /// findRegisterDefOperandIdx() - Returns the operand index that is a def of 756f22ef01cSRoman Divacky /// the specified register or -1 if it is not found. If isDead is true, defs 757f22ef01cSRoman Divacky /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it 758f22ef01cSRoman Divacky /// also checks if there is a def of a super-register. 759f22ef01cSRoman Divacky int 760f22ef01cSRoman Divacky MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap, 761f22ef01cSRoman Divacky const TargetRegisterInfo *TRI) const { 762f22ef01cSRoman Divacky bool isPhys = TargetRegisterInfo::isPhysicalRegister(Reg); 763f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 764f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 765dff0c46cSDimitry Andric // Accept regmask operands when Overlap is set. 766dff0c46cSDimitry Andric // Ignore them when looking for a specific def operand (Overlap == false). 767dff0c46cSDimitry Andric if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg)) 768dff0c46cSDimitry Andric return i; 769f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 770f22ef01cSRoman Divacky continue; 771f22ef01cSRoman Divacky unsigned MOReg = MO.getReg(); 772f22ef01cSRoman Divacky bool Found = (MOReg == Reg); 773f22ef01cSRoman Divacky if (!Found && TRI && isPhys && 774f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(MOReg)) { 775f22ef01cSRoman Divacky if (Overlap) 776f22ef01cSRoman Divacky Found = TRI->regsOverlap(MOReg, Reg); 777f22ef01cSRoman Divacky else 778f22ef01cSRoman Divacky Found = TRI->isSubRegister(MOReg, Reg); 779f22ef01cSRoman Divacky } 780f22ef01cSRoman Divacky if (Found && (!isDead || MO.isDead())) 781f22ef01cSRoman Divacky return i; 782f22ef01cSRoman Divacky } 783f22ef01cSRoman Divacky return -1; 784f22ef01cSRoman Divacky } 785f22ef01cSRoman Divacky 786f22ef01cSRoman Divacky /// findFirstPredOperandIdx() - Find the index of the first operand in the 787f22ef01cSRoman Divacky /// operand list that is used to represent the predicate. It returns -1 if 788f22ef01cSRoman Divacky /// none is found. 789f22ef01cSRoman Divacky int MachineInstr::findFirstPredOperandIdx() const { 7906122f3e6SDimitry Andric // Don't call MCID.findFirstPredOperandIdx() because this variant 7916122f3e6SDimitry Andric // is sometimes called on an instruction that's not yet complete, and 7926122f3e6SDimitry Andric // so the number of operands is less than the MCID indicates. In 7936122f3e6SDimitry Andric // particular, the PTX target does this. 79417a519f9SDimitry Andric const MCInstrDesc &MCID = getDesc(); 79517a519f9SDimitry Andric if (MCID.isPredicable()) { 796f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 79717a519f9SDimitry Andric if (MCID.OpInfo[i].isPredicate()) 798f22ef01cSRoman Divacky return i; 799f22ef01cSRoman Divacky } 800f22ef01cSRoman Divacky 801f22ef01cSRoman Divacky return -1; 802f22ef01cSRoman Divacky } 803f22ef01cSRoman Divacky 8043861d79fSDimitry Andric // MachineOperand::TiedTo is 4 bits wide. 8053861d79fSDimitry Andric const unsigned TiedMax = 15; 8066122f3e6SDimitry Andric 8073861d79fSDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other. 8083861d79fSDimitry Andric /// 8093861d79fSDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo 8103861d79fSDimitry Andric /// field. TiedTo can have these values: 8113861d79fSDimitry Andric /// 8123861d79fSDimitry Andric /// 0: Operand is not tied to anything. 8133861d79fSDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1). 8143861d79fSDimitry Andric /// TiedMax: Tied to an operand >= TiedMax-1. 8153861d79fSDimitry Andric /// 8163861d79fSDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal 8173861d79fSDimitry Andric /// instruction. INLINEASM instructions allow more tied defs. 8183861d79fSDimitry Andric /// 8193861d79fSDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) { 8203861d79fSDimitry Andric MachineOperand &DefMO = getOperand(DefIdx); 8213861d79fSDimitry Andric MachineOperand &UseMO = getOperand(UseIdx); 8223861d79fSDimitry Andric assert(DefMO.isDef() && "DefIdx must be a def operand"); 8233861d79fSDimitry Andric assert(UseMO.isUse() && "UseIdx must be a use operand"); 8243861d79fSDimitry Andric assert(!DefMO.isTied() && "Def is already tied to another use"); 8253861d79fSDimitry Andric assert(!UseMO.isTied() && "Use is already tied to another def"); 8266122f3e6SDimitry Andric 8273861d79fSDimitry Andric if (DefIdx < TiedMax) 8283861d79fSDimitry Andric UseMO.TiedTo = DefIdx + 1; 8293861d79fSDimitry Andric else { 8303861d79fSDimitry Andric // Inline asm can use the group descriptors to find tied operands, but on 8313861d79fSDimitry Andric // normal instruction, the tied def must be within the first TiedMax 8323861d79fSDimitry Andric // operands. 8333861d79fSDimitry Andric assert(isInlineAsm() && "DefIdx out of range"); 8343861d79fSDimitry Andric UseMO.TiedTo = TiedMax; 8353861d79fSDimitry Andric } 8363861d79fSDimitry Andric 8373861d79fSDimitry Andric // UseIdx can be out of range, we'll search for it in findTiedOperandIdx(). 8383861d79fSDimitry Andric DefMO.TiedTo = std::min(UseIdx + 1, TiedMax); 8393861d79fSDimitry Andric } 8403861d79fSDimitry Andric 8413861d79fSDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to. 8423861d79fSDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand 8433861d79fSDimitry Andric /// which must exist. 8443861d79fSDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const { 8453861d79fSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 8463861d79fSDimitry Andric assert(MO.isTied() && "Operand isn't tied"); 8473861d79fSDimitry Andric 8483861d79fSDimitry Andric // Normally TiedTo is in range. 8493861d79fSDimitry Andric if (MO.TiedTo < TiedMax) 8503861d79fSDimitry Andric return MO.TiedTo - 1; 8513861d79fSDimitry Andric 8523861d79fSDimitry Andric // Uses on normal instructions can be out of range. 8533861d79fSDimitry Andric if (!isInlineAsm()) { 8543861d79fSDimitry Andric // Normal tied defs must be in the 0..TiedMax-1 range. 8553861d79fSDimitry Andric if (MO.isUse()) 8563861d79fSDimitry Andric return TiedMax - 1; 8573861d79fSDimitry Andric // MO is a def. Search for the tied use. 8583861d79fSDimitry Andric for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) { 8593861d79fSDimitry Andric const MachineOperand &UseMO = getOperand(i); 8603861d79fSDimitry Andric if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1) 8613861d79fSDimitry Andric return i; 8623861d79fSDimitry Andric } 8633861d79fSDimitry Andric llvm_unreachable("Can't find tied use"); 8643861d79fSDimitry Andric } 8653861d79fSDimitry Andric 8663861d79fSDimitry Andric // Now deal with inline asm by parsing the operand group descriptor flags. 8673861d79fSDimitry Andric // Find the beginning of each operand group. 8683861d79fSDimitry Andric SmallVector<unsigned, 8> GroupIdx; 8693861d79fSDimitry Andric unsigned OpIdxGroup = ~0u; 8703861d79fSDimitry Andric unsigned NumOps; 8713861d79fSDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 8723861d79fSDimitry Andric i += NumOps) { 8733861d79fSDimitry Andric const MachineOperand &FlagMO = getOperand(i); 8743861d79fSDimitry Andric assert(FlagMO.isImm() && "Invalid tied operand on inline asm"); 8753861d79fSDimitry Andric unsigned CurGroup = GroupIdx.size(); 8763861d79fSDimitry Andric GroupIdx.push_back(i); 8773861d79fSDimitry Andric NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); 8783861d79fSDimitry Andric // OpIdx belongs to this operand group. 8793861d79fSDimitry Andric if (OpIdx > i && OpIdx < i + NumOps) 8803861d79fSDimitry Andric OpIdxGroup = CurGroup; 8813861d79fSDimitry Andric unsigned TiedGroup; 8823861d79fSDimitry Andric if (!InlineAsm::isUseOperandTiedToDef(FlagMO.getImm(), TiedGroup)) 883f22ef01cSRoman Divacky continue; 8843861d79fSDimitry Andric // Operands in this group are tied to operands in TiedGroup which must be 8853861d79fSDimitry Andric // earlier. Find the number of operands between the two groups. 8863861d79fSDimitry Andric unsigned Delta = i - GroupIdx[TiedGroup]; 887f22ef01cSRoman Divacky 8883861d79fSDimitry Andric // OpIdx is a use tied to TiedGroup. 8893861d79fSDimitry Andric if (OpIdxGroup == CurGroup) 8903861d79fSDimitry Andric return OpIdx - Delta; 891f22ef01cSRoman Divacky 8923861d79fSDimitry Andric // OpIdx is a def tied to this use group. 8933861d79fSDimitry Andric if (OpIdxGroup == TiedGroup) 8943861d79fSDimitry Andric return OpIdx + Delta; 895f22ef01cSRoman Divacky } 8963861d79fSDimitry Andric llvm_unreachable("Invalid tied operand on inline asm"); 897f22ef01cSRoman Divacky } 898f22ef01cSRoman Divacky 899f22ef01cSRoman Divacky /// clearKillInfo - Clears kill flags on all operands. 900f22ef01cSRoman Divacky /// 901f22ef01cSRoman Divacky void MachineInstr::clearKillInfo() { 902ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 903f22ef01cSRoman Divacky if (MO.isReg() && MO.isUse()) 904f22ef01cSRoman Divacky MO.setIsKill(false); 905f22ef01cSRoman Divacky } 906f22ef01cSRoman Divacky } 907f22ef01cSRoman Divacky 908ffd1746dSEd Schouten void MachineInstr::substituteRegister(unsigned FromReg, 909ffd1746dSEd Schouten unsigned ToReg, 910ffd1746dSEd Schouten unsigned SubIdx, 911ffd1746dSEd Schouten const TargetRegisterInfo &RegInfo) { 912ffd1746dSEd Schouten if (TargetRegisterInfo::isPhysicalRegister(ToReg)) { 913ffd1746dSEd Schouten if (SubIdx) 914ffd1746dSEd Schouten ToReg = RegInfo.getSubReg(ToReg, SubIdx); 915ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 916ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 917ffd1746dSEd Schouten continue; 918ffd1746dSEd Schouten MO.substPhysReg(ToReg, RegInfo); 919ffd1746dSEd Schouten } 920ffd1746dSEd Schouten } else { 921ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 922ffd1746dSEd Schouten if (!MO.isReg() || MO.getReg() != FromReg) 923ffd1746dSEd Schouten continue; 924ffd1746dSEd Schouten MO.substVirtReg(ToReg, SubIdx, RegInfo); 925ffd1746dSEd Schouten } 926ffd1746dSEd Schouten } 927ffd1746dSEd Schouten } 928ffd1746dSEd Schouten 929f22ef01cSRoman Divacky /// isSafeToMove - Return true if it is safe to move this instruction. If 930f22ef01cSRoman Divacky /// SawStore is set to true, it means that there is a store (or call) between 931f22ef01cSRoman Divacky /// the instruction's location and its intended destination. 932ff0cc061SDimitry Andric bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const { 933f22ef01cSRoman Divacky // Ignore stuff that we obviously can't move. 9343861d79fSDimitry Andric // 9353861d79fSDimitry Andric // Treat volatile loads as stores. This is not strictly necessary for 9363861d79fSDimitry Andric // volatiles, but it is required for atomic loads. It is not allowed to move 9373861d79fSDimitry Andric // a load across an atomic load with Ordering > Monotonic. 9382cab237bSDimitry Andric if (mayStore() || isCall() || isPHI() || 9393861d79fSDimitry Andric (mayLoad() && hasOrderedMemoryRef())) { 940f22ef01cSRoman Divacky SawStore = true; 941f22ef01cSRoman Divacky return false; 942f22ef01cSRoman Divacky } 9432754fe60SDimitry Andric 94491bc56edSDimitry Andric if (isPosition() || isDebugValue() || isTerminator() || 94591bc56edSDimitry Andric hasUnmodeledSideEffects()) 946f22ef01cSRoman Divacky return false; 947f22ef01cSRoman Divacky 948f22ef01cSRoman Divacky // See if this instruction does a load. If so, we have to guarantee that the 949f22ef01cSRoman Divacky // loaded value doesn't change between the load and the its intended 950f22ef01cSRoman Divacky // destination. The check for isInvariantLoad gives the targe the chance to 951f22ef01cSRoman Divacky // classify the load as always returning a constant, e.g. a constant pool 952f22ef01cSRoman Divacky // load. 953d88c1a5aSDimitry Andric if (mayLoad() && !isDereferenceableInvariantLoad(AA)) 954f22ef01cSRoman Divacky // Otherwise, this is a real load. If there is a store between the load and 9553861d79fSDimitry Andric // end of block, we can't move it. 9563861d79fSDimitry Andric return !SawStore; 957f22ef01cSRoman Divacky 958f22ef01cSRoman Divacky return true; 959f22ef01cSRoman Divacky } 960f22ef01cSRoman Divacky 9617a7e6055SDimitry Andric bool MachineInstr::mayAlias(AliasAnalysis *AA, MachineInstr &Other, 9627a7e6055SDimitry Andric bool UseTBAA) { 9632cab237bSDimitry Andric const MachineFunction *MF = getMF(); 9647a7e6055SDimitry Andric const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 9652cab237bSDimitry Andric const MachineFrameInfo &MFI = MF->getFrameInfo(); 9667a7e6055SDimitry Andric 9677a7e6055SDimitry Andric // If neither instruction stores to memory, they can't alias in any 9687a7e6055SDimitry Andric // meaningful way, even if they read from the same address. 9697a7e6055SDimitry Andric if (!mayStore() && !Other.mayStore()) 9707a7e6055SDimitry Andric return false; 9717a7e6055SDimitry Andric 9727a7e6055SDimitry Andric // Let the target decide if memory accesses cannot possibly overlap. 9737a7e6055SDimitry Andric if (TII->areMemAccessesTriviallyDisjoint(*this, Other, AA)) 9747a7e6055SDimitry Andric return false; 9757a7e6055SDimitry Andric 9767a7e6055SDimitry Andric // FIXME: Need to handle multiple memory operands to support all targets. 9777a7e6055SDimitry Andric if (!hasOneMemOperand() || !Other.hasOneMemOperand()) 9787a7e6055SDimitry Andric return true; 9797a7e6055SDimitry Andric 9807a7e6055SDimitry Andric MachineMemOperand *MMOa = *memoperands_begin(); 9817a7e6055SDimitry Andric MachineMemOperand *MMOb = *Other.memoperands_begin(); 9827a7e6055SDimitry Andric 9837a7e6055SDimitry Andric // The following interface to AA is fashioned after DAGCombiner::isAlias 9847a7e6055SDimitry Andric // and operates with MachineMemOperand offset with some important 9857a7e6055SDimitry Andric // assumptions: 9867a7e6055SDimitry Andric // - LLVM fundamentally assumes flat address spaces. 9877a7e6055SDimitry Andric // - MachineOperand offset can *only* result from legalization and 9887a7e6055SDimitry Andric // cannot affect queries other than the trivial case of overlap 9897a7e6055SDimitry Andric // checking. 9907a7e6055SDimitry Andric // - These offsets never wrap and never step outside 9917a7e6055SDimitry Andric // of allocated objects. 9927a7e6055SDimitry Andric // - There should never be any negative offsets here. 9937a7e6055SDimitry Andric // 9947a7e6055SDimitry Andric // FIXME: Modify API to hide this math from "user" 9952cab237bSDimitry Andric // Even before we go to AA we can reason locally about some 9967a7e6055SDimitry Andric // memory objects. It can save compile time, and possibly catch some 9977a7e6055SDimitry Andric // corner cases not currently covered. 9987a7e6055SDimitry Andric 9992cab237bSDimitry Andric int64_t OffsetA = MMOa->getOffset(); 10002cab237bSDimitry Andric int64_t OffsetB = MMOb->getOffset(); 10017a7e6055SDimitry Andric 10022cab237bSDimitry Andric int64_t MinOffset = std::min(OffsetA, OffsetB); 10032cab237bSDimitry Andric int64_t WidthA = MMOa->getSize(); 10042cab237bSDimitry Andric int64_t WidthB = MMOb->getSize(); 10052cab237bSDimitry Andric const Value *ValA = MMOa->getValue(); 10062cab237bSDimitry Andric const Value *ValB = MMOb->getValue(); 10072cab237bSDimitry Andric bool SameVal = (ValA && ValB && (ValA == ValB)); 10082cab237bSDimitry Andric if (!SameVal) { 10092cab237bSDimitry Andric const PseudoSourceValue *PSVa = MMOa->getPseudoValue(); 10102cab237bSDimitry Andric const PseudoSourceValue *PSVb = MMOb->getPseudoValue(); 10112cab237bSDimitry Andric if (PSVa && ValB && !PSVa->mayAlias(&MFI)) 10122cab237bSDimitry Andric return false; 10132cab237bSDimitry Andric if (PSVb && ValA && !PSVb->mayAlias(&MFI)) 10142cab237bSDimitry Andric return false; 10152cab237bSDimitry Andric if (PSVa && PSVb && (PSVa == PSVb)) 10162cab237bSDimitry Andric SameVal = true; 10172cab237bSDimitry Andric } 10187a7e6055SDimitry Andric 10192cab237bSDimitry Andric if (SameVal) { 10202cab237bSDimitry Andric int64_t MaxOffset = std::max(OffsetA, OffsetB); 10212cab237bSDimitry Andric int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB; 10222cab237bSDimitry Andric return (MinOffset + LowWidth > MaxOffset); 10232cab237bSDimitry Andric } 10242cab237bSDimitry Andric 10252cab237bSDimitry Andric if (!AA) 10262cab237bSDimitry Andric return true; 10272cab237bSDimitry Andric 10282cab237bSDimitry Andric if (!ValA || !ValB) 10292cab237bSDimitry Andric return true; 10302cab237bSDimitry Andric 10312cab237bSDimitry Andric assert((OffsetA >= 0) && "Negative MachineMemOperand offset"); 10322cab237bSDimitry Andric assert((OffsetB >= 0) && "Negative MachineMemOperand offset"); 10332cab237bSDimitry Andric 10342cab237bSDimitry Andric int64_t Overlapa = WidthA + OffsetA - MinOffset; 10352cab237bSDimitry Andric int64_t Overlapb = WidthB + OffsetB - MinOffset; 10362cab237bSDimitry Andric 10372cab237bSDimitry Andric AliasResult AAResult = AA->alias( 10382cab237bSDimitry Andric MemoryLocation(ValA, Overlapa, 10397a7e6055SDimitry Andric UseTBAA ? MMOa->getAAInfo() : AAMDNodes()), 10402cab237bSDimitry Andric MemoryLocation(ValB, Overlapb, 10417a7e6055SDimitry Andric UseTBAA ? MMOb->getAAInfo() : AAMDNodes())); 10427a7e6055SDimitry Andric 10437a7e6055SDimitry Andric return (AAResult != NoAlias); 10447a7e6055SDimitry Andric } 10457a7e6055SDimitry Andric 10463861d79fSDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered 10473861d79fSDimitry Andric /// or volatile memory reference, or if the information describing the memory 10483861d79fSDimitry Andric /// reference is not available. Return false if it is known to have no ordered 10493861d79fSDimitry Andric /// memory references. 10503861d79fSDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const { 1051f22ef01cSRoman Divacky // An instruction known never to access memory won't have a volatile access. 1052dff0c46cSDimitry Andric if (!mayStore() && 1053dff0c46cSDimitry Andric !mayLoad() && 1054dff0c46cSDimitry Andric !isCall() && 10552754fe60SDimitry Andric !hasUnmodeledSideEffects()) 1056f22ef01cSRoman Divacky return false; 1057f22ef01cSRoman Divacky 1058f22ef01cSRoman Divacky // Otherwise, if the instruction has no memory reference information, 1059f22ef01cSRoman Divacky // conservatively assume it wasn't preserved. 1060f22ef01cSRoman Divacky if (memoperands_empty()) 1061f22ef01cSRoman Divacky return true; 1062f22ef01cSRoman Divacky 10633ca95b02SDimitry Andric // Check if any of our memory operands are ordered. 1064f9448bf3SDimitry Andric return llvm::any_of(memoperands(), [](const MachineMemOperand *MMO) { 10653ca95b02SDimitry Andric return !MMO->isUnordered(); 10663ca95b02SDimitry Andric }); 1067f22ef01cSRoman Divacky } 1068f22ef01cSRoman Divacky 1069d88c1a5aSDimitry Andric /// isDereferenceableInvariantLoad - Return true if this instruction will never 1070d88c1a5aSDimitry Andric /// trap and is loading from a location whose value is invariant across a run of 1071d88c1a5aSDimitry Andric /// this function. 1072d88c1a5aSDimitry Andric bool MachineInstr::isDereferenceableInvariantLoad(AliasAnalysis *AA) const { 1073f22ef01cSRoman Divacky // If the instruction doesn't load at all, it isn't an invariant load. 1074dff0c46cSDimitry Andric if (!mayLoad()) 1075f22ef01cSRoman Divacky return false; 1076f22ef01cSRoman Divacky 1077f22ef01cSRoman Divacky // If the instruction has lost its memoperands, conservatively assume that 1078f22ef01cSRoman Divacky // it may not be an invariant load. 1079f22ef01cSRoman Divacky if (memoperands_empty()) 1080f22ef01cSRoman Divacky return false; 1081f22ef01cSRoman Divacky 1082d88c1a5aSDimitry Andric const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo(); 1083f22ef01cSRoman Divacky 10843ca95b02SDimitry Andric for (MachineMemOperand *MMO : memoperands()) { 10853ca95b02SDimitry Andric if (MMO->isVolatile()) return false; 10863ca95b02SDimitry Andric if (MMO->isStore()) return false; 1087d88c1a5aSDimitry Andric if (MMO->isInvariant() && MMO->isDereferenceable()) 1088d88c1a5aSDimitry Andric continue; 108991bc56edSDimitry Andric 1090f22ef01cSRoman Divacky // A load from a constant PseudoSourceValue is invariant. 10913ca95b02SDimitry Andric if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) 1092d88c1a5aSDimitry Andric if (PSV->isConstant(&MFI)) 1093f22ef01cSRoman Divacky continue; 109491bc56edSDimitry Andric 10953ca95b02SDimitry Andric if (const Value *V = MMO->getValue()) { 1096f22ef01cSRoman Divacky // If we have an AliasAnalysis, ask it whether the memory is constant. 10978f0fd8f6SDimitry Andric if (AA && 10988f0fd8f6SDimitry Andric AA->pointsToConstantMemory( 10993ca95b02SDimitry Andric MemoryLocation(V, MMO->getSize(), MMO->getAAInfo()))) 1100f22ef01cSRoman Divacky continue; 1101f22ef01cSRoman Divacky } 1102f22ef01cSRoman Divacky 1103f22ef01cSRoman Divacky // Otherwise assume conservatively. 1104f22ef01cSRoman Divacky return false; 1105f22ef01cSRoman Divacky } 1106f22ef01cSRoman Divacky 1107f22ef01cSRoman Divacky // Everything checks out. 1108f22ef01cSRoman Divacky return true; 1109f22ef01cSRoman Divacky } 1110f22ef01cSRoman Divacky 1111f22ef01cSRoman Divacky /// isConstantValuePHI - If the specified instruction is a PHI that always 1112f22ef01cSRoman Divacky /// merges together the same virtual register, return the register, otherwise 1113f22ef01cSRoman Divacky /// return 0. 1114f22ef01cSRoman Divacky unsigned MachineInstr::isConstantValuePHI() const { 1115f22ef01cSRoman Divacky if (!isPHI()) 1116f22ef01cSRoman Divacky return 0; 1117f22ef01cSRoman Divacky assert(getNumOperands() >= 3 && 1118f22ef01cSRoman Divacky "It's illegal to have a PHI without source operands"); 1119f22ef01cSRoman Divacky 1120f22ef01cSRoman Divacky unsigned Reg = getOperand(1).getReg(); 1121f22ef01cSRoman Divacky for (unsigned i = 3, e = getNumOperands(); i < e; i += 2) 1122f22ef01cSRoman Divacky if (getOperand(i).getReg() != Reg) 1123f22ef01cSRoman Divacky return 0; 1124f22ef01cSRoman Divacky return Reg; 1125f22ef01cSRoman Divacky } 1126f22ef01cSRoman Divacky 11272754fe60SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const { 1128dff0c46cSDimitry Andric if (hasProperty(MCID::UnmodeledSideEffects)) 11292754fe60SDimitry Andric return true; 11302754fe60SDimitry Andric if (isInlineAsm()) { 11312754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 11322754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 11332754fe60SDimitry Andric return true; 11342754fe60SDimitry Andric } 11352754fe60SDimitry Andric 11362754fe60SDimitry Andric return false; 11372754fe60SDimitry Andric } 11382754fe60SDimitry Andric 11397d523365SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const { 11407d523365SDimitry Andric return mayStore() || isCall() || hasUnmodeledSideEffects(); 11417d523365SDimitry Andric } 11427d523365SDimitry Andric 1143f22ef01cSRoman Divacky /// allDefsAreDead - Return true if all the defs of this instruction are dead. 1144f22ef01cSRoman Divacky /// 1145f22ef01cSRoman Divacky bool MachineInstr::allDefsAreDead() const { 1146ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 1147f22ef01cSRoman Divacky if (!MO.isReg() || MO.isUse()) 1148f22ef01cSRoman Divacky continue; 1149f22ef01cSRoman Divacky if (!MO.isDead()) 1150f22ef01cSRoman Divacky return false; 1151f22ef01cSRoman Divacky } 1152f22ef01cSRoman Divacky return true; 1153f22ef01cSRoman Divacky } 1154f22ef01cSRoman Divacky 11552754fe60SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified 11562754fe60SDimitry Andric /// instruction to this instruction. 1157139f7f9bSDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF, 11583ca95b02SDimitry Andric const MachineInstr &MI) { 11593ca95b02SDimitry Andric for (unsigned i = MI.getDesc().getNumOperands(), e = MI.getNumOperands(); 11602754fe60SDimitry Andric i != e; ++i) { 11613ca95b02SDimitry Andric const MachineOperand &MO = MI.getOperand(i); 116291bc56edSDimitry Andric if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask()) 1163139f7f9bSDimitry Andric addOperand(MF, MO); 11642754fe60SDimitry Andric } 11652754fe60SDimitry Andric } 11662754fe60SDimitry Andric 11672cab237bSDimitry Andric bool MachineInstr::hasComplexRegisterTies() const { 11682cab237bSDimitry Andric const MCInstrDesc &MCID = getDesc(); 11692cab237bSDimitry Andric for (unsigned I = 0, E = getNumOperands(); I < E; ++I) { 11702cab237bSDimitry Andric const auto &Operand = getOperand(I); 11712cab237bSDimitry Andric if (!Operand.isReg() || Operand.isDef()) 11722cab237bSDimitry Andric // Ignore the defined registers as MCID marks only the uses as tied. 11732cab237bSDimitry Andric continue; 11742cab237bSDimitry Andric int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO); 11752cab237bSDimitry Andric int TiedIdx = Operand.isTied() ? int(findTiedOperandIdx(I)) : -1; 11762cab237bSDimitry Andric if (ExpectedTiedIdx != TiedIdx) 11772cab237bSDimitry Andric return true; 11782cab237bSDimitry Andric } 11792cab237bSDimitry Andric return false; 11802cab237bSDimitry Andric } 11812cab237bSDimitry Andric 11822cab237bSDimitry Andric LLT MachineInstr::getTypeToPrint(unsigned OpIdx, SmallBitVector &PrintedTypes, 11832cab237bSDimitry Andric const MachineRegisterInfo &MRI) const { 11842cab237bSDimitry Andric const MachineOperand &Op = getOperand(OpIdx); 11852cab237bSDimitry Andric if (!Op.isReg()) 11862cab237bSDimitry Andric return LLT{}; 11872cab237bSDimitry Andric 11882cab237bSDimitry Andric if (isVariadic() || OpIdx >= getNumExplicitOperands()) 11892cab237bSDimitry Andric return MRI.getType(Op.getReg()); 11902cab237bSDimitry Andric 11912cab237bSDimitry Andric auto &OpInfo = getDesc().OpInfo[OpIdx]; 11922cab237bSDimitry Andric if (!OpInfo.isGenericType()) 11932cab237bSDimitry Andric return MRI.getType(Op.getReg()); 11942cab237bSDimitry Andric 11952cab237bSDimitry Andric if (PrintedTypes[OpInfo.getGenericTypeIndex()]) 11962cab237bSDimitry Andric return LLT{}; 11972cab237bSDimitry Andric 11982cab237bSDimitry Andric PrintedTypes.set(OpInfo.getGenericTypeIndex()); 11992cab237bSDimitry Andric return MRI.getType(Op.getReg()); 12002cab237bSDimitry Andric } 12012cab237bSDimitry Andric 12023861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 12037a7e6055SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dump() const { 1204d88c1a5aSDimitry Andric dbgs() << " "; 12057a7e6055SDimitry Andric print(dbgs()); 1206f22ef01cSRoman Divacky } 12077a7e6055SDimitry Andric #endif 1208f22ef01cSRoman Divacky 12097a7e6055SDimitry Andric void MachineInstr::print(raw_ostream &OS, bool SkipOpers, bool SkipDebugLoc, 1210d88c1a5aSDimitry Andric const TargetInstrInfo *TII) const { 12113dac3a9bSDimitry Andric const Module *M = nullptr; 12123dac3a9bSDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 12133dac3a9bSDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 12142cab237bSDimitry Andric M = MF->getFunction().getParent(); 12153dac3a9bSDimitry Andric 12163dac3a9bSDimitry Andric ModuleSlotTracker MST(M); 12177a7e6055SDimitry Andric print(OS, MST, SkipOpers, SkipDebugLoc, TII); 12183dac3a9bSDimitry Andric } 12193dac3a9bSDimitry Andric 12203dac3a9bSDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, 12217a7e6055SDimitry Andric bool SkipOpers, bool SkipDebugLoc, 12227a7e6055SDimitry Andric const TargetInstrInfo *TII) const { 1223ff0cc061SDimitry Andric // We can be a bit tidier if we know the MachineFunction. 122491bc56edSDimitry Andric const MachineFunction *MF = nullptr; 1225ff0cc061SDimitry Andric const TargetRegisterInfo *TRI = nullptr; 122691bc56edSDimitry Andric const MachineRegisterInfo *MRI = nullptr; 1227d88c1a5aSDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo = nullptr; 1228d88c1a5aSDimitry Andric 1229f22ef01cSRoman Divacky if (const MachineBasicBlock *MBB = getParent()) { 1230f22ef01cSRoman Divacky MF = MBB->getParent(); 1231ff0cc061SDimitry Andric if (MF) { 1232e580952dSDimitry Andric MRI = &MF->getRegInfo(); 1233ff0cc061SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo(); 1234d88c1a5aSDimitry Andric if (!TII) 1235ff0cc061SDimitry Andric TII = MF->getSubtarget().getInstrInfo(); 1236d88c1a5aSDimitry Andric IntrinsicInfo = MF->getTarget().getIntrinsicInfo(); 1237ff0cc061SDimitry Andric } 1238f22ef01cSRoman Divacky } 1239f22ef01cSRoman Divacky 1240e580952dSDimitry Andric // Save a list of virtual registers. 1241e580952dSDimitry Andric SmallVector<unsigned, 8> VirtRegs; 1242e580952dSDimitry Andric 12432cab237bSDimitry Andric SmallBitVector PrintedTypes(8); 12442cab237bSDimitry Andric bool ShouldPrintRegisterTies = hasComplexRegisterTies(); 12452cab237bSDimitry Andric auto getTiedOperandIdx = [&](unsigned OpIdx) { 12462cab237bSDimitry Andric if (!ShouldPrintRegisterTies) 12472cab237bSDimitry Andric return 0U; 12482cab237bSDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 12492cab237bSDimitry Andric if (MO.isReg() && MO.isTied() && !MO.isDef()) 12502cab237bSDimitry Andric return findTiedOperandIdx(OpIdx); 12512cab237bSDimitry Andric return 0U; 12522cab237bSDimitry Andric }; 1253f22ef01cSRoman Divacky // Print explicitly defined operands on the left of an assignment syntax. 1254f22ef01cSRoman Divacky unsigned StartOp = 0, e = getNumOperands(); 1255f22ef01cSRoman Divacky for (; StartOp < e && getOperand(StartOp).isReg() && 12562cab237bSDimitry Andric getOperand(StartOp).isDef() && !getOperand(StartOp).isImplicit(); 1257f22ef01cSRoman Divacky ++StartOp) { 12582cab237bSDimitry Andric if (StartOp != 0) 12592cab237bSDimitry Andric OS << ", "; 12602cab237bSDimitry Andric LLT TypeToPrint = MRI ? getTypeToPrint(StartOp, PrintedTypes, *MRI) : LLT{}; 12612cab237bSDimitry Andric unsigned TiedOperandIdx = getTiedOperandIdx(StartOp); 12622cab237bSDimitry Andric getOperand(StartOp).print(OS, MST, TypeToPrint, /*PrintDef=*/false, 12632cab237bSDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, 12642cab237bSDimitry Andric IntrinsicInfo); 1265e580952dSDimitry Andric unsigned Reg = getOperand(StartOp).getReg(); 12662cab237bSDimitry Andric if (TargetRegisterInfo::isVirtualRegister(Reg)) 1267e580952dSDimitry Andric VirtRegs.push_back(Reg); 1268f22ef01cSRoman Divacky } 1269f22ef01cSRoman Divacky 1270f22ef01cSRoman Divacky if (StartOp != 0) 1271f22ef01cSRoman Divacky OS << " = "; 1272f22ef01cSRoman Divacky 1273f22ef01cSRoman Divacky // Print the opcode name. 1274ff0cc061SDimitry Andric if (TII) 1275ff0cc061SDimitry Andric OS << TII->getName(getOpcode()); 1276dff0c46cSDimitry Andric else 1277dff0c46cSDimitry Andric OS << "UNKNOWN"; 1278f22ef01cSRoman Divacky 1279139f7f9bSDimitry Andric if (SkipOpers) 1280139f7f9bSDimitry Andric return; 1281139f7f9bSDimitry Andric 1282f22ef01cSRoman Divacky // Print the rest of the operands. 1283f22ef01cSRoman Divacky bool FirstOp = true; 128417a519f9SDimitry Andric unsigned AsmDescOp = ~0u; 128517a519f9SDimitry Andric unsigned AsmOpCount = 0; 12862754fe60SDimitry Andric 12876122f3e6SDimitry Andric if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { 12882754fe60SDimitry Andric // Print asm string. 12892754fe60SDimitry Andric OS << " "; 12902cab237bSDimitry Andric const unsigned OpIdx = InlineAsm::MIOp_AsmString; 12912cab237bSDimitry Andric LLT TypeToPrint = MRI ? getTypeToPrint(OpIdx, PrintedTypes, *MRI) : LLT{}; 12922cab237bSDimitry Andric unsigned TiedOperandIdx = getTiedOperandIdx(OpIdx); 12932cab237bSDimitry Andric getOperand(OpIdx).print(OS, MST, TypeToPrint, /*PrintDef=*/true, 12942cab237bSDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, 12952cab237bSDimitry Andric IntrinsicInfo); 12962754fe60SDimitry Andric 1297139f7f9bSDimitry Andric // Print HasSideEffects, MayLoad, MayStore, IsAlignStack 12982754fe60SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 12992754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 13002754fe60SDimitry Andric OS << " [sideeffect]"; 1301139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayLoad) 1302139f7f9bSDimitry Andric OS << " [mayload]"; 1303139f7f9bSDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayStore) 1304139f7f9bSDimitry Andric OS << " [maystore]"; 13053ca95b02SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsConvergent) 13063ca95b02SDimitry Andric OS << " [isconvergent]"; 13072754fe60SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 13082754fe60SDimitry Andric OS << " [alignstack]"; 13093861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_ATT) 13103861d79fSDimitry Andric OS << " [attdialect]"; 13113861d79fSDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_Intel) 13123861d79fSDimitry Andric OS << " [inteldialect]"; 13132754fe60SDimitry Andric 131417a519f9SDimitry Andric StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand; 13152754fe60SDimitry Andric FirstOp = false; 13162754fe60SDimitry Andric } 13172754fe60SDimitry Andric 1318f22ef01cSRoman Divacky for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 1319f22ef01cSRoman Divacky const MachineOperand &MO = getOperand(i); 1320f22ef01cSRoman Divacky 13212754fe60SDimitry Andric if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) 1322e580952dSDimitry Andric VirtRegs.push_back(MO.getReg()); 1323e580952dSDimitry Andric 1324f22ef01cSRoman Divacky if (FirstOp) FirstOp = false; else OS << ","; 1325f22ef01cSRoman Divacky OS << " "; 1326f22ef01cSRoman Divacky if (i < getDesc().NumOperands) { 132717a519f9SDimitry Andric const MCOperandInfo &MCOI = getDesc().OpInfo[i]; 132817a519f9SDimitry Andric if (MCOI.isPredicate()) 1329f22ef01cSRoman Divacky OS << "pred:"; 133017a519f9SDimitry Andric if (MCOI.isOptionalDef()) 1331f22ef01cSRoman Divacky OS << "opt:"; 1332f22ef01cSRoman Divacky } 1333f22ef01cSRoman Divacky if (isDebugValue() && MO.isMetadata()) { 1334f22ef01cSRoman Divacky // Pretty print DBG_VALUE instructions. 1335ff0cc061SDimitry Andric auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata()); 1336ff0cc061SDimitry Andric if (DIV && !DIV->getName().empty()) 1337ff0cc061SDimitry Andric OS << "!\"" << DIV->getName() << '\"'; 13382cab237bSDimitry Andric else { 13392cab237bSDimitry Andric LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{}; 13402cab237bSDimitry Andric unsigned TiedOperandIdx = getTiedOperandIdx(i); 13412cab237bSDimitry Andric MO.print(OS, MST, TypeToPrint, /*PrintDef=*/true, 13422cab237bSDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo); 13432cab237bSDimitry Andric } 1344f1a29dd3SDimitry Andric } else if (TRI && (isInsertSubreg() || isRegSequence() || 1345f1a29dd3SDimitry Andric (isSubregToReg() && i == 3)) && MO.isImm()) { 1346ff0cc061SDimitry Andric OS << TRI->getSubRegIndexName(MO.getImm()); 134717a519f9SDimitry Andric } else if (i == AsmDescOp && MO.isImm()) { 134817a519f9SDimitry Andric // Pretty print the inline asm operand descriptor. 134917a519f9SDimitry Andric OS << '$' << AsmOpCount++; 135017a519f9SDimitry Andric unsigned Flag = MO.getImm(); 135117a519f9SDimitry Andric switch (InlineAsm::getKind(Flag)) { 13526122f3e6SDimitry Andric case InlineAsm::Kind_RegUse: OS << ":[reguse"; break; 13536122f3e6SDimitry Andric case InlineAsm::Kind_RegDef: OS << ":[regdef"; break; 13546122f3e6SDimitry Andric case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec"; break; 13556122f3e6SDimitry Andric case InlineAsm::Kind_Clobber: OS << ":[clobber"; break; 13566122f3e6SDimitry Andric case InlineAsm::Kind_Imm: OS << ":[imm"; break; 13576122f3e6SDimitry Andric case InlineAsm::Kind_Mem: OS << ":[mem"; break; 13586122f3e6SDimitry Andric default: OS << ":[??" << InlineAsm::getKind(Flag); break; 13596122f3e6SDimitry Andric } 13606122f3e6SDimitry Andric 13616122f3e6SDimitry Andric unsigned RCID = 0; 13623ca95b02SDimitry Andric if (!InlineAsm::isImmKind(Flag) && !InlineAsm::isMemKind(Flag) && 13633ca95b02SDimitry Andric InlineAsm::hasRegClassConstraint(Flag, RCID)) { 1364ff0cc061SDimitry Andric if (TRI) { 1365ff0cc061SDimitry Andric OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID)); 136639d628a0SDimitry Andric } else 13676122f3e6SDimitry Andric OS << ":RC" << RCID; 136817a519f9SDimitry Andric } 136917a519f9SDimitry Andric 13703ca95b02SDimitry Andric if (InlineAsm::isMemKind(Flag)) { 13713ca95b02SDimitry Andric unsigned MCID = InlineAsm::getMemoryConstraintID(Flag); 13723ca95b02SDimitry Andric switch (MCID) { 13733ca95b02SDimitry Andric case InlineAsm::Constraint_es: OS << ":es"; break; 13743ca95b02SDimitry Andric case InlineAsm::Constraint_i: OS << ":i"; break; 13753ca95b02SDimitry Andric case InlineAsm::Constraint_m: OS << ":m"; break; 13763ca95b02SDimitry Andric case InlineAsm::Constraint_o: OS << ":o"; break; 13773ca95b02SDimitry Andric case InlineAsm::Constraint_v: OS << ":v"; break; 13783ca95b02SDimitry Andric case InlineAsm::Constraint_Q: OS << ":Q"; break; 13793ca95b02SDimitry Andric case InlineAsm::Constraint_R: OS << ":R"; break; 13803ca95b02SDimitry Andric case InlineAsm::Constraint_S: OS << ":S"; break; 13813ca95b02SDimitry Andric case InlineAsm::Constraint_T: OS << ":T"; break; 13823ca95b02SDimitry Andric case InlineAsm::Constraint_Um: OS << ":Um"; break; 13833ca95b02SDimitry Andric case InlineAsm::Constraint_Un: OS << ":Un"; break; 13843ca95b02SDimitry Andric case InlineAsm::Constraint_Uq: OS << ":Uq"; break; 13853ca95b02SDimitry Andric case InlineAsm::Constraint_Us: OS << ":Us"; break; 13863ca95b02SDimitry Andric case InlineAsm::Constraint_Ut: OS << ":Ut"; break; 13873ca95b02SDimitry Andric case InlineAsm::Constraint_Uv: OS << ":Uv"; break; 13883ca95b02SDimitry Andric case InlineAsm::Constraint_Uy: OS << ":Uy"; break; 13893ca95b02SDimitry Andric case InlineAsm::Constraint_X: OS << ":X"; break; 13903ca95b02SDimitry Andric case InlineAsm::Constraint_Z: OS << ":Z"; break; 13913ca95b02SDimitry Andric case InlineAsm::Constraint_ZC: OS << ":ZC"; break; 13923ca95b02SDimitry Andric case InlineAsm::Constraint_Zy: OS << ":Zy"; break; 13933ca95b02SDimitry Andric default: OS << ":?"; break; 13943ca95b02SDimitry Andric } 13953ca95b02SDimitry Andric } 13963ca95b02SDimitry Andric 139717a519f9SDimitry Andric unsigned TiedTo = 0; 139817a519f9SDimitry Andric if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo)) 13996122f3e6SDimitry Andric OS << " tiedto:$" << TiedTo; 14006122f3e6SDimitry Andric 14016122f3e6SDimitry Andric OS << ']'; 140217a519f9SDimitry Andric 140317a519f9SDimitry Andric // Compute the index of the next operand descriptor. 140417a519f9SDimitry Andric AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); 14052cab237bSDimitry Andric } else { 14062cab237bSDimitry Andric LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{}; 14072cab237bSDimitry Andric unsigned TiedOperandIdx = getTiedOperandIdx(i); 14082cab237bSDimitry Andric if (MO.isImm() && isOperandSubregIdx(i)) 14092cab237bSDimitry Andric MachineOperand::printSubregIdx(OS, MO.getImm(), TRI); 14102cab237bSDimitry Andric else 14112cab237bSDimitry Andric MO.print(OS, MST, TypeToPrint, /*PrintDef=*/true, 14122cab237bSDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo); 14132cab237bSDimitry Andric } 1414f22ef01cSRoman Divacky } 1415f22ef01cSRoman Divacky 1416f22ef01cSRoman Divacky bool HaveSemi = false; 14177d523365SDimitry Andric const unsigned PrintableFlags = FrameSetup | FrameDestroy; 1418139f7f9bSDimitry Andric if (Flags & PrintableFlags) { 14194d0b32cdSDimitry Andric if (!HaveSemi) { 14204d0b32cdSDimitry Andric OS << ";"; 14214d0b32cdSDimitry Andric HaveSemi = true; 14224d0b32cdSDimitry Andric } 14233b0f4066SDimitry Andric OS << " flags: "; 14243b0f4066SDimitry Andric 14253b0f4066SDimitry Andric if (Flags & FrameSetup) 14263b0f4066SDimitry Andric OS << "FrameSetup"; 14277d523365SDimitry Andric 14287d523365SDimitry Andric if (Flags & FrameDestroy) 14297d523365SDimitry Andric OS << "FrameDestroy"; 14303b0f4066SDimitry Andric } 14313b0f4066SDimitry Andric 1432f22ef01cSRoman Divacky if (!memoperands_empty()) { 14334d0b32cdSDimitry Andric if (!HaveSemi) { 14344d0b32cdSDimitry Andric OS << ";"; 14354d0b32cdSDimitry Andric HaveSemi = true; 14364d0b32cdSDimitry Andric } 1437f22ef01cSRoman Divacky 1438f22ef01cSRoman Divacky OS << " mem:"; 1439f22ef01cSRoman Divacky for (mmo_iterator i = memoperands_begin(), e = memoperands_end(); 1440f22ef01cSRoman Divacky i != e; ++i) { 14413dac3a9bSDimitry Andric (*i)->print(OS, MST); 144291bc56edSDimitry Andric if (std::next(i) != e) 1443f22ef01cSRoman Divacky OS << " "; 1444f22ef01cSRoman Divacky } 1445f22ef01cSRoman Divacky } 1446f22ef01cSRoman Divacky 1447e580952dSDimitry Andric // Print the regclass of any virtual registers encountered. 1448e580952dSDimitry Andric if (MRI && !VirtRegs.empty()) { 14494d0b32cdSDimitry Andric if (!HaveSemi) { 14504d0b32cdSDimitry Andric OS << ";"; 14514d0b32cdSDimitry Andric HaveSemi = true; 14524d0b32cdSDimitry Andric } 1453e580952dSDimitry Andric for (unsigned i = 0; i != VirtRegs.size(); ++i) { 14543ca95b02SDimitry Andric const RegClassOrRegBank &RC = MRI->getRegClassOrRegBank(VirtRegs[i]); 14553ca95b02SDimitry Andric if (!RC) 14563ca95b02SDimitry Andric continue; 14573ca95b02SDimitry Andric // Generic virtual registers do not have register classes. 14583ca95b02SDimitry Andric if (RC.is<const RegisterBank *>()) 14593ca95b02SDimitry Andric OS << " " << RC.get<const RegisterBank *>()->getName(); 14603ca95b02SDimitry Andric else 14613ca95b02SDimitry Andric OS << " " 14623ca95b02SDimitry Andric << TRI->getRegClassName(RC.get<const TargetRegisterClass *>()); 14632cab237bSDimitry Andric OS << ':' << printReg(VirtRegs[i]); 1464e580952dSDimitry Andric for (unsigned j = i+1; j != VirtRegs.size();) { 14653ca95b02SDimitry Andric if (MRI->getRegClassOrRegBank(VirtRegs[j]) != RC) { 1466e580952dSDimitry Andric ++j; 1467e580952dSDimitry Andric continue; 1468e580952dSDimitry Andric } 1469e580952dSDimitry Andric if (VirtRegs[i] != VirtRegs[j]) 14702cab237bSDimitry Andric OS << "," << printReg(VirtRegs[j]); 1471e580952dSDimitry Andric VirtRegs.erase(VirtRegs.begin()+j); 1472e580952dSDimitry Andric } 1473e580952dSDimitry Andric } 1474e580952dSDimitry Andric } 1475e580952dSDimitry Andric 14763b0f4066SDimitry Andric // Print debug location information. 1477ff0cc061SDimitry Andric if (isDebugValue() && getOperand(e - 2).isMetadata()) { 14784d0b32cdSDimitry Andric if (!HaveSemi) 14794d0b32cdSDimitry Andric OS << ";"; 1480ff0cc061SDimitry Andric auto *DV = cast<DILocalVariable>(getOperand(e - 2).getMetadata()); 1481ff0cc061SDimitry Andric OS << " line no:" << DV->getLine(); 1482ff0cc061SDimitry Andric if (auto *InlinedAt = debugLoc->getInlinedAt()) { 1483ff0cc061SDimitry Andric DebugLoc InlinedAtDL(InlinedAt); 1484ff0cc061SDimitry Andric if (InlinedAtDL && MF) { 14856122f3e6SDimitry Andric OS << " inlined @[ "; 1486ff0cc061SDimitry Andric InlinedAtDL.print(OS); 14876122f3e6SDimitry Andric OS << " ]"; 14886122f3e6SDimitry Andric } 14896122f3e6SDimitry Andric } 149039d628a0SDimitry Andric if (isIndirectDebugValue()) 149139d628a0SDimitry Andric OS << " indirect"; 14927a7e6055SDimitry Andric } else if (SkipDebugLoc) { 14937a7e6055SDimitry Andric return; 1494ff0cc061SDimitry Andric } else if (debugLoc && MF) { 14954d0b32cdSDimitry Andric if (!HaveSemi) 14964d0b32cdSDimitry Andric OS << ";"; 1497f22ef01cSRoman Divacky OS << " dbg:"; 1498ff0cc061SDimitry Andric debugLoc.print(OS); 1499f22ef01cSRoman Divacky } 1500f22ef01cSRoman Divacky 15013b0f4066SDimitry Andric OS << '\n'; 1502f22ef01cSRoman Divacky } 1503f22ef01cSRoman Divacky 1504f22ef01cSRoman Divacky bool MachineInstr::addRegisterKilled(unsigned IncomingReg, 1505f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 1506f22ef01cSRoman Divacky bool AddIfNotFound) { 1507f22ef01cSRoman Divacky bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); 15087ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 15097ae0e2c9SDimitry Andric MCRegAliasIterator(IncomingReg, RegInfo, false).isValid(); 1510f22ef01cSRoman Divacky bool Found = false; 1511f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 1512f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1513f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1514f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isUse() || MO.isUndef()) 1515f22ef01cSRoman Divacky continue; 15163ca95b02SDimitry Andric 15173ca95b02SDimitry Andric // DEBUG_VALUE nodes do not contribute to code generation and should 15183ca95b02SDimitry Andric // always be ignored. Failure to do so may result in trying to modify 15193ca95b02SDimitry Andric // KILL flags on DEBUG_VALUE nodes. 15203ca95b02SDimitry Andric if (MO.isDebug()) 15213ca95b02SDimitry Andric continue; 15223ca95b02SDimitry Andric 1523f22ef01cSRoman Divacky unsigned Reg = MO.getReg(); 1524f22ef01cSRoman Divacky if (!Reg) 1525f22ef01cSRoman Divacky continue; 1526f22ef01cSRoman Divacky 1527f22ef01cSRoman Divacky if (Reg == IncomingReg) { 1528f22ef01cSRoman Divacky if (!Found) { 1529f22ef01cSRoman Divacky if (MO.isKill()) 1530f22ef01cSRoman Divacky // The register is already marked kill. 1531f22ef01cSRoman Divacky return true; 1532f22ef01cSRoman Divacky if (isPhysReg && isRegTiedToDefOperand(i)) 1533f22ef01cSRoman Divacky // Two-address uses of physregs must not be marked kill. 1534f22ef01cSRoman Divacky return true; 1535f22ef01cSRoman Divacky MO.setIsKill(); 1536f22ef01cSRoman Divacky Found = true; 1537f22ef01cSRoman Divacky } 1538f22ef01cSRoman Divacky } else if (hasAliases && MO.isKill() && 1539f22ef01cSRoman Divacky TargetRegisterInfo::isPhysicalRegister(Reg)) { 1540f22ef01cSRoman Divacky // A super-register kill already exists. 1541f22ef01cSRoman Divacky if (RegInfo->isSuperRegister(IncomingReg, Reg)) 1542f22ef01cSRoman Divacky return true; 1543f22ef01cSRoman Divacky if (RegInfo->isSubRegister(IncomingReg, Reg)) 1544f22ef01cSRoman Divacky DeadOps.push_back(i); 1545f22ef01cSRoman Divacky } 1546f22ef01cSRoman Divacky } 1547f22ef01cSRoman Divacky 1548f22ef01cSRoman Divacky // Trim unneeded kill operands. 1549f22ef01cSRoman Divacky while (!DeadOps.empty()) { 1550f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 1551f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 1552f22ef01cSRoman Divacky RemoveOperand(OpIdx); 1553f22ef01cSRoman Divacky else 1554f22ef01cSRoman Divacky getOperand(OpIdx).setIsKill(false); 1555f22ef01cSRoman Divacky DeadOps.pop_back(); 1556f22ef01cSRoman Divacky } 1557f22ef01cSRoman Divacky 1558f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is killed. Add a 1559f22ef01cSRoman Divacky // new implicit operand if required. 1560f22ef01cSRoman Divacky if (!Found && AddIfNotFound) { 1561f22ef01cSRoman Divacky addOperand(MachineOperand::CreateReg(IncomingReg, 1562f22ef01cSRoman Divacky false /*IsDef*/, 1563f22ef01cSRoman Divacky true /*IsImp*/, 1564f22ef01cSRoman Divacky true /*IsKill*/)); 1565f22ef01cSRoman Divacky return true; 1566f22ef01cSRoman Divacky } 1567f22ef01cSRoman Divacky return Found; 1568f22ef01cSRoman Divacky } 1569f22ef01cSRoman Divacky 1570dff0c46cSDimitry Andric void MachineInstr::clearRegisterKills(unsigned Reg, 1571dff0c46cSDimitry Andric const TargetRegisterInfo *RegInfo) { 1572dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) 157391bc56edSDimitry Andric RegInfo = nullptr; 1574ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1575dff0c46cSDimitry Andric if (!MO.isReg() || !MO.isUse() || !MO.isKill()) 1576dff0c46cSDimitry Andric continue; 1577dff0c46cSDimitry Andric unsigned OpReg = MO.getReg(); 15783ca95b02SDimitry Andric if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg) 1579dff0c46cSDimitry Andric MO.setIsKill(false); 1580dff0c46cSDimitry Andric } 1581dff0c46cSDimitry Andric } 1582dff0c46cSDimitry Andric 1583f785676fSDimitry Andric bool MachineInstr::addRegisterDead(unsigned Reg, 1584f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo, 1585f22ef01cSRoman Divacky bool AddIfNotFound) { 1586f785676fSDimitry Andric bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(Reg); 15877ae0e2c9SDimitry Andric bool hasAliases = isPhysReg && 1588f785676fSDimitry Andric MCRegAliasIterator(Reg, RegInfo, false).isValid(); 1589f22ef01cSRoman Divacky bool Found = false; 1590f22ef01cSRoman Divacky SmallVector<unsigned,4> DeadOps; 1591f22ef01cSRoman Divacky for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 1592f22ef01cSRoman Divacky MachineOperand &MO = getOperand(i); 1593f22ef01cSRoman Divacky if (!MO.isReg() || !MO.isDef()) 1594f22ef01cSRoman Divacky continue; 1595f785676fSDimitry Andric unsigned MOReg = MO.getReg(); 1596f785676fSDimitry Andric if (!MOReg) 1597f22ef01cSRoman Divacky continue; 1598f22ef01cSRoman Divacky 1599f785676fSDimitry Andric if (MOReg == Reg) { 1600f22ef01cSRoman Divacky MO.setIsDead(); 1601f22ef01cSRoman Divacky Found = true; 1602f22ef01cSRoman Divacky } else if (hasAliases && MO.isDead() && 1603f785676fSDimitry Andric TargetRegisterInfo::isPhysicalRegister(MOReg)) { 1604f22ef01cSRoman Divacky // There exists a super-register that's marked dead. 1605f785676fSDimitry Andric if (RegInfo->isSuperRegister(Reg, MOReg)) 1606f22ef01cSRoman Divacky return true; 1607f785676fSDimitry Andric if (RegInfo->isSubRegister(Reg, MOReg)) 1608f22ef01cSRoman Divacky DeadOps.push_back(i); 1609f22ef01cSRoman Divacky } 1610f22ef01cSRoman Divacky } 1611f22ef01cSRoman Divacky 1612f22ef01cSRoman Divacky // Trim unneeded dead operands. 1613f22ef01cSRoman Divacky while (!DeadOps.empty()) { 1614f22ef01cSRoman Divacky unsigned OpIdx = DeadOps.back(); 1615f22ef01cSRoman Divacky if (getOperand(OpIdx).isImplicit()) 1616f22ef01cSRoman Divacky RemoveOperand(OpIdx); 1617f22ef01cSRoman Divacky else 1618f22ef01cSRoman Divacky getOperand(OpIdx).setIsDead(false); 1619f22ef01cSRoman Divacky DeadOps.pop_back(); 1620f22ef01cSRoman Divacky } 1621f22ef01cSRoman Divacky 1622f22ef01cSRoman Divacky // If not found, this means an alias of one of the operands is dead. Add a 1623f22ef01cSRoman Divacky // new implicit operand if required. 1624f22ef01cSRoman Divacky if (Found || !AddIfNotFound) 1625f22ef01cSRoman Divacky return Found; 1626f22ef01cSRoman Divacky 1627f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 1628f22ef01cSRoman Divacky true /*IsDef*/, 1629f22ef01cSRoman Divacky true /*IsImp*/, 1630f22ef01cSRoman Divacky false /*IsKill*/, 1631f22ef01cSRoman Divacky true /*IsDead*/)); 1632f22ef01cSRoman Divacky return true; 1633f22ef01cSRoman Divacky } 1634f22ef01cSRoman Divacky 1635ff0cc061SDimitry Andric void MachineInstr::clearRegisterDeads(unsigned Reg) { 1636ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1637ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg) 1638ff0cc061SDimitry Andric continue; 1639ff0cc061SDimitry Andric MO.setIsDead(false); 1640ff0cc061SDimitry Andric } 1641ff0cc061SDimitry Andric } 1642ff0cc061SDimitry Andric 16437d523365SDimitry Andric void MachineInstr::setRegisterDefReadUndef(unsigned Reg, bool IsUndef) { 1644ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1645ff0cc061SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0) 1646ff0cc061SDimitry Andric continue; 16477d523365SDimitry Andric MO.setIsUndef(IsUndef); 1648ff0cc061SDimitry Andric } 1649ff0cc061SDimitry Andric } 1650ff0cc061SDimitry Andric 1651f785676fSDimitry Andric void MachineInstr::addRegisterDefined(unsigned Reg, 1652f22ef01cSRoman Divacky const TargetRegisterInfo *RegInfo) { 1653f785676fSDimitry Andric if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 1654f785676fSDimitry Andric MachineOperand *MO = findRegisterDefOperand(Reg, false, RegInfo); 1655f22ef01cSRoman Divacky if (MO) 1656f22ef01cSRoman Divacky return; 1657f22ef01cSRoman Divacky } else { 1658ff0cc061SDimitry Andric for (const MachineOperand &MO : operands()) { 1659f785676fSDimitry Andric if (MO.isReg() && MO.getReg() == Reg && MO.isDef() && 1660f22ef01cSRoman Divacky MO.getSubReg() == 0) 1661f22ef01cSRoman Divacky return; 1662f22ef01cSRoman Divacky } 1663f22ef01cSRoman Divacky } 1664f785676fSDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 1665f22ef01cSRoman Divacky true /*IsDef*/, 1666f22ef01cSRoman Divacky true /*IsImp*/)); 1667f22ef01cSRoman Divacky } 1668f22ef01cSRoman Divacky 1669dff0c46cSDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs, 1670ffd1746dSEd Schouten const TargetRegisterInfo &TRI) { 1671dff0c46cSDimitry Andric bool HasRegMask = false; 1672ff0cc061SDimitry Andric for (MachineOperand &MO : operands()) { 1673dff0c46cSDimitry Andric if (MO.isRegMask()) { 1674dff0c46cSDimitry Andric HasRegMask = true; 1675dff0c46cSDimitry Andric continue; 1676dff0c46cSDimitry Andric } 1677ffd1746dSEd Schouten if (!MO.isReg() || !MO.isDef()) continue; 1678ffd1746dSEd Schouten unsigned Reg = MO.getReg(); 1679dff0c46cSDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg)) continue; 1680ffd1746dSEd Schouten // If there are no uses, including partial uses, the def is dead. 1681f9448bf3SDimitry Andric if (llvm::none_of(UsedRegs, 1682ff0cc061SDimitry Andric [&](unsigned Use) { return TRI.regsOverlap(Use, Reg); })) 1683ff0cc061SDimitry Andric MO.setIsDead(); 1684ffd1746dSEd Schouten } 1685dff0c46cSDimitry Andric 1686dff0c46cSDimitry Andric // This is a call with a register mask operand. 1687dff0c46cSDimitry Andric // Mask clobbers are always dead, so add defs for the non-dead defines. 1688dff0c46cSDimitry Andric if (HasRegMask) 1689dff0c46cSDimitry Andric for (ArrayRef<unsigned>::iterator I = UsedRegs.begin(), E = UsedRegs.end(); 1690dff0c46cSDimitry Andric I != E; ++I) 1691dff0c46cSDimitry Andric addRegisterDefined(*I, &TRI); 1692ffd1746dSEd Schouten } 1693ffd1746dSEd Schouten 1694f22ef01cSRoman Divacky unsigned 1695f22ef01cSRoman Divacky MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { 1696dff0c46cSDimitry Andric // Build up a buffer of hash code components. 1697dff0c46cSDimitry Andric SmallVector<size_t, 8> HashComponents; 1698dff0c46cSDimitry Andric HashComponents.reserve(MI->getNumOperands() + 1); 1699dff0c46cSDimitry Andric HashComponents.push_back(MI->getOpcode()); 1700ff0cc061SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 17017ae0e2c9SDimitry Andric if (MO.isReg() && MO.isDef() && 17027ae0e2c9SDimitry Andric TargetRegisterInfo::isVirtualRegister(MO.getReg())) 1703f22ef01cSRoman Divacky continue; // Skip virtual register defs. 17047ae0e2c9SDimitry Andric 17057ae0e2c9SDimitry Andric HashComponents.push_back(hash_value(MO)); 1706f22ef01cSRoman Divacky } 1707dff0c46cSDimitry Andric return hash_combine_range(HashComponents.begin(), HashComponents.end()); 1708f22ef01cSRoman Divacky } 170917a519f9SDimitry Andric 171017a519f9SDimitry Andric void MachineInstr::emitError(StringRef Msg) const { 171117a519f9SDimitry Andric // Find the source location cookie. 171217a519f9SDimitry Andric unsigned LocCookie = 0; 171391bc56edSDimitry Andric const MDNode *LocMD = nullptr; 171417a519f9SDimitry Andric for (unsigned i = getNumOperands(); i != 0; --i) { 171517a519f9SDimitry Andric if (getOperand(i-1).isMetadata() && 171617a519f9SDimitry Andric (LocMD = getOperand(i-1).getMetadata()) && 171717a519f9SDimitry Andric LocMD->getNumOperands() != 0) { 171839d628a0SDimitry Andric if (const ConstantInt *CI = 171939d628a0SDimitry Andric mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) { 172017a519f9SDimitry Andric LocCookie = CI->getZExtValue(); 172117a519f9SDimitry Andric break; 172217a519f9SDimitry Andric } 172317a519f9SDimitry Andric } 172417a519f9SDimitry Andric } 172517a519f9SDimitry Andric 172617a519f9SDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 172717a519f9SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 172817a519f9SDimitry Andric return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg); 172917a519f9SDimitry Andric report_fatal_error(Msg); 173017a519f9SDimitry Andric } 17313ca95b02SDimitry Andric 17323ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, 17333ca95b02SDimitry Andric const MCInstrDesc &MCID, bool IsIndirect, 17342cab237bSDimitry Andric unsigned Reg, const MDNode *Variable, 17352cab237bSDimitry Andric const MDNode *Expr) { 17363ca95b02SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 17373ca95b02SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 17383ca95b02SDimitry Andric assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 17393ca95b02SDimitry Andric "Expected inlined-at fields to agree"); 17403ca95b02SDimitry Andric if (IsIndirect) 17413ca95b02SDimitry Andric return BuildMI(MF, DL, MCID) 17423ca95b02SDimitry Andric .addReg(Reg, RegState::Debug) 17432cab237bSDimitry Andric .addImm(0U) 17443ca95b02SDimitry Andric .addMetadata(Variable) 17453ca95b02SDimitry Andric .addMetadata(Expr); 17462cab237bSDimitry Andric else 17473ca95b02SDimitry Andric return BuildMI(MF, DL, MCID) 17483ca95b02SDimitry Andric .addReg(Reg, RegState::Debug) 17493ca95b02SDimitry Andric .addReg(0U, RegState::Debug) 17503ca95b02SDimitry Andric .addMetadata(Variable) 17513ca95b02SDimitry Andric .addMetadata(Expr); 17523ca95b02SDimitry Andric } 17533ca95b02SDimitry Andric 17543ca95b02SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, 17553ca95b02SDimitry Andric MachineBasicBlock::iterator I, 17563ca95b02SDimitry Andric const DebugLoc &DL, const MCInstrDesc &MCID, 17573ca95b02SDimitry Andric bool IsIndirect, unsigned Reg, 17582cab237bSDimitry Andric const MDNode *Variable, const MDNode *Expr) { 17593ca95b02SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 17603ca95b02SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 17613ca95b02SDimitry Andric MachineFunction &MF = *BB.getParent(); 17622cab237bSDimitry Andric MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Variable, Expr); 17633ca95b02SDimitry Andric BB.insert(I, MI); 17643ca95b02SDimitry Andric return MachineInstrBuilder(MF, MI); 17653ca95b02SDimitry Andric } 17666bc11b14SDimitry Andric 17672cab237bSDimitry Andric /// Compute the new DIExpression to use with a DBG_VALUE for a spill slot. 17682cab237bSDimitry Andric /// This prepends DW_OP_deref when spilling an indirect DBG_VALUE. 17692cab237bSDimitry Andric static const DIExpression *computeExprForSpill(const MachineInstr &MI) { 17702cab237bSDimitry Andric assert(MI.getOperand(0).isReg() && "can't spill non-register"); 17712cab237bSDimitry Andric assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) && 17722cab237bSDimitry Andric "Expected inlined-at fields to agree"); 17732cab237bSDimitry Andric 17742cab237bSDimitry Andric const DIExpression *Expr = MI.getDebugExpression(); 17752cab237bSDimitry Andric if (MI.isIndirectDebugValue()) { 17762cab237bSDimitry Andric assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset"); 17772cab237bSDimitry Andric Expr = DIExpression::prepend(Expr, DIExpression::WithDeref); 17782cab237bSDimitry Andric } 17792cab237bSDimitry Andric return Expr; 17802cab237bSDimitry Andric } 17812cab237bSDimitry Andric 17826bc11b14SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB, 17836bc11b14SDimitry Andric MachineBasicBlock::iterator I, 17846bc11b14SDimitry Andric const MachineInstr &Orig, 17856bc11b14SDimitry Andric int FrameIndex) { 17862cab237bSDimitry Andric const DIExpression *Expr = computeExprForSpill(Orig); 17872cab237bSDimitry Andric return BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc()) 17886bc11b14SDimitry Andric .addFrameIndex(FrameIndex) 17892cab237bSDimitry Andric .addImm(0U) 17902cab237bSDimitry Andric .addMetadata(Orig.getDebugVariable()) 17916bc11b14SDimitry Andric .addMetadata(Expr); 17926bc11b14SDimitry Andric } 17932cab237bSDimitry Andric 17942cab237bSDimitry Andric void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex) { 17952cab237bSDimitry Andric const DIExpression *Expr = computeExprForSpill(Orig); 17962cab237bSDimitry Andric Orig.getOperand(0).ChangeToFrameIndex(FrameIndex); 17972cab237bSDimitry Andric Orig.getOperand(1).ChangeToImmediate(0U); 17982cab237bSDimitry Andric Orig.getOperand(3).setMetadata(Expr); 17992cab237bSDimitry Andric } 1800