10b57cec5SDimitry Andric //===- lib/CodeGen/MachineInstr.cpp ---------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Methods common to all machine instructions. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 140b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 150b57cec5SDimitry Andric #include "llvm/ADT/Hashing.h" 160b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 170b57cec5SDimitry Andric #include "llvm/ADT/SmallBitVector.h" 180b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 190b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 200b57cec5SDimitry Andric #include "llvm/Analysis/MemoryLocation.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h" 260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h" 270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 300b57cec5SDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h" 3106c3fb27SDimitry Andric #include "llvm/CodeGen/Register.h" 32e8d8bef9SDimitry Andric #include "llvm/CodeGen/StackMaps.h" 330b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 340b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 350b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 36*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h" 370b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 380b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 390b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 400b57cec5SDimitry Andric #include "llvm/IR/Function.h" 410b57cec5SDimitry Andric #include "llvm/IR/InlineAsm.h" 42*0fca6ea1SDimitry Andric #include "llvm/IR/Instructions.h" 430b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 440b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 450b57cec5SDimitry Andric #include "llvm/IR/Module.h" 460b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h" 470b57cec5SDimitry Andric #include "llvm/IR/Operator.h" 480b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 490b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 500b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 510b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 520b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 530b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 545ffd83dbSDimitry Andric #include "llvm/Support/FormattedStream.h" 550b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 560b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 570b57cec5SDimitry Andric #include <algorithm> 580b57cec5SDimitry Andric #include <cassert> 590b57cec5SDimitry Andric #include <cstdint> 600b57cec5SDimitry Andric #include <cstring> 610b57cec5SDimitry Andric #include <utility> 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric using namespace llvm; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineInstr &MI) { 660b57cec5SDimitry Andric if (const MachineBasicBlock *MBB = MI.getParent()) 670b57cec5SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 680b57cec5SDimitry Andric return MF; 690b57cec5SDimitry Andric return nullptr; 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from 730b57cec5SDimitry Andric // it. 740b57cec5SDimitry Andric static void tryToGetTargetInfo(const MachineInstr &MI, 750b57cec5SDimitry Andric const TargetRegisterInfo *&TRI, 760b57cec5SDimitry Andric const MachineRegisterInfo *&MRI, 770b57cec5SDimitry Andric const TargetIntrinsicInfo *&IntrinsicInfo, 780b57cec5SDimitry Andric const TargetInstrInfo *&TII) { 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(MI)) { 810b57cec5SDimitry Andric TRI = MF->getSubtarget().getRegisterInfo(); 820b57cec5SDimitry Andric MRI = &MF->getRegInfo(); 830b57cec5SDimitry Andric IntrinsicInfo = MF->getTarget().getIntrinsicInfo(); 840b57cec5SDimitry Andric TII = MF->getSubtarget().getInstrInfo(); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) { 89bdd1243dSDimitry Andric for (MCPhysReg ImpDef : MCID->implicit_defs()) 90bdd1243dSDimitry Andric addOperand(MF, MachineOperand::CreateReg(ImpDef, true, true)); 91bdd1243dSDimitry Andric for (MCPhysReg ImpUse : MCID->implicit_uses()) 92bdd1243dSDimitry Andric addOperand(MF, MachineOperand::CreateReg(ImpUse, false, true)); 930b57cec5SDimitry Andric } 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric /// MachineInstr ctor - This constructor creates a MachineInstr and adds the 960b57cec5SDimitry Andric /// implicit operands. It reserves space for the number of operands specified by 970b57cec5SDimitry Andric /// the MCInstrDesc. 980eae32dcSDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &TID, 990eae32dcSDimitry Andric DebugLoc DL, bool NoImp) 10006c3fb27SDimitry Andric : MCID(&TID), NumOperands(0), Flags(0), AsmPrinterFlags(0), 101*0fca6ea1SDimitry Andric DbgLoc(std::move(DL)), DebugInstrNum(0), Opcode(TID.Opcode) { 1020eae32dcSDimitry Andric assert(DbgLoc.hasTrivialDestructor() && "Expected trivial destructor"); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric // Reserve space for the expected number of operands. 105bdd1243dSDimitry Andric if (unsigned NumOps = MCID->getNumOperands() + MCID->implicit_defs().size() + 106bdd1243dSDimitry Andric MCID->implicit_uses().size()) { 1070b57cec5SDimitry Andric CapOperands = OperandCapacity::get(NumOps); 1080b57cec5SDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric if (!NoImp) 1120b57cec5SDimitry Andric addImplicitDefUseOperands(MF); 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric 115e8d8bef9SDimitry Andric /// MachineInstr ctor - Copies MachineInstr arg exactly. 116e8d8bef9SDimitry Andric /// Does not copy the number from debug instruction numbering, to preserve 117e8d8bef9SDimitry Andric /// uniqueness. 1180b57cec5SDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) 11906c3fb27SDimitry Andric : MCID(&MI.getDesc()), NumOperands(0), Flags(0), AsmPrinterFlags(0), 120*0fca6ea1SDimitry Andric Info(MI.Info), DbgLoc(MI.getDebugLoc()), DebugInstrNum(0), 121*0fca6ea1SDimitry Andric Opcode(MI.getOpcode()) { 1220eae32dcSDimitry Andric assert(DbgLoc.hasTrivialDestructor() && "Expected trivial destructor"); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric CapOperands = OperandCapacity::get(MI.getNumOperands()); 1250b57cec5SDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric // Copy operands. 1280b57cec5SDimitry Andric for (const MachineOperand &MO : MI.operands()) 1290b57cec5SDimitry Andric addOperand(MF, MO); 1300b57cec5SDimitry Andric 131bdd1243dSDimitry Andric // Replicate ties between the operands, which addOperand was not 132bdd1243dSDimitry Andric // able to do reliably. 133bdd1243dSDimitry Andric for (unsigned i = 0, e = getNumOperands(); i < e; ++i) { 134bdd1243dSDimitry Andric MachineOperand &NewMO = getOperand(i); 135bdd1243dSDimitry Andric const MachineOperand &OrigMO = MI.getOperand(i); 136bdd1243dSDimitry Andric NewMO.TiedTo = OrigMO.TiedTo; 137bdd1243dSDimitry Andric } 138bdd1243dSDimitry Andric 1390b57cec5SDimitry Andric // Copy all the sensible flags. 1400b57cec5SDimitry Andric setFlags(MI.Flags); 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1435f757f3fSDimitry Andric void MachineInstr::setDesc(const MCInstrDesc &TID) { 1445f757f3fSDimitry Andric if (getParent()) 1455f757f3fSDimitry Andric getMF()->handleChangeDesc(*this, TID); 1465f757f3fSDimitry Andric MCID = &TID; 147*0fca6ea1SDimitry Andric Opcode = TID.Opcode; 1485f757f3fSDimitry Andric } 1495f757f3fSDimitry Andric 150e8d8bef9SDimitry Andric void MachineInstr::moveBefore(MachineInstr *MovePos) { 151e8d8bef9SDimitry Andric MovePos->getParent()->splice(MovePos, getParent(), getIterator()); 152e8d8bef9SDimitry Andric } 153e8d8bef9SDimitry Andric 1540b57cec5SDimitry Andric /// getRegInfo - If this instruction is embedded into a MachineFunction, 1550b57cec5SDimitry Andric /// return the MachineRegisterInfo object for the current function, otherwise 1560b57cec5SDimitry Andric /// return null. 1570b57cec5SDimitry Andric MachineRegisterInfo *MachineInstr::getRegInfo() { 1580b57cec5SDimitry Andric if (MachineBasicBlock *MBB = getParent()) 1590b57cec5SDimitry Andric return &MBB->getParent()->getRegInfo(); 1600b57cec5SDimitry Andric return nullptr; 1610b57cec5SDimitry Andric } 1620b57cec5SDimitry Andric 16306c3fb27SDimitry Andric const MachineRegisterInfo *MachineInstr::getRegInfo() const { 16406c3fb27SDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 16506c3fb27SDimitry Andric return &MBB->getParent()->getRegInfo(); 16606c3fb27SDimitry Andric return nullptr; 16706c3fb27SDimitry Andric } 16806c3fb27SDimitry Andric 16981ad6265SDimitry Andric void MachineInstr::removeRegOperandsFromUseLists(MachineRegisterInfo &MRI) { 1700b57cec5SDimitry Andric for (MachineOperand &MO : operands()) 1710b57cec5SDimitry Andric if (MO.isReg()) 1720b57cec5SDimitry Andric MRI.removeRegOperandFromUseList(&MO); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 17581ad6265SDimitry Andric void MachineInstr::addRegOperandsToUseLists(MachineRegisterInfo &MRI) { 1760b57cec5SDimitry Andric for (MachineOperand &MO : operands()) 1770b57cec5SDimitry Andric if (MO.isReg()) 1780b57cec5SDimitry Andric MRI.addRegOperandToUseList(&MO); 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) { 1820b57cec5SDimitry Andric MachineBasicBlock *MBB = getParent(); 1830b57cec5SDimitry Andric assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs"); 1840b57cec5SDimitry Andric MachineFunction *MF = MBB->getParent(); 1850b57cec5SDimitry Andric assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs"); 1860b57cec5SDimitry Andric addOperand(*MF, Op); 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping 1900b57cec5SDimitry Andric /// ranges. If MRI is non-null also update use-def chains. 1910b57cec5SDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src, 1920b57cec5SDimitry Andric unsigned NumOps, MachineRegisterInfo *MRI) { 1930b57cec5SDimitry Andric if (MRI) 1940b57cec5SDimitry Andric return MRI->moveOperands(Dst, Src, NumOps); 1950b57cec5SDimitry Andric // MachineOperand is a trivially copyable type so we can just use memmove. 196480093f4SDimitry Andric assert(Dst && Src && "Unknown operands"); 1970b57cec5SDimitry Andric std::memmove(Dst, Src, NumOps * sizeof(MachineOperand)); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric /// addOperand - Add the specified operand to the instruction. If it is an 2010b57cec5SDimitry Andric /// implicit operand, it is added to the end of the operand list. If it is 2020b57cec5SDimitry Andric /// an explicit operand it is added at the end of the explicit operand list 2030b57cec5SDimitry Andric /// (before the first implicit operand). 2040b57cec5SDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) { 20506c3fb27SDimitry Andric assert(isUInt<LLVM_MI_NUMOPERANDS_BITS>(NumOperands + 1) && 20606c3fb27SDimitry Andric "Cannot add more operands."); 2070b57cec5SDimitry Andric assert(MCID && "Cannot add operands before providing an instr descriptor"); 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric // Check if we're adding one of our existing operands. 2100b57cec5SDimitry Andric if (&Op >= Operands && &Op < Operands + NumOperands) { 2110b57cec5SDimitry Andric // This is unusual: MI->addOperand(MI->getOperand(i)). 2120b57cec5SDimitry Andric // If adding Op requires reallocating or moving existing operands around, 2130b57cec5SDimitry Andric // the Op reference could go stale. Support it by copying Op. 2140b57cec5SDimitry Andric MachineOperand CopyOp(Op); 2150b57cec5SDimitry Andric return addOperand(MF, CopyOp); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric // Find the insert location for the new operand. Implicit registers go at 2190b57cec5SDimitry Andric // the end, everything else goes before the implicit regs. 2200b57cec5SDimitry Andric // 2210b57cec5SDimitry Andric // FIXME: Allow mixed explicit and implicit operands on inline asm. 2220b57cec5SDimitry Andric // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as 2230b57cec5SDimitry Andric // implicit-defs, but they must not be moved around. See the FIXME in 2240b57cec5SDimitry Andric // InstrEmitter.cpp. 2250b57cec5SDimitry Andric unsigned OpNo = getNumOperands(); 2260b57cec5SDimitry Andric bool isImpReg = Op.isReg() && Op.isImplicit(); 2270b57cec5SDimitry Andric if (!isImpReg && !isInlineAsm()) { 2280b57cec5SDimitry Andric while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) { 2290b57cec5SDimitry Andric --OpNo; 2300b57cec5SDimitry Andric assert(!Operands[OpNo].isTied() && "Cannot move tied operands"); 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric // OpNo now points as the desired insertion point. Unless this is a variadic 2350b57cec5SDimitry Andric // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). 2360b57cec5SDimitry Andric // RegMask operands go between the explicit and implicit operands. 2370b57cec5SDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric // Determine if the Operands array needs to be reallocated. 2400b57cec5SDimitry Andric // Save the old capacity and operand array. 2410b57cec5SDimitry Andric OperandCapacity OldCap = CapOperands; 2420b57cec5SDimitry Andric MachineOperand *OldOperands = Operands; 2430b57cec5SDimitry Andric if (!OldOperands || OldCap.getSize() == getNumOperands()) { 2440b57cec5SDimitry Andric CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1); 2450b57cec5SDimitry Andric Operands = MF.allocateOperandArray(CapOperands); 2460b57cec5SDimitry Andric // Move the operands before the insertion point. 2470b57cec5SDimitry Andric if (OpNo) 2480b57cec5SDimitry Andric moveOperands(Operands, OldOperands, OpNo, MRI); 2490b57cec5SDimitry Andric } 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric // Move the operands following the insertion point. 2520b57cec5SDimitry Andric if (OpNo != NumOperands) 2530b57cec5SDimitry Andric moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo, 2540b57cec5SDimitry Andric MRI); 2550b57cec5SDimitry Andric ++NumOperands; 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric // Deallocate the old operand array. 2580b57cec5SDimitry Andric if (OldOperands != Operands && OldOperands) 2590b57cec5SDimitry Andric MF.deallocateOperandArray(OldCap, OldOperands); 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric // Copy Op into place. It still needs to be inserted into the MRI use lists. 2620b57cec5SDimitry Andric MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op); 2630b57cec5SDimitry Andric NewMO->ParentMI = this; 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric // When adding a register operand, tell MRI about it. 2660b57cec5SDimitry Andric if (NewMO->isReg()) { 2670b57cec5SDimitry Andric // Ensure isOnRegUseList() returns false, regardless of Op's status. 2680b57cec5SDimitry Andric NewMO->Contents.Reg.Prev = nullptr; 2690b57cec5SDimitry Andric // Ignore existing ties. This is not a property that can be copied. 2700b57cec5SDimitry Andric NewMO->TiedTo = 0; 2710b57cec5SDimitry Andric // Add the new operand to MRI, but only for instructions in an MBB. 2720b57cec5SDimitry Andric if (MRI) 2730b57cec5SDimitry Andric MRI->addRegOperandToUseList(NewMO); 2740b57cec5SDimitry Andric // The MCID operand information isn't accurate until we start adding 2750b57cec5SDimitry Andric // explicit operands. The implicit operands are added first, then the 2760b57cec5SDimitry Andric // explicits are inserted before them. 2770b57cec5SDimitry Andric if (!isImpReg) { 2780b57cec5SDimitry Andric // Tie uses to defs as indicated in MCInstrDesc. 2790b57cec5SDimitry Andric if (NewMO->isUse()) { 2800b57cec5SDimitry Andric int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO); 2810b57cec5SDimitry Andric if (DefIdx != -1) 2820b57cec5SDimitry Andric tieOperands(DefIdx, OpNo); 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric // If the register operand is flagged as early, mark the operand as such. 2850b57cec5SDimitry Andric if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) 2860b57cec5SDimitry Andric NewMO->setIsEarlyClobber(true); 2870b57cec5SDimitry Andric } 288349cc55cSDimitry Andric // Ensure debug instructions set debug flag on register uses. 289349cc55cSDimitry Andric if (NewMO->isUse() && isDebugInstr()) 290349cc55cSDimitry Andric NewMO->setIsDebug(); 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 29481ad6265SDimitry Andric void MachineInstr::removeOperand(unsigned OpNo) { 2950b57cec5SDimitry Andric assert(OpNo < getNumOperands() && "Invalid operand number"); 2960b57cec5SDimitry Andric untieRegOperand(OpNo); 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric #ifndef NDEBUG 2990b57cec5SDimitry Andric // Moving tied operands would break the ties. 3000b57cec5SDimitry Andric for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i) 3010b57cec5SDimitry Andric if (Operands[i].isReg()) 3020b57cec5SDimitry Andric assert(!Operands[i].isTied() && "Cannot move tied operands"); 3030b57cec5SDimitry Andric #endif 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric MachineRegisterInfo *MRI = getRegInfo(); 3060b57cec5SDimitry Andric if (MRI && Operands[OpNo].isReg()) 3070b57cec5SDimitry Andric MRI->removeRegOperandFromUseList(Operands + OpNo); 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric // Don't call the MachineOperand destructor. A lot of this code depends on 3100b57cec5SDimitry Andric // MachineOperand having a trivial destructor anyway, and adding a call here 3110b57cec5SDimitry Andric // wouldn't make it 'destructor-correct'. 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric if (unsigned N = NumOperands - 1 - OpNo) 3140b57cec5SDimitry Andric moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI); 3150b57cec5SDimitry Andric --NumOperands; 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 318c14a5a88SDimitry Andric void MachineInstr::setExtraInfo(MachineFunction &MF, 319c14a5a88SDimitry Andric ArrayRef<MachineMemOperand *> MMOs, 320c14a5a88SDimitry Andric MCSymbol *PreInstrSymbol, 321c14a5a88SDimitry Andric MCSymbol *PostInstrSymbol, 322bdd1243dSDimitry Andric MDNode *HeapAllocMarker, MDNode *PCSections, 323*0fca6ea1SDimitry Andric uint32_t CFIType, MDNode *MMRAs) { 324c14a5a88SDimitry Andric bool HasPreInstrSymbol = PreInstrSymbol != nullptr; 325c14a5a88SDimitry Andric bool HasPostInstrSymbol = PostInstrSymbol != nullptr; 326c14a5a88SDimitry Andric bool HasHeapAllocMarker = HeapAllocMarker != nullptr; 327bdd1243dSDimitry Andric bool HasPCSections = PCSections != nullptr; 328bdd1243dSDimitry Andric bool HasCFIType = CFIType != 0; 329*0fca6ea1SDimitry Andric bool HasMMRAs = MMRAs != nullptr; 330bdd1243dSDimitry Andric int NumPointers = MMOs.size() + HasPreInstrSymbol + HasPostInstrSymbol + 331*0fca6ea1SDimitry Andric HasHeapAllocMarker + HasPCSections + HasCFIType + HasMMRAs; 332c14a5a88SDimitry Andric 333c14a5a88SDimitry Andric // Drop all extra info if there is none. 334c14a5a88SDimitry Andric if (NumPointers <= 0) { 335c14a5a88SDimitry Andric Info.clear(); 336c14a5a88SDimitry Andric return; 337c14a5a88SDimitry Andric } 338c14a5a88SDimitry Andric 339c14a5a88SDimitry Andric // If more than one pointer, then store out of line. Store heap alloc markers 340c14a5a88SDimitry Andric // out of line because PointerSumType cannot hold more than 4 tag types with 341c14a5a88SDimitry Andric // 32-bit pointers. 342c14a5a88SDimitry Andric // FIXME: Maybe we should make the symbols in the extra info mutable? 343*0fca6ea1SDimitry Andric else if (NumPointers > 1 || HasMMRAs || HasHeapAllocMarker || HasPCSections || 344bdd1243dSDimitry Andric HasCFIType) { 345bdd1243dSDimitry Andric Info.set<EIIK_OutOfLine>( 346bdd1243dSDimitry Andric MF.createMIExtraInfo(MMOs, PreInstrSymbol, PostInstrSymbol, 347*0fca6ea1SDimitry Andric HeapAllocMarker, PCSections, CFIType, MMRAs)); 348c14a5a88SDimitry Andric return; 349c14a5a88SDimitry Andric } 350c14a5a88SDimitry Andric 351c14a5a88SDimitry Andric // Otherwise store the single pointer inline. 352c14a5a88SDimitry Andric if (HasPreInstrSymbol) 353c14a5a88SDimitry Andric Info.set<EIIK_PreInstrSymbol>(PreInstrSymbol); 354c14a5a88SDimitry Andric else if (HasPostInstrSymbol) 355c14a5a88SDimitry Andric Info.set<EIIK_PostInstrSymbol>(PostInstrSymbol); 356c14a5a88SDimitry Andric else 357c14a5a88SDimitry Andric Info.set<EIIK_MMO>(MMOs[0]); 358c14a5a88SDimitry Andric } 359c14a5a88SDimitry Andric 3600b57cec5SDimitry Andric void MachineInstr::dropMemRefs(MachineFunction &MF) { 3610b57cec5SDimitry Andric if (memoperands_empty()) 3620b57cec5SDimitry Andric return; 3630b57cec5SDimitry Andric 364c14a5a88SDimitry Andric setExtraInfo(MF, {}, getPreInstrSymbol(), getPostInstrSymbol(), 365*0fca6ea1SDimitry Andric getHeapAllocMarker(), getPCSections(), getCFIType(), 366*0fca6ea1SDimitry Andric getMMRAMetadata()); 3670b57cec5SDimitry Andric } 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric void MachineInstr::setMemRefs(MachineFunction &MF, 3700b57cec5SDimitry Andric ArrayRef<MachineMemOperand *> MMOs) { 3710b57cec5SDimitry Andric if (MMOs.empty()) { 3720b57cec5SDimitry Andric dropMemRefs(MF); 3730b57cec5SDimitry Andric return; 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric 376c14a5a88SDimitry Andric setExtraInfo(MF, MMOs, getPreInstrSymbol(), getPostInstrSymbol(), 377*0fca6ea1SDimitry Andric getHeapAllocMarker(), getPCSections(), getCFIType(), 378*0fca6ea1SDimitry Andric getMMRAMetadata()); 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric void MachineInstr::addMemOperand(MachineFunction &MF, 3820b57cec5SDimitry Andric MachineMemOperand *MO) { 3830b57cec5SDimitry Andric SmallVector<MachineMemOperand *, 2> MMOs; 3840b57cec5SDimitry Andric MMOs.append(memoperands_begin(), memoperands_end()); 3850b57cec5SDimitry Andric MMOs.push_back(MO); 3860b57cec5SDimitry Andric setMemRefs(MF, MMOs); 3870b57cec5SDimitry Andric } 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric void MachineInstr::cloneMemRefs(MachineFunction &MF, const MachineInstr &MI) { 3900b57cec5SDimitry Andric if (this == &MI) 3910b57cec5SDimitry Andric // Nothing to do for a self-clone! 3920b57cec5SDimitry Andric return; 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric assert(&MF == MI.getMF() && 3950b57cec5SDimitry Andric "Invalid machine functions when cloning memory refrences!"); 3960b57cec5SDimitry Andric // See if we can just steal the extra info already allocated for the 3970b57cec5SDimitry Andric // instruction. We can do this whenever the pre- and post-instruction symbols 3980b57cec5SDimitry Andric // are the same (including null). 3990b57cec5SDimitry Andric if (getPreInstrSymbol() == MI.getPreInstrSymbol() && 400c14a5a88SDimitry Andric getPostInstrSymbol() == MI.getPostInstrSymbol() && 401bdd1243dSDimitry Andric getHeapAllocMarker() == MI.getHeapAllocMarker() && 402*0fca6ea1SDimitry Andric getPCSections() == MI.getPCSections() && getMMRAMetadata() && 403*0fca6ea1SDimitry Andric MI.getMMRAMetadata()) { 4040b57cec5SDimitry Andric Info = MI.Info; 4050b57cec5SDimitry Andric return; 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric // Otherwise, fall back on a copy-based clone. 4090b57cec5SDimitry Andric setMemRefs(MF, MI.memoperands()); 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric /// Check to see if the MMOs pointed to by the two MemRefs arrays are 4130b57cec5SDimitry Andric /// identical. 4140b57cec5SDimitry Andric static bool hasIdenticalMMOs(ArrayRef<MachineMemOperand *> LHS, 4150b57cec5SDimitry Andric ArrayRef<MachineMemOperand *> RHS) { 4160b57cec5SDimitry Andric if (LHS.size() != RHS.size()) 4170b57cec5SDimitry Andric return false; 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric auto LHSPointees = make_pointee_range(LHS); 4200b57cec5SDimitry Andric auto RHSPointees = make_pointee_range(RHS); 4210b57cec5SDimitry Andric return std::equal(LHSPointees.begin(), LHSPointees.end(), 4220b57cec5SDimitry Andric RHSPointees.begin()); 4230b57cec5SDimitry Andric } 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric void MachineInstr::cloneMergedMemRefs(MachineFunction &MF, 4260b57cec5SDimitry Andric ArrayRef<const MachineInstr *> MIs) { 4270b57cec5SDimitry Andric // Try handling easy numbers of MIs with simpler mechanisms. 4280b57cec5SDimitry Andric if (MIs.empty()) { 4290b57cec5SDimitry Andric dropMemRefs(MF); 4300b57cec5SDimitry Andric return; 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric if (MIs.size() == 1) { 4330b57cec5SDimitry Andric cloneMemRefs(MF, *MIs[0]); 4340b57cec5SDimitry Andric return; 4350b57cec5SDimitry Andric } 4360b57cec5SDimitry Andric // Because an empty memoperands list provides *no* information and must be 4370b57cec5SDimitry Andric // handled conservatively (assuming the instruction can do anything), the only 4380b57cec5SDimitry Andric // way to merge with it is to drop all other memoperands. 4390b57cec5SDimitry Andric if (MIs[0]->memoperands_empty()) { 4400b57cec5SDimitry Andric dropMemRefs(MF); 4410b57cec5SDimitry Andric return; 4420b57cec5SDimitry Andric } 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric // Handle the general case. 4450b57cec5SDimitry Andric SmallVector<MachineMemOperand *, 2> MergedMMOs; 4460b57cec5SDimitry Andric // Start with the first instruction. 4470b57cec5SDimitry Andric assert(&MF == MIs[0]->getMF() && 4480b57cec5SDimitry Andric "Invalid machine functions when cloning memory references!"); 4490b57cec5SDimitry Andric MergedMMOs.append(MIs[0]->memoperands_begin(), MIs[0]->memoperands_end()); 4500b57cec5SDimitry Andric // Now walk all the other instructions and accumulate any different MMOs. 4510b57cec5SDimitry Andric for (const MachineInstr &MI : make_pointee_range(MIs.slice(1))) { 4520b57cec5SDimitry Andric assert(&MF == MI.getMF() && 4530b57cec5SDimitry Andric "Invalid machine functions when cloning memory references!"); 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric // Skip MIs with identical operands to the first. This is a somewhat 4560b57cec5SDimitry Andric // arbitrary hack but will catch common cases without being quadratic. 4570b57cec5SDimitry Andric // TODO: We could fully implement merge semantics here if needed. 4580b57cec5SDimitry Andric if (hasIdenticalMMOs(MIs[0]->memoperands(), MI.memoperands())) 4590b57cec5SDimitry Andric continue; 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric // Because an empty memoperands list provides *no* information and must be 4620b57cec5SDimitry Andric // handled conservatively (assuming the instruction can do anything), the 4630b57cec5SDimitry Andric // only way to merge with it is to drop all other memoperands. 4640b57cec5SDimitry Andric if (MI.memoperands_empty()) { 4650b57cec5SDimitry Andric dropMemRefs(MF); 4660b57cec5SDimitry Andric return; 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric // Otherwise accumulate these into our temporary buffer of the merged state. 4700b57cec5SDimitry Andric MergedMMOs.append(MI.memoperands_begin(), MI.memoperands_end()); 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric setMemRefs(MF, MergedMMOs); 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric void MachineInstr::setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) { 477c14a5a88SDimitry Andric // Do nothing if old and new symbols are the same. 478c14a5a88SDimitry Andric if (Symbol == getPreInstrSymbol()) 4790b57cec5SDimitry Andric return; 480c14a5a88SDimitry Andric 481c14a5a88SDimitry Andric // If there was only one symbol and we're removing it, just clear info. 482c14a5a88SDimitry Andric if (!Symbol && Info.is<EIIK_PreInstrSymbol>()) { 4830b57cec5SDimitry Andric Info.clear(); 4840b57cec5SDimitry Andric return; 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric 487c14a5a88SDimitry Andric setExtraInfo(MF, memoperands(), Symbol, getPostInstrSymbol(), 488*0fca6ea1SDimitry Andric getHeapAllocMarker(), getPCSections(), getCFIType(), 489*0fca6ea1SDimitry Andric getMMRAMetadata()); 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) { 493c14a5a88SDimitry Andric // Do nothing if old and new symbols are the same. 494c14a5a88SDimitry Andric if (Symbol == getPostInstrSymbol()) 4950b57cec5SDimitry Andric return; 496c14a5a88SDimitry Andric 497c14a5a88SDimitry Andric // If there was only one symbol and we're removing it, just clear info. 498c14a5a88SDimitry Andric if (!Symbol && Info.is<EIIK_PostInstrSymbol>()) { 4990b57cec5SDimitry Andric Info.clear(); 5000b57cec5SDimitry Andric return; 5010b57cec5SDimitry Andric } 5020b57cec5SDimitry Andric 503c14a5a88SDimitry Andric setExtraInfo(MF, memoperands(), getPreInstrSymbol(), Symbol, 504*0fca6ea1SDimitry Andric getHeapAllocMarker(), getPCSections(), getCFIType(), 505*0fca6ea1SDimitry Andric getMMRAMetadata()); 5060b57cec5SDimitry Andric } 5070b57cec5SDimitry Andric 508c14a5a88SDimitry Andric void MachineInstr::setHeapAllocMarker(MachineFunction &MF, MDNode *Marker) { 509c14a5a88SDimitry Andric // Do nothing if old and new symbols are the same. 510c14a5a88SDimitry Andric if (Marker == getHeapAllocMarker()) 5110b57cec5SDimitry Andric return; 5120b57cec5SDimitry Andric 513c14a5a88SDimitry Andric setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(), 514*0fca6ea1SDimitry Andric Marker, getPCSections(), getCFIType(), getMMRAMetadata()); 515bdd1243dSDimitry Andric } 516bdd1243dSDimitry Andric 517bdd1243dSDimitry Andric void MachineInstr::setPCSections(MachineFunction &MF, MDNode *PCSections) { 518bdd1243dSDimitry Andric // Do nothing if old and new symbols are the same. 519bdd1243dSDimitry Andric if (PCSections == getPCSections()) 520bdd1243dSDimitry Andric return; 521bdd1243dSDimitry Andric 522bdd1243dSDimitry Andric setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(), 523*0fca6ea1SDimitry Andric getHeapAllocMarker(), PCSections, getCFIType(), 524*0fca6ea1SDimitry Andric getMMRAMetadata()); 525bdd1243dSDimitry Andric } 526bdd1243dSDimitry Andric 527bdd1243dSDimitry Andric void MachineInstr::setCFIType(MachineFunction &MF, uint32_t Type) { 528bdd1243dSDimitry Andric // Do nothing if old and new types are the same. 529bdd1243dSDimitry Andric if (Type == getCFIType()) 530bdd1243dSDimitry Andric return; 531bdd1243dSDimitry Andric 532bdd1243dSDimitry Andric setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(), 533*0fca6ea1SDimitry Andric getHeapAllocMarker(), getPCSections(), Type, getMMRAMetadata()); 534*0fca6ea1SDimitry Andric } 535*0fca6ea1SDimitry Andric 536*0fca6ea1SDimitry Andric void MachineInstr::setMMRAMetadata(MachineFunction &MF, MDNode *MMRAs) { 537*0fca6ea1SDimitry Andric // Do nothing if old and new symbols are the same. 538*0fca6ea1SDimitry Andric if (MMRAs == getMMRAMetadata()) 539*0fca6ea1SDimitry Andric return; 540*0fca6ea1SDimitry Andric 541*0fca6ea1SDimitry Andric setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(), 542*0fca6ea1SDimitry Andric getHeapAllocMarker(), getPCSections(), getCFIType(), MMRAs); 5430b57cec5SDimitry Andric } 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric void MachineInstr::cloneInstrSymbols(MachineFunction &MF, 5460b57cec5SDimitry Andric const MachineInstr &MI) { 5470b57cec5SDimitry Andric if (this == &MI) 5480b57cec5SDimitry Andric // Nothing to do for a self-clone! 5490b57cec5SDimitry Andric return; 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric assert(&MF == MI.getMF() && 5520b57cec5SDimitry Andric "Invalid machine functions when cloning instruction symbols!"); 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric setPreInstrSymbol(MF, MI.getPreInstrSymbol()); 5550b57cec5SDimitry Andric setPostInstrSymbol(MF, MI.getPostInstrSymbol()); 556c14a5a88SDimitry Andric setHeapAllocMarker(MF, MI.getHeapAllocMarker()); 557bdd1243dSDimitry Andric setPCSections(MF, MI.getPCSections()); 558*0fca6ea1SDimitry Andric setMMRAMetadata(MF, MI.getMMRAMetadata()); 5590b57cec5SDimitry Andric } 5600b57cec5SDimitry Andric 56106c3fb27SDimitry Andric uint32_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const { 5620b57cec5SDimitry Andric // For now, the just return the union of the flags. If the flags get more 5630b57cec5SDimitry Andric // complicated over time, we might need more logic here. 5640b57cec5SDimitry Andric return getFlags() | Other.getFlags(); 5650b57cec5SDimitry Andric } 5660b57cec5SDimitry Andric 56706c3fb27SDimitry Andric uint32_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) { 56806c3fb27SDimitry Andric uint32_t MIFlags = 0; 5690b57cec5SDimitry Andric // Copy the wrapping flags. 5700b57cec5SDimitry Andric if (const OverflowingBinaryOperator *OB = 5710b57cec5SDimitry Andric dyn_cast<OverflowingBinaryOperator>(&I)) { 5720b57cec5SDimitry Andric if (OB->hasNoSignedWrap()) 5730b57cec5SDimitry Andric MIFlags |= MachineInstr::MIFlag::NoSWrap; 5740b57cec5SDimitry Andric if (OB->hasNoUnsignedWrap()) 5750b57cec5SDimitry Andric MIFlags |= MachineInstr::MIFlag::NoUWrap; 576*0fca6ea1SDimitry Andric } else if (const TruncInst *TI = dyn_cast<TruncInst>(&I)) { 577*0fca6ea1SDimitry Andric if (TI->hasNoSignedWrap()) 578*0fca6ea1SDimitry Andric MIFlags |= MachineInstr::MIFlag::NoSWrap; 579*0fca6ea1SDimitry Andric if (TI->hasNoUnsignedWrap()) 580*0fca6ea1SDimitry Andric MIFlags |= MachineInstr::MIFlag::NoUWrap; 581*0fca6ea1SDimitry Andric } else if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&I)) { 582*0fca6ea1SDimitry Andric if (GEP->hasNoUnsignedSignedWrap()) 583*0fca6ea1SDimitry Andric MIFlags |= MachineInstr::MIFlag::NoUSWrap; 584*0fca6ea1SDimitry Andric if (GEP->hasNoUnsignedWrap()) 585*0fca6ea1SDimitry Andric MIFlags |= MachineInstr::MIFlag::NoUWrap; 586*0fca6ea1SDimitry Andric } 587*0fca6ea1SDimitry Andric 588*0fca6ea1SDimitry Andric // Copy the nonneg flag. 589*0fca6ea1SDimitry Andric if (const PossiblyNonNegInst *PNI = dyn_cast<PossiblyNonNegInst>(&I)) { 590*0fca6ea1SDimitry Andric if (PNI->hasNonNeg()) 591*0fca6ea1SDimitry Andric MIFlags |= MachineInstr::MIFlag::NonNeg; 592*0fca6ea1SDimitry Andric // Copy the disjoint flag. 593*0fca6ea1SDimitry Andric } else if (const PossiblyDisjointInst *PD = 594*0fca6ea1SDimitry Andric dyn_cast<PossiblyDisjointInst>(&I)) { 595*0fca6ea1SDimitry Andric if (PD->isDisjoint()) 596*0fca6ea1SDimitry Andric MIFlags |= MachineInstr::MIFlag::Disjoint; 5970b57cec5SDimitry Andric } 5980b57cec5SDimitry Andric 5990b57cec5SDimitry Andric // Copy the exact flag. 6000b57cec5SDimitry Andric if (const PossiblyExactOperator *PE = dyn_cast<PossiblyExactOperator>(&I)) 6010b57cec5SDimitry Andric if (PE->isExact()) 6020b57cec5SDimitry Andric MIFlags |= MachineInstr::MIFlag::IsExact; 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric // Copy the fast-math flags. 6050b57cec5SDimitry Andric if (const FPMathOperator *FP = dyn_cast<FPMathOperator>(&I)) { 6060b57cec5SDimitry Andric const FastMathFlags Flags = FP->getFastMathFlags(); 6070b57cec5SDimitry Andric if (Flags.noNaNs()) 6080b57cec5SDimitry Andric MIFlags |= MachineInstr::MIFlag::FmNoNans; 6090b57cec5SDimitry Andric if (Flags.noInfs()) 6100b57cec5SDimitry Andric MIFlags |= MachineInstr::MIFlag::FmNoInfs; 6110b57cec5SDimitry Andric if (Flags.noSignedZeros()) 6120b57cec5SDimitry Andric MIFlags |= MachineInstr::MIFlag::FmNsz; 6130b57cec5SDimitry Andric if (Flags.allowReciprocal()) 6140b57cec5SDimitry Andric MIFlags |= MachineInstr::MIFlag::FmArcp; 6150b57cec5SDimitry Andric if (Flags.allowContract()) 6160b57cec5SDimitry Andric MIFlags |= MachineInstr::MIFlag::FmContract; 6170b57cec5SDimitry Andric if (Flags.approxFunc()) 6180b57cec5SDimitry Andric MIFlags |= MachineInstr::MIFlag::FmAfn; 6190b57cec5SDimitry Andric if (Flags.allowReassoc()) 6200b57cec5SDimitry Andric MIFlags |= MachineInstr::MIFlag::FmReassoc; 6210b57cec5SDimitry Andric } 6220b57cec5SDimitry Andric 62306c3fb27SDimitry Andric if (I.getMetadata(LLVMContext::MD_unpredictable)) 62406c3fb27SDimitry Andric MIFlags |= MachineInstr::MIFlag::Unpredictable; 62506c3fb27SDimitry Andric 6260b57cec5SDimitry Andric return MIFlags; 6270b57cec5SDimitry Andric } 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric void MachineInstr::copyIRFlags(const Instruction &I) { 6300b57cec5SDimitry Andric Flags = copyFlagsFromInstruction(I); 6310b57cec5SDimitry Andric } 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric bool MachineInstr::hasPropertyInBundle(uint64_t Mask, QueryType Type) const { 6340b57cec5SDimitry Andric assert(!isBundledWithPred() && "Must be called on bundle header"); 6350b57cec5SDimitry Andric for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) { 6360b57cec5SDimitry Andric if (MII->getDesc().getFlags() & Mask) { 6370b57cec5SDimitry Andric if (Type == AnyInBundle) 6380b57cec5SDimitry Andric return true; 6390b57cec5SDimitry Andric } else { 6400b57cec5SDimitry Andric if (Type == AllInBundle && !MII->isBundle()) 6410b57cec5SDimitry Andric return false; 6420b57cec5SDimitry Andric } 6430b57cec5SDimitry Andric // This was the last instruction in the bundle. 6440b57cec5SDimitry Andric if (!MII->isBundledWithSucc()) 6450b57cec5SDimitry Andric return Type == AllInBundle; 6460b57cec5SDimitry Andric } 6470b57cec5SDimitry Andric } 6480b57cec5SDimitry Andric 6490b57cec5SDimitry Andric bool MachineInstr::isIdenticalTo(const MachineInstr &Other, 6500b57cec5SDimitry Andric MICheckType Check) const { 6510b57cec5SDimitry Andric // If opcodes or number of operands are not the same then the two 6520b57cec5SDimitry Andric // instructions are obviously not identical. 6530b57cec5SDimitry Andric if (Other.getOpcode() != getOpcode() || 6540b57cec5SDimitry Andric Other.getNumOperands() != getNumOperands()) 6550b57cec5SDimitry Andric return false; 6560b57cec5SDimitry Andric 6570b57cec5SDimitry Andric if (isBundle()) { 6580b57cec5SDimitry Andric // We have passed the test above that both instructions have the same 6590b57cec5SDimitry Andric // opcode, so we know that both instructions are bundles here. Let's compare 6600b57cec5SDimitry Andric // MIs inside the bundle. 6610b57cec5SDimitry Andric assert(Other.isBundle() && "Expected that both instructions are bundles."); 6620b57cec5SDimitry Andric MachineBasicBlock::const_instr_iterator I1 = getIterator(); 6630b57cec5SDimitry Andric MachineBasicBlock::const_instr_iterator I2 = Other.getIterator(); 6640b57cec5SDimitry Andric // Loop until we analysed the last intruction inside at least one of the 6650b57cec5SDimitry Andric // bundles. 6660b57cec5SDimitry Andric while (I1->isBundledWithSucc() && I2->isBundledWithSucc()) { 6670b57cec5SDimitry Andric ++I1; 6680b57cec5SDimitry Andric ++I2; 6690b57cec5SDimitry Andric if (!I1->isIdenticalTo(*I2, Check)) 6700b57cec5SDimitry Andric return false; 6710b57cec5SDimitry Andric } 6720b57cec5SDimitry Andric // If we've reached the end of just one of the two bundles, but not both, 6730b57cec5SDimitry Andric // the instructions are not identical. 6740b57cec5SDimitry Andric if (I1->isBundledWithSucc() || I2->isBundledWithSucc()) 6750b57cec5SDimitry Andric return false; 6760b57cec5SDimitry Andric } 6770b57cec5SDimitry Andric 6780b57cec5SDimitry Andric // Check operands to make sure they match. 6790b57cec5SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 6800b57cec5SDimitry Andric const MachineOperand &MO = getOperand(i); 6810b57cec5SDimitry Andric const MachineOperand &OMO = Other.getOperand(i); 6820b57cec5SDimitry Andric if (!MO.isReg()) { 6830b57cec5SDimitry Andric if (!MO.isIdenticalTo(OMO)) 6840b57cec5SDimitry Andric return false; 6850b57cec5SDimitry Andric continue; 6860b57cec5SDimitry Andric } 6870b57cec5SDimitry Andric 6880b57cec5SDimitry Andric // Clients may or may not want to ignore defs when testing for equality. 6890b57cec5SDimitry Andric // For example, machine CSE pass only cares about finding common 6900b57cec5SDimitry Andric // subexpressions, so it's safe to ignore virtual register defs. 6910b57cec5SDimitry Andric if (MO.isDef()) { 6920b57cec5SDimitry Andric if (Check == IgnoreDefs) 6930b57cec5SDimitry Andric continue; 6940b57cec5SDimitry Andric else if (Check == IgnoreVRegDefs) { 695bdd1243dSDimitry Andric if (!MO.getReg().isVirtual() || !OMO.getReg().isVirtual()) 6960b57cec5SDimitry Andric if (!MO.isIdenticalTo(OMO)) 6970b57cec5SDimitry Andric return false; 6980b57cec5SDimitry Andric } else { 6990b57cec5SDimitry Andric if (!MO.isIdenticalTo(OMO)) 7000b57cec5SDimitry Andric return false; 7010b57cec5SDimitry Andric if (Check == CheckKillDead && MO.isDead() != OMO.isDead()) 7020b57cec5SDimitry Andric return false; 7030b57cec5SDimitry Andric } 7040b57cec5SDimitry Andric } else { 7050b57cec5SDimitry Andric if (!MO.isIdenticalTo(OMO)) 7060b57cec5SDimitry Andric return false; 7070b57cec5SDimitry Andric if (Check == CheckKillDead && MO.isKill() != OMO.isKill()) 7080b57cec5SDimitry Andric return false; 7090b57cec5SDimitry Andric } 7100b57cec5SDimitry Andric } 7110b57cec5SDimitry Andric // If DebugLoc does not match then two debug instructions are not identical. 7120b57cec5SDimitry Andric if (isDebugInstr()) 7130b57cec5SDimitry Andric if (getDebugLoc() && Other.getDebugLoc() && 7140b57cec5SDimitry Andric getDebugLoc() != Other.getDebugLoc()) 7150b57cec5SDimitry Andric return false; 716bdd1243dSDimitry Andric // If pre- or post-instruction symbols do not match then the two instructions 717bdd1243dSDimitry Andric // are not identical. 718bdd1243dSDimitry Andric if (getPreInstrSymbol() != Other.getPreInstrSymbol() || 719bdd1243dSDimitry Andric getPostInstrSymbol() != Other.getPostInstrSymbol()) 720bdd1243dSDimitry Andric return false; 721bdd1243dSDimitry Andric // Call instructions with different CFI types are not identical. 722bdd1243dSDimitry Andric if (isCall() && getCFIType() != Other.getCFIType()) 723bdd1243dSDimitry Andric return false; 724bdd1243dSDimitry Andric 725bdd1243dSDimitry Andric return true; 726bdd1243dSDimitry Andric } 727bdd1243dSDimitry Andric 728bdd1243dSDimitry Andric bool MachineInstr::isEquivalentDbgInstr(const MachineInstr &Other) const { 729bdd1243dSDimitry Andric if (!isDebugValueLike() || !Other.isDebugValueLike()) 730bdd1243dSDimitry Andric return false; 731bdd1243dSDimitry Andric if (getDebugLoc() != Other.getDebugLoc()) 732bdd1243dSDimitry Andric return false; 733bdd1243dSDimitry Andric if (getDebugVariable() != Other.getDebugVariable()) 734bdd1243dSDimitry Andric return false; 735bdd1243dSDimitry Andric if (getNumDebugOperands() != Other.getNumDebugOperands()) 736bdd1243dSDimitry Andric return false; 737bdd1243dSDimitry Andric for (unsigned OpIdx = 0; OpIdx < getNumDebugOperands(); ++OpIdx) 738bdd1243dSDimitry Andric if (!getDebugOperand(OpIdx).isIdenticalTo(Other.getDebugOperand(OpIdx))) 739bdd1243dSDimitry Andric return false; 740bdd1243dSDimitry Andric if (!DIExpression::isEqualExpression( 741bdd1243dSDimitry Andric getDebugExpression(), isIndirectDebugValue(), 742bdd1243dSDimitry Andric Other.getDebugExpression(), Other.isIndirectDebugValue())) 743bdd1243dSDimitry Andric return false; 7440b57cec5SDimitry Andric return true; 7450b57cec5SDimitry Andric } 7460b57cec5SDimitry Andric 7470b57cec5SDimitry Andric const MachineFunction *MachineInstr::getMF() const { 7480b57cec5SDimitry Andric return getParent()->getParent(); 7490b57cec5SDimitry Andric } 7500b57cec5SDimitry Andric 7510b57cec5SDimitry Andric MachineInstr *MachineInstr::removeFromParent() { 7520b57cec5SDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 7530b57cec5SDimitry Andric return getParent()->remove(this); 7540b57cec5SDimitry Andric } 7550b57cec5SDimitry Andric 7560b57cec5SDimitry Andric MachineInstr *MachineInstr::removeFromBundle() { 7570b57cec5SDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 7580b57cec5SDimitry Andric return getParent()->remove_instr(this); 7590b57cec5SDimitry Andric } 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric void MachineInstr::eraseFromParent() { 7620b57cec5SDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 7630b57cec5SDimitry Andric getParent()->erase(this); 7640b57cec5SDimitry Andric } 7650b57cec5SDimitry Andric 7660b57cec5SDimitry Andric void MachineInstr::eraseFromBundle() { 7670b57cec5SDimitry Andric assert(getParent() && "Not embedded in a basic block!"); 7680b57cec5SDimitry Andric getParent()->erase_instr(this); 7690b57cec5SDimitry Andric } 7700b57cec5SDimitry Andric 7715ffd83dbSDimitry Andric bool MachineInstr::isCandidateForCallSiteEntry(QueryType Type) const { 7725ffd83dbSDimitry Andric if (!isCall(Type)) 7735ffd83dbSDimitry Andric return false; 7745ffd83dbSDimitry Andric switch (getOpcode()) { 7755ffd83dbSDimitry Andric case TargetOpcode::PATCHPOINT: 7765ffd83dbSDimitry Andric case TargetOpcode::STACKMAP: 7775ffd83dbSDimitry Andric case TargetOpcode::STATEPOINT: 778e8d8bef9SDimitry Andric case TargetOpcode::FENTRY_CALL: 7795ffd83dbSDimitry Andric return false; 7805ffd83dbSDimitry Andric } 7815ffd83dbSDimitry Andric return true; 7825ffd83dbSDimitry Andric } 7835ffd83dbSDimitry Andric 7845ffd83dbSDimitry Andric bool MachineInstr::shouldUpdateCallSiteInfo() const { 7855ffd83dbSDimitry Andric if (isBundle()) 7865ffd83dbSDimitry Andric return isCandidateForCallSiteEntry(MachineInstr::AnyInBundle); 7875ffd83dbSDimitry Andric return isCandidateForCallSiteEntry(); 7885ffd83dbSDimitry Andric } 7895ffd83dbSDimitry Andric 7900b57cec5SDimitry Andric unsigned MachineInstr::getNumExplicitOperands() const { 7910b57cec5SDimitry Andric unsigned NumOperands = MCID->getNumOperands(); 7920b57cec5SDimitry Andric if (!MCID->isVariadic()) 7930b57cec5SDimitry Andric return NumOperands; 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andric for (unsigned I = NumOperands, E = getNumOperands(); I != E; ++I) { 7960b57cec5SDimitry Andric const MachineOperand &MO = getOperand(I); 7970b57cec5SDimitry Andric // The operands must always be in the following order: 7980b57cec5SDimitry Andric // - explicit reg defs, 7990b57cec5SDimitry Andric // - other explicit operands (reg uses, immediates, etc.), 8000b57cec5SDimitry Andric // - implicit reg defs 8010b57cec5SDimitry Andric // - implicit reg uses 8020b57cec5SDimitry Andric if (MO.isReg() && MO.isImplicit()) 8030b57cec5SDimitry Andric break; 8040b57cec5SDimitry Andric ++NumOperands; 8050b57cec5SDimitry Andric } 8060b57cec5SDimitry Andric return NumOperands; 8070b57cec5SDimitry Andric } 8080b57cec5SDimitry Andric 8090b57cec5SDimitry Andric unsigned MachineInstr::getNumExplicitDefs() const { 8100b57cec5SDimitry Andric unsigned NumDefs = MCID->getNumDefs(); 8110b57cec5SDimitry Andric if (!MCID->isVariadic()) 8120b57cec5SDimitry Andric return NumDefs; 8130b57cec5SDimitry Andric 8140b57cec5SDimitry Andric for (unsigned I = NumDefs, E = getNumOperands(); I != E; ++I) { 8150b57cec5SDimitry Andric const MachineOperand &MO = getOperand(I); 8160b57cec5SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.isImplicit()) 8170b57cec5SDimitry Andric break; 8180b57cec5SDimitry Andric ++NumDefs; 8190b57cec5SDimitry Andric } 8200b57cec5SDimitry Andric return NumDefs; 8210b57cec5SDimitry Andric } 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric void MachineInstr::bundleWithPred() { 8240b57cec5SDimitry Andric assert(!isBundledWithPred() && "MI is already bundled with its predecessor"); 8250b57cec5SDimitry Andric setFlag(BundledPred); 8260b57cec5SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 8270b57cec5SDimitry Andric --Pred; 8280b57cec5SDimitry Andric assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 8290b57cec5SDimitry Andric Pred->setFlag(BundledSucc); 8300b57cec5SDimitry Andric } 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric void MachineInstr::bundleWithSucc() { 8330b57cec5SDimitry Andric assert(!isBundledWithSucc() && "MI is already bundled with its successor"); 8340b57cec5SDimitry Andric setFlag(BundledSucc); 8350b57cec5SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 8360b57cec5SDimitry Andric ++Succ; 8370b57cec5SDimitry Andric assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags"); 8380b57cec5SDimitry Andric Succ->setFlag(BundledPred); 8390b57cec5SDimitry Andric } 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric void MachineInstr::unbundleFromPred() { 8420b57cec5SDimitry Andric assert(isBundledWithPred() && "MI isn't bundled with its predecessor"); 8430b57cec5SDimitry Andric clearFlag(BundledPred); 8440b57cec5SDimitry Andric MachineBasicBlock::instr_iterator Pred = getIterator(); 8450b57cec5SDimitry Andric --Pred; 8460b57cec5SDimitry Andric assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags"); 8470b57cec5SDimitry Andric Pred->clearFlag(BundledSucc); 8480b57cec5SDimitry Andric } 8490b57cec5SDimitry Andric 8500b57cec5SDimitry Andric void MachineInstr::unbundleFromSucc() { 8510b57cec5SDimitry Andric assert(isBundledWithSucc() && "MI isn't bundled with its successor"); 8520b57cec5SDimitry Andric clearFlag(BundledSucc); 8530b57cec5SDimitry Andric MachineBasicBlock::instr_iterator Succ = getIterator(); 8540b57cec5SDimitry Andric ++Succ; 8550b57cec5SDimitry Andric assert(Succ->isBundledWithPred() && "Inconsistent bundle flags"); 8560b57cec5SDimitry Andric Succ->clearFlag(BundledPred); 8570b57cec5SDimitry Andric } 8580b57cec5SDimitry Andric 8590b57cec5SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const { 8600b57cec5SDimitry Andric if (isInlineAsm()) { 8610b57cec5SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 8620b57cec5SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 8630b57cec5SDimitry Andric return true; 8640b57cec5SDimitry Andric } 8650b57cec5SDimitry Andric return false; 8660b57cec5SDimitry Andric } 8670b57cec5SDimitry Andric 8680b57cec5SDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const { 8690b57cec5SDimitry Andric assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!"); 8700b57cec5SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 8710b57cec5SDimitry Andric return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0); 8720b57cec5SDimitry Andric } 8730b57cec5SDimitry Andric 8740b57cec5SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx, 8750b57cec5SDimitry Andric unsigned *GroupNo) const { 8760b57cec5SDimitry Andric assert(isInlineAsm() && "Expected an inline asm instruction"); 8770b57cec5SDimitry Andric assert(OpIdx < getNumOperands() && "OpIdx out of range"); 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric // Ignore queries about the initial operands. 8800b57cec5SDimitry Andric if (OpIdx < InlineAsm::MIOp_FirstOperand) 8810b57cec5SDimitry Andric return -1; 8820b57cec5SDimitry Andric 8830b57cec5SDimitry Andric unsigned Group = 0; 8840b57cec5SDimitry Andric unsigned NumOps; 8850b57cec5SDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 8860b57cec5SDimitry Andric i += NumOps) { 8870b57cec5SDimitry Andric const MachineOperand &FlagMO = getOperand(i); 8880b57cec5SDimitry Andric // If we reach the implicit register operands, stop looking. 8890b57cec5SDimitry Andric if (!FlagMO.isImm()) 8900b57cec5SDimitry Andric return -1; 8915f757f3fSDimitry Andric const InlineAsm::Flag F(FlagMO.getImm()); 8925f757f3fSDimitry Andric NumOps = 1 + F.getNumOperandRegisters(); 8930b57cec5SDimitry Andric if (i + NumOps > OpIdx) { 8940b57cec5SDimitry Andric if (GroupNo) 8950b57cec5SDimitry Andric *GroupNo = Group; 8960b57cec5SDimitry Andric return i; 8970b57cec5SDimitry Andric } 8980b57cec5SDimitry Andric ++Group; 8990b57cec5SDimitry Andric } 9000b57cec5SDimitry Andric return -1; 9010b57cec5SDimitry Andric } 9020b57cec5SDimitry Andric 9030b57cec5SDimitry Andric const DILabel *MachineInstr::getDebugLabel() const { 9040b57cec5SDimitry Andric assert(isDebugLabel() && "not a DBG_LABEL"); 9050b57cec5SDimitry Andric return cast<DILabel>(getOperand(0).getMetadata()); 9060b57cec5SDimitry Andric } 9070b57cec5SDimitry Andric 9085ffd83dbSDimitry Andric const MachineOperand &MachineInstr::getDebugVariableOp() const { 909bdd1243dSDimitry Andric assert((isDebugValueLike()) && "not a DBG_VALUE*"); 910bdd1243dSDimitry Andric unsigned VariableOp = isNonListDebugValue() ? 2 : 0; 911fe6060f1SDimitry Andric return getOperand(VariableOp); 9125ffd83dbSDimitry Andric } 9135ffd83dbSDimitry Andric 9145ffd83dbSDimitry Andric MachineOperand &MachineInstr::getDebugVariableOp() { 915bdd1243dSDimitry Andric assert((isDebugValueLike()) && "not a DBG_VALUE*"); 916bdd1243dSDimitry Andric unsigned VariableOp = isNonListDebugValue() ? 2 : 0; 917fe6060f1SDimitry Andric return getOperand(VariableOp); 9185ffd83dbSDimitry Andric } 9195ffd83dbSDimitry Andric 9200b57cec5SDimitry Andric const DILocalVariable *MachineInstr::getDebugVariable() const { 921fe6060f1SDimitry Andric return cast<DILocalVariable>(getDebugVariableOp().getMetadata()); 922fe6060f1SDimitry Andric } 923fe6060f1SDimitry Andric 924fe6060f1SDimitry Andric const MachineOperand &MachineInstr::getDebugExpressionOp() const { 925bdd1243dSDimitry Andric assert((isDebugValueLike()) && "not a DBG_VALUE*"); 926bdd1243dSDimitry Andric unsigned ExpressionOp = isNonListDebugValue() ? 3 : 1; 927fe6060f1SDimitry Andric return getOperand(ExpressionOp); 9280b57cec5SDimitry Andric } 9290b57cec5SDimitry Andric 9305ffd83dbSDimitry Andric MachineOperand &MachineInstr::getDebugExpressionOp() { 931bdd1243dSDimitry Andric assert((isDebugValueLike()) && "not a DBG_VALUE*"); 932bdd1243dSDimitry Andric unsigned ExpressionOp = isNonListDebugValue() ? 3 : 1; 933fe6060f1SDimitry Andric return getOperand(ExpressionOp); 9345ffd83dbSDimitry Andric } 9355ffd83dbSDimitry Andric 9360b57cec5SDimitry Andric const DIExpression *MachineInstr::getDebugExpression() const { 937fe6060f1SDimitry Andric return cast<DIExpression>(getDebugExpressionOp().getMetadata()); 9380b57cec5SDimitry Andric } 9390b57cec5SDimitry Andric 9408bcb0991SDimitry Andric bool MachineInstr::isDebugEntryValue() const { 9418bcb0991SDimitry Andric return isDebugValue() && getDebugExpression()->isEntryValue(); 9428bcb0991SDimitry Andric } 9438bcb0991SDimitry Andric 9440b57cec5SDimitry Andric const TargetRegisterClass* 9450b57cec5SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx, 9460b57cec5SDimitry Andric const TargetInstrInfo *TII, 9470b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const { 9480b57cec5SDimitry Andric assert(getParent() && "Can't have an MBB reference here!"); 9490b57cec5SDimitry Andric assert(getMF() && "Can't have an MF reference here!"); 9500b57cec5SDimitry Andric const MachineFunction &MF = *getMF(); 9510b57cec5SDimitry Andric 9520b57cec5SDimitry Andric // Most opcodes have fixed constraints in their MCInstrDesc. 9530b57cec5SDimitry Andric if (!isInlineAsm()) 9540b57cec5SDimitry Andric return TII->getRegClass(getDesc(), OpIdx, TRI, MF); 9550b57cec5SDimitry Andric 9560b57cec5SDimitry Andric if (!getOperand(OpIdx).isReg()) 9570b57cec5SDimitry Andric return nullptr; 9580b57cec5SDimitry Andric 9590b57cec5SDimitry Andric // For tied uses on inline asm, get the constraint from the def. 9600b57cec5SDimitry Andric unsigned DefIdx; 9610b57cec5SDimitry Andric if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx)) 9620b57cec5SDimitry Andric OpIdx = DefIdx; 9630b57cec5SDimitry Andric 9640b57cec5SDimitry Andric // Inline asm stores register class constraints in the flag word. 9650b57cec5SDimitry Andric int FlagIdx = findInlineAsmFlagIdx(OpIdx); 9660b57cec5SDimitry Andric if (FlagIdx < 0) 9670b57cec5SDimitry Andric return nullptr; 9680b57cec5SDimitry Andric 9695f757f3fSDimitry Andric const InlineAsm::Flag F(getOperand(FlagIdx).getImm()); 9700b57cec5SDimitry Andric unsigned RCID; 9715f757f3fSDimitry Andric if ((F.isRegUseKind() || F.isRegDefKind() || F.isRegDefEarlyClobberKind()) && 9725f757f3fSDimitry Andric F.hasRegClassConstraint(RCID)) 9730b57cec5SDimitry Andric return TRI->getRegClass(RCID); 9740b57cec5SDimitry Andric 9750b57cec5SDimitry Andric // Assume that all registers in a memory operand are pointers. 9765f757f3fSDimitry Andric if (F.isMemKind()) 9770b57cec5SDimitry Andric return TRI->getPointerRegClass(MF); 9780b57cec5SDimitry Andric 9790b57cec5SDimitry Andric return nullptr; 9800b57cec5SDimitry Andric } 9810b57cec5SDimitry Andric 9820b57cec5SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg( 9838bcb0991SDimitry Andric Register Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII, 9840b57cec5SDimitry Andric const TargetRegisterInfo *TRI, bool ExploreBundle) const { 9850b57cec5SDimitry Andric // Check every operands inside the bundle if we have 9860b57cec5SDimitry Andric // been asked to. 9870b57cec5SDimitry Andric if (ExploreBundle) 9880b57cec5SDimitry Andric for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC; 9890b57cec5SDimitry Andric ++OpndIt) 9900b57cec5SDimitry Andric CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl( 9910b57cec5SDimitry Andric OpndIt.getOperandNo(), Reg, CurRC, TII, TRI); 9920b57cec5SDimitry Andric else 9930b57cec5SDimitry Andric // Otherwise, just check the current operands. 9940b57cec5SDimitry Andric for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i) 9950b57cec5SDimitry Andric CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI); 9960b57cec5SDimitry Andric return CurRC; 9970b57cec5SDimitry Andric } 9980b57cec5SDimitry Andric 9990b57cec5SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl( 10008bcb0991SDimitry Andric unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC, 10010b57cec5SDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 10020b57cec5SDimitry Andric assert(CurRC && "Invalid initial register class"); 10030b57cec5SDimitry Andric // Check if Reg is constrained by some of its use/def from MI. 10040b57cec5SDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 10050b57cec5SDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 10060b57cec5SDimitry Andric return CurRC; 10070b57cec5SDimitry Andric // If yes, accumulate the constraints through the operand. 10080b57cec5SDimitry Andric return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI); 10090b57cec5SDimitry Andric } 10100b57cec5SDimitry Andric 10110b57cec5SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect( 10120b57cec5SDimitry Andric unsigned OpIdx, const TargetRegisterClass *CurRC, 10130b57cec5SDimitry Andric const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const { 10140b57cec5SDimitry Andric const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI); 10150b57cec5SDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 10160b57cec5SDimitry Andric assert(MO.isReg() && 10170b57cec5SDimitry Andric "Cannot get register constraints for non-register operand"); 10180b57cec5SDimitry Andric assert(CurRC && "Invalid initial register class"); 10190b57cec5SDimitry Andric if (unsigned SubIdx = MO.getSubReg()) { 10200b57cec5SDimitry Andric if (OpRC) 10210b57cec5SDimitry Andric CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx); 10220b57cec5SDimitry Andric else 10230b57cec5SDimitry Andric CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx); 10240b57cec5SDimitry Andric } else if (OpRC) 10250b57cec5SDimitry Andric CurRC = TRI->getCommonSubClass(CurRC, OpRC); 10260b57cec5SDimitry Andric return CurRC; 10270b57cec5SDimitry Andric } 10280b57cec5SDimitry Andric 10290b57cec5SDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the 10300b57cec5SDimitry Andric /// header instruction. 10310b57cec5SDimitry Andric unsigned MachineInstr::getBundleSize() const { 10320b57cec5SDimitry Andric MachineBasicBlock::const_instr_iterator I = getIterator(); 10330b57cec5SDimitry Andric unsigned Size = 0; 10340b57cec5SDimitry Andric while (I->isBundledWithSucc()) { 10350b57cec5SDimitry Andric ++Size; 10360b57cec5SDimitry Andric ++I; 10370b57cec5SDimitry Andric } 10380b57cec5SDimitry Andric return Size; 10390b57cec5SDimitry Andric } 10400b57cec5SDimitry Andric 10410b57cec5SDimitry Andric /// Returns true if the MachineInstr has an implicit-use operand of exactly 10420b57cec5SDimitry Andric /// the given register (not considering sub/super-registers). 10438bcb0991SDimitry Andric bool MachineInstr::hasRegisterImplicitUseOperand(Register Reg) const { 1044*0fca6ea1SDimitry Andric for (const MachineOperand &MO : operands()) { 10450b57cec5SDimitry Andric if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == Reg) 10460b57cec5SDimitry Andric return true; 10470b57cec5SDimitry Andric } 10480b57cec5SDimitry Andric return false; 10490b57cec5SDimitry Andric } 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andric /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of 10520b57cec5SDimitry Andric /// the specific register or -1 if it is not found. It further tightens 10530b57cec5SDimitry Andric /// the search criteria to a use that kills the register if isKill is true. 1054*0fca6ea1SDimitry Andric int MachineInstr::findRegisterUseOperandIdx(Register Reg, 1055*0fca6ea1SDimitry Andric const TargetRegisterInfo *TRI, 1056*0fca6ea1SDimitry Andric bool isKill) const { 10570b57cec5SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 10580b57cec5SDimitry Andric const MachineOperand &MO = getOperand(i); 10590b57cec5SDimitry Andric if (!MO.isReg() || !MO.isUse()) 10600b57cec5SDimitry Andric continue; 10618bcb0991SDimitry Andric Register MOReg = MO.getReg(); 10620b57cec5SDimitry Andric if (!MOReg) 10630b57cec5SDimitry Andric continue; 10640b57cec5SDimitry Andric if (MOReg == Reg || (TRI && Reg && MOReg && TRI->regsOverlap(MOReg, Reg))) 10650b57cec5SDimitry Andric if (!isKill || MO.isKill()) 10660b57cec5SDimitry Andric return i; 10670b57cec5SDimitry Andric } 10680b57cec5SDimitry Andric return -1; 10690b57cec5SDimitry Andric } 10700b57cec5SDimitry Andric 10710b57cec5SDimitry Andric /// readsWritesVirtualRegister - Return a pair of bools (reads, writes) 10720b57cec5SDimitry Andric /// indicating if this instruction reads or writes Reg. This also considers 10730b57cec5SDimitry Andric /// partial defines. 10740b57cec5SDimitry Andric std::pair<bool,bool> 10758bcb0991SDimitry Andric MachineInstr::readsWritesVirtualRegister(Register Reg, 10760b57cec5SDimitry Andric SmallVectorImpl<unsigned> *Ops) const { 10770b57cec5SDimitry Andric bool PartDef = false; // Partial redefine. 10780b57cec5SDimitry Andric bool FullDef = false; // Full define. 10790b57cec5SDimitry Andric bool Use = false; 10800b57cec5SDimitry Andric 10810b57cec5SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 10820b57cec5SDimitry Andric const MachineOperand &MO = getOperand(i); 10830b57cec5SDimitry Andric if (!MO.isReg() || MO.getReg() != Reg) 10840b57cec5SDimitry Andric continue; 10850b57cec5SDimitry Andric if (Ops) 10860b57cec5SDimitry Andric Ops->push_back(i); 10870b57cec5SDimitry Andric if (MO.isUse()) 10880b57cec5SDimitry Andric Use |= !MO.isUndef(); 10890b57cec5SDimitry Andric else if (MO.getSubReg() && !MO.isUndef()) 10900b57cec5SDimitry Andric // A partial def undef doesn't count as reading the register. 10910b57cec5SDimitry Andric PartDef = true; 10920b57cec5SDimitry Andric else 10930b57cec5SDimitry Andric FullDef = true; 10940b57cec5SDimitry Andric } 10950b57cec5SDimitry Andric // A partial redefine uses Reg unless there is also a full define. 10960b57cec5SDimitry Andric return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef); 10970b57cec5SDimitry Andric } 10980b57cec5SDimitry Andric 10990b57cec5SDimitry Andric /// findRegisterDefOperandIdx() - Returns the operand index that is a def of 11000b57cec5SDimitry Andric /// the specified register or -1 if it is not found. If isDead is true, defs 11010b57cec5SDimitry Andric /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it 11020b57cec5SDimitry Andric /// also checks if there is a def of a super-register. 1103*0fca6ea1SDimitry Andric int MachineInstr::findRegisterDefOperandIdx(Register Reg, 1104*0fca6ea1SDimitry Andric const TargetRegisterInfo *TRI, 1105*0fca6ea1SDimitry Andric bool isDead, bool Overlap) const { 1106bdd1243dSDimitry Andric bool isPhys = Reg.isPhysical(); 11070b57cec5SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 11080b57cec5SDimitry Andric const MachineOperand &MO = getOperand(i); 11090b57cec5SDimitry Andric // Accept regmask operands when Overlap is set. 11100b57cec5SDimitry Andric // Ignore them when looking for a specific def operand (Overlap == false). 11110b57cec5SDimitry Andric if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg)) 11120b57cec5SDimitry Andric return i; 11130b57cec5SDimitry Andric if (!MO.isReg() || !MO.isDef()) 11140b57cec5SDimitry Andric continue; 11158bcb0991SDimitry Andric Register MOReg = MO.getReg(); 11160b57cec5SDimitry Andric bool Found = (MOReg == Reg); 1117bdd1243dSDimitry Andric if (!Found && TRI && isPhys && MOReg.isPhysical()) { 11180b57cec5SDimitry Andric if (Overlap) 11190b57cec5SDimitry Andric Found = TRI->regsOverlap(MOReg, Reg); 11200b57cec5SDimitry Andric else 11210b57cec5SDimitry Andric Found = TRI->isSubRegister(MOReg, Reg); 11220b57cec5SDimitry Andric } 11230b57cec5SDimitry Andric if (Found && (!isDead || MO.isDead())) 11240b57cec5SDimitry Andric return i; 11250b57cec5SDimitry Andric } 11260b57cec5SDimitry Andric return -1; 11270b57cec5SDimitry Andric } 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andric /// findFirstPredOperandIdx() - Find the index of the first operand in the 11300b57cec5SDimitry Andric /// operand list that is used to represent the predicate. It returns -1 if 11310b57cec5SDimitry Andric /// none is found. 11320b57cec5SDimitry Andric int MachineInstr::findFirstPredOperandIdx() const { 11330b57cec5SDimitry Andric // Don't call MCID.findFirstPredOperandIdx() because this variant 11340b57cec5SDimitry Andric // is sometimes called on an instruction that's not yet complete, and 11350b57cec5SDimitry Andric // so the number of operands is less than the MCID indicates. In 11360b57cec5SDimitry Andric // particular, the PTX target does this. 11370b57cec5SDimitry Andric const MCInstrDesc &MCID = getDesc(); 11380b57cec5SDimitry Andric if (MCID.isPredicable()) { 11390b57cec5SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) 1140bdd1243dSDimitry Andric if (MCID.operands()[i].isPredicate()) 11410b57cec5SDimitry Andric return i; 11420b57cec5SDimitry Andric } 11430b57cec5SDimitry Andric 11440b57cec5SDimitry Andric return -1; 11450b57cec5SDimitry Andric } 11460b57cec5SDimitry Andric 11470b57cec5SDimitry Andric // MachineOperand::TiedTo is 4 bits wide. 11480b57cec5SDimitry Andric const unsigned TiedMax = 15; 11490b57cec5SDimitry Andric 11500b57cec5SDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other. 11510b57cec5SDimitry Andric /// 11520b57cec5SDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo 11530b57cec5SDimitry Andric /// field. TiedTo can have these values: 11540b57cec5SDimitry Andric /// 11550b57cec5SDimitry Andric /// 0: Operand is not tied to anything. 11560b57cec5SDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1). 11570b57cec5SDimitry Andric /// TiedMax: Tied to an operand >= TiedMax-1. 11580b57cec5SDimitry Andric /// 11590b57cec5SDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal 11600b57cec5SDimitry Andric /// instruction. INLINEASM instructions allow more tied defs. 11610b57cec5SDimitry Andric /// 11620b57cec5SDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) { 11630b57cec5SDimitry Andric MachineOperand &DefMO = getOperand(DefIdx); 11640b57cec5SDimitry Andric MachineOperand &UseMO = getOperand(UseIdx); 11650b57cec5SDimitry Andric assert(DefMO.isDef() && "DefIdx must be a def operand"); 11660b57cec5SDimitry Andric assert(UseMO.isUse() && "UseIdx must be a use operand"); 11670b57cec5SDimitry Andric assert(!DefMO.isTied() && "Def is already tied to another use"); 11680b57cec5SDimitry Andric assert(!UseMO.isTied() && "Use is already tied to another def"); 11690b57cec5SDimitry Andric 11700b57cec5SDimitry Andric if (DefIdx < TiedMax) 11710b57cec5SDimitry Andric UseMO.TiedTo = DefIdx + 1; 11720b57cec5SDimitry Andric else { 1173e8d8bef9SDimitry Andric // Inline asm can use the group descriptors to find tied operands, 1174e8d8bef9SDimitry Andric // statepoint tied operands are trivial to match (1-1 reg def with reg use), 1175e8d8bef9SDimitry Andric // but on normal instruction, the tied def must be within the first TiedMax 11760b57cec5SDimitry Andric // operands. 1177e8d8bef9SDimitry Andric assert((isInlineAsm() || getOpcode() == TargetOpcode::STATEPOINT) && 1178e8d8bef9SDimitry Andric "DefIdx out of range"); 11790b57cec5SDimitry Andric UseMO.TiedTo = TiedMax; 11800b57cec5SDimitry Andric } 11810b57cec5SDimitry Andric 11820b57cec5SDimitry Andric // UseIdx can be out of range, we'll search for it in findTiedOperandIdx(). 11830b57cec5SDimitry Andric DefMO.TiedTo = std::min(UseIdx + 1, TiedMax); 11840b57cec5SDimitry Andric } 11850b57cec5SDimitry Andric 11860b57cec5SDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to. 11870b57cec5SDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand 11880b57cec5SDimitry Andric /// which must exist. 11890b57cec5SDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const { 11900b57cec5SDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 11910b57cec5SDimitry Andric assert(MO.isTied() && "Operand isn't tied"); 11920b57cec5SDimitry Andric 11930b57cec5SDimitry Andric // Normally TiedTo is in range. 11940b57cec5SDimitry Andric if (MO.TiedTo < TiedMax) 11950b57cec5SDimitry Andric return MO.TiedTo - 1; 11960b57cec5SDimitry Andric 11970b57cec5SDimitry Andric // Uses on normal instructions can be out of range. 1198e8d8bef9SDimitry Andric if (!isInlineAsm() && getOpcode() != TargetOpcode::STATEPOINT) { 11990b57cec5SDimitry Andric // Normal tied defs must be in the 0..TiedMax-1 range. 12000b57cec5SDimitry Andric if (MO.isUse()) 12010b57cec5SDimitry Andric return TiedMax - 1; 12020b57cec5SDimitry Andric // MO is a def. Search for the tied use. 12030b57cec5SDimitry Andric for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) { 12040b57cec5SDimitry Andric const MachineOperand &UseMO = getOperand(i); 12050b57cec5SDimitry Andric if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1) 12060b57cec5SDimitry Andric return i; 12070b57cec5SDimitry Andric } 12080b57cec5SDimitry Andric llvm_unreachable("Can't find tied use"); 12090b57cec5SDimitry Andric } 12100b57cec5SDimitry Andric 1211e8d8bef9SDimitry Andric if (getOpcode() == TargetOpcode::STATEPOINT) { 1212e8d8bef9SDimitry Andric // In STATEPOINT defs correspond 1-1 to GC pointer operands passed 1213e8d8bef9SDimitry Andric // on registers. 1214e8d8bef9SDimitry Andric StatepointOpers SO(this); 1215e8d8bef9SDimitry Andric unsigned CurUseIdx = SO.getFirstGCPtrIdx(); 1216e8d8bef9SDimitry Andric assert(CurUseIdx != -1U && "only gc pointer statepoint operands can be tied"); 1217e8d8bef9SDimitry Andric unsigned NumDefs = getNumDefs(); 1218e8d8bef9SDimitry Andric for (unsigned CurDefIdx = 0; CurDefIdx < NumDefs; ++CurDefIdx) { 1219e8d8bef9SDimitry Andric while (!getOperand(CurUseIdx).isReg()) 1220e8d8bef9SDimitry Andric CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx); 1221e8d8bef9SDimitry Andric if (OpIdx == CurDefIdx) 1222e8d8bef9SDimitry Andric return CurUseIdx; 1223e8d8bef9SDimitry Andric if (OpIdx == CurUseIdx) 1224e8d8bef9SDimitry Andric return CurDefIdx; 1225e8d8bef9SDimitry Andric CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx); 1226e8d8bef9SDimitry Andric } 1227e8d8bef9SDimitry Andric llvm_unreachable("Can't find tied use"); 1228e8d8bef9SDimitry Andric } 1229e8d8bef9SDimitry Andric 12300b57cec5SDimitry Andric // Now deal with inline asm by parsing the operand group descriptor flags. 12310b57cec5SDimitry Andric // Find the beginning of each operand group. 12320b57cec5SDimitry Andric SmallVector<unsigned, 8> GroupIdx; 12330b57cec5SDimitry Andric unsigned OpIdxGroup = ~0u; 12340b57cec5SDimitry Andric unsigned NumOps; 12350b57cec5SDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; 12360b57cec5SDimitry Andric i += NumOps) { 12370b57cec5SDimitry Andric const MachineOperand &FlagMO = getOperand(i); 12380b57cec5SDimitry Andric assert(FlagMO.isImm() && "Invalid tied operand on inline asm"); 12390b57cec5SDimitry Andric unsigned CurGroup = GroupIdx.size(); 12400b57cec5SDimitry Andric GroupIdx.push_back(i); 12415f757f3fSDimitry Andric const InlineAsm::Flag F(FlagMO.getImm()); 12425f757f3fSDimitry Andric NumOps = 1 + F.getNumOperandRegisters(); 12430b57cec5SDimitry Andric // OpIdx belongs to this operand group. 12440b57cec5SDimitry Andric if (OpIdx > i && OpIdx < i + NumOps) 12450b57cec5SDimitry Andric OpIdxGroup = CurGroup; 12460b57cec5SDimitry Andric unsigned TiedGroup; 12475f757f3fSDimitry Andric if (!F.isUseOperandTiedToDef(TiedGroup)) 12480b57cec5SDimitry Andric continue; 12490b57cec5SDimitry Andric // Operands in this group are tied to operands in TiedGroup which must be 12500b57cec5SDimitry Andric // earlier. Find the number of operands between the two groups. 12510b57cec5SDimitry Andric unsigned Delta = i - GroupIdx[TiedGroup]; 12520b57cec5SDimitry Andric 12530b57cec5SDimitry Andric // OpIdx is a use tied to TiedGroup. 12540b57cec5SDimitry Andric if (OpIdxGroup == CurGroup) 12550b57cec5SDimitry Andric return OpIdx - Delta; 12560b57cec5SDimitry Andric 12570b57cec5SDimitry Andric // OpIdx is a def tied to this use group. 12580b57cec5SDimitry Andric if (OpIdxGroup == TiedGroup) 12590b57cec5SDimitry Andric return OpIdx + Delta; 12600b57cec5SDimitry Andric } 12610b57cec5SDimitry Andric llvm_unreachable("Invalid tied operand on inline asm"); 12620b57cec5SDimitry Andric } 12630b57cec5SDimitry Andric 12640b57cec5SDimitry Andric /// clearKillInfo - Clears kill flags on all operands. 12650b57cec5SDimitry Andric /// 12660b57cec5SDimitry Andric void MachineInstr::clearKillInfo() { 12670b57cec5SDimitry Andric for (MachineOperand &MO : operands()) { 12680b57cec5SDimitry Andric if (MO.isReg() && MO.isUse()) 12690b57cec5SDimitry Andric MO.setIsKill(false); 12700b57cec5SDimitry Andric } 12710b57cec5SDimitry Andric } 12720b57cec5SDimitry Andric 12738bcb0991SDimitry Andric void MachineInstr::substituteRegister(Register FromReg, Register ToReg, 12740b57cec5SDimitry Andric unsigned SubIdx, 12750b57cec5SDimitry Andric const TargetRegisterInfo &RegInfo) { 1276bdd1243dSDimitry Andric if (ToReg.isPhysical()) { 12770b57cec5SDimitry Andric if (SubIdx) 12780b57cec5SDimitry Andric ToReg = RegInfo.getSubReg(ToReg, SubIdx); 12790b57cec5SDimitry Andric for (MachineOperand &MO : operands()) { 12800b57cec5SDimitry Andric if (!MO.isReg() || MO.getReg() != FromReg) 12810b57cec5SDimitry Andric continue; 12820b57cec5SDimitry Andric MO.substPhysReg(ToReg, RegInfo); 12830b57cec5SDimitry Andric } 12840b57cec5SDimitry Andric } else { 12850b57cec5SDimitry Andric for (MachineOperand &MO : operands()) { 12860b57cec5SDimitry Andric if (!MO.isReg() || MO.getReg() != FromReg) 12870b57cec5SDimitry Andric continue; 12880b57cec5SDimitry Andric MO.substVirtReg(ToReg, SubIdx, RegInfo); 12890b57cec5SDimitry Andric } 12900b57cec5SDimitry Andric } 12910b57cec5SDimitry Andric } 12920b57cec5SDimitry Andric 12930b57cec5SDimitry Andric /// isSafeToMove - Return true if it is safe to move this instruction. If 12940b57cec5SDimitry Andric /// SawStore is set to true, it means that there is a store (or call) between 12950b57cec5SDimitry Andric /// the instruction's location and its intended destination. 12968bcb0991SDimitry Andric bool MachineInstr::isSafeToMove(AAResults *AA, bool &SawStore) const { 12970b57cec5SDimitry Andric // Ignore stuff that we obviously can't move. 12980b57cec5SDimitry Andric // 12990b57cec5SDimitry Andric // Treat volatile loads as stores. This is not strictly necessary for 13000b57cec5SDimitry Andric // volatiles, but it is required for atomic loads. It is not allowed to move 13010b57cec5SDimitry Andric // a load across an atomic load with Ordering > Monotonic. 13020b57cec5SDimitry Andric if (mayStore() || isCall() || isPHI() || 13030b57cec5SDimitry Andric (mayLoad() && hasOrderedMemoryRef())) { 13040b57cec5SDimitry Andric SawStore = true; 13050b57cec5SDimitry Andric return false; 13060b57cec5SDimitry Andric } 13070b57cec5SDimitry Andric 13080b57cec5SDimitry Andric if (isPosition() || isDebugInstr() || isTerminator() || 13095f757f3fSDimitry Andric mayRaiseFPException() || hasUnmodeledSideEffects() || 13105f757f3fSDimitry Andric isJumpTableDebugInfo()) 13110b57cec5SDimitry Andric return false; 13120b57cec5SDimitry Andric 13130b57cec5SDimitry Andric // See if this instruction does a load. If so, we have to guarantee that the 13140b57cec5SDimitry Andric // loaded value doesn't change between the load and the its intended 1315e8d8bef9SDimitry Andric // destination. The check for isInvariantLoad gives the target the chance to 13160b57cec5SDimitry Andric // classify the load as always returning a constant, e.g. a constant pool 13170b57cec5SDimitry Andric // load. 1318fcaf7f86SDimitry Andric if (mayLoad() && !isDereferenceableInvariantLoad()) 13190b57cec5SDimitry Andric // Otherwise, this is a real load. If there is a store between the load and 13200b57cec5SDimitry Andric // end of block, we can't move it. 13210b57cec5SDimitry Andric return !SawStore; 13220b57cec5SDimitry Andric 13230b57cec5SDimitry Andric return true; 13240b57cec5SDimitry Andric } 13250b57cec5SDimitry Andric 1326e8d8bef9SDimitry Andric static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA, 1327e8d8bef9SDimitry Andric bool UseTBAA, const MachineMemOperand *MMOa, 1328e8d8bef9SDimitry Andric const MachineMemOperand *MMOb) { 1329e8d8bef9SDimitry Andric // The following interface to AA is fashioned after DAGCombiner::isAlias and 1330e8d8bef9SDimitry Andric // operates with MachineMemOperand offset with some important assumptions: 13310b57cec5SDimitry Andric // - LLVM fundamentally assumes flat address spaces. 1332e8d8bef9SDimitry Andric // - MachineOperand offset can *only* result from legalization and cannot 1333e8d8bef9SDimitry Andric // affect queries other than the trivial case of overlap checking. 1334e8d8bef9SDimitry Andric // - These offsets never wrap and never step outside of allocated objects. 13350b57cec5SDimitry Andric // - There should never be any negative offsets here. 13360b57cec5SDimitry Andric // 13370b57cec5SDimitry Andric // FIXME: Modify API to hide this math from "user" 1338e8d8bef9SDimitry Andric // Even before we go to AA we can reason locally about some memory objects. It 1339e8d8bef9SDimitry Andric // can save compile time, and possibly catch some corner cases not currently 1340e8d8bef9SDimitry Andric // covered. 13410b57cec5SDimitry Andric 13420b57cec5SDimitry Andric int64_t OffsetA = MMOa->getOffset(); 13430b57cec5SDimitry Andric int64_t OffsetB = MMOb->getOffset(); 13440b57cec5SDimitry Andric int64_t MinOffset = std::min(OffsetA, OffsetB); 13450b57cec5SDimitry Andric 1346*0fca6ea1SDimitry Andric LocationSize WidthA = MMOa->getSize(); 1347*0fca6ea1SDimitry Andric LocationSize WidthB = MMOb->getSize(); 1348*0fca6ea1SDimitry Andric bool KnownWidthA = WidthA.hasValue(); 1349*0fca6ea1SDimitry Andric bool KnownWidthB = WidthB.hasValue(); 1350*0fca6ea1SDimitry Andric bool BothMMONonScalable = !WidthA.isScalable() && !WidthB.isScalable(); 13510b57cec5SDimitry Andric 13520b57cec5SDimitry Andric const Value *ValA = MMOa->getValue(); 13530b57cec5SDimitry Andric const Value *ValB = MMOb->getValue(); 13540b57cec5SDimitry Andric bool SameVal = (ValA && ValB && (ValA == ValB)); 13550b57cec5SDimitry Andric if (!SameVal) { 13560b57cec5SDimitry Andric const PseudoSourceValue *PSVa = MMOa->getPseudoValue(); 13570b57cec5SDimitry Andric const PseudoSourceValue *PSVb = MMOb->getPseudoValue(); 13580b57cec5SDimitry Andric if (PSVa && ValB && !PSVa->mayAlias(&MFI)) 13590b57cec5SDimitry Andric return false; 13600b57cec5SDimitry Andric if (PSVb && ValA && !PSVb->mayAlias(&MFI)) 13610b57cec5SDimitry Andric return false; 13620b57cec5SDimitry Andric if (PSVa && PSVb && (PSVa == PSVb)) 13630b57cec5SDimitry Andric SameVal = true; 13640b57cec5SDimitry Andric } 13650b57cec5SDimitry Andric 1366*0fca6ea1SDimitry Andric if (SameVal && BothMMONonScalable) { 13670b57cec5SDimitry Andric if (!KnownWidthA || !KnownWidthB) 13680b57cec5SDimitry Andric return true; 13690b57cec5SDimitry Andric int64_t MaxOffset = std::max(OffsetA, OffsetB); 1370*0fca6ea1SDimitry Andric int64_t LowWidth = (MinOffset == OffsetA) 1371*0fca6ea1SDimitry Andric ? WidthA.getValue().getKnownMinValue() 1372*0fca6ea1SDimitry Andric : WidthB.getValue().getKnownMinValue(); 13730b57cec5SDimitry Andric return (MinOffset + LowWidth > MaxOffset); 13740b57cec5SDimitry Andric } 13750b57cec5SDimitry Andric 13760b57cec5SDimitry Andric if (!AA) 13770b57cec5SDimitry Andric return true; 13780b57cec5SDimitry Andric 13790b57cec5SDimitry Andric if (!ValA || !ValB) 13800b57cec5SDimitry Andric return true; 13810b57cec5SDimitry Andric 13820b57cec5SDimitry Andric assert((OffsetA >= 0) && "Negative MachineMemOperand offset"); 13830b57cec5SDimitry Andric assert((OffsetB >= 0) && "Negative MachineMemOperand offset"); 13840b57cec5SDimitry Andric 1385*0fca6ea1SDimitry Andric // If Scalable Location Size has non-zero offset, Width + Offset does not work 1386*0fca6ea1SDimitry Andric // at the moment 1387*0fca6ea1SDimitry Andric if ((WidthA.isScalable() && OffsetA > 0) || 1388*0fca6ea1SDimitry Andric (WidthB.isScalable() && OffsetB > 0)) 1389*0fca6ea1SDimitry Andric return true; 1390*0fca6ea1SDimitry Andric 1391e8d8bef9SDimitry Andric int64_t OverlapA = 1392*0fca6ea1SDimitry Andric KnownWidthA ? WidthA.getValue().getKnownMinValue() + OffsetA - MinOffset 1393*0fca6ea1SDimitry Andric : MemoryLocation::UnknownSize; 1394e8d8bef9SDimitry Andric int64_t OverlapB = 1395*0fca6ea1SDimitry Andric KnownWidthB ? WidthB.getValue().getKnownMinValue() + OffsetB - MinOffset 1396*0fca6ea1SDimitry Andric : MemoryLocation::UnknownSize; 1397*0fca6ea1SDimitry Andric 1398*0fca6ea1SDimitry Andric LocationSize LocA = (WidthA.isScalable() || !KnownWidthA) 1399*0fca6ea1SDimitry Andric ? WidthA 1400*0fca6ea1SDimitry Andric : LocationSize::precise(OverlapA); 1401*0fca6ea1SDimitry Andric LocationSize LocB = (WidthB.isScalable() || !KnownWidthB) 1402*0fca6ea1SDimitry Andric ? WidthB 1403*0fca6ea1SDimitry Andric : LocationSize::precise(OverlapB); 14040b57cec5SDimitry Andric 1405fe6060f1SDimitry Andric return !AA->isNoAlias( 1406*0fca6ea1SDimitry Andric MemoryLocation(ValA, LocA, UseTBAA ? MMOa->getAAInfo() : AAMDNodes()), 1407*0fca6ea1SDimitry Andric MemoryLocation(ValB, LocB, UseTBAA ? MMOb->getAAInfo() : AAMDNodes())); 14080b57cec5SDimitry Andric } 14090b57cec5SDimitry Andric 1410e8d8bef9SDimitry Andric bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other, 1411e8d8bef9SDimitry Andric bool UseTBAA) const { 1412e8d8bef9SDimitry Andric const MachineFunction *MF = getMF(); 1413e8d8bef9SDimitry Andric const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 1414e8d8bef9SDimitry Andric const MachineFrameInfo &MFI = MF->getFrameInfo(); 1415e8d8bef9SDimitry Andric 1416e8d8bef9SDimitry Andric // Exclude call instruction which may alter the memory but can not be handled 1417e8d8bef9SDimitry Andric // by this function. 1418e8d8bef9SDimitry Andric if (isCall() || Other.isCall()) 1419e8d8bef9SDimitry Andric return true; 1420e8d8bef9SDimitry Andric 1421e8d8bef9SDimitry Andric // If neither instruction stores to memory, they can't alias in any 1422e8d8bef9SDimitry Andric // meaningful way, even if they read from the same address. 1423e8d8bef9SDimitry Andric if (!mayStore() && !Other.mayStore()) 1424e8d8bef9SDimitry Andric return false; 1425e8d8bef9SDimitry Andric 1426e8d8bef9SDimitry Andric // Both instructions must be memory operations to be able to alias. 1427e8d8bef9SDimitry Andric if (!mayLoadOrStore() || !Other.mayLoadOrStore()) 1428e8d8bef9SDimitry Andric return false; 1429e8d8bef9SDimitry Andric 1430e8d8bef9SDimitry Andric // Let the target decide if memory accesses cannot possibly overlap. 1431e8d8bef9SDimitry Andric if (TII->areMemAccessesTriviallyDisjoint(*this, Other)) 1432e8d8bef9SDimitry Andric return false; 1433e8d8bef9SDimitry Andric 1434e8d8bef9SDimitry Andric // Memory operations without memory operands may access anything. Be 1435e8d8bef9SDimitry Andric // conservative and assume `MayAlias`. 1436e8d8bef9SDimitry Andric if (memoperands_empty() || Other.memoperands_empty()) 1437e8d8bef9SDimitry Andric return true; 1438e8d8bef9SDimitry Andric 1439e8d8bef9SDimitry Andric // Skip if there are too many memory operands. 1440e8d8bef9SDimitry Andric auto NumChecks = getNumMemOperands() * Other.getNumMemOperands(); 1441e8d8bef9SDimitry Andric if (NumChecks > TII->getMemOperandAACheckLimit()) 1442e8d8bef9SDimitry Andric return true; 1443e8d8bef9SDimitry Andric 1444e8d8bef9SDimitry Andric // Check each pair of memory operands from both instructions, which can't 1445e8d8bef9SDimitry Andric // alias only if all pairs won't alias. 1446e8d8bef9SDimitry Andric for (auto *MMOa : memoperands()) 1447e8d8bef9SDimitry Andric for (auto *MMOb : Other.memoperands()) 1448e8d8bef9SDimitry Andric if (MemOperandsHaveAlias(MFI, AA, UseTBAA, MMOa, MMOb)) 1449e8d8bef9SDimitry Andric return true; 1450e8d8bef9SDimitry Andric 1451e8d8bef9SDimitry Andric return false; 1452e8d8bef9SDimitry Andric } 1453e8d8bef9SDimitry Andric 14540b57cec5SDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered 14550b57cec5SDimitry Andric /// or volatile memory reference, or if the information describing the memory 14560b57cec5SDimitry Andric /// reference is not available. Return false if it is known to have no ordered 14570b57cec5SDimitry Andric /// memory references. 14580b57cec5SDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const { 14590b57cec5SDimitry Andric // An instruction known never to access memory won't have a volatile access. 14600b57cec5SDimitry Andric if (!mayStore() && 14610b57cec5SDimitry Andric !mayLoad() && 14620b57cec5SDimitry Andric !isCall() && 14630b57cec5SDimitry Andric !hasUnmodeledSideEffects()) 14640b57cec5SDimitry Andric return false; 14650b57cec5SDimitry Andric 14660b57cec5SDimitry Andric // Otherwise, if the instruction has no memory reference information, 14670b57cec5SDimitry Andric // conservatively assume it wasn't preserved. 14680b57cec5SDimitry Andric if (memoperands_empty()) 14690b57cec5SDimitry Andric return true; 14700b57cec5SDimitry Andric 14710b57cec5SDimitry Andric // Check if any of our memory operands are ordered. 14720b57cec5SDimitry Andric return llvm::any_of(memoperands(), [](const MachineMemOperand *MMO) { 14730b57cec5SDimitry Andric return !MMO->isUnordered(); 14740b57cec5SDimitry Andric }); 14750b57cec5SDimitry Andric } 14760b57cec5SDimitry Andric 14770b57cec5SDimitry Andric /// isDereferenceableInvariantLoad - Return true if this instruction will never 14780b57cec5SDimitry Andric /// trap and is loading from a location whose value is invariant across a run of 14790b57cec5SDimitry Andric /// this function. 1480fcaf7f86SDimitry Andric bool MachineInstr::isDereferenceableInvariantLoad() const { 14810b57cec5SDimitry Andric // If the instruction doesn't load at all, it isn't an invariant load. 14820b57cec5SDimitry Andric if (!mayLoad()) 14830b57cec5SDimitry Andric return false; 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric // If the instruction has lost its memoperands, conservatively assume that 14860b57cec5SDimitry Andric // it may not be an invariant load. 14870b57cec5SDimitry Andric if (memoperands_empty()) 14880b57cec5SDimitry Andric return false; 14890b57cec5SDimitry Andric 14900b57cec5SDimitry Andric const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo(); 14910b57cec5SDimitry Andric 14920b57cec5SDimitry Andric for (MachineMemOperand *MMO : memoperands()) { 14930b57cec5SDimitry Andric if (!MMO->isUnordered()) 14940b57cec5SDimitry Andric // If the memory operand has ordering side effects, we can't move the 14950b57cec5SDimitry Andric // instruction. Such an instruction is technically an invariant load, 14960b57cec5SDimitry Andric // but the caller code would need updated to expect that. 14970b57cec5SDimitry Andric return false; 14980b57cec5SDimitry Andric if (MMO->isStore()) return false; 14990b57cec5SDimitry Andric if (MMO->isInvariant() && MMO->isDereferenceable()) 15000b57cec5SDimitry Andric continue; 15010b57cec5SDimitry Andric 15020b57cec5SDimitry Andric // A load from a constant PseudoSourceValue is invariant. 150381ad6265SDimitry Andric if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) { 15040b57cec5SDimitry Andric if (PSV->isConstant(&MFI)) 15050b57cec5SDimitry Andric continue; 15060b57cec5SDimitry Andric } 15070b57cec5SDimitry Andric 15080b57cec5SDimitry Andric // Otherwise assume conservatively. 15090b57cec5SDimitry Andric return false; 15100b57cec5SDimitry Andric } 15110b57cec5SDimitry Andric 15120b57cec5SDimitry Andric // Everything checks out. 15130b57cec5SDimitry Andric return true; 15140b57cec5SDimitry Andric } 15150b57cec5SDimitry Andric 15160b57cec5SDimitry Andric /// isConstantValuePHI - If the specified instruction is a PHI that always 15170b57cec5SDimitry Andric /// merges together the same virtual register, return the register, otherwise 15180b57cec5SDimitry Andric /// return 0. 15190b57cec5SDimitry Andric unsigned MachineInstr::isConstantValuePHI() const { 15200b57cec5SDimitry Andric if (!isPHI()) 15210b57cec5SDimitry Andric return 0; 15220b57cec5SDimitry Andric assert(getNumOperands() >= 3 && 15230b57cec5SDimitry Andric "It's illegal to have a PHI without source operands"); 15240b57cec5SDimitry Andric 15258bcb0991SDimitry Andric Register Reg = getOperand(1).getReg(); 15260b57cec5SDimitry Andric for (unsigned i = 3, e = getNumOperands(); i < e; i += 2) 15270b57cec5SDimitry Andric if (getOperand(i).getReg() != Reg) 15280b57cec5SDimitry Andric return 0; 15290b57cec5SDimitry Andric return Reg; 15300b57cec5SDimitry Andric } 15310b57cec5SDimitry Andric 15320b57cec5SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const { 15330b57cec5SDimitry Andric if (hasProperty(MCID::UnmodeledSideEffects)) 15340b57cec5SDimitry Andric return true; 15350b57cec5SDimitry Andric if (isInlineAsm()) { 15360b57cec5SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 15370b57cec5SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 15380b57cec5SDimitry Andric return true; 15390b57cec5SDimitry Andric } 15400b57cec5SDimitry Andric 15410b57cec5SDimitry Andric return false; 15420b57cec5SDimitry Andric } 15430b57cec5SDimitry Andric 15440b57cec5SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const { 1545d409305fSDimitry Andric return mayStore() || isCall() || 1546d409305fSDimitry Andric (hasUnmodeledSideEffects() && !isPseudoProbe()); 15470b57cec5SDimitry Andric } 15480b57cec5SDimitry Andric 15490b57cec5SDimitry Andric /// allDefsAreDead - Return true if all the defs of this instruction are dead. 15500b57cec5SDimitry Andric /// 15510b57cec5SDimitry Andric bool MachineInstr::allDefsAreDead() const { 15520b57cec5SDimitry Andric for (const MachineOperand &MO : operands()) { 15530b57cec5SDimitry Andric if (!MO.isReg() || MO.isUse()) 15540b57cec5SDimitry Andric continue; 15550b57cec5SDimitry Andric if (!MO.isDead()) 15560b57cec5SDimitry Andric return false; 15570b57cec5SDimitry Andric } 15580b57cec5SDimitry Andric return true; 15590b57cec5SDimitry Andric } 15600b57cec5SDimitry Andric 15615f757f3fSDimitry Andric bool MachineInstr::allImplicitDefsAreDead() const { 15625f757f3fSDimitry Andric for (const MachineOperand &MO : implicit_operands()) { 15635f757f3fSDimitry Andric if (!MO.isReg() || MO.isUse()) 15645f757f3fSDimitry Andric continue; 15655f757f3fSDimitry Andric if (!MO.isDead()) 15665f757f3fSDimitry Andric return false; 15675f757f3fSDimitry Andric } 15685f757f3fSDimitry Andric return true; 15695f757f3fSDimitry Andric } 15705f757f3fSDimitry Andric 15710b57cec5SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified 15720b57cec5SDimitry Andric /// instruction to this instruction. 15730b57cec5SDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF, 15740b57cec5SDimitry Andric const MachineInstr &MI) { 15754824e7fdSDimitry Andric for (const MachineOperand &MO : 15764824e7fdSDimitry Andric llvm::drop_begin(MI.operands(), MI.getDesc().getNumOperands())) 15770b57cec5SDimitry Andric if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask()) 15780b57cec5SDimitry Andric addOperand(MF, MO); 15790b57cec5SDimitry Andric } 15800b57cec5SDimitry Andric 15810b57cec5SDimitry Andric bool MachineInstr::hasComplexRegisterTies() const { 15820b57cec5SDimitry Andric const MCInstrDesc &MCID = getDesc(); 1583e8d8bef9SDimitry Andric if (MCID.Opcode == TargetOpcode::STATEPOINT) 1584e8d8bef9SDimitry Andric return true; 15850b57cec5SDimitry Andric for (unsigned I = 0, E = getNumOperands(); I < E; ++I) { 15860b57cec5SDimitry Andric const auto &Operand = getOperand(I); 15870b57cec5SDimitry Andric if (!Operand.isReg() || Operand.isDef()) 15880b57cec5SDimitry Andric // Ignore the defined registers as MCID marks only the uses as tied. 15890b57cec5SDimitry Andric continue; 15900b57cec5SDimitry Andric int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO); 15910b57cec5SDimitry Andric int TiedIdx = Operand.isTied() ? int(findTiedOperandIdx(I)) : -1; 15920b57cec5SDimitry Andric if (ExpectedTiedIdx != TiedIdx) 15930b57cec5SDimitry Andric return true; 15940b57cec5SDimitry Andric } 15950b57cec5SDimitry Andric return false; 15960b57cec5SDimitry Andric } 15970b57cec5SDimitry Andric 15980b57cec5SDimitry Andric LLT MachineInstr::getTypeToPrint(unsigned OpIdx, SmallBitVector &PrintedTypes, 15990b57cec5SDimitry Andric const MachineRegisterInfo &MRI) const { 16000b57cec5SDimitry Andric const MachineOperand &Op = getOperand(OpIdx); 16010b57cec5SDimitry Andric if (!Op.isReg()) 16020b57cec5SDimitry Andric return LLT{}; 16030b57cec5SDimitry Andric 16040b57cec5SDimitry Andric if (isVariadic() || OpIdx >= getNumExplicitOperands()) 16050b57cec5SDimitry Andric return MRI.getType(Op.getReg()); 16060b57cec5SDimitry Andric 1607bdd1243dSDimitry Andric auto &OpInfo = getDesc().operands()[OpIdx]; 16080b57cec5SDimitry Andric if (!OpInfo.isGenericType()) 16090b57cec5SDimitry Andric return MRI.getType(Op.getReg()); 16100b57cec5SDimitry Andric 16110b57cec5SDimitry Andric if (PrintedTypes[OpInfo.getGenericTypeIndex()]) 16120b57cec5SDimitry Andric return LLT{}; 16130b57cec5SDimitry Andric 16140b57cec5SDimitry Andric LLT TypeToPrint = MRI.getType(Op.getReg()); 16150b57cec5SDimitry Andric // Don't mark the type index printed if it wasn't actually printed: maybe 16160b57cec5SDimitry Andric // another operand with the same type index has an actual type attached: 16170b57cec5SDimitry Andric if (TypeToPrint.isValid()) 16180b57cec5SDimitry Andric PrintedTypes.set(OpInfo.getGenericTypeIndex()); 16190b57cec5SDimitry Andric return TypeToPrint; 16200b57cec5SDimitry Andric } 16210b57cec5SDimitry Andric 16220b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 16230b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dump() const { 16240b57cec5SDimitry Andric dbgs() << " "; 16250b57cec5SDimitry Andric print(dbgs()); 16260b57cec5SDimitry Andric } 16275ffd83dbSDimitry Andric 16285ffd83dbSDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dumprImpl( 16295ffd83dbSDimitry Andric const MachineRegisterInfo &MRI, unsigned Depth, unsigned MaxDepth, 16305ffd83dbSDimitry Andric SmallPtrSetImpl<const MachineInstr *> &AlreadySeenInstrs) const { 16315ffd83dbSDimitry Andric if (Depth >= MaxDepth) 16325ffd83dbSDimitry Andric return; 16335ffd83dbSDimitry Andric if (!AlreadySeenInstrs.insert(this).second) 16345ffd83dbSDimitry Andric return; 16355ffd83dbSDimitry Andric // PadToColumn always inserts at least one space. 16365ffd83dbSDimitry Andric // Don't mess up the alignment if we don't want any space. 16375ffd83dbSDimitry Andric if (Depth) 16385ffd83dbSDimitry Andric fdbgs().PadToColumn(Depth * 2); 16395ffd83dbSDimitry Andric print(fdbgs()); 16405ffd83dbSDimitry Andric for (const MachineOperand &MO : operands()) { 16415ffd83dbSDimitry Andric if (!MO.isReg() || MO.isDef()) 16425ffd83dbSDimitry Andric continue; 16435ffd83dbSDimitry Andric Register Reg = MO.getReg(); 16445ffd83dbSDimitry Andric if (Reg.isPhysical()) 16455ffd83dbSDimitry Andric continue; 16465ffd83dbSDimitry Andric const MachineInstr *NewMI = MRI.getUniqueVRegDef(Reg); 16475ffd83dbSDimitry Andric if (NewMI == nullptr) 16485ffd83dbSDimitry Andric continue; 16495ffd83dbSDimitry Andric NewMI->dumprImpl(MRI, Depth + 1, MaxDepth, AlreadySeenInstrs); 16505ffd83dbSDimitry Andric } 16515ffd83dbSDimitry Andric } 16525ffd83dbSDimitry Andric 16535ffd83dbSDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dumpr(const MachineRegisterInfo &MRI, 16545ffd83dbSDimitry Andric unsigned MaxDepth) const { 16555ffd83dbSDimitry Andric SmallPtrSet<const MachineInstr *, 16> AlreadySeenInstrs; 16565ffd83dbSDimitry Andric dumprImpl(MRI, 0, MaxDepth, AlreadySeenInstrs); 16575ffd83dbSDimitry Andric } 16580b57cec5SDimitry Andric #endif 16590b57cec5SDimitry Andric 16600b57cec5SDimitry Andric void MachineInstr::print(raw_ostream &OS, bool IsStandalone, bool SkipOpers, 16610b57cec5SDimitry Andric bool SkipDebugLoc, bool AddNewLine, 16620b57cec5SDimitry Andric const TargetInstrInfo *TII) const { 16630b57cec5SDimitry Andric const Module *M = nullptr; 16640b57cec5SDimitry Andric const Function *F = nullptr; 16650b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 16660b57cec5SDimitry Andric F = &MF->getFunction(); 16670b57cec5SDimitry Andric M = F->getParent(); 16680b57cec5SDimitry Andric if (!TII) 16690b57cec5SDimitry Andric TII = MF->getSubtarget().getInstrInfo(); 16700b57cec5SDimitry Andric } 16710b57cec5SDimitry Andric 16720b57cec5SDimitry Andric ModuleSlotTracker MST(M); 16730b57cec5SDimitry Andric if (F) 16740b57cec5SDimitry Andric MST.incorporateFunction(*F); 16750b57cec5SDimitry Andric print(OS, MST, IsStandalone, SkipOpers, SkipDebugLoc, AddNewLine, TII); 16760b57cec5SDimitry Andric } 16770b57cec5SDimitry Andric 16780b57cec5SDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST, 16790b57cec5SDimitry Andric bool IsStandalone, bool SkipOpers, bool SkipDebugLoc, 16800b57cec5SDimitry Andric bool AddNewLine, const TargetInstrInfo *TII) const { 16810b57cec5SDimitry Andric // We can be a bit tidier if we know the MachineFunction. 16820b57cec5SDimitry Andric const TargetRegisterInfo *TRI = nullptr; 16830b57cec5SDimitry Andric const MachineRegisterInfo *MRI = nullptr; 16840b57cec5SDimitry Andric const TargetIntrinsicInfo *IntrinsicInfo = nullptr; 16850b57cec5SDimitry Andric tryToGetTargetInfo(*this, TRI, MRI, IntrinsicInfo, TII); 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andric if (isCFIInstruction()) 16880b57cec5SDimitry Andric assert(getNumOperands() == 1 && "Expected 1 operand in CFI instruction"); 16890b57cec5SDimitry Andric 16900b57cec5SDimitry Andric SmallBitVector PrintedTypes(8); 16910b57cec5SDimitry Andric bool ShouldPrintRegisterTies = IsStandalone || hasComplexRegisterTies(); 16920b57cec5SDimitry Andric auto getTiedOperandIdx = [&](unsigned OpIdx) { 16930b57cec5SDimitry Andric if (!ShouldPrintRegisterTies) 16940b57cec5SDimitry Andric return 0U; 16950b57cec5SDimitry Andric const MachineOperand &MO = getOperand(OpIdx); 16960b57cec5SDimitry Andric if (MO.isReg() && MO.isTied() && !MO.isDef()) 16970b57cec5SDimitry Andric return findTiedOperandIdx(OpIdx); 16980b57cec5SDimitry Andric return 0U; 16990b57cec5SDimitry Andric }; 17000b57cec5SDimitry Andric unsigned StartOp = 0; 17010b57cec5SDimitry Andric unsigned e = getNumOperands(); 17020b57cec5SDimitry Andric 17030b57cec5SDimitry Andric // Print explicitly defined operands on the left of an assignment syntax. 17040b57cec5SDimitry Andric while (StartOp < e) { 17050b57cec5SDimitry Andric const MachineOperand &MO = getOperand(StartOp); 17060b57cec5SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.isImplicit()) 17070b57cec5SDimitry Andric break; 17080b57cec5SDimitry Andric 17090b57cec5SDimitry Andric if (StartOp != 0) 17100b57cec5SDimitry Andric OS << ", "; 17110b57cec5SDimitry Andric 17120b57cec5SDimitry Andric LLT TypeToPrint = MRI ? getTypeToPrint(StartOp, PrintedTypes, *MRI) : LLT{}; 17130b57cec5SDimitry Andric unsigned TiedOperandIdx = getTiedOperandIdx(StartOp); 1714480093f4SDimitry Andric MO.print(OS, MST, TypeToPrint, StartOp, /*PrintDef=*/false, IsStandalone, 17150b57cec5SDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo); 17160b57cec5SDimitry Andric ++StartOp; 17170b57cec5SDimitry Andric } 17180b57cec5SDimitry Andric 17190b57cec5SDimitry Andric if (StartOp != 0) 17200b57cec5SDimitry Andric OS << " = "; 17210b57cec5SDimitry Andric 17220b57cec5SDimitry Andric if (getFlag(MachineInstr::FrameSetup)) 17230b57cec5SDimitry Andric OS << "frame-setup "; 17240b57cec5SDimitry Andric if (getFlag(MachineInstr::FrameDestroy)) 17250b57cec5SDimitry Andric OS << "frame-destroy "; 17260b57cec5SDimitry Andric if (getFlag(MachineInstr::FmNoNans)) 17270b57cec5SDimitry Andric OS << "nnan "; 17280b57cec5SDimitry Andric if (getFlag(MachineInstr::FmNoInfs)) 17290b57cec5SDimitry Andric OS << "ninf "; 17300b57cec5SDimitry Andric if (getFlag(MachineInstr::FmNsz)) 17310b57cec5SDimitry Andric OS << "nsz "; 17320b57cec5SDimitry Andric if (getFlag(MachineInstr::FmArcp)) 17330b57cec5SDimitry Andric OS << "arcp "; 17340b57cec5SDimitry Andric if (getFlag(MachineInstr::FmContract)) 17350b57cec5SDimitry Andric OS << "contract "; 17360b57cec5SDimitry Andric if (getFlag(MachineInstr::FmAfn)) 17370b57cec5SDimitry Andric OS << "afn "; 17380b57cec5SDimitry Andric if (getFlag(MachineInstr::FmReassoc)) 17390b57cec5SDimitry Andric OS << "reassoc "; 17400b57cec5SDimitry Andric if (getFlag(MachineInstr::NoUWrap)) 17410b57cec5SDimitry Andric OS << "nuw "; 17420b57cec5SDimitry Andric if (getFlag(MachineInstr::NoSWrap)) 17430b57cec5SDimitry Andric OS << "nsw "; 17440b57cec5SDimitry Andric if (getFlag(MachineInstr::IsExact)) 17450b57cec5SDimitry Andric OS << "exact "; 1746480093f4SDimitry Andric if (getFlag(MachineInstr::NoFPExcept)) 1747480093f4SDimitry Andric OS << "nofpexcept "; 17485ffd83dbSDimitry Andric if (getFlag(MachineInstr::NoMerge)) 17495ffd83dbSDimitry Andric OS << "nomerge "; 1750*0fca6ea1SDimitry Andric if (getFlag(MachineInstr::NonNeg)) 1751*0fca6ea1SDimitry Andric OS << "nneg "; 1752*0fca6ea1SDimitry Andric if (getFlag(MachineInstr::Disjoint)) 1753*0fca6ea1SDimitry Andric OS << "disjoint "; 17540b57cec5SDimitry Andric 17550b57cec5SDimitry Andric // Print the opcode name. 17560b57cec5SDimitry Andric if (TII) 17570b57cec5SDimitry Andric OS << TII->getName(getOpcode()); 17580b57cec5SDimitry Andric else 17590b57cec5SDimitry Andric OS << "UNKNOWN"; 17600b57cec5SDimitry Andric 17610b57cec5SDimitry Andric if (SkipOpers) 17620b57cec5SDimitry Andric return; 17630b57cec5SDimitry Andric 17640b57cec5SDimitry Andric // Print the rest of the operands. 17650b57cec5SDimitry Andric bool FirstOp = true; 17660b57cec5SDimitry Andric unsigned AsmDescOp = ~0u; 17670b57cec5SDimitry Andric unsigned AsmOpCount = 0; 17680b57cec5SDimitry Andric 17690b57cec5SDimitry Andric if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) { 17700b57cec5SDimitry Andric // Print asm string. 17710b57cec5SDimitry Andric OS << " "; 17720b57cec5SDimitry Andric const unsigned OpIdx = InlineAsm::MIOp_AsmString; 17730b57cec5SDimitry Andric LLT TypeToPrint = MRI ? getTypeToPrint(OpIdx, PrintedTypes, *MRI) : LLT{}; 17740b57cec5SDimitry Andric unsigned TiedOperandIdx = getTiedOperandIdx(OpIdx); 1775480093f4SDimitry Andric getOperand(OpIdx).print(OS, MST, TypeToPrint, OpIdx, /*PrintDef=*/true, IsStandalone, 17760b57cec5SDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, 17770b57cec5SDimitry Andric IntrinsicInfo); 17780b57cec5SDimitry Andric 17790b57cec5SDimitry Andric // Print HasSideEffects, MayLoad, MayStore, IsAlignStack 17800b57cec5SDimitry Andric unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); 17810b57cec5SDimitry Andric if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 17820b57cec5SDimitry Andric OS << " [sideeffect]"; 17830b57cec5SDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayLoad) 17840b57cec5SDimitry Andric OS << " [mayload]"; 17850b57cec5SDimitry Andric if (ExtraInfo & InlineAsm::Extra_MayStore) 17860b57cec5SDimitry Andric OS << " [maystore]"; 17870b57cec5SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsConvergent) 17880b57cec5SDimitry Andric OS << " [isconvergent]"; 17890b57cec5SDimitry Andric if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 17900b57cec5SDimitry Andric OS << " [alignstack]"; 17910b57cec5SDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_ATT) 17920b57cec5SDimitry Andric OS << " [attdialect]"; 17930b57cec5SDimitry Andric if (getInlineAsmDialect() == InlineAsm::AD_Intel) 17940b57cec5SDimitry Andric OS << " [inteldialect]"; 17950b57cec5SDimitry Andric 17960b57cec5SDimitry Andric StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand; 17970b57cec5SDimitry Andric FirstOp = false; 17980b57cec5SDimitry Andric } 17990b57cec5SDimitry Andric 18000b57cec5SDimitry Andric for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) { 18010b57cec5SDimitry Andric const MachineOperand &MO = getOperand(i); 18020b57cec5SDimitry Andric 18030b57cec5SDimitry Andric if (FirstOp) FirstOp = false; else OS << ","; 18040b57cec5SDimitry Andric OS << " "; 18050b57cec5SDimitry Andric 180606c3fb27SDimitry Andric if (isDebugValueLike() && MO.isMetadata()) { 1807fe6060f1SDimitry Andric // Pretty print DBG_VALUE* instructions. 18080b57cec5SDimitry Andric auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata()); 18090b57cec5SDimitry Andric if (DIV && !DIV->getName().empty()) 18100b57cec5SDimitry Andric OS << "!\"" << DIV->getName() << '\"'; 18110b57cec5SDimitry Andric else { 18120b57cec5SDimitry Andric LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{}; 18130b57cec5SDimitry Andric unsigned TiedOperandIdx = getTiedOperandIdx(i); 1814480093f4SDimitry Andric MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone, 18150b57cec5SDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo); 18160b57cec5SDimitry Andric } 18170b57cec5SDimitry Andric } else if (isDebugLabel() && MO.isMetadata()) { 18180b57cec5SDimitry Andric // Pretty print DBG_LABEL instructions. 18190b57cec5SDimitry Andric auto *DIL = dyn_cast<DILabel>(MO.getMetadata()); 18200b57cec5SDimitry Andric if (DIL && !DIL->getName().empty()) 18210b57cec5SDimitry Andric OS << "\"" << DIL->getName() << '\"'; 18220b57cec5SDimitry Andric else { 18230b57cec5SDimitry Andric LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{}; 18240b57cec5SDimitry Andric unsigned TiedOperandIdx = getTiedOperandIdx(i); 1825480093f4SDimitry Andric MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone, 18260b57cec5SDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo); 18270b57cec5SDimitry Andric } 18280b57cec5SDimitry Andric } else if (i == AsmDescOp && MO.isImm()) { 18290b57cec5SDimitry Andric // Pretty print the inline asm operand descriptor. 18300b57cec5SDimitry Andric OS << '$' << AsmOpCount++; 18310b57cec5SDimitry Andric unsigned Flag = MO.getImm(); 18325f757f3fSDimitry Andric const InlineAsm::Flag F(Flag); 18335ffd83dbSDimitry Andric OS << ":["; 18345f757f3fSDimitry Andric OS << F.getKindName(); 18350b57cec5SDimitry Andric 18365f757f3fSDimitry Andric unsigned RCID; 18375f757f3fSDimitry Andric if (!F.isImmKind() && !F.isMemKind() && F.hasRegClassConstraint(RCID)) { 18380b57cec5SDimitry Andric if (TRI) { 18390b57cec5SDimitry Andric OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID)); 18400b57cec5SDimitry Andric } else 18410b57cec5SDimitry Andric OS << ":RC" << RCID; 18420b57cec5SDimitry Andric } 18430b57cec5SDimitry Andric 18445f757f3fSDimitry Andric if (F.isMemKind()) { 18455f757f3fSDimitry Andric const InlineAsm::ConstraintCode MCID = F.getMemoryConstraintID(); 18465ffd83dbSDimitry Andric OS << ":" << InlineAsm::getMemConstraintName(MCID); 18470b57cec5SDimitry Andric } 18480b57cec5SDimitry Andric 18495f757f3fSDimitry Andric unsigned TiedTo; 18505f757f3fSDimitry Andric if (F.isUseOperandTiedToDef(TiedTo)) 18510b57cec5SDimitry Andric OS << " tiedto:$" << TiedTo; 18520b57cec5SDimitry Andric 18535f757f3fSDimitry Andric if ((F.isRegDefKind() || F.isRegDefEarlyClobberKind() || 18545f757f3fSDimitry Andric F.isRegUseKind()) && 18555f757f3fSDimitry Andric F.getRegMayBeFolded()) { 18565f757f3fSDimitry Andric OS << " foldable"; 18575f757f3fSDimitry Andric } 18585f757f3fSDimitry Andric 18590b57cec5SDimitry Andric OS << ']'; 18600b57cec5SDimitry Andric 18610b57cec5SDimitry Andric // Compute the index of the next operand descriptor. 18625f757f3fSDimitry Andric AsmDescOp += 1 + F.getNumOperandRegisters(); 18630b57cec5SDimitry Andric } else { 18640b57cec5SDimitry Andric LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{}; 18650b57cec5SDimitry Andric unsigned TiedOperandIdx = getTiedOperandIdx(i); 18660b57cec5SDimitry Andric if (MO.isImm() && isOperandSubregIdx(i)) 18670b57cec5SDimitry Andric MachineOperand::printSubRegIdx(OS, MO.getImm(), TRI); 18680b57cec5SDimitry Andric else 1869480093f4SDimitry Andric MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone, 18700b57cec5SDimitry Andric ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo); 18710b57cec5SDimitry Andric } 18720b57cec5SDimitry Andric } 18730b57cec5SDimitry Andric 18740b57cec5SDimitry Andric // Print any optional symbols attached to this instruction as-if they were 18750b57cec5SDimitry Andric // operands. 18760b57cec5SDimitry Andric if (MCSymbol *PreInstrSymbol = getPreInstrSymbol()) { 18770b57cec5SDimitry Andric if (!FirstOp) { 18780b57cec5SDimitry Andric FirstOp = false; 18790b57cec5SDimitry Andric OS << ','; 18800b57cec5SDimitry Andric } 18810b57cec5SDimitry Andric OS << " pre-instr-symbol "; 18820b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *PreInstrSymbol); 18830b57cec5SDimitry Andric } 18840b57cec5SDimitry Andric if (MCSymbol *PostInstrSymbol = getPostInstrSymbol()) { 18850b57cec5SDimitry Andric if (!FirstOp) { 18860b57cec5SDimitry Andric FirstOp = false; 18870b57cec5SDimitry Andric OS << ','; 18880b57cec5SDimitry Andric } 18890b57cec5SDimitry Andric OS << " post-instr-symbol "; 18900b57cec5SDimitry Andric MachineOperand::printSymbol(OS, *PostInstrSymbol); 18910b57cec5SDimitry Andric } 1892c14a5a88SDimitry Andric if (MDNode *HeapAllocMarker = getHeapAllocMarker()) { 1893c14a5a88SDimitry Andric if (!FirstOp) { 1894c14a5a88SDimitry Andric FirstOp = false; 1895c14a5a88SDimitry Andric OS << ','; 1896c14a5a88SDimitry Andric } 1897c14a5a88SDimitry Andric OS << " heap-alloc-marker "; 1898480093f4SDimitry Andric HeapAllocMarker->printAsOperand(OS, MST); 1899c14a5a88SDimitry Andric } 1900bdd1243dSDimitry Andric if (MDNode *PCSections = getPCSections()) { 1901bdd1243dSDimitry Andric if (!FirstOp) { 1902bdd1243dSDimitry Andric FirstOp = false; 1903bdd1243dSDimitry Andric OS << ','; 1904bdd1243dSDimitry Andric } 1905bdd1243dSDimitry Andric OS << " pcsections "; 1906bdd1243dSDimitry Andric PCSections->printAsOperand(OS, MST); 1907bdd1243dSDimitry Andric } 1908*0fca6ea1SDimitry Andric if (MDNode *MMRA = getMMRAMetadata()) { 1909*0fca6ea1SDimitry Andric if (!FirstOp) { 1910*0fca6ea1SDimitry Andric FirstOp = false; 1911*0fca6ea1SDimitry Andric OS << ','; 1912*0fca6ea1SDimitry Andric } 1913*0fca6ea1SDimitry Andric OS << " mmra "; 1914*0fca6ea1SDimitry Andric MMRA->printAsOperand(OS, MST); 1915*0fca6ea1SDimitry Andric } 1916bdd1243dSDimitry Andric if (uint32_t CFIType = getCFIType()) { 1917bdd1243dSDimitry Andric if (!FirstOp) 1918bdd1243dSDimitry Andric OS << ','; 1919bdd1243dSDimitry Andric OS << " cfi-type " << CFIType; 1920bdd1243dSDimitry Andric } 19210b57cec5SDimitry Andric 1922e8d8bef9SDimitry Andric if (DebugInstrNum) { 1923e8d8bef9SDimitry Andric if (!FirstOp) 1924e8d8bef9SDimitry Andric OS << ","; 1925e8d8bef9SDimitry Andric OS << " debug-instr-number " << DebugInstrNum; 1926e8d8bef9SDimitry Andric } 1927e8d8bef9SDimitry Andric 19280b57cec5SDimitry Andric if (!SkipDebugLoc) { 19290b57cec5SDimitry Andric if (const DebugLoc &DL = getDebugLoc()) { 19300b57cec5SDimitry Andric if (!FirstOp) 19310b57cec5SDimitry Andric OS << ','; 19320b57cec5SDimitry Andric OS << " debug-location "; 19330b57cec5SDimitry Andric DL->printAsOperand(OS, MST); 19340b57cec5SDimitry Andric } 19350b57cec5SDimitry Andric } 19360b57cec5SDimitry Andric 19370b57cec5SDimitry Andric if (!memoperands_empty()) { 19380b57cec5SDimitry Andric SmallVector<StringRef, 0> SSNs; 19390b57cec5SDimitry Andric const LLVMContext *Context = nullptr; 19400b57cec5SDimitry Andric std::unique_ptr<LLVMContext> CtxPtr; 19410b57cec5SDimitry Andric const MachineFrameInfo *MFI = nullptr; 19420b57cec5SDimitry Andric if (const MachineFunction *MF = getMFIfAvailable(*this)) { 19430b57cec5SDimitry Andric MFI = &MF->getFrameInfo(); 19440b57cec5SDimitry Andric Context = &MF->getFunction().getContext(); 19450b57cec5SDimitry Andric } else { 19468bcb0991SDimitry Andric CtxPtr = std::make_unique<LLVMContext>(); 19470b57cec5SDimitry Andric Context = CtxPtr.get(); 19480b57cec5SDimitry Andric } 19490b57cec5SDimitry Andric 19500b57cec5SDimitry Andric OS << " :: "; 19510b57cec5SDimitry Andric bool NeedComma = false; 19520b57cec5SDimitry Andric for (const MachineMemOperand *Op : memoperands()) { 19530b57cec5SDimitry Andric if (NeedComma) 19540b57cec5SDimitry Andric OS << ", "; 19550b57cec5SDimitry Andric Op->print(OS, MST, SSNs, *Context, MFI, TII); 19560b57cec5SDimitry Andric NeedComma = true; 19570b57cec5SDimitry Andric } 19580b57cec5SDimitry Andric } 19590b57cec5SDimitry Andric 19600b57cec5SDimitry Andric if (SkipDebugLoc) 19610b57cec5SDimitry Andric return; 19620b57cec5SDimitry Andric 19630b57cec5SDimitry Andric bool HaveSemi = false; 19640b57cec5SDimitry Andric 19650b57cec5SDimitry Andric // Print debug location information. 19660b57cec5SDimitry Andric if (const DebugLoc &DL = getDebugLoc()) { 19670b57cec5SDimitry Andric if (!HaveSemi) { 19680b57cec5SDimitry Andric OS << ';'; 19690b57cec5SDimitry Andric HaveSemi = true; 19700b57cec5SDimitry Andric } 19710b57cec5SDimitry Andric OS << ' '; 19720b57cec5SDimitry Andric DL.print(OS); 19730b57cec5SDimitry Andric } 19740b57cec5SDimitry Andric 19755f757f3fSDimitry Andric // Print extra comments for DEBUG_VALUE and friends if they are well-formed. 19765f757f3fSDimitry Andric if ((isNonListDebugValue() && getNumOperands() >= 4) || 19775f757f3fSDimitry Andric (isDebugValueList() && getNumOperands() >= 2) || 19785f757f3fSDimitry Andric (isDebugRef() && getNumOperands() >= 3)) { 19795f757f3fSDimitry Andric if (getDebugVariableOp().isMetadata()) { 19800b57cec5SDimitry Andric if (!HaveSemi) { 19810b57cec5SDimitry Andric OS << ";"; 19820b57cec5SDimitry Andric HaveSemi = true; 19830b57cec5SDimitry Andric } 19845ffd83dbSDimitry Andric auto *DV = getDebugVariable(); 19850b57cec5SDimitry Andric OS << " line no:" << DV->getLine(); 19860b57cec5SDimitry Andric if (isIndirectDebugValue()) 19870b57cec5SDimitry Andric OS << " indirect"; 19880b57cec5SDimitry Andric } 19895f757f3fSDimitry Andric } 19900b57cec5SDimitry Andric // TODO: DBG_LABEL 19910b57cec5SDimitry Andric 19920b57cec5SDimitry Andric if (AddNewLine) 19930b57cec5SDimitry Andric OS << '\n'; 19940b57cec5SDimitry Andric } 19950b57cec5SDimitry Andric 19968bcb0991SDimitry Andric bool MachineInstr::addRegisterKilled(Register IncomingReg, 19970b57cec5SDimitry Andric const TargetRegisterInfo *RegInfo, 19980b57cec5SDimitry Andric bool AddIfNotFound) { 1999bdd1243dSDimitry Andric bool isPhysReg = IncomingReg.isPhysical(); 20000b57cec5SDimitry Andric bool hasAliases = isPhysReg && 20010b57cec5SDimitry Andric MCRegAliasIterator(IncomingReg, RegInfo, false).isValid(); 20020b57cec5SDimitry Andric bool Found = false; 20030b57cec5SDimitry Andric SmallVector<unsigned,4> DeadOps; 20040b57cec5SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 20050b57cec5SDimitry Andric MachineOperand &MO = getOperand(i); 20060b57cec5SDimitry Andric if (!MO.isReg() || !MO.isUse() || MO.isUndef()) 20070b57cec5SDimitry Andric continue; 20080b57cec5SDimitry Andric 20090b57cec5SDimitry Andric // DEBUG_VALUE nodes do not contribute to code generation and should 20100b57cec5SDimitry Andric // always be ignored. Failure to do so may result in trying to modify 20110b57cec5SDimitry Andric // KILL flags on DEBUG_VALUE nodes. 20120b57cec5SDimitry Andric if (MO.isDebug()) 20130b57cec5SDimitry Andric continue; 20140b57cec5SDimitry Andric 20158bcb0991SDimitry Andric Register Reg = MO.getReg(); 20160b57cec5SDimitry Andric if (!Reg) 20170b57cec5SDimitry Andric continue; 20180b57cec5SDimitry Andric 20190b57cec5SDimitry Andric if (Reg == IncomingReg) { 20200b57cec5SDimitry Andric if (!Found) { 20210b57cec5SDimitry Andric if (MO.isKill()) 20220b57cec5SDimitry Andric // The register is already marked kill. 20230b57cec5SDimitry Andric return true; 20240b57cec5SDimitry Andric if (isPhysReg && isRegTiedToDefOperand(i)) 20250b57cec5SDimitry Andric // Two-address uses of physregs must not be marked kill. 20260b57cec5SDimitry Andric return true; 20270b57cec5SDimitry Andric MO.setIsKill(); 20280b57cec5SDimitry Andric Found = true; 20290b57cec5SDimitry Andric } 2030bdd1243dSDimitry Andric } else if (hasAliases && MO.isKill() && Reg.isPhysical()) { 20310b57cec5SDimitry Andric // A super-register kill already exists. 20320b57cec5SDimitry Andric if (RegInfo->isSuperRegister(IncomingReg, Reg)) 20330b57cec5SDimitry Andric return true; 20340b57cec5SDimitry Andric if (RegInfo->isSubRegister(IncomingReg, Reg)) 20350b57cec5SDimitry Andric DeadOps.push_back(i); 20360b57cec5SDimitry Andric } 20370b57cec5SDimitry Andric } 20380b57cec5SDimitry Andric 20390b57cec5SDimitry Andric // Trim unneeded kill operands. 20400b57cec5SDimitry Andric while (!DeadOps.empty()) { 20410b57cec5SDimitry Andric unsigned OpIdx = DeadOps.back(); 20420b57cec5SDimitry Andric if (getOperand(OpIdx).isImplicit() && 20430b57cec5SDimitry Andric (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0)) 204481ad6265SDimitry Andric removeOperand(OpIdx); 20450b57cec5SDimitry Andric else 20460b57cec5SDimitry Andric getOperand(OpIdx).setIsKill(false); 20470b57cec5SDimitry Andric DeadOps.pop_back(); 20480b57cec5SDimitry Andric } 20490b57cec5SDimitry Andric 20500b57cec5SDimitry Andric // If not found, this means an alias of one of the operands is killed. Add a 20510b57cec5SDimitry Andric // new implicit operand if required. 20520b57cec5SDimitry Andric if (!Found && AddIfNotFound) { 20530b57cec5SDimitry Andric addOperand(MachineOperand::CreateReg(IncomingReg, 20540b57cec5SDimitry Andric false /*IsDef*/, 20550b57cec5SDimitry Andric true /*IsImp*/, 20560b57cec5SDimitry Andric true /*IsKill*/)); 20570b57cec5SDimitry Andric return true; 20580b57cec5SDimitry Andric } 20590b57cec5SDimitry Andric return Found; 20600b57cec5SDimitry Andric } 20610b57cec5SDimitry Andric 20628bcb0991SDimitry Andric void MachineInstr::clearRegisterKills(Register Reg, 20630b57cec5SDimitry Andric const TargetRegisterInfo *RegInfo) { 2064bdd1243dSDimitry Andric if (!Reg.isPhysical()) 20650b57cec5SDimitry Andric RegInfo = nullptr; 20660b57cec5SDimitry Andric for (MachineOperand &MO : operands()) { 20670b57cec5SDimitry Andric if (!MO.isReg() || !MO.isUse() || !MO.isKill()) 20680b57cec5SDimitry Andric continue; 20698bcb0991SDimitry Andric Register OpReg = MO.getReg(); 20700b57cec5SDimitry Andric if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg) 20710b57cec5SDimitry Andric MO.setIsKill(false); 20720b57cec5SDimitry Andric } 20730b57cec5SDimitry Andric } 20740b57cec5SDimitry Andric 20758bcb0991SDimitry Andric bool MachineInstr::addRegisterDead(Register Reg, 20760b57cec5SDimitry Andric const TargetRegisterInfo *RegInfo, 20770b57cec5SDimitry Andric bool AddIfNotFound) { 2078bdd1243dSDimitry Andric bool isPhysReg = Reg.isPhysical(); 20790b57cec5SDimitry Andric bool hasAliases = isPhysReg && 20800b57cec5SDimitry Andric MCRegAliasIterator(Reg, RegInfo, false).isValid(); 20810b57cec5SDimitry Andric bool Found = false; 20820b57cec5SDimitry Andric SmallVector<unsigned,4> DeadOps; 20830b57cec5SDimitry Andric for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { 20840b57cec5SDimitry Andric MachineOperand &MO = getOperand(i); 20850b57cec5SDimitry Andric if (!MO.isReg() || !MO.isDef()) 20860b57cec5SDimitry Andric continue; 20878bcb0991SDimitry Andric Register MOReg = MO.getReg(); 20880b57cec5SDimitry Andric if (!MOReg) 20890b57cec5SDimitry Andric continue; 20900b57cec5SDimitry Andric 20910b57cec5SDimitry Andric if (MOReg == Reg) { 20920b57cec5SDimitry Andric MO.setIsDead(); 20930b57cec5SDimitry Andric Found = true; 2094bdd1243dSDimitry Andric } else if (hasAliases && MO.isDead() && MOReg.isPhysical()) { 20950b57cec5SDimitry Andric // There exists a super-register that's marked dead. 20960b57cec5SDimitry Andric if (RegInfo->isSuperRegister(Reg, MOReg)) 20970b57cec5SDimitry Andric return true; 20980b57cec5SDimitry Andric if (RegInfo->isSubRegister(Reg, MOReg)) 20990b57cec5SDimitry Andric DeadOps.push_back(i); 21000b57cec5SDimitry Andric } 21010b57cec5SDimitry Andric } 21020b57cec5SDimitry Andric 21030b57cec5SDimitry Andric // Trim unneeded dead operands. 21040b57cec5SDimitry Andric while (!DeadOps.empty()) { 21050b57cec5SDimitry Andric unsigned OpIdx = DeadOps.back(); 21060b57cec5SDimitry Andric if (getOperand(OpIdx).isImplicit() && 21070b57cec5SDimitry Andric (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0)) 210881ad6265SDimitry Andric removeOperand(OpIdx); 21090b57cec5SDimitry Andric else 21100b57cec5SDimitry Andric getOperand(OpIdx).setIsDead(false); 21110b57cec5SDimitry Andric DeadOps.pop_back(); 21120b57cec5SDimitry Andric } 21130b57cec5SDimitry Andric 21140b57cec5SDimitry Andric // If not found, this means an alias of one of the operands is dead. Add a 21150b57cec5SDimitry Andric // new implicit operand if required. 21160b57cec5SDimitry Andric if (Found || !AddIfNotFound) 21170b57cec5SDimitry Andric return Found; 21180b57cec5SDimitry Andric 21190b57cec5SDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 21200b57cec5SDimitry Andric true /*IsDef*/, 21210b57cec5SDimitry Andric true /*IsImp*/, 21220b57cec5SDimitry Andric false /*IsKill*/, 21230b57cec5SDimitry Andric true /*IsDead*/)); 21240b57cec5SDimitry Andric return true; 21250b57cec5SDimitry Andric } 21260b57cec5SDimitry Andric 21278bcb0991SDimitry Andric void MachineInstr::clearRegisterDeads(Register Reg) { 21280b57cec5SDimitry Andric for (MachineOperand &MO : operands()) { 21290b57cec5SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg) 21300b57cec5SDimitry Andric continue; 21310b57cec5SDimitry Andric MO.setIsDead(false); 21320b57cec5SDimitry Andric } 21330b57cec5SDimitry Andric } 21340b57cec5SDimitry Andric 21358bcb0991SDimitry Andric void MachineInstr::setRegisterDefReadUndef(Register Reg, bool IsUndef) { 21360b57cec5SDimitry Andric for (MachineOperand &MO : operands()) { 21370b57cec5SDimitry Andric if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0) 21380b57cec5SDimitry Andric continue; 21390b57cec5SDimitry Andric MO.setIsUndef(IsUndef); 21400b57cec5SDimitry Andric } 21410b57cec5SDimitry Andric } 21420b57cec5SDimitry Andric 21438bcb0991SDimitry Andric void MachineInstr::addRegisterDefined(Register Reg, 21440b57cec5SDimitry Andric const TargetRegisterInfo *RegInfo) { 2145bdd1243dSDimitry Andric if (Reg.isPhysical()) { 2146*0fca6ea1SDimitry Andric MachineOperand *MO = findRegisterDefOperand(Reg, RegInfo, false, false); 21470b57cec5SDimitry Andric if (MO) 21480b57cec5SDimitry Andric return; 21490b57cec5SDimitry Andric } else { 21500b57cec5SDimitry Andric for (const MachineOperand &MO : operands()) { 21510b57cec5SDimitry Andric if (MO.isReg() && MO.getReg() == Reg && MO.isDef() && 21520b57cec5SDimitry Andric MO.getSubReg() == 0) 21530b57cec5SDimitry Andric return; 21540b57cec5SDimitry Andric } 21550b57cec5SDimitry Andric } 21560b57cec5SDimitry Andric addOperand(MachineOperand::CreateReg(Reg, 21570b57cec5SDimitry Andric true /*IsDef*/, 21580b57cec5SDimitry Andric true /*IsImp*/)); 21590b57cec5SDimitry Andric } 21600b57cec5SDimitry Andric 21618bcb0991SDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs, 21620b57cec5SDimitry Andric const TargetRegisterInfo &TRI) { 21630b57cec5SDimitry Andric bool HasRegMask = false; 21640b57cec5SDimitry Andric for (MachineOperand &MO : operands()) { 21650b57cec5SDimitry Andric if (MO.isRegMask()) { 21660b57cec5SDimitry Andric HasRegMask = true; 21670b57cec5SDimitry Andric continue; 21680b57cec5SDimitry Andric } 21690b57cec5SDimitry Andric if (!MO.isReg() || !MO.isDef()) continue; 21708bcb0991SDimitry Andric Register Reg = MO.getReg(); 21718bcb0991SDimitry Andric if (!Reg.isPhysical()) 21728bcb0991SDimitry Andric continue; 21730b57cec5SDimitry Andric // If there are no uses, including partial uses, the def is dead. 21740b57cec5SDimitry Andric if (llvm::none_of(UsedRegs, 21758bcb0991SDimitry Andric [&](MCRegister Use) { return TRI.regsOverlap(Use, Reg); })) 21760b57cec5SDimitry Andric MO.setIsDead(); 21770b57cec5SDimitry Andric } 21780b57cec5SDimitry Andric 21790b57cec5SDimitry Andric // This is a call with a register mask operand. 21800b57cec5SDimitry Andric // Mask clobbers are always dead, so add defs for the non-dead defines. 21810b57cec5SDimitry Andric if (HasRegMask) 2182fe6060f1SDimitry Andric for (const Register &UsedReg : UsedRegs) 2183fe6060f1SDimitry Andric addRegisterDefined(UsedReg, &TRI); 21840b57cec5SDimitry Andric } 21850b57cec5SDimitry Andric 21860b57cec5SDimitry Andric unsigned 21870b57cec5SDimitry Andric MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) { 21880b57cec5SDimitry Andric // Build up a buffer of hash code components. 2189480093f4SDimitry Andric SmallVector<size_t, 16> HashComponents; 21900b57cec5SDimitry Andric HashComponents.reserve(MI->getNumOperands() + 1); 21910b57cec5SDimitry Andric HashComponents.push_back(MI->getOpcode()); 21920b57cec5SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 2193bdd1243dSDimitry Andric if (MO.isReg() && MO.isDef() && MO.getReg().isVirtual()) 21940b57cec5SDimitry Andric continue; // Skip virtual register defs. 21950b57cec5SDimitry Andric 21960b57cec5SDimitry Andric HashComponents.push_back(hash_value(MO)); 21970b57cec5SDimitry Andric } 21980b57cec5SDimitry Andric return hash_combine_range(HashComponents.begin(), HashComponents.end()); 21990b57cec5SDimitry Andric } 22000b57cec5SDimitry Andric 22010b57cec5SDimitry Andric void MachineInstr::emitError(StringRef Msg) const { 22020b57cec5SDimitry Andric // Find the source location cookie. 2203fe6060f1SDimitry Andric uint64_t LocCookie = 0; 22040b57cec5SDimitry Andric const MDNode *LocMD = nullptr; 22050b57cec5SDimitry Andric for (unsigned i = getNumOperands(); i != 0; --i) { 22060b57cec5SDimitry Andric if (getOperand(i-1).isMetadata() && 22070b57cec5SDimitry Andric (LocMD = getOperand(i-1).getMetadata()) && 22080b57cec5SDimitry Andric LocMD->getNumOperands() != 0) { 22090b57cec5SDimitry Andric if (const ConstantInt *CI = 22100b57cec5SDimitry Andric mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) { 22110b57cec5SDimitry Andric LocCookie = CI->getZExtValue(); 22120b57cec5SDimitry Andric break; 22130b57cec5SDimitry Andric } 22140b57cec5SDimitry Andric } 22150b57cec5SDimitry Andric } 22160b57cec5SDimitry Andric 22170b57cec5SDimitry Andric if (const MachineBasicBlock *MBB = getParent()) 22180b57cec5SDimitry Andric if (const MachineFunction *MF = MBB->getParent()) 2219*0fca6ea1SDimitry Andric return MF->getFunction().getContext().emitError(LocCookie, Msg); 22200b57cec5SDimitry Andric report_fatal_error(Msg); 22210b57cec5SDimitry Andric } 22220b57cec5SDimitry Andric 22230b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, 22240b57cec5SDimitry Andric const MCInstrDesc &MCID, bool IsIndirect, 22258bcb0991SDimitry Andric Register Reg, const MDNode *Variable, 22260b57cec5SDimitry Andric const MDNode *Expr) { 22270b57cec5SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 22280b57cec5SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 22290b57cec5SDimitry Andric assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 22300b57cec5SDimitry Andric "Expected inlined-at fields to agree"); 2231349cc55cSDimitry Andric auto MIB = BuildMI(MF, DL, MCID).addReg(Reg); 22320b57cec5SDimitry Andric if (IsIndirect) 22330b57cec5SDimitry Andric MIB.addImm(0U); 22340b57cec5SDimitry Andric else 2235349cc55cSDimitry Andric MIB.addReg(0U); 22360b57cec5SDimitry Andric return MIB.addMetadata(Variable).addMetadata(Expr); 22370b57cec5SDimitry Andric } 22380b57cec5SDimitry Andric 22390b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL, 22400b57cec5SDimitry Andric const MCInstrDesc &MCID, bool IsIndirect, 2241bdd1243dSDimitry Andric ArrayRef<MachineOperand> DebugOps, 2242fe6060f1SDimitry Andric const MDNode *Variable, const MDNode *Expr) { 22430b57cec5SDimitry Andric assert(isa<DILocalVariable>(Variable) && "not a variable"); 22440b57cec5SDimitry Andric assert(cast<DIExpression>(Expr)->isValid() && "not an expression"); 22450b57cec5SDimitry Andric assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && 22460b57cec5SDimitry Andric "Expected inlined-at fields to agree"); 2247bdd1243dSDimitry Andric if (MCID.Opcode == TargetOpcode::DBG_VALUE) { 2248bdd1243dSDimitry Andric assert(DebugOps.size() == 1 && 2249bdd1243dSDimitry Andric "DBG_VALUE must contain exactly one debug operand"); 2250bdd1243dSDimitry Andric MachineOperand DebugOp = DebugOps[0]; 2251bdd1243dSDimitry Andric if (DebugOp.isReg()) 2252bdd1243dSDimitry Andric return BuildMI(MF, DL, MCID, IsIndirect, DebugOp.getReg(), Variable, 2253bdd1243dSDimitry Andric Expr); 22540b57cec5SDimitry Andric 2255bdd1243dSDimitry Andric auto MIB = BuildMI(MF, DL, MCID).add(DebugOp); 22560b57cec5SDimitry Andric if (IsIndirect) 22570b57cec5SDimitry Andric MIB.addImm(0U); 22580b57cec5SDimitry Andric else 2259349cc55cSDimitry Andric MIB.addReg(0U); 22600b57cec5SDimitry Andric return MIB.addMetadata(Variable).addMetadata(Expr); 22610b57cec5SDimitry Andric } 22620b57cec5SDimitry Andric 2263fe6060f1SDimitry Andric auto MIB = BuildMI(MF, DL, MCID); 2264fe6060f1SDimitry Andric MIB.addMetadata(Variable).addMetadata(Expr); 2265bdd1243dSDimitry Andric for (const MachineOperand &DebugOp : DebugOps) 2266bdd1243dSDimitry Andric if (DebugOp.isReg()) 2267bdd1243dSDimitry Andric MIB.addReg(DebugOp.getReg()); 2268fe6060f1SDimitry Andric else 2269bdd1243dSDimitry Andric MIB.add(DebugOp); 2270fe6060f1SDimitry Andric return MIB; 2271fe6060f1SDimitry Andric } 2272fe6060f1SDimitry Andric 22730b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, 22740b57cec5SDimitry Andric MachineBasicBlock::iterator I, 22750b57cec5SDimitry Andric const DebugLoc &DL, const MCInstrDesc &MCID, 22768bcb0991SDimitry Andric bool IsIndirect, Register Reg, 22770b57cec5SDimitry Andric const MDNode *Variable, const MDNode *Expr) { 22780b57cec5SDimitry Andric MachineFunction &MF = *BB.getParent(); 22790b57cec5SDimitry Andric MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Variable, Expr); 22800b57cec5SDimitry Andric BB.insert(I, MI); 22810b57cec5SDimitry Andric return MachineInstrBuilder(MF, MI); 22820b57cec5SDimitry Andric } 22830b57cec5SDimitry Andric 22840b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB, 22850b57cec5SDimitry Andric MachineBasicBlock::iterator I, 22860b57cec5SDimitry Andric const DebugLoc &DL, const MCInstrDesc &MCID, 2287bdd1243dSDimitry Andric bool IsIndirect, 2288bdd1243dSDimitry Andric ArrayRef<MachineOperand> DebugOps, 22890b57cec5SDimitry Andric const MDNode *Variable, const MDNode *Expr) { 22900b57cec5SDimitry Andric MachineFunction &MF = *BB.getParent(); 2291bdd1243dSDimitry Andric MachineInstr *MI = 2292bdd1243dSDimitry Andric BuildMI(MF, DL, MCID, IsIndirect, DebugOps, Variable, Expr); 2293fe6060f1SDimitry Andric BB.insert(I, MI); 2294fe6060f1SDimitry Andric return MachineInstrBuilder(MF, *MI); 2295fe6060f1SDimitry Andric } 2296fe6060f1SDimitry Andric 22970b57cec5SDimitry Andric /// Compute the new DIExpression to use with a DBG_VALUE for a spill slot. 22980b57cec5SDimitry Andric /// This prepends DW_OP_deref when spilling an indirect DBG_VALUE. 2299fe6060f1SDimitry Andric static const DIExpression * 2300fe6060f1SDimitry Andric computeExprForSpill(const MachineInstr &MI, 2301fe6060f1SDimitry Andric SmallVectorImpl<const MachineOperand *> &SpilledOperands) { 23020b57cec5SDimitry Andric assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) && 23030b57cec5SDimitry Andric "Expected inlined-at fields to agree"); 23040b57cec5SDimitry Andric 23050b57cec5SDimitry Andric const DIExpression *Expr = MI.getDebugExpression(); 23060b57cec5SDimitry Andric if (MI.isIndirectDebugValue()) { 23075ffd83dbSDimitry Andric assert(MI.getDebugOffset().getImm() == 0 && 23085ffd83dbSDimitry Andric "DBG_VALUE with nonzero offset"); 23090b57cec5SDimitry Andric Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore); 2310fe6060f1SDimitry Andric } else if (MI.isDebugValueList()) { 2311fe6060f1SDimitry Andric // We will replace the spilled register with a frame index, so 2312fe6060f1SDimitry Andric // immediately deref all references to the spilled register. 2313fe6060f1SDimitry Andric std::array<uint64_t, 1> Ops{{dwarf::DW_OP_deref}}; 2314fe6060f1SDimitry Andric for (const MachineOperand *Op : SpilledOperands) { 2315fe6060f1SDimitry Andric unsigned OpIdx = MI.getDebugOperandIndex(Op); 2316fe6060f1SDimitry Andric Expr = DIExpression::appendOpsToArg(Expr, Ops, OpIdx); 2317fe6060f1SDimitry Andric } 23180b57cec5SDimitry Andric } 23190b57cec5SDimitry Andric return Expr; 23200b57cec5SDimitry Andric } 2321fe6060f1SDimitry Andric static const DIExpression *computeExprForSpill(const MachineInstr &MI, 2322fe6060f1SDimitry Andric Register SpillReg) { 2323fe6060f1SDimitry Andric assert(MI.hasDebugOperandForReg(SpillReg) && "Spill Reg is not used in MI."); 2324fe6060f1SDimitry Andric SmallVector<const MachineOperand *> SpillOperands; 2325fe6060f1SDimitry Andric for (const MachineOperand &Op : MI.getDebugOperandsForReg(SpillReg)) 2326fe6060f1SDimitry Andric SpillOperands.push_back(&Op); 2327fe6060f1SDimitry Andric return computeExprForSpill(MI, SpillOperands); 2328fe6060f1SDimitry Andric } 23290b57cec5SDimitry Andric 23300b57cec5SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB, 23310b57cec5SDimitry Andric MachineBasicBlock::iterator I, 23320b57cec5SDimitry Andric const MachineInstr &Orig, 2333fe6060f1SDimitry Andric int FrameIndex, Register SpillReg) { 2334bdd1243dSDimitry Andric assert(!Orig.isDebugRef() && 2335bdd1243dSDimitry Andric "DBG_INSTR_REF should not reference a virtual register."); 2336fe6060f1SDimitry Andric const DIExpression *Expr = computeExprForSpill(Orig, SpillReg); 2337fe6060f1SDimitry Andric MachineInstrBuilder NewMI = 2338fe6060f1SDimitry Andric BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc()); 2339fe6060f1SDimitry Andric // Non-Variadic Operands: Location, Offset, Variable, Expression 2340fe6060f1SDimitry Andric // Variadic Operands: Variable, Expression, Locations... 2341fe6060f1SDimitry Andric if (Orig.isNonListDebugValue()) 2342fe6060f1SDimitry Andric NewMI.addFrameIndex(FrameIndex).addImm(0U); 2343fe6060f1SDimitry Andric NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr); 2344fe6060f1SDimitry Andric if (Orig.isDebugValueList()) { 2345fe6060f1SDimitry Andric for (const MachineOperand &Op : Orig.debug_operands()) 2346fe6060f1SDimitry Andric if (Op.isReg() && Op.getReg() == SpillReg) 2347fe6060f1SDimitry Andric NewMI.addFrameIndex(FrameIndex); 2348fe6060f1SDimitry Andric else 2349fe6060f1SDimitry Andric NewMI.add(MachineOperand(Op)); 2350fe6060f1SDimitry Andric } 2351fe6060f1SDimitry Andric return NewMI; 2352fe6060f1SDimitry Andric } 2353fe6060f1SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill( 2354fe6060f1SDimitry Andric MachineBasicBlock &BB, MachineBasicBlock::iterator I, 2355fe6060f1SDimitry Andric const MachineInstr &Orig, int FrameIndex, 2356fe6060f1SDimitry Andric SmallVectorImpl<const MachineOperand *> &SpilledOperands) { 2357fe6060f1SDimitry Andric const DIExpression *Expr = computeExprForSpill(Orig, SpilledOperands); 2358fe6060f1SDimitry Andric MachineInstrBuilder NewMI = 2359fe6060f1SDimitry Andric BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc()); 2360fe6060f1SDimitry Andric // Non-Variadic Operands: Location, Offset, Variable, Expression 2361fe6060f1SDimitry Andric // Variadic Operands: Variable, Expression, Locations... 2362fe6060f1SDimitry Andric if (Orig.isNonListDebugValue()) 2363fe6060f1SDimitry Andric NewMI.addFrameIndex(FrameIndex).addImm(0U); 2364fe6060f1SDimitry Andric NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr); 2365fe6060f1SDimitry Andric if (Orig.isDebugValueList()) { 2366fe6060f1SDimitry Andric for (const MachineOperand &Op : Orig.debug_operands()) 2367fe6060f1SDimitry Andric if (is_contained(SpilledOperands, &Op)) 2368fe6060f1SDimitry Andric NewMI.addFrameIndex(FrameIndex); 2369fe6060f1SDimitry Andric else 2370fe6060f1SDimitry Andric NewMI.add(MachineOperand(Op)); 2371fe6060f1SDimitry Andric } 2372fe6060f1SDimitry Andric return NewMI; 23730b57cec5SDimitry Andric } 23740b57cec5SDimitry Andric 2375fe6060f1SDimitry Andric void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex, 2376fe6060f1SDimitry Andric Register Reg) { 2377fe6060f1SDimitry Andric const DIExpression *Expr = computeExprForSpill(Orig, Reg); 2378fe6060f1SDimitry Andric if (Orig.isNonListDebugValue()) 23795ffd83dbSDimitry Andric Orig.getDebugOffset().ChangeToImmediate(0U); 2380fe6060f1SDimitry Andric for (MachineOperand &Op : Orig.getDebugOperandsForReg(Reg)) 2381fe6060f1SDimitry Andric Op.ChangeToFrameIndex(FrameIndex); 23825ffd83dbSDimitry Andric Orig.getDebugExpressionOp().setMetadata(Expr); 23830b57cec5SDimitry Andric } 23840b57cec5SDimitry Andric 23850b57cec5SDimitry Andric void MachineInstr::collectDebugValues( 23860b57cec5SDimitry Andric SmallVectorImpl<MachineInstr *> &DbgValues) { 23870b57cec5SDimitry Andric MachineInstr &MI = *this; 23880b57cec5SDimitry Andric if (!MI.getOperand(0).isReg()) 23890b57cec5SDimitry Andric return; 23900b57cec5SDimitry Andric 23910b57cec5SDimitry Andric MachineBasicBlock::iterator DI = MI; ++DI; 23920b57cec5SDimitry Andric for (MachineBasicBlock::iterator DE = MI.getParent()->end(); 23930b57cec5SDimitry Andric DI != DE; ++DI) { 23940b57cec5SDimitry Andric if (!DI->isDebugValue()) 23950b57cec5SDimitry Andric return; 2396fe6060f1SDimitry Andric if (DI->hasDebugOperandForReg(MI.getOperand(0).getReg())) 23970b57cec5SDimitry Andric DbgValues.push_back(&*DI); 23980b57cec5SDimitry Andric } 23990b57cec5SDimitry Andric } 24000b57cec5SDimitry Andric 24018bcb0991SDimitry Andric void MachineInstr::changeDebugValuesDefReg(Register Reg) { 24020b57cec5SDimitry Andric // Collect matching debug values. 24030b57cec5SDimitry Andric SmallVector<MachineInstr *, 2> DbgValues; 24048bcb0991SDimitry Andric 24058bcb0991SDimitry Andric if (!getOperand(0).isReg()) 24068bcb0991SDimitry Andric return; 24078bcb0991SDimitry Andric 24085ffd83dbSDimitry Andric Register DefReg = getOperand(0).getReg(); 24098bcb0991SDimitry Andric auto *MRI = getRegInfo(); 24108bcb0991SDimitry Andric for (auto &MO : MRI->use_operands(DefReg)) { 24118bcb0991SDimitry Andric auto *DI = MO.getParent(); 24128bcb0991SDimitry Andric if (!DI->isDebugValue()) 24138bcb0991SDimitry Andric continue; 2414fe6060f1SDimitry Andric if (DI->hasDebugOperandForReg(DefReg)) { 24158bcb0991SDimitry Andric DbgValues.push_back(DI); 24168bcb0991SDimitry Andric } 24178bcb0991SDimitry Andric } 24180b57cec5SDimitry Andric 24190b57cec5SDimitry Andric // Propagate Reg to debug value instructions. 24200b57cec5SDimitry Andric for (auto *DBI : DbgValues) 2421fe6060f1SDimitry Andric for (MachineOperand &Op : DBI->getDebugOperandsForReg(DefReg)) 2422fe6060f1SDimitry Andric Op.setReg(Reg); 24230b57cec5SDimitry Andric } 24240b57cec5SDimitry Andric 24250b57cec5SDimitry Andric using MMOList = SmallVector<const MachineMemOperand *, 2>; 24260b57cec5SDimitry Andric 2427*0fca6ea1SDimitry Andric static LocationSize getSpillSlotSize(const MMOList &Accesses, 24280b57cec5SDimitry Andric const MachineFrameInfo &MFI) { 2429*0fca6ea1SDimitry Andric uint64_t Size = 0; 2430*0fca6ea1SDimitry Andric for (const auto *A : Accesses) { 24310b57cec5SDimitry Andric if (MFI.isSpillSlotObjectIndex( 24320b57cec5SDimitry Andric cast<FixedStackPseudoSourceValue>(A->getPseudoValue()) 2433*0fca6ea1SDimitry Andric ->getFrameIndex())) { 2434*0fca6ea1SDimitry Andric LocationSize S = A->getSize(); 2435*0fca6ea1SDimitry Andric if (!S.hasValue()) 2436*0fca6ea1SDimitry Andric return LocationSize::beforeOrAfterPointer(); 2437*0fca6ea1SDimitry Andric Size += S.getValue(); 2438*0fca6ea1SDimitry Andric } 2439*0fca6ea1SDimitry Andric } 24400b57cec5SDimitry Andric return Size; 24410b57cec5SDimitry Andric } 24420b57cec5SDimitry Andric 2443*0fca6ea1SDimitry Andric std::optional<LocationSize> 24440b57cec5SDimitry Andric MachineInstr::getSpillSize(const TargetInstrInfo *TII) const { 24450b57cec5SDimitry Andric int FI; 24460b57cec5SDimitry Andric if (TII->isStoreToStackSlotPostFE(*this, FI)) { 24470b57cec5SDimitry Andric const MachineFrameInfo &MFI = getMF()->getFrameInfo(); 24480b57cec5SDimitry Andric if (MFI.isSpillSlotObjectIndex(FI)) 24490b57cec5SDimitry Andric return (*memoperands_begin())->getSize(); 24500b57cec5SDimitry Andric } 2451bdd1243dSDimitry Andric return std::nullopt; 24520b57cec5SDimitry Andric } 24530b57cec5SDimitry Andric 2454*0fca6ea1SDimitry Andric std::optional<LocationSize> 24550b57cec5SDimitry Andric MachineInstr::getFoldedSpillSize(const TargetInstrInfo *TII) const { 24560b57cec5SDimitry Andric MMOList Accesses; 24570b57cec5SDimitry Andric if (TII->hasStoreToStackSlot(*this, Accesses)) 24580b57cec5SDimitry Andric return getSpillSlotSize(Accesses, getMF()->getFrameInfo()); 2459bdd1243dSDimitry Andric return std::nullopt; 24600b57cec5SDimitry Andric } 24610b57cec5SDimitry Andric 2462*0fca6ea1SDimitry Andric std::optional<LocationSize> 24630b57cec5SDimitry Andric MachineInstr::getRestoreSize(const TargetInstrInfo *TII) const { 24640b57cec5SDimitry Andric int FI; 24650b57cec5SDimitry Andric if (TII->isLoadFromStackSlotPostFE(*this, FI)) { 24660b57cec5SDimitry Andric const MachineFrameInfo &MFI = getMF()->getFrameInfo(); 24670b57cec5SDimitry Andric if (MFI.isSpillSlotObjectIndex(FI)) 24680b57cec5SDimitry Andric return (*memoperands_begin())->getSize(); 24690b57cec5SDimitry Andric } 2470bdd1243dSDimitry Andric return std::nullopt; 24710b57cec5SDimitry Andric } 24720b57cec5SDimitry Andric 2473*0fca6ea1SDimitry Andric std::optional<LocationSize> 24740b57cec5SDimitry Andric MachineInstr::getFoldedRestoreSize(const TargetInstrInfo *TII) const { 24750b57cec5SDimitry Andric MMOList Accesses; 24760b57cec5SDimitry Andric if (TII->hasLoadFromStackSlot(*this, Accesses)) 24770b57cec5SDimitry Andric return getSpillSlotSize(Accesses, getMF()->getFrameInfo()); 2478bdd1243dSDimitry Andric return std::nullopt; 24790b57cec5SDimitry Andric } 2480e8d8bef9SDimitry Andric 2481e8d8bef9SDimitry Andric unsigned MachineInstr::getDebugInstrNum() { 2482e8d8bef9SDimitry Andric if (DebugInstrNum == 0) 2483e8d8bef9SDimitry Andric DebugInstrNum = getParent()->getParent()->getNewDebugInstrNum(); 2484e8d8bef9SDimitry Andric return DebugInstrNum; 2485e8d8bef9SDimitry Andric } 2486fe6060f1SDimitry Andric 2487fe6060f1SDimitry Andric unsigned MachineInstr::getDebugInstrNum(MachineFunction &MF) { 2488fe6060f1SDimitry Andric if (DebugInstrNum == 0) 2489fe6060f1SDimitry Andric DebugInstrNum = MF.getNewDebugInstrNum(); 2490fe6060f1SDimitry Andric return DebugInstrNum; 2491fe6060f1SDimitry Andric } 249206c3fb27SDimitry Andric 249306c3fb27SDimitry Andric std::tuple<LLT, LLT> MachineInstr::getFirst2LLTs() const { 249406c3fb27SDimitry Andric return std::tuple(getRegInfo()->getType(getOperand(0).getReg()), 249506c3fb27SDimitry Andric getRegInfo()->getType(getOperand(1).getReg())); 249606c3fb27SDimitry Andric } 249706c3fb27SDimitry Andric 249806c3fb27SDimitry Andric std::tuple<LLT, LLT, LLT> MachineInstr::getFirst3LLTs() const { 249906c3fb27SDimitry Andric return std::tuple(getRegInfo()->getType(getOperand(0).getReg()), 250006c3fb27SDimitry Andric getRegInfo()->getType(getOperand(1).getReg()), 250106c3fb27SDimitry Andric getRegInfo()->getType(getOperand(2).getReg())); 250206c3fb27SDimitry Andric } 250306c3fb27SDimitry Andric 250406c3fb27SDimitry Andric std::tuple<LLT, LLT, LLT, LLT> MachineInstr::getFirst4LLTs() const { 250506c3fb27SDimitry Andric return std::tuple(getRegInfo()->getType(getOperand(0).getReg()), 250606c3fb27SDimitry Andric getRegInfo()->getType(getOperand(1).getReg()), 250706c3fb27SDimitry Andric getRegInfo()->getType(getOperand(2).getReg()), 250806c3fb27SDimitry Andric getRegInfo()->getType(getOperand(3).getReg())); 250906c3fb27SDimitry Andric } 251006c3fb27SDimitry Andric 251106c3fb27SDimitry Andric std::tuple<LLT, LLT, LLT, LLT, LLT> MachineInstr::getFirst5LLTs() const { 251206c3fb27SDimitry Andric return std::tuple(getRegInfo()->getType(getOperand(0).getReg()), 251306c3fb27SDimitry Andric getRegInfo()->getType(getOperand(1).getReg()), 251406c3fb27SDimitry Andric getRegInfo()->getType(getOperand(2).getReg()), 251506c3fb27SDimitry Andric getRegInfo()->getType(getOperand(3).getReg()), 251606c3fb27SDimitry Andric getRegInfo()->getType(getOperand(4).getReg())); 251706c3fb27SDimitry Andric } 251806c3fb27SDimitry Andric 251906c3fb27SDimitry Andric std::tuple<Register, LLT, Register, LLT> 252006c3fb27SDimitry Andric MachineInstr::getFirst2RegLLTs() const { 252106c3fb27SDimitry Andric Register Reg0 = getOperand(0).getReg(); 252206c3fb27SDimitry Andric Register Reg1 = getOperand(1).getReg(); 252306c3fb27SDimitry Andric return std::tuple(Reg0, getRegInfo()->getType(Reg0), Reg1, 252406c3fb27SDimitry Andric getRegInfo()->getType(Reg1)); 252506c3fb27SDimitry Andric } 252606c3fb27SDimitry Andric 252706c3fb27SDimitry Andric std::tuple<Register, LLT, Register, LLT, Register, LLT> 252806c3fb27SDimitry Andric MachineInstr::getFirst3RegLLTs() const { 252906c3fb27SDimitry Andric Register Reg0 = getOperand(0).getReg(); 253006c3fb27SDimitry Andric Register Reg1 = getOperand(1).getReg(); 253106c3fb27SDimitry Andric Register Reg2 = getOperand(2).getReg(); 253206c3fb27SDimitry Andric return std::tuple(Reg0, getRegInfo()->getType(Reg0), Reg1, 253306c3fb27SDimitry Andric getRegInfo()->getType(Reg1), Reg2, 253406c3fb27SDimitry Andric getRegInfo()->getType(Reg2)); 253506c3fb27SDimitry Andric } 253606c3fb27SDimitry Andric 253706c3fb27SDimitry Andric std::tuple<Register, LLT, Register, LLT, Register, LLT, Register, LLT> 253806c3fb27SDimitry Andric MachineInstr::getFirst4RegLLTs() const { 253906c3fb27SDimitry Andric Register Reg0 = getOperand(0).getReg(); 254006c3fb27SDimitry Andric Register Reg1 = getOperand(1).getReg(); 254106c3fb27SDimitry Andric Register Reg2 = getOperand(2).getReg(); 254206c3fb27SDimitry Andric Register Reg3 = getOperand(3).getReg(); 254306c3fb27SDimitry Andric return std::tuple( 254406c3fb27SDimitry Andric Reg0, getRegInfo()->getType(Reg0), Reg1, getRegInfo()->getType(Reg1), 254506c3fb27SDimitry Andric Reg2, getRegInfo()->getType(Reg2), Reg3, getRegInfo()->getType(Reg3)); 254606c3fb27SDimitry Andric } 254706c3fb27SDimitry Andric 254806c3fb27SDimitry Andric std::tuple<Register, LLT, Register, LLT, Register, LLT, Register, LLT, Register, 254906c3fb27SDimitry Andric LLT> 255006c3fb27SDimitry Andric MachineInstr::getFirst5RegLLTs() const { 255106c3fb27SDimitry Andric Register Reg0 = getOperand(0).getReg(); 255206c3fb27SDimitry Andric Register Reg1 = getOperand(1).getReg(); 255306c3fb27SDimitry Andric Register Reg2 = getOperand(2).getReg(); 255406c3fb27SDimitry Andric Register Reg3 = getOperand(3).getReg(); 255506c3fb27SDimitry Andric Register Reg4 = getOperand(4).getReg(); 255606c3fb27SDimitry Andric return std::tuple( 255706c3fb27SDimitry Andric Reg0, getRegInfo()->getType(Reg0), Reg1, getRegInfo()->getType(Reg1), 255806c3fb27SDimitry Andric Reg2, getRegInfo()->getType(Reg2), Reg3, getRegInfo()->getType(Reg3), 255906c3fb27SDimitry Andric Reg4, getRegInfo()->getType(Reg4)); 256006c3fb27SDimitry Andric } 25615f757f3fSDimitry Andric 25625f757f3fSDimitry Andric void MachineInstr::insert(mop_iterator InsertBefore, 25635f757f3fSDimitry Andric ArrayRef<MachineOperand> Ops) { 25645f757f3fSDimitry Andric assert(InsertBefore != nullptr && "invalid iterator"); 25655f757f3fSDimitry Andric assert(InsertBefore->getParent() == this && 25665f757f3fSDimitry Andric "iterator points to operand of other inst"); 25675f757f3fSDimitry Andric if (Ops.empty()) 25685f757f3fSDimitry Andric return; 25695f757f3fSDimitry Andric 25705f757f3fSDimitry Andric // Do one pass to untie operands. 25715f757f3fSDimitry Andric SmallDenseMap<unsigned, unsigned> TiedOpIndices; 25725f757f3fSDimitry Andric for (const MachineOperand &MO : operands()) { 25735f757f3fSDimitry Andric if (MO.isReg() && MO.isTied()) { 25745f757f3fSDimitry Andric unsigned OpNo = getOperandNo(&MO); 25755f757f3fSDimitry Andric unsigned TiedTo = findTiedOperandIdx(OpNo); 25765f757f3fSDimitry Andric TiedOpIndices[OpNo] = TiedTo; 25775f757f3fSDimitry Andric untieRegOperand(OpNo); 25785f757f3fSDimitry Andric } 25795f757f3fSDimitry Andric } 25805f757f3fSDimitry Andric 25815f757f3fSDimitry Andric unsigned OpIdx = getOperandNo(InsertBefore); 25825f757f3fSDimitry Andric unsigned NumOperands = getNumOperands(); 25835f757f3fSDimitry Andric unsigned OpsToMove = NumOperands - OpIdx; 25845f757f3fSDimitry Andric 25855f757f3fSDimitry Andric SmallVector<MachineOperand> MovingOps; 25865f757f3fSDimitry Andric MovingOps.reserve(OpsToMove); 25875f757f3fSDimitry Andric 25885f757f3fSDimitry Andric for (unsigned I = 0; I < OpsToMove; ++I) { 25895f757f3fSDimitry Andric MovingOps.emplace_back(getOperand(OpIdx)); 25905f757f3fSDimitry Andric removeOperand(OpIdx); 25915f757f3fSDimitry Andric } 25925f757f3fSDimitry Andric for (const MachineOperand &MO : Ops) 25935f757f3fSDimitry Andric addOperand(MO); 25945f757f3fSDimitry Andric for (const MachineOperand &OpMoved : MovingOps) 25955f757f3fSDimitry Andric addOperand(OpMoved); 25965f757f3fSDimitry Andric 25975f757f3fSDimitry Andric // Re-tie operands. 25985f757f3fSDimitry Andric for (auto [Tie1, Tie2] : TiedOpIndices) { 25995f757f3fSDimitry Andric if (Tie1 >= OpIdx) 26005f757f3fSDimitry Andric Tie1 += Ops.size(); 26015f757f3fSDimitry Andric if (Tie2 >= OpIdx) 26025f757f3fSDimitry Andric Tie2 += Ops.size(); 26035f757f3fSDimitry Andric tieOperands(Tie1, Tie2); 26045f757f3fSDimitry Andric } 26055f757f3fSDimitry Andric } 26065f757f3fSDimitry Andric 26075f757f3fSDimitry Andric bool MachineInstr::mayFoldInlineAsmRegOp(unsigned OpId) const { 26085f757f3fSDimitry Andric assert(OpId && "expected non-zero operand id"); 26095f757f3fSDimitry Andric assert(isInlineAsm() && "should only be used on inline asm"); 26105f757f3fSDimitry Andric 26115f757f3fSDimitry Andric if (!getOperand(OpId).isReg()) 26125f757f3fSDimitry Andric return false; 26135f757f3fSDimitry Andric 26145f757f3fSDimitry Andric const MachineOperand &MD = getOperand(OpId - 1); 26155f757f3fSDimitry Andric if (!MD.isImm()) 26165f757f3fSDimitry Andric return false; 26175f757f3fSDimitry Andric 26185f757f3fSDimitry Andric InlineAsm::Flag F(MD.getImm()); 26195f757f3fSDimitry Andric if (F.isRegUseKind() || F.isRegDefKind() || F.isRegDefEarlyClobberKind()) 26205f757f3fSDimitry Andric return F.getRegMayBeFolded(); 26215f757f3fSDimitry Andric return false; 26225f757f3fSDimitry Andric } 2623