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"
21fe013be4SDimitry Andric #include "llvm/CodeGen/LowLevelType.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h"
32fe013be4SDimitry Andric #include "llvm/CodeGen/Register.h"
33e8d8bef9SDimitry Andric #include "llvm/CodeGen/StackMaps.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.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"
420b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
430b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
440b57cec5SDimitry Andric #include "llvm/IR/Module.h"
450b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
460b57cec5SDimitry Andric #include "llvm/IR/Operator.h"
470b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
480b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
490b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
500b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
510b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
520b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
535ffd83dbSDimitry Andric #include "llvm/Support/FormattedStream.h"
540b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
550b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
560b57cec5SDimitry Andric #include <algorithm>
570b57cec5SDimitry Andric #include <cassert>
580b57cec5SDimitry Andric #include <cstdint>
590b57cec5SDimitry Andric #include <cstring>
600b57cec5SDimitry Andric #include <utility>
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric using namespace llvm;
630b57cec5SDimitry Andric 
getMFIfAvailable(const MachineInstr & MI)640b57cec5SDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineInstr &MI) {
650b57cec5SDimitry Andric   if (const MachineBasicBlock *MBB = MI.getParent())
660b57cec5SDimitry Andric     if (const MachineFunction *MF = MBB->getParent())
670b57cec5SDimitry Andric       return MF;
680b57cec5SDimitry Andric   return nullptr;
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from
720b57cec5SDimitry Andric // it.
tryToGetTargetInfo(const MachineInstr & MI,const TargetRegisterInfo * & TRI,const MachineRegisterInfo * & MRI,const TargetIntrinsicInfo * & IntrinsicInfo,const TargetInstrInfo * & TII)730b57cec5SDimitry Andric static void tryToGetTargetInfo(const MachineInstr &MI,
740b57cec5SDimitry Andric                                const TargetRegisterInfo *&TRI,
750b57cec5SDimitry Andric                                const MachineRegisterInfo *&MRI,
760b57cec5SDimitry Andric                                const TargetIntrinsicInfo *&IntrinsicInfo,
770b57cec5SDimitry Andric                                const TargetInstrInfo *&TII) {
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(MI)) {
800b57cec5SDimitry Andric     TRI = MF->getSubtarget().getRegisterInfo();
810b57cec5SDimitry Andric     MRI = &MF->getRegInfo();
820b57cec5SDimitry Andric     IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
830b57cec5SDimitry Andric     TII = MF->getSubtarget().getInstrInfo();
840b57cec5SDimitry Andric   }
850b57cec5SDimitry Andric }
860b57cec5SDimitry Andric 
addImplicitDefUseOperands(MachineFunction & MF)870b57cec5SDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) {
88bdd1243dSDimitry Andric   for (MCPhysReg ImpDef : MCID->implicit_defs())
89bdd1243dSDimitry Andric     addOperand(MF, MachineOperand::CreateReg(ImpDef, true, true));
90bdd1243dSDimitry Andric   for (MCPhysReg ImpUse : MCID->implicit_uses())
91bdd1243dSDimitry Andric     addOperand(MF, MachineOperand::CreateReg(ImpUse, false, true));
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric /// MachineInstr ctor - This constructor creates a MachineInstr and adds the
950b57cec5SDimitry Andric /// implicit operands. It reserves space for the number of operands specified by
960b57cec5SDimitry Andric /// the MCInstrDesc.
MachineInstr(MachineFunction & MF,const MCInstrDesc & TID,DebugLoc DL,bool NoImp)970eae32dcSDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &TID,
980eae32dcSDimitry Andric                            DebugLoc DL, bool NoImp)
99fe013be4SDimitry Andric     : MCID(&TID), NumOperands(0), Flags(0), AsmPrinterFlags(0),
100fe013be4SDimitry Andric       DbgLoc(std::move(DL)), DebugInstrNum(0) {
1010eae32dcSDimitry Andric   assert(DbgLoc.hasTrivialDestructor() && "Expected trivial destructor");
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   // Reserve space for the expected number of operands.
104bdd1243dSDimitry Andric   if (unsigned NumOps = MCID->getNumOperands() + MCID->implicit_defs().size() +
105bdd1243dSDimitry Andric                         MCID->implicit_uses().size()) {
1060b57cec5SDimitry Andric     CapOperands = OperandCapacity::get(NumOps);
1070b57cec5SDimitry Andric     Operands = MF.allocateOperandArray(CapOperands);
1080b57cec5SDimitry Andric   }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   if (!NoImp)
1110b57cec5SDimitry Andric     addImplicitDefUseOperands(MF);
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric 
114e8d8bef9SDimitry Andric /// MachineInstr ctor - Copies MachineInstr arg exactly.
115e8d8bef9SDimitry Andric /// Does not copy the number from debug instruction numbering, to preserve
116e8d8bef9SDimitry Andric /// uniqueness.
MachineInstr(MachineFunction & MF,const MachineInstr & MI)1170b57cec5SDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
118fe013be4SDimitry Andric     : MCID(&MI.getDesc()), NumOperands(0), Flags(0), AsmPrinterFlags(0),
119fe013be4SDimitry Andric       Info(MI.Info), DbgLoc(MI.getDebugLoc()), DebugInstrNum(0) {
1200eae32dcSDimitry Andric   assert(DbgLoc.hasTrivialDestructor() && "Expected trivial destructor");
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   CapOperands = OperandCapacity::get(MI.getNumOperands());
1230b57cec5SDimitry Andric   Operands = MF.allocateOperandArray(CapOperands);
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   // Copy operands.
1260b57cec5SDimitry Andric   for (const MachineOperand &MO : MI.operands())
1270b57cec5SDimitry Andric     addOperand(MF, MO);
1280b57cec5SDimitry Andric 
129bdd1243dSDimitry Andric   // Replicate ties between the operands, which addOperand was not
130bdd1243dSDimitry Andric   // able to do reliably.
131bdd1243dSDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i < e; ++i) {
132bdd1243dSDimitry Andric     MachineOperand &NewMO = getOperand(i);
133bdd1243dSDimitry Andric     const MachineOperand &OrigMO = MI.getOperand(i);
134bdd1243dSDimitry Andric     NewMO.TiedTo = OrigMO.TiedTo;
135bdd1243dSDimitry Andric   }
136bdd1243dSDimitry Andric 
1370b57cec5SDimitry Andric   // Copy all the sensible flags.
1380b57cec5SDimitry Andric   setFlags(MI.Flags);
1390b57cec5SDimitry Andric }
1400b57cec5SDimitry Andric 
setDesc(const MCInstrDesc & TID)141*c9157d92SDimitry Andric void MachineInstr::setDesc(const MCInstrDesc &TID) {
142*c9157d92SDimitry Andric   if (getParent())
143*c9157d92SDimitry Andric     getMF()->handleChangeDesc(*this, TID);
144*c9157d92SDimitry Andric   MCID = &TID;
145*c9157d92SDimitry Andric }
146*c9157d92SDimitry Andric 
moveBefore(MachineInstr * MovePos)147e8d8bef9SDimitry Andric void MachineInstr::moveBefore(MachineInstr *MovePos) {
148e8d8bef9SDimitry Andric   MovePos->getParent()->splice(MovePos, getParent(), getIterator());
149e8d8bef9SDimitry Andric }
150e8d8bef9SDimitry Andric 
1510b57cec5SDimitry Andric /// getRegInfo - If this instruction is embedded into a MachineFunction,
1520b57cec5SDimitry Andric /// return the MachineRegisterInfo object for the current function, otherwise
1530b57cec5SDimitry Andric /// return null.
getRegInfo()1540b57cec5SDimitry Andric MachineRegisterInfo *MachineInstr::getRegInfo() {
1550b57cec5SDimitry Andric   if (MachineBasicBlock *MBB = getParent())
1560b57cec5SDimitry Andric     return &MBB->getParent()->getRegInfo();
1570b57cec5SDimitry Andric   return nullptr;
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric 
getRegInfo() const160fe013be4SDimitry Andric const MachineRegisterInfo *MachineInstr::getRegInfo() const {
161fe013be4SDimitry Andric   if (const MachineBasicBlock *MBB = getParent())
162fe013be4SDimitry Andric     return &MBB->getParent()->getRegInfo();
163fe013be4SDimitry Andric   return nullptr;
164fe013be4SDimitry Andric }
165fe013be4SDimitry Andric 
removeRegOperandsFromUseLists(MachineRegisterInfo & MRI)16681ad6265SDimitry Andric void MachineInstr::removeRegOperandsFromUseLists(MachineRegisterInfo &MRI) {
1670b57cec5SDimitry Andric   for (MachineOperand &MO : operands())
1680b57cec5SDimitry Andric     if (MO.isReg())
1690b57cec5SDimitry Andric       MRI.removeRegOperandFromUseList(&MO);
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric 
addRegOperandsToUseLists(MachineRegisterInfo & MRI)17281ad6265SDimitry Andric void MachineInstr::addRegOperandsToUseLists(MachineRegisterInfo &MRI) {
1730b57cec5SDimitry Andric   for (MachineOperand &MO : operands())
1740b57cec5SDimitry Andric     if (MO.isReg())
1750b57cec5SDimitry Andric       MRI.addRegOperandToUseList(&MO);
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric 
addOperand(const MachineOperand & Op)1780b57cec5SDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) {
1790b57cec5SDimitry Andric   MachineBasicBlock *MBB = getParent();
1800b57cec5SDimitry Andric   assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs");
1810b57cec5SDimitry Andric   MachineFunction *MF = MBB->getParent();
1820b57cec5SDimitry Andric   assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs");
1830b57cec5SDimitry Andric   addOperand(*MF, Op);
1840b57cec5SDimitry Andric }
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping
1870b57cec5SDimitry Andric /// ranges. If MRI is non-null also update use-def chains.
moveOperands(MachineOperand * Dst,MachineOperand * Src,unsigned NumOps,MachineRegisterInfo * MRI)1880b57cec5SDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src,
1890b57cec5SDimitry Andric                          unsigned NumOps, MachineRegisterInfo *MRI) {
1900b57cec5SDimitry Andric   if (MRI)
1910b57cec5SDimitry Andric     return MRI->moveOperands(Dst, Src, NumOps);
1920b57cec5SDimitry Andric   // MachineOperand is a trivially copyable type so we can just use memmove.
193480093f4SDimitry Andric   assert(Dst && Src && "Unknown operands");
1940b57cec5SDimitry Andric   std::memmove(Dst, Src, NumOps * sizeof(MachineOperand));
1950b57cec5SDimitry Andric }
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric /// addOperand - Add the specified operand to the instruction.  If it is an
1980b57cec5SDimitry Andric /// implicit operand, it is added to the end of the operand list.  If it is
1990b57cec5SDimitry Andric /// an explicit operand it is added at the end of the explicit operand list
2000b57cec5SDimitry Andric /// (before the first implicit operand).
addOperand(MachineFunction & MF,const MachineOperand & Op)2010b57cec5SDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) {
202fe013be4SDimitry Andric   assert(isUInt<LLVM_MI_NUMOPERANDS_BITS>(NumOperands + 1) &&
203fe013be4SDimitry Andric          "Cannot add more operands.");
2040b57cec5SDimitry Andric   assert(MCID && "Cannot add operands before providing an instr descriptor");
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   // Check if we're adding one of our existing operands.
2070b57cec5SDimitry Andric   if (&Op >= Operands && &Op < Operands + NumOperands) {
2080b57cec5SDimitry Andric     // This is unusual: MI->addOperand(MI->getOperand(i)).
2090b57cec5SDimitry Andric     // If adding Op requires reallocating or moving existing operands around,
2100b57cec5SDimitry Andric     // the Op reference could go stale. Support it by copying Op.
2110b57cec5SDimitry Andric     MachineOperand CopyOp(Op);
2120b57cec5SDimitry Andric     return addOperand(MF, CopyOp);
2130b57cec5SDimitry Andric   }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   // Find the insert location for the new operand.  Implicit registers go at
2160b57cec5SDimitry Andric   // the end, everything else goes before the implicit regs.
2170b57cec5SDimitry Andric   //
2180b57cec5SDimitry Andric   // FIXME: Allow mixed explicit and implicit operands on inline asm.
2190b57cec5SDimitry Andric   // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as
2200b57cec5SDimitry Andric   // implicit-defs, but they must not be moved around.  See the FIXME in
2210b57cec5SDimitry Andric   // InstrEmitter.cpp.
2220b57cec5SDimitry Andric   unsigned OpNo = getNumOperands();
2230b57cec5SDimitry Andric   bool isImpReg = Op.isReg() && Op.isImplicit();
2240b57cec5SDimitry Andric   if (!isImpReg && !isInlineAsm()) {
2250b57cec5SDimitry Andric     while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) {
2260b57cec5SDimitry Andric       --OpNo;
2270b57cec5SDimitry Andric       assert(!Operands[OpNo].isTied() && "Cannot move tied operands");
2280b57cec5SDimitry Andric     }
2290b57cec5SDimitry Andric   }
2300b57cec5SDimitry Andric 
2310b57cec5SDimitry Andric   // OpNo now points as the desired insertion point.  Unless this is a variadic
2320b57cec5SDimitry Andric   // instruction, only implicit regs are allowed beyond MCID->getNumOperands().
2330b57cec5SDimitry Andric   // RegMask operands go between the explicit and implicit operands.
2340b57cec5SDimitry Andric   MachineRegisterInfo *MRI = getRegInfo();
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric   // Determine if the Operands array needs to be reallocated.
2370b57cec5SDimitry Andric   // Save the old capacity and operand array.
2380b57cec5SDimitry Andric   OperandCapacity OldCap = CapOperands;
2390b57cec5SDimitry Andric   MachineOperand *OldOperands = Operands;
2400b57cec5SDimitry Andric   if (!OldOperands || OldCap.getSize() == getNumOperands()) {
2410b57cec5SDimitry Andric     CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1);
2420b57cec5SDimitry Andric     Operands = MF.allocateOperandArray(CapOperands);
2430b57cec5SDimitry Andric     // Move the operands before the insertion point.
2440b57cec5SDimitry Andric     if (OpNo)
2450b57cec5SDimitry Andric       moveOperands(Operands, OldOperands, OpNo, MRI);
2460b57cec5SDimitry Andric   }
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   // Move the operands following the insertion point.
2490b57cec5SDimitry Andric   if (OpNo != NumOperands)
2500b57cec5SDimitry Andric     moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo,
2510b57cec5SDimitry Andric                  MRI);
2520b57cec5SDimitry Andric   ++NumOperands;
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   // Deallocate the old operand array.
2550b57cec5SDimitry Andric   if (OldOperands != Operands && OldOperands)
2560b57cec5SDimitry Andric     MF.deallocateOperandArray(OldCap, OldOperands);
2570b57cec5SDimitry Andric 
2580b57cec5SDimitry Andric   // Copy Op into place. It still needs to be inserted into the MRI use lists.
2590b57cec5SDimitry Andric   MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op);
2600b57cec5SDimitry Andric   NewMO->ParentMI = this;
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric   // When adding a register operand, tell MRI about it.
2630b57cec5SDimitry Andric   if (NewMO->isReg()) {
2640b57cec5SDimitry Andric     // Ensure isOnRegUseList() returns false, regardless of Op's status.
2650b57cec5SDimitry Andric     NewMO->Contents.Reg.Prev = nullptr;
2660b57cec5SDimitry Andric     // Ignore existing ties. This is not a property that can be copied.
2670b57cec5SDimitry Andric     NewMO->TiedTo = 0;
2680b57cec5SDimitry Andric     // Add the new operand to MRI, but only for instructions in an MBB.
2690b57cec5SDimitry Andric     if (MRI)
2700b57cec5SDimitry Andric       MRI->addRegOperandToUseList(NewMO);
2710b57cec5SDimitry Andric     // The MCID operand information isn't accurate until we start adding
2720b57cec5SDimitry Andric     // explicit operands. The implicit operands are added first, then the
2730b57cec5SDimitry Andric     // explicits are inserted before them.
2740b57cec5SDimitry Andric     if (!isImpReg) {
2750b57cec5SDimitry Andric       // Tie uses to defs as indicated in MCInstrDesc.
2760b57cec5SDimitry Andric       if (NewMO->isUse()) {
2770b57cec5SDimitry Andric         int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO);
2780b57cec5SDimitry Andric         if (DefIdx != -1)
2790b57cec5SDimitry Andric           tieOperands(DefIdx, OpNo);
2800b57cec5SDimitry Andric       }
2810b57cec5SDimitry Andric       // If the register operand is flagged as early, mark the operand as such.
2820b57cec5SDimitry Andric       if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1)
2830b57cec5SDimitry Andric         NewMO->setIsEarlyClobber(true);
2840b57cec5SDimitry Andric     }
285349cc55cSDimitry Andric     // Ensure debug instructions set debug flag on register uses.
286349cc55cSDimitry Andric     if (NewMO->isUse() && isDebugInstr())
287349cc55cSDimitry Andric       NewMO->setIsDebug();
2880b57cec5SDimitry Andric   }
2890b57cec5SDimitry Andric }
2900b57cec5SDimitry Andric 
removeOperand(unsigned OpNo)29181ad6265SDimitry Andric void MachineInstr::removeOperand(unsigned OpNo) {
2920b57cec5SDimitry Andric   assert(OpNo < getNumOperands() && "Invalid operand number");
2930b57cec5SDimitry Andric   untieRegOperand(OpNo);
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric #ifndef NDEBUG
2960b57cec5SDimitry Andric   // Moving tied operands would break the ties.
2970b57cec5SDimitry Andric   for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i)
2980b57cec5SDimitry Andric     if (Operands[i].isReg())
2990b57cec5SDimitry Andric       assert(!Operands[i].isTied() && "Cannot move tied operands");
3000b57cec5SDimitry Andric #endif
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric   MachineRegisterInfo *MRI = getRegInfo();
3030b57cec5SDimitry Andric   if (MRI && Operands[OpNo].isReg())
3040b57cec5SDimitry Andric     MRI->removeRegOperandFromUseList(Operands + OpNo);
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   // Don't call the MachineOperand destructor. A lot of this code depends on
3070b57cec5SDimitry Andric   // MachineOperand having a trivial destructor anyway, and adding a call here
3080b57cec5SDimitry Andric   // wouldn't make it 'destructor-correct'.
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   if (unsigned N = NumOperands - 1 - OpNo)
3110b57cec5SDimitry Andric     moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI);
3120b57cec5SDimitry Andric   --NumOperands;
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric 
setExtraInfo(MachineFunction & MF,ArrayRef<MachineMemOperand * > MMOs,MCSymbol * PreInstrSymbol,MCSymbol * PostInstrSymbol,MDNode * HeapAllocMarker,MDNode * PCSections,uint32_t CFIType)315c14a5a88SDimitry Andric void MachineInstr::setExtraInfo(MachineFunction &MF,
316c14a5a88SDimitry Andric                                 ArrayRef<MachineMemOperand *> MMOs,
317c14a5a88SDimitry Andric                                 MCSymbol *PreInstrSymbol,
318c14a5a88SDimitry Andric                                 MCSymbol *PostInstrSymbol,
319bdd1243dSDimitry Andric                                 MDNode *HeapAllocMarker, MDNode *PCSections,
320bdd1243dSDimitry Andric                                 uint32_t CFIType) {
321c14a5a88SDimitry Andric   bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
322c14a5a88SDimitry Andric   bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
323c14a5a88SDimitry Andric   bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
324bdd1243dSDimitry Andric   bool HasPCSections = PCSections != nullptr;
325bdd1243dSDimitry Andric   bool HasCFIType = CFIType != 0;
326bdd1243dSDimitry Andric   int NumPointers = MMOs.size() + HasPreInstrSymbol + HasPostInstrSymbol +
327bdd1243dSDimitry Andric                     HasHeapAllocMarker + HasPCSections + HasCFIType;
328c14a5a88SDimitry Andric 
329c14a5a88SDimitry Andric   // Drop all extra info if there is none.
330c14a5a88SDimitry Andric   if (NumPointers <= 0) {
331c14a5a88SDimitry Andric     Info.clear();
332c14a5a88SDimitry Andric     return;
333c14a5a88SDimitry Andric   }
334c14a5a88SDimitry Andric 
335c14a5a88SDimitry Andric   // If more than one pointer, then store out of line. Store heap alloc markers
336c14a5a88SDimitry Andric   // out of line because PointerSumType cannot hold more than 4 tag types with
337c14a5a88SDimitry Andric   // 32-bit pointers.
338c14a5a88SDimitry Andric   // FIXME: Maybe we should make the symbols in the extra info mutable?
339bdd1243dSDimitry Andric   else if (NumPointers > 1 || HasHeapAllocMarker || HasPCSections ||
340bdd1243dSDimitry Andric            HasCFIType) {
341bdd1243dSDimitry Andric     Info.set<EIIK_OutOfLine>(
342bdd1243dSDimitry Andric         MF.createMIExtraInfo(MMOs, PreInstrSymbol, PostInstrSymbol,
343bdd1243dSDimitry Andric                              HeapAllocMarker, PCSections, CFIType));
344c14a5a88SDimitry Andric     return;
345c14a5a88SDimitry Andric   }
346c14a5a88SDimitry Andric 
347c14a5a88SDimitry Andric   // Otherwise store the single pointer inline.
348c14a5a88SDimitry Andric   if (HasPreInstrSymbol)
349c14a5a88SDimitry Andric     Info.set<EIIK_PreInstrSymbol>(PreInstrSymbol);
350c14a5a88SDimitry Andric   else if (HasPostInstrSymbol)
351c14a5a88SDimitry Andric     Info.set<EIIK_PostInstrSymbol>(PostInstrSymbol);
352c14a5a88SDimitry Andric   else
353c14a5a88SDimitry Andric     Info.set<EIIK_MMO>(MMOs[0]);
354c14a5a88SDimitry Andric }
355c14a5a88SDimitry Andric 
dropMemRefs(MachineFunction & MF)3560b57cec5SDimitry Andric void MachineInstr::dropMemRefs(MachineFunction &MF) {
3570b57cec5SDimitry Andric   if (memoperands_empty())
3580b57cec5SDimitry Andric     return;
3590b57cec5SDimitry Andric 
360c14a5a88SDimitry Andric   setExtraInfo(MF, {}, getPreInstrSymbol(), getPostInstrSymbol(),
361bdd1243dSDimitry Andric                getHeapAllocMarker(), getPCSections(), getCFIType());
3620b57cec5SDimitry Andric }
3630b57cec5SDimitry Andric 
setMemRefs(MachineFunction & MF,ArrayRef<MachineMemOperand * > MMOs)3640b57cec5SDimitry Andric void MachineInstr::setMemRefs(MachineFunction &MF,
3650b57cec5SDimitry Andric                               ArrayRef<MachineMemOperand *> MMOs) {
3660b57cec5SDimitry Andric   if (MMOs.empty()) {
3670b57cec5SDimitry Andric     dropMemRefs(MF);
3680b57cec5SDimitry Andric     return;
3690b57cec5SDimitry Andric   }
3700b57cec5SDimitry Andric 
371c14a5a88SDimitry Andric   setExtraInfo(MF, MMOs, getPreInstrSymbol(), getPostInstrSymbol(),
372bdd1243dSDimitry Andric                getHeapAllocMarker(), getPCSections(), getCFIType());
3730b57cec5SDimitry Andric }
3740b57cec5SDimitry Andric 
addMemOperand(MachineFunction & MF,MachineMemOperand * MO)3750b57cec5SDimitry Andric void MachineInstr::addMemOperand(MachineFunction &MF,
3760b57cec5SDimitry Andric                                  MachineMemOperand *MO) {
3770b57cec5SDimitry Andric   SmallVector<MachineMemOperand *, 2> MMOs;
3780b57cec5SDimitry Andric   MMOs.append(memoperands_begin(), memoperands_end());
3790b57cec5SDimitry Andric   MMOs.push_back(MO);
3800b57cec5SDimitry Andric   setMemRefs(MF, MMOs);
3810b57cec5SDimitry Andric }
3820b57cec5SDimitry Andric 
cloneMemRefs(MachineFunction & MF,const MachineInstr & MI)3830b57cec5SDimitry Andric void MachineInstr::cloneMemRefs(MachineFunction &MF, const MachineInstr &MI) {
3840b57cec5SDimitry Andric   if (this == &MI)
3850b57cec5SDimitry Andric     // Nothing to do for a self-clone!
3860b57cec5SDimitry Andric     return;
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric   assert(&MF == MI.getMF() &&
3890b57cec5SDimitry Andric          "Invalid machine functions when cloning memory refrences!");
3900b57cec5SDimitry Andric   // See if we can just steal the extra info already allocated for the
3910b57cec5SDimitry Andric   // instruction. We can do this whenever the pre- and post-instruction symbols
3920b57cec5SDimitry Andric   // are the same (including null).
3930b57cec5SDimitry Andric   if (getPreInstrSymbol() == MI.getPreInstrSymbol() &&
394c14a5a88SDimitry Andric       getPostInstrSymbol() == MI.getPostInstrSymbol() &&
395bdd1243dSDimitry Andric       getHeapAllocMarker() == MI.getHeapAllocMarker() &&
396bdd1243dSDimitry Andric       getPCSections() == MI.getPCSections()) {
3970b57cec5SDimitry Andric     Info = MI.Info;
3980b57cec5SDimitry Andric     return;
3990b57cec5SDimitry Andric   }
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   // Otherwise, fall back on a copy-based clone.
4020b57cec5SDimitry Andric   setMemRefs(MF, MI.memoperands());
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric /// Check to see if the MMOs pointed to by the two MemRefs arrays are
4060b57cec5SDimitry Andric /// identical.
hasIdenticalMMOs(ArrayRef<MachineMemOperand * > LHS,ArrayRef<MachineMemOperand * > RHS)4070b57cec5SDimitry Andric static bool hasIdenticalMMOs(ArrayRef<MachineMemOperand *> LHS,
4080b57cec5SDimitry Andric                              ArrayRef<MachineMemOperand *> RHS) {
4090b57cec5SDimitry Andric   if (LHS.size() != RHS.size())
4100b57cec5SDimitry Andric     return false;
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric   auto LHSPointees = make_pointee_range(LHS);
4130b57cec5SDimitry Andric   auto RHSPointees = make_pointee_range(RHS);
4140b57cec5SDimitry Andric   return std::equal(LHSPointees.begin(), LHSPointees.end(),
4150b57cec5SDimitry Andric                     RHSPointees.begin());
4160b57cec5SDimitry Andric }
4170b57cec5SDimitry Andric 
cloneMergedMemRefs(MachineFunction & MF,ArrayRef<const MachineInstr * > MIs)4180b57cec5SDimitry Andric void MachineInstr::cloneMergedMemRefs(MachineFunction &MF,
4190b57cec5SDimitry Andric                                       ArrayRef<const MachineInstr *> MIs) {
4200b57cec5SDimitry Andric   // Try handling easy numbers of MIs with simpler mechanisms.
4210b57cec5SDimitry Andric   if (MIs.empty()) {
4220b57cec5SDimitry Andric     dropMemRefs(MF);
4230b57cec5SDimitry Andric     return;
4240b57cec5SDimitry Andric   }
4250b57cec5SDimitry Andric   if (MIs.size() == 1) {
4260b57cec5SDimitry Andric     cloneMemRefs(MF, *MIs[0]);
4270b57cec5SDimitry Andric     return;
4280b57cec5SDimitry Andric   }
4290b57cec5SDimitry Andric   // Because an empty memoperands list provides *no* information and must be
4300b57cec5SDimitry Andric   // handled conservatively (assuming the instruction can do anything), the only
4310b57cec5SDimitry Andric   // way to merge with it is to drop all other memoperands.
4320b57cec5SDimitry Andric   if (MIs[0]->memoperands_empty()) {
4330b57cec5SDimitry Andric     dropMemRefs(MF);
4340b57cec5SDimitry Andric     return;
4350b57cec5SDimitry Andric   }
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric   // Handle the general case.
4380b57cec5SDimitry Andric   SmallVector<MachineMemOperand *, 2> MergedMMOs;
4390b57cec5SDimitry Andric   // Start with the first instruction.
4400b57cec5SDimitry Andric   assert(&MF == MIs[0]->getMF() &&
4410b57cec5SDimitry Andric          "Invalid machine functions when cloning memory references!");
4420b57cec5SDimitry Andric   MergedMMOs.append(MIs[0]->memoperands_begin(), MIs[0]->memoperands_end());
4430b57cec5SDimitry Andric   // Now walk all the other instructions and accumulate any different MMOs.
4440b57cec5SDimitry Andric   for (const MachineInstr &MI : make_pointee_range(MIs.slice(1))) {
4450b57cec5SDimitry Andric     assert(&MF == MI.getMF() &&
4460b57cec5SDimitry Andric            "Invalid machine functions when cloning memory references!");
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric     // Skip MIs with identical operands to the first. This is a somewhat
4490b57cec5SDimitry Andric     // arbitrary hack but will catch common cases without being quadratic.
4500b57cec5SDimitry Andric     // TODO: We could fully implement merge semantics here if needed.
4510b57cec5SDimitry Andric     if (hasIdenticalMMOs(MIs[0]->memoperands(), MI.memoperands()))
4520b57cec5SDimitry Andric       continue;
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric     // Because an empty memoperands list provides *no* information and must be
4550b57cec5SDimitry Andric     // handled conservatively (assuming the instruction can do anything), the
4560b57cec5SDimitry Andric     // only way to merge with it is to drop all other memoperands.
4570b57cec5SDimitry Andric     if (MI.memoperands_empty()) {
4580b57cec5SDimitry Andric       dropMemRefs(MF);
4590b57cec5SDimitry Andric       return;
4600b57cec5SDimitry Andric     }
4610b57cec5SDimitry Andric 
4620b57cec5SDimitry Andric     // Otherwise accumulate these into our temporary buffer of the merged state.
4630b57cec5SDimitry Andric     MergedMMOs.append(MI.memoperands_begin(), MI.memoperands_end());
4640b57cec5SDimitry Andric   }
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric   setMemRefs(MF, MergedMMOs);
4670b57cec5SDimitry Andric }
4680b57cec5SDimitry Andric 
setPreInstrSymbol(MachineFunction & MF,MCSymbol * Symbol)4690b57cec5SDimitry Andric void MachineInstr::setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
470c14a5a88SDimitry Andric   // Do nothing if old and new symbols are the same.
471c14a5a88SDimitry Andric   if (Symbol == getPreInstrSymbol())
4720b57cec5SDimitry Andric     return;
473c14a5a88SDimitry Andric 
474c14a5a88SDimitry Andric   // If there was only one symbol and we're removing it, just clear info.
475c14a5a88SDimitry Andric   if (!Symbol && Info.is<EIIK_PreInstrSymbol>()) {
4760b57cec5SDimitry Andric     Info.clear();
4770b57cec5SDimitry Andric     return;
4780b57cec5SDimitry Andric   }
4790b57cec5SDimitry Andric 
480c14a5a88SDimitry Andric   setExtraInfo(MF, memoperands(), Symbol, getPostInstrSymbol(),
481bdd1243dSDimitry Andric                getHeapAllocMarker(), getPCSections(), getCFIType());
4820b57cec5SDimitry Andric }
4830b57cec5SDimitry Andric 
setPostInstrSymbol(MachineFunction & MF,MCSymbol * Symbol)4840b57cec5SDimitry Andric void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
485c14a5a88SDimitry Andric   // Do nothing if old and new symbols are the same.
486c14a5a88SDimitry Andric   if (Symbol == getPostInstrSymbol())
4870b57cec5SDimitry Andric     return;
488c14a5a88SDimitry Andric 
489c14a5a88SDimitry Andric   // If there was only one symbol and we're removing it, just clear info.
490c14a5a88SDimitry Andric   if (!Symbol && Info.is<EIIK_PostInstrSymbol>()) {
4910b57cec5SDimitry Andric     Info.clear();
4920b57cec5SDimitry Andric     return;
4930b57cec5SDimitry Andric   }
4940b57cec5SDimitry Andric 
495c14a5a88SDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), Symbol,
496bdd1243dSDimitry Andric                getHeapAllocMarker(), getPCSections(), getCFIType());
4970b57cec5SDimitry Andric }
4980b57cec5SDimitry Andric 
setHeapAllocMarker(MachineFunction & MF,MDNode * Marker)499c14a5a88SDimitry Andric void MachineInstr::setHeapAllocMarker(MachineFunction &MF, MDNode *Marker) {
500c14a5a88SDimitry Andric   // Do nothing if old and new symbols are the same.
501c14a5a88SDimitry Andric   if (Marker == getHeapAllocMarker())
5020b57cec5SDimitry Andric     return;
5030b57cec5SDimitry Andric 
504c14a5a88SDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(),
505bdd1243dSDimitry Andric                Marker, getPCSections(), getCFIType());
506bdd1243dSDimitry Andric }
507bdd1243dSDimitry Andric 
setPCSections(MachineFunction & MF,MDNode * PCSections)508bdd1243dSDimitry Andric void MachineInstr::setPCSections(MachineFunction &MF, MDNode *PCSections) {
509bdd1243dSDimitry Andric   // Do nothing if old and new symbols are the same.
510bdd1243dSDimitry Andric   if (PCSections == getPCSections())
511bdd1243dSDimitry Andric     return;
512bdd1243dSDimitry Andric 
513bdd1243dSDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(),
514bdd1243dSDimitry Andric                getHeapAllocMarker(), PCSections, getCFIType());
515bdd1243dSDimitry Andric }
516bdd1243dSDimitry Andric 
setCFIType(MachineFunction & MF,uint32_t Type)517bdd1243dSDimitry Andric void MachineInstr::setCFIType(MachineFunction &MF, uint32_t Type) {
518bdd1243dSDimitry Andric   // Do nothing if old and new types are the same.
519bdd1243dSDimitry Andric   if (Type == getCFIType())
520bdd1243dSDimitry Andric     return;
521bdd1243dSDimitry Andric 
522bdd1243dSDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(),
523bdd1243dSDimitry Andric                getHeapAllocMarker(), getPCSections(), Type);
5240b57cec5SDimitry Andric }
5250b57cec5SDimitry Andric 
cloneInstrSymbols(MachineFunction & MF,const MachineInstr & MI)5260b57cec5SDimitry Andric void MachineInstr::cloneInstrSymbols(MachineFunction &MF,
5270b57cec5SDimitry Andric                                      const MachineInstr &MI) {
5280b57cec5SDimitry Andric   if (this == &MI)
5290b57cec5SDimitry Andric     // Nothing to do for a self-clone!
5300b57cec5SDimitry Andric     return;
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric   assert(&MF == MI.getMF() &&
5330b57cec5SDimitry Andric          "Invalid machine functions when cloning instruction symbols!");
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric   setPreInstrSymbol(MF, MI.getPreInstrSymbol());
5360b57cec5SDimitry Andric   setPostInstrSymbol(MF, MI.getPostInstrSymbol());
537c14a5a88SDimitry Andric   setHeapAllocMarker(MF, MI.getHeapAllocMarker());
538bdd1243dSDimitry Andric   setPCSections(MF, MI.getPCSections());
5390b57cec5SDimitry Andric }
5400b57cec5SDimitry Andric 
mergeFlagsWith(const MachineInstr & Other) const541fe013be4SDimitry Andric uint32_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const {
5420b57cec5SDimitry Andric   // For now, the just return the union of the flags. If the flags get more
5430b57cec5SDimitry Andric   // complicated over time, we might need more logic here.
5440b57cec5SDimitry Andric   return getFlags() | Other.getFlags();
5450b57cec5SDimitry Andric }
5460b57cec5SDimitry Andric 
copyFlagsFromInstruction(const Instruction & I)547fe013be4SDimitry Andric uint32_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) {
548fe013be4SDimitry Andric   uint32_t MIFlags = 0;
5490b57cec5SDimitry Andric   // Copy the wrapping flags.
5500b57cec5SDimitry Andric   if (const OverflowingBinaryOperator *OB =
5510b57cec5SDimitry Andric           dyn_cast<OverflowingBinaryOperator>(&I)) {
5520b57cec5SDimitry Andric     if (OB->hasNoSignedWrap())
5530b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::NoSWrap;
5540b57cec5SDimitry Andric     if (OB->hasNoUnsignedWrap())
5550b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::NoUWrap;
5560b57cec5SDimitry Andric   }
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric   // Copy the exact flag.
5590b57cec5SDimitry Andric   if (const PossiblyExactOperator *PE = dyn_cast<PossiblyExactOperator>(&I))
5600b57cec5SDimitry Andric     if (PE->isExact())
5610b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::IsExact;
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric   // Copy the fast-math flags.
5640b57cec5SDimitry Andric   if (const FPMathOperator *FP = dyn_cast<FPMathOperator>(&I)) {
5650b57cec5SDimitry Andric     const FastMathFlags Flags = FP->getFastMathFlags();
5660b57cec5SDimitry Andric     if (Flags.noNaNs())
5670b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmNoNans;
5680b57cec5SDimitry Andric     if (Flags.noInfs())
5690b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmNoInfs;
5700b57cec5SDimitry Andric     if (Flags.noSignedZeros())
5710b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmNsz;
5720b57cec5SDimitry Andric     if (Flags.allowReciprocal())
5730b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmArcp;
5740b57cec5SDimitry Andric     if (Flags.allowContract())
5750b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmContract;
5760b57cec5SDimitry Andric     if (Flags.approxFunc())
5770b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmAfn;
5780b57cec5SDimitry Andric     if (Flags.allowReassoc())
5790b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmReassoc;
5800b57cec5SDimitry Andric   }
5810b57cec5SDimitry Andric 
582fe013be4SDimitry Andric   if (I.getMetadata(LLVMContext::MD_unpredictable))
583fe013be4SDimitry Andric     MIFlags |= MachineInstr::MIFlag::Unpredictable;
584fe013be4SDimitry Andric 
5850b57cec5SDimitry Andric   return MIFlags;
5860b57cec5SDimitry Andric }
5870b57cec5SDimitry Andric 
copyIRFlags(const Instruction & I)5880b57cec5SDimitry Andric void MachineInstr::copyIRFlags(const Instruction &I) {
5890b57cec5SDimitry Andric   Flags = copyFlagsFromInstruction(I);
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric 
hasPropertyInBundle(uint64_t Mask,QueryType Type) const5920b57cec5SDimitry Andric bool MachineInstr::hasPropertyInBundle(uint64_t Mask, QueryType Type) const {
5930b57cec5SDimitry Andric   assert(!isBundledWithPred() && "Must be called on bundle header");
5940b57cec5SDimitry Andric   for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) {
5950b57cec5SDimitry Andric     if (MII->getDesc().getFlags() & Mask) {
5960b57cec5SDimitry Andric       if (Type == AnyInBundle)
5970b57cec5SDimitry Andric         return true;
5980b57cec5SDimitry Andric     } else {
5990b57cec5SDimitry Andric       if (Type == AllInBundle && !MII->isBundle())
6000b57cec5SDimitry Andric         return false;
6010b57cec5SDimitry Andric     }
6020b57cec5SDimitry Andric     // This was the last instruction in the bundle.
6030b57cec5SDimitry Andric     if (!MII->isBundledWithSucc())
6040b57cec5SDimitry Andric       return Type == AllInBundle;
6050b57cec5SDimitry Andric   }
6060b57cec5SDimitry Andric }
6070b57cec5SDimitry Andric 
isIdenticalTo(const MachineInstr & Other,MICheckType Check) const6080b57cec5SDimitry Andric bool MachineInstr::isIdenticalTo(const MachineInstr &Other,
6090b57cec5SDimitry Andric                                  MICheckType Check) const {
6100b57cec5SDimitry Andric   // If opcodes or number of operands are not the same then the two
6110b57cec5SDimitry Andric   // instructions are obviously not identical.
6120b57cec5SDimitry Andric   if (Other.getOpcode() != getOpcode() ||
6130b57cec5SDimitry Andric       Other.getNumOperands() != getNumOperands())
6140b57cec5SDimitry Andric     return false;
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric   if (isBundle()) {
6170b57cec5SDimitry Andric     // We have passed the test above that both instructions have the same
6180b57cec5SDimitry Andric     // opcode, so we know that both instructions are bundles here. Let's compare
6190b57cec5SDimitry Andric     // MIs inside the bundle.
6200b57cec5SDimitry Andric     assert(Other.isBundle() && "Expected that both instructions are bundles.");
6210b57cec5SDimitry Andric     MachineBasicBlock::const_instr_iterator I1 = getIterator();
6220b57cec5SDimitry Andric     MachineBasicBlock::const_instr_iterator I2 = Other.getIterator();
6230b57cec5SDimitry Andric     // Loop until we analysed the last intruction inside at least one of the
6240b57cec5SDimitry Andric     // bundles.
6250b57cec5SDimitry Andric     while (I1->isBundledWithSucc() && I2->isBundledWithSucc()) {
6260b57cec5SDimitry Andric       ++I1;
6270b57cec5SDimitry Andric       ++I2;
6280b57cec5SDimitry Andric       if (!I1->isIdenticalTo(*I2, Check))
6290b57cec5SDimitry Andric         return false;
6300b57cec5SDimitry Andric     }
6310b57cec5SDimitry Andric     // If we've reached the end of just one of the two bundles, but not both,
6320b57cec5SDimitry Andric     // the instructions are not identical.
6330b57cec5SDimitry Andric     if (I1->isBundledWithSucc() || I2->isBundledWithSucc())
6340b57cec5SDimitry Andric       return false;
6350b57cec5SDimitry Andric   }
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric   // Check operands to make sure they match.
6380b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
6390b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
6400b57cec5SDimitry Andric     const MachineOperand &OMO = Other.getOperand(i);
6410b57cec5SDimitry Andric     if (!MO.isReg()) {
6420b57cec5SDimitry Andric       if (!MO.isIdenticalTo(OMO))
6430b57cec5SDimitry Andric         return false;
6440b57cec5SDimitry Andric       continue;
6450b57cec5SDimitry Andric     }
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric     // Clients may or may not want to ignore defs when testing for equality.
6480b57cec5SDimitry Andric     // For example, machine CSE pass only cares about finding common
6490b57cec5SDimitry Andric     // subexpressions, so it's safe to ignore virtual register defs.
6500b57cec5SDimitry Andric     if (MO.isDef()) {
6510b57cec5SDimitry Andric       if (Check == IgnoreDefs)
6520b57cec5SDimitry Andric         continue;
6530b57cec5SDimitry Andric       else if (Check == IgnoreVRegDefs) {
654bdd1243dSDimitry Andric         if (!MO.getReg().isVirtual() || !OMO.getReg().isVirtual())
6550b57cec5SDimitry Andric           if (!MO.isIdenticalTo(OMO))
6560b57cec5SDimitry Andric             return false;
6570b57cec5SDimitry Andric       } else {
6580b57cec5SDimitry Andric         if (!MO.isIdenticalTo(OMO))
6590b57cec5SDimitry Andric           return false;
6600b57cec5SDimitry Andric         if (Check == CheckKillDead && MO.isDead() != OMO.isDead())
6610b57cec5SDimitry Andric           return false;
6620b57cec5SDimitry Andric       }
6630b57cec5SDimitry Andric     } else {
6640b57cec5SDimitry Andric       if (!MO.isIdenticalTo(OMO))
6650b57cec5SDimitry Andric         return false;
6660b57cec5SDimitry Andric       if (Check == CheckKillDead && MO.isKill() != OMO.isKill())
6670b57cec5SDimitry Andric         return false;
6680b57cec5SDimitry Andric     }
6690b57cec5SDimitry Andric   }
6700b57cec5SDimitry Andric   // If DebugLoc does not match then two debug instructions are not identical.
6710b57cec5SDimitry Andric   if (isDebugInstr())
6720b57cec5SDimitry Andric     if (getDebugLoc() && Other.getDebugLoc() &&
6730b57cec5SDimitry Andric         getDebugLoc() != Other.getDebugLoc())
6740b57cec5SDimitry Andric       return false;
675bdd1243dSDimitry Andric   // If pre- or post-instruction symbols do not match then the two instructions
676bdd1243dSDimitry Andric   // are not identical.
677bdd1243dSDimitry Andric   if (getPreInstrSymbol() != Other.getPreInstrSymbol() ||
678bdd1243dSDimitry Andric       getPostInstrSymbol() != Other.getPostInstrSymbol())
679bdd1243dSDimitry Andric     return false;
680bdd1243dSDimitry Andric   // Call instructions with different CFI types are not identical.
681bdd1243dSDimitry Andric   if (isCall() && getCFIType() != Other.getCFIType())
682bdd1243dSDimitry Andric     return false;
683bdd1243dSDimitry Andric 
684bdd1243dSDimitry Andric   return true;
685bdd1243dSDimitry Andric }
686bdd1243dSDimitry Andric 
isEquivalentDbgInstr(const MachineInstr & Other) const687bdd1243dSDimitry Andric bool MachineInstr::isEquivalentDbgInstr(const MachineInstr &Other) const {
688bdd1243dSDimitry Andric   if (!isDebugValueLike() || !Other.isDebugValueLike())
689bdd1243dSDimitry Andric     return false;
690bdd1243dSDimitry Andric   if (getDebugLoc() != Other.getDebugLoc())
691bdd1243dSDimitry Andric     return false;
692bdd1243dSDimitry Andric   if (getDebugVariable() != Other.getDebugVariable())
693bdd1243dSDimitry Andric     return false;
694bdd1243dSDimitry Andric   if (getNumDebugOperands() != Other.getNumDebugOperands())
695bdd1243dSDimitry Andric     return false;
696bdd1243dSDimitry Andric   for (unsigned OpIdx = 0; OpIdx < getNumDebugOperands(); ++OpIdx)
697bdd1243dSDimitry Andric     if (!getDebugOperand(OpIdx).isIdenticalTo(Other.getDebugOperand(OpIdx)))
698bdd1243dSDimitry Andric       return false;
699bdd1243dSDimitry Andric   if (!DIExpression::isEqualExpression(
700bdd1243dSDimitry Andric           getDebugExpression(), isIndirectDebugValue(),
701bdd1243dSDimitry Andric           Other.getDebugExpression(), Other.isIndirectDebugValue()))
702bdd1243dSDimitry Andric     return false;
7030b57cec5SDimitry Andric   return true;
7040b57cec5SDimitry Andric }
7050b57cec5SDimitry Andric 
getMF() const7060b57cec5SDimitry Andric const MachineFunction *MachineInstr::getMF() const {
7070b57cec5SDimitry Andric   return getParent()->getParent();
7080b57cec5SDimitry Andric }
7090b57cec5SDimitry Andric 
removeFromParent()7100b57cec5SDimitry Andric MachineInstr *MachineInstr::removeFromParent() {
7110b57cec5SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
7120b57cec5SDimitry Andric   return getParent()->remove(this);
7130b57cec5SDimitry Andric }
7140b57cec5SDimitry Andric 
removeFromBundle()7150b57cec5SDimitry Andric MachineInstr *MachineInstr::removeFromBundle() {
7160b57cec5SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
7170b57cec5SDimitry Andric   return getParent()->remove_instr(this);
7180b57cec5SDimitry Andric }
7190b57cec5SDimitry Andric 
eraseFromParent()7200b57cec5SDimitry Andric void MachineInstr::eraseFromParent() {
7210b57cec5SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
7220b57cec5SDimitry Andric   getParent()->erase(this);
7230b57cec5SDimitry Andric }
7240b57cec5SDimitry Andric 
eraseFromBundle()7250b57cec5SDimitry Andric void MachineInstr::eraseFromBundle() {
7260b57cec5SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
7270b57cec5SDimitry Andric   getParent()->erase_instr(this);
7280b57cec5SDimitry Andric }
7290b57cec5SDimitry Andric 
isCandidateForCallSiteEntry(QueryType Type) const7305ffd83dbSDimitry Andric bool MachineInstr::isCandidateForCallSiteEntry(QueryType Type) const {
7315ffd83dbSDimitry Andric   if (!isCall(Type))
7325ffd83dbSDimitry Andric     return false;
7335ffd83dbSDimitry Andric   switch (getOpcode()) {
7345ffd83dbSDimitry Andric   case TargetOpcode::PATCHPOINT:
7355ffd83dbSDimitry Andric   case TargetOpcode::STACKMAP:
7365ffd83dbSDimitry Andric   case TargetOpcode::STATEPOINT:
737e8d8bef9SDimitry Andric   case TargetOpcode::FENTRY_CALL:
7385ffd83dbSDimitry Andric     return false;
7395ffd83dbSDimitry Andric   }
7405ffd83dbSDimitry Andric   return true;
7415ffd83dbSDimitry Andric }
7425ffd83dbSDimitry Andric 
shouldUpdateCallSiteInfo() const7435ffd83dbSDimitry Andric bool MachineInstr::shouldUpdateCallSiteInfo() const {
7445ffd83dbSDimitry Andric   if (isBundle())
7455ffd83dbSDimitry Andric     return isCandidateForCallSiteEntry(MachineInstr::AnyInBundle);
7465ffd83dbSDimitry Andric   return isCandidateForCallSiteEntry();
7475ffd83dbSDimitry Andric }
7485ffd83dbSDimitry Andric 
getNumExplicitOperands() const7490b57cec5SDimitry Andric unsigned MachineInstr::getNumExplicitOperands() const {
7500b57cec5SDimitry Andric   unsigned NumOperands = MCID->getNumOperands();
7510b57cec5SDimitry Andric   if (!MCID->isVariadic())
7520b57cec5SDimitry Andric     return NumOperands;
7530b57cec5SDimitry Andric 
7540b57cec5SDimitry Andric   for (unsigned I = NumOperands, E = getNumOperands(); I != E; ++I) {
7550b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(I);
7560b57cec5SDimitry Andric     // The operands must always be in the following order:
7570b57cec5SDimitry Andric     // - explicit reg defs,
7580b57cec5SDimitry Andric     // - other explicit operands (reg uses, immediates, etc.),
7590b57cec5SDimitry Andric     // - implicit reg defs
7600b57cec5SDimitry Andric     // - implicit reg uses
7610b57cec5SDimitry Andric     if (MO.isReg() && MO.isImplicit())
7620b57cec5SDimitry Andric       break;
7630b57cec5SDimitry Andric     ++NumOperands;
7640b57cec5SDimitry Andric   }
7650b57cec5SDimitry Andric   return NumOperands;
7660b57cec5SDimitry Andric }
7670b57cec5SDimitry Andric 
getNumExplicitDefs() const7680b57cec5SDimitry Andric unsigned MachineInstr::getNumExplicitDefs() const {
7690b57cec5SDimitry Andric   unsigned NumDefs = MCID->getNumDefs();
7700b57cec5SDimitry Andric   if (!MCID->isVariadic())
7710b57cec5SDimitry Andric     return NumDefs;
7720b57cec5SDimitry Andric 
7730b57cec5SDimitry Andric   for (unsigned I = NumDefs, E = getNumOperands(); I != E; ++I) {
7740b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(I);
7750b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
7760b57cec5SDimitry Andric       break;
7770b57cec5SDimitry Andric     ++NumDefs;
7780b57cec5SDimitry Andric   }
7790b57cec5SDimitry Andric   return NumDefs;
7800b57cec5SDimitry Andric }
7810b57cec5SDimitry Andric 
bundleWithPred()7820b57cec5SDimitry Andric void MachineInstr::bundleWithPred() {
7830b57cec5SDimitry Andric   assert(!isBundledWithPred() && "MI is already bundled with its predecessor");
7840b57cec5SDimitry Andric   setFlag(BundledPred);
7850b57cec5SDimitry Andric   MachineBasicBlock::instr_iterator Pred = getIterator();
7860b57cec5SDimitry Andric   --Pred;
7870b57cec5SDimitry Andric   assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags");
7880b57cec5SDimitry Andric   Pred->setFlag(BundledSucc);
7890b57cec5SDimitry Andric }
7900b57cec5SDimitry Andric 
bundleWithSucc()7910b57cec5SDimitry Andric void MachineInstr::bundleWithSucc() {
7920b57cec5SDimitry Andric   assert(!isBundledWithSucc() && "MI is already bundled with its successor");
7930b57cec5SDimitry Andric   setFlag(BundledSucc);
7940b57cec5SDimitry Andric   MachineBasicBlock::instr_iterator Succ = getIterator();
7950b57cec5SDimitry Andric   ++Succ;
7960b57cec5SDimitry Andric   assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags");
7970b57cec5SDimitry Andric   Succ->setFlag(BundledPred);
7980b57cec5SDimitry Andric }
7990b57cec5SDimitry Andric 
unbundleFromPred()8000b57cec5SDimitry Andric void MachineInstr::unbundleFromPred() {
8010b57cec5SDimitry Andric   assert(isBundledWithPred() && "MI isn't bundled with its predecessor");
8020b57cec5SDimitry Andric   clearFlag(BundledPred);
8030b57cec5SDimitry Andric   MachineBasicBlock::instr_iterator Pred = getIterator();
8040b57cec5SDimitry Andric   --Pred;
8050b57cec5SDimitry Andric   assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags");
8060b57cec5SDimitry Andric   Pred->clearFlag(BundledSucc);
8070b57cec5SDimitry Andric }
8080b57cec5SDimitry Andric 
unbundleFromSucc()8090b57cec5SDimitry Andric void MachineInstr::unbundleFromSucc() {
8100b57cec5SDimitry Andric   assert(isBundledWithSucc() && "MI isn't bundled with its successor");
8110b57cec5SDimitry Andric   clearFlag(BundledSucc);
8120b57cec5SDimitry Andric   MachineBasicBlock::instr_iterator Succ = getIterator();
8130b57cec5SDimitry Andric   ++Succ;
8140b57cec5SDimitry Andric   assert(Succ->isBundledWithPred() && "Inconsistent bundle flags");
8150b57cec5SDimitry Andric   Succ->clearFlag(BundledPred);
8160b57cec5SDimitry Andric }
8170b57cec5SDimitry Andric 
isStackAligningInlineAsm() const8180b57cec5SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const {
8190b57cec5SDimitry Andric   if (isInlineAsm()) {
8200b57cec5SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
8210b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
8220b57cec5SDimitry Andric       return true;
8230b57cec5SDimitry Andric   }
8240b57cec5SDimitry Andric   return false;
8250b57cec5SDimitry Andric }
8260b57cec5SDimitry Andric 
getInlineAsmDialect() const8270b57cec5SDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const {
8280b57cec5SDimitry Andric   assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!");
8290b57cec5SDimitry Andric   unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
8300b57cec5SDimitry Andric   return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0);
8310b57cec5SDimitry Andric }
8320b57cec5SDimitry Andric 
findInlineAsmFlagIdx(unsigned OpIdx,unsigned * GroupNo) const8330b57cec5SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx,
8340b57cec5SDimitry Andric                                        unsigned *GroupNo) const {
8350b57cec5SDimitry Andric   assert(isInlineAsm() && "Expected an inline asm instruction");
8360b57cec5SDimitry Andric   assert(OpIdx < getNumOperands() && "OpIdx out of range");
8370b57cec5SDimitry Andric 
8380b57cec5SDimitry Andric   // Ignore queries about the initial operands.
8390b57cec5SDimitry Andric   if (OpIdx < InlineAsm::MIOp_FirstOperand)
8400b57cec5SDimitry Andric     return -1;
8410b57cec5SDimitry Andric 
8420b57cec5SDimitry Andric   unsigned Group = 0;
8430b57cec5SDimitry Andric   unsigned NumOps;
8440b57cec5SDimitry Andric   for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e;
8450b57cec5SDimitry Andric        i += NumOps) {
8460b57cec5SDimitry Andric     const MachineOperand &FlagMO = getOperand(i);
8470b57cec5SDimitry Andric     // If we reach the implicit register operands, stop looking.
8480b57cec5SDimitry Andric     if (!FlagMO.isImm())
8490b57cec5SDimitry Andric       return -1;
850*c9157d92SDimitry Andric     const InlineAsm::Flag F(FlagMO.getImm());
851*c9157d92SDimitry Andric     NumOps = 1 + F.getNumOperandRegisters();
8520b57cec5SDimitry Andric     if (i + NumOps > OpIdx) {
8530b57cec5SDimitry Andric       if (GroupNo)
8540b57cec5SDimitry Andric         *GroupNo = Group;
8550b57cec5SDimitry Andric       return i;
8560b57cec5SDimitry Andric     }
8570b57cec5SDimitry Andric     ++Group;
8580b57cec5SDimitry Andric   }
8590b57cec5SDimitry Andric   return -1;
8600b57cec5SDimitry Andric }
8610b57cec5SDimitry Andric 
getDebugLabel() const8620b57cec5SDimitry Andric const DILabel *MachineInstr::getDebugLabel() const {
8630b57cec5SDimitry Andric   assert(isDebugLabel() && "not a DBG_LABEL");
8640b57cec5SDimitry Andric   return cast<DILabel>(getOperand(0).getMetadata());
8650b57cec5SDimitry Andric }
8660b57cec5SDimitry Andric 
getDebugVariableOp() const8675ffd83dbSDimitry Andric const MachineOperand &MachineInstr::getDebugVariableOp() const {
868bdd1243dSDimitry Andric   assert((isDebugValueLike()) && "not a DBG_VALUE*");
869bdd1243dSDimitry Andric   unsigned VariableOp = isNonListDebugValue() ? 2 : 0;
870fe6060f1SDimitry Andric   return getOperand(VariableOp);
8715ffd83dbSDimitry Andric }
8725ffd83dbSDimitry Andric 
getDebugVariableOp()8735ffd83dbSDimitry Andric MachineOperand &MachineInstr::getDebugVariableOp() {
874bdd1243dSDimitry Andric   assert((isDebugValueLike()) && "not a DBG_VALUE*");
875bdd1243dSDimitry Andric   unsigned VariableOp = isNonListDebugValue() ? 2 : 0;
876fe6060f1SDimitry Andric   return getOperand(VariableOp);
8775ffd83dbSDimitry Andric }
8785ffd83dbSDimitry Andric 
getDebugVariable() const8790b57cec5SDimitry Andric const DILocalVariable *MachineInstr::getDebugVariable() const {
880fe6060f1SDimitry Andric   return cast<DILocalVariable>(getDebugVariableOp().getMetadata());
881fe6060f1SDimitry Andric }
882fe6060f1SDimitry Andric 
getDebugExpressionOp() const883fe6060f1SDimitry Andric const MachineOperand &MachineInstr::getDebugExpressionOp() const {
884bdd1243dSDimitry Andric   assert((isDebugValueLike()) && "not a DBG_VALUE*");
885bdd1243dSDimitry Andric   unsigned ExpressionOp = isNonListDebugValue() ? 3 : 1;
886fe6060f1SDimitry Andric   return getOperand(ExpressionOp);
8870b57cec5SDimitry Andric }
8880b57cec5SDimitry Andric 
getDebugExpressionOp()8895ffd83dbSDimitry Andric MachineOperand &MachineInstr::getDebugExpressionOp() {
890bdd1243dSDimitry Andric   assert((isDebugValueLike()) && "not a DBG_VALUE*");
891bdd1243dSDimitry Andric   unsigned ExpressionOp = isNonListDebugValue() ? 3 : 1;
892fe6060f1SDimitry Andric   return getOperand(ExpressionOp);
8935ffd83dbSDimitry Andric }
8945ffd83dbSDimitry Andric 
getDebugExpression() const8950b57cec5SDimitry Andric const DIExpression *MachineInstr::getDebugExpression() const {
896fe6060f1SDimitry Andric   return cast<DIExpression>(getDebugExpressionOp().getMetadata());
8970b57cec5SDimitry Andric }
8980b57cec5SDimitry Andric 
isDebugEntryValue() const8998bcb0991SDimitry Andric bool MachineInstr::isDebugEntryValue() const {
9008bcb0991SDimitry Andric   return isDebugValue() && getDebugExpression()->isEntryValue();
9018bcb0991SDimitry Andric }
9028bcb0991SDimitry Andric 
9030b57cec5SDimitry Andric const TargetRegisterClass*
getRegClassConstraint(unsigned OpIdx,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const9040b57cec5SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx,
9050b57cec5SDimitry Andric                                     const TargetInstrInfo *TII,
9060b57cec5SDimitry Andric                                     const TargetRegisterInfo *TRI) const {
9070b57cec5SDimitry Andric   assert(getParent() && "Can't have an MBB reference here!");
9080b57cec5SDimitry Andric   assert(getMF() && "Can't have an MF reference here!");
9090b57cec5SDimitry Andric   const MachineFunction &MF = *getMF();
9100b57cec5SDimitry Andric 
9110b57cec5SDimitry Andric   // Most opcodes have fixed constraints in their MCInstrDesc.
9120b57cec5SDimitry Andric   if (!isInlineAsm())
9130b57cec5SDimitry Andric     return TII->getRegClass(getDesc(), OpIdx, TRI, MF);
9140b57cec5SDimitry Andric 
9150b57cec5SDimitry Andric   if (!getOperand(OpIdx).isReg())
9160b57cec5SDimitry Andric     return nullptr;
9170b57cec5SDimitry Andric 
9180b57cec5SDimitry Andric   // For tied uses on inline asm, get the constraint from the def.
9190b57cec5SDimitry Andric   unsigned DefIdx;
9200b57cec5SDimitry Andric   if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx))
9210b57cec5SDimitry Andric     OpIdx = DefIdx;
9220b57cec5SDimitry Andric 
9230b57cec5SDimitry Andric   // Inline asm stores register class constraints in the flag word.
9240b57cec5SDimitry Andric   int FlagIdx = findInlineAsmFlagIdx(OpIdx);
9250b57cec5SDimitry Andric   if (FlagIdx < 0)
9260b57cec5SDimitry Andric     return nullptr;
9270b57cec5SDimitry Andric 
928*c9157d92SDimitry Andric   const InlineAsm::Flag F(getOperand(FlagIdx).getImm());
9290b57cec5SDimitry Andric   unsigned RCID;
930*c9157d92SDimitry Andric   if ((F.isRegUseKind() || F.isRegDefKind() || F.isRegDefEarlyClobberKind()) &&
931*c9157d92SDimitry Andric       F.hasRegClassConstraint(RCID))
9320b57cec5SDimitry Andric     return TRI->getRegClass(RCID);
9330b57cec5SDimitry Andric 
9340b57cec5SDimitry Andric   // Assume that all registers in a memory operand are pointers.
935*c9157d92SDimitry Andric   if (F.isMemKind())
9360b57cec5SDimitry Andric     return TRI->getPointerRegClass(MF);
9370b57cec5SDimitry Andric 
9380b57cec5SDimitry Andric   return nullptr;
9390b57cec5SDimitry Andric }
9400b57cec5SDimitry Andric 
getRegClassConstraintEffectForVReg(Register Reg,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI,bool ExploreBundle) const9410b57cec5SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg(
9428bcb0991SDimitry Andric     Register Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII,
9430b57cec5SDimitry Andric     const TargetRegisterInfo *TRI, bool ExploreBundle) const {
9440b57cec5SDimitry Andric   // Check every operands inside the bundle if we have
9450b57cec5SDimitry Andric   // been asked to.
9460b57cec5SDimitry Andric   if (ExploreBundle)
9470b57cec5SDimitry Andric     for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC;
9480b57cec5SDimitry Andric          ++OpndIt)
9490b57cec5SDimitry Andric       CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl(
9500b57cec5SDimitry Andric           OpndIt.getOperandNo(), Reg, CurRC, TII, TRI);
9510b57cec5SDimitry Andric   else
9520b57cec5SDimitry Andric     // Otherwise, just check the current operands.
9530b57cec5SDimitry Andric     for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i)
9540b57cec5SDimitry Andric       CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI);
9550b57cec5SDimitry Andric   return CurRC;
9560b57cec5SDimitry Andric }
9570b57cec5SDimitry Andric 
getRegClassConstraintEffectForVRegImpl(unsigned OpIdx,Register Reg,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const9580b57cec5SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl(
9598bcb0991SDimitry Andric     unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
9600b57cec5SDimitry Andric     const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
9610b57cec5SDimitry Andric   assert(CurRC && "Invalid initial register class");
9620b57cec5SDimitry Andric   // Check if Reg is constrained by some of its use/def from MI.
9630b57cec5SDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
9640b57cec5SDimitry Andric   if (!MO.isReg() || MO.getReg() != Reg)
9650b57cec5SDimitry Andric     return CurRC;
9660b57cec5SDimitry Andric   // If yes, accumulate the constraints through the operand.
9670b57cec5SDimitry Andric   return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI);
9680b57cec5SDimitry Andric }
9690b57cec5SDimitry Andric 
getRegClassConstraintEffect(unsigned OpIdx,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const9700b57cec5SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect(
9710b57cec5SDimitry Andric     unsigned OpIdx, const TargetRegisterClass *CurRC,
9720b57cec5SDimitry Andric     const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
9730b57cec5SDimitry Andric   const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI);
9740b57cec5SDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
9750b57cec5SDimitry Andric   assert(MO.isReg() &&
9760b57cec5SDimitry Andric          "Cannot get register constraints for non-register operand");
9770b57cec5SDimitry Andric   assert(CurRC && "Invalid initial register class");
9780b57cec5SDimitry Andric   if (unsigned SubIdx = MO.getSubReg()) {
9790b57cec5SDimitry Andric     if (OpRC)
9800b57cec5SDimitry Andric       CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx);
9810b57cec5SDimitry Andric     else
9820b57cec5SDimitry Andric       CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx);
9830b57cec5SDimitry Andric   } else if (OpRC)
9840b57cec5SDimitry Andric     CurRC = TRI->getCommonSubClass(CurRC, OpRC);
9850b57cec5SDimitry Andric   return CurRC;
9860b57cec5SDimitry Andric }
9870b57cec5SDimitry Andric 
9880b57cec5SDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the
9890b57cec5SDimitry Andric /// header instruction.
getBundleSize() const9900b57cec5SDimitry Andric unsigned MachineInstr::getBundleSize() const {
9910b57cec5SDimitry Andric   MachineBasicBlock::const_instr_iterator I = getIterator();
9920b57cec5SDimitry Andric   unsigned Size = 0;
9930b57cec5SDimitry Andric   while (I->isBundledWithSucc()) {
9940b57cec5SDimitry Andric     ++Size;
9950b57cec5SDimitry Andric     ++I;
9960b57cec5SDimitry Andric   }
9970b57cec5SDimitry Andric   return Size;
9980b57cec5SDimitry Andric }
9990b57cec5SDimitry Andric 
10000b57cec5SDimitry Andric /// Returns true if the MachineInstr has an implicit-use operand of exactly
10010b57cec5SDimitry Andric /// the given register (not considering sub/super-registers).
hasRegisterImplicitUseOperand(Register Reg) const10028bcb0991SDimitry Andric bool MachineInstr::hasRegisterImplicitUseOperand(Register Reg) const {
10030b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
10040b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
10050b57cec5SDimitry Andric     if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == Reg)
10060b57cec5SDimitry Andric       return true;
10070b57cec5SDimitry Andric   }
10080b57cec5SDimitry Andric   return false;
10090b57cec5SDimitry Andric }
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of
10120b57cec5SDimitry Andric /// the specific register or -1 if it is not found. It further tightens
10130b57cec5SDimitry Andric /// the search criteria to a use that kills the register if isKill is true.
findRegisterUseOperandIdx(Register Reg,bool isKill,const TargetRegisterInfo * TRI) const10140b57cec5SDimitry Andric int MachineInstr::findRegisterUseOperandIdx(
10158bcb0991SDimitry Andric     Register Reg, bool isKill, const TargetRegisterInfo *TRI) const {
10160b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
10170b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
10180b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isUse())
10190b57cec5SDimitry Andric       continue;
10208bcb0991SDimitry Andric     Register MOReg = MO.getReg();
10210b57cec5SDimitry Andric     if (!MOReg)
10220b57cec5SDimitry Andric       continue;
10230b57cec5SDimitry Andric     if (MOReg == Reg || (TRI && Reg && MOReg && TRI->regsOverlap(MOReg, Reg)))
10240b57cec5SDimitry Andric       if (!isKill || MO.isKill())
10250b57cec5SDimitry Andric         return i;
10260b57cec5SDimitry Andric   }
10270b57cec5SDimitry Andric   return -1;
10280b57cec5SDimitry Andric }
10290b57cec5SDimitry Andric 
10300b57cec5SDimitry Andric /// readsWritesVirtualRegister - Return a pair of bools (reads, writes)
10310b57cec5SDimitry Andric /// indicating if this instruction reads or writes Reg. This also considers
10320b57cec5SDimitry Andric /// partial defines.
10330b57cec5SDimitry Andric std::pair<bool,bool>
readsWritesVirtualRegister(Register Reg,SmallVectorImpl<unsigned> * Ops) const10348bcb0991SDimitry Andric MachineInstr::readsWritesVirtualRegister(Register Reg,
10350b57cec5SDimitry Andric                                          SmallVectorImpl<unsigned> *Ops) const {
10360b57cec5SDimitry Andric   bool PartDef = false; // Partial redefine.
10370b57cec5SDimitry Andric   bool FullDef = false; // Full define.
10380b57cec5SDimitry Andric   bool Use = false;
10390b57cec5SDimitry Andric 
10400b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
10410b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
10420b57cec5SDimitry Andric     if (!MO.isReg() || MO.getReg() != Reg)
10430b57cec5SDimitry Andric       continue;
10440b57cec5SDimitry Andric     if (Ops)
10450b57cec5SDimitry Andric       Ops->push_back(i);
10460b57cec5SDimitry Andric     if (MO.isUse())
10470b57cec5SDimitry Andric       Use |= !MO.isUndef();
10480b57cec5SDimitry Andric     else if (MO.getSubReg() && !MO.isUndef())
10490b57cec5SDimitry Andric       // A partial def undef doesn't count as reading the register.
10500b57cec5SDimitry Andric       PartDef = true;
10510b57cec5SDimitry Andric     else
10520b57cec5SDimitry Andric       FullDef = true;
10530b57cec5SDimitry Andric   }
10540b57cec5SDimitry Andric   // A partial redefine uses Reg unless there is also a full define.
10550b57cec5SDimitry Andric   return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef);
10560b57cec5SDimitry Andric }
10570b57cec5SDimitry Andric 
10580b57cec5SDimitry Andric /// findRegisterDefOperandIdx() - Returns the operand index that is a def of
10590b57cec5SDimitry Andric /// the specified register or -1 if it is not found. If isDead is true, defs
10600b57cec5SDimitry Andric /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it
10610b57cec5SDimitry Andric /// also checks if there is a def of a super-register.
10620b57cec5SDimitry Andric int
findRegisterDefOperandIdx(Register Reg,bool isDead,bool Overlap,const TargetRegisterInfo * TRI) const10638bcb0991SDimitry Andric MachineInstr::findRegisterDefOperandIdx(Register Reg, bool isDead, bool Overlap,
10640b57cec5SDimitry Andric                                         const TargetRegisterInfo *TRI) const {
1065bdd1243dSDimitry Andric   bool isPhys = Reg.isPhysical();
10660b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
10670b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
10680b57cec5SDimitry Andric     // Accept regmask operands when Overlap is set.
10690b57cec5SDimitry Andric     // Ignore them when looking for a specific def operand (Overlap == false).
10700b57cec5SDimitry Andric     if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg))
10710b57cec5SDimitry Andric       return i;
10720b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef())
10730b57cec5SDimitry Andric       continue;
10748bcb0991SDimitry Andric     Register MOReg = MO.getReg();
10750b57cec5SDimitry Andric     bool Found = (MOReg == Reg);
1076bdd1243dSDimitry Andric     if (!Found && TRI && isPhys && MOReg.isPhysical()) {
10770b57cec5SDimitry Andric       if (Overlap)
10780b57cec5SDimitry Andric         Found = TRI->regsOverlap(MOReg, Reg);
10790b57cec5SDimitry Andric       else
10800b57cec5SDimitry Andric         Found = TRI->isSubRegister(MOReg, Reg);
10810b57cec5SDimitry Andric     }
10820b57cec5SDimitry Andric     if (Found && (!isDead || MO.isDead()))
10830b57cec5SDimitry Andric       return i;
10840b57cec5SDimitry Andric   }
10850b57cec5SDimitry Andric   return -1;
10860b57cec5SDimitry Andric }
10870b57cec5SDimitry Andric 
10880b57cec5SDimitry Andric /// findFirstPredOperandIdx() - Find the index of the first operand in the
10890b57cec5SDimitry Andric /// operand list that is used to represent the predicate. It returns -1 if
10900b57cec5SDimitry Andric /// none is found.
findFirstPredOperandIdx() const10910b57cec5SDimitry Andric int MachineInstr::findFirstPredOperandIdx() const {
10920b57cec5SDimitry Andric   // Don't call MCID.findFirstPredOperandIdx() because this variant
10930b57cec5SDimitry Andric   // is sometimes called on an instruction that's not yet complete, and
10940b57cec5SDimitry Andric   // so the number of operands is less than the MCID indicates. In
10950b57cec5SDimitry Andric   // particular, the PTX target does this.
10960b57cec5SDimitry Andric   const MCInstrDesc &MCID = getDesc();
10970b57cec5SDimitry Andric   if (MCID.isPredicable()) {
10980b57cec5SDimitry Andric     for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
1099bdd1243dSDimitry Andric       if (MCID.operands()[i].isPredicate())
11000b57cec5SDimitry Andric         return i;
11010b57cec5SDimitry Andric   }
11020b57cec5SDimitry Andric 
11030b57cec5SDimitry Andric   return -1;
11040b57cec5SDimitry Andric }
11050b57cec5SDimitry Andric 
11060b57cec5SDimitry Andric // MachineOperand::TiedTo is 4 bits wide.
11070b57cec5SDimitry Andric const unsigned TiedMax = 15;
11080b57cec5SDimitry Andric 
11090b57cec5SDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other.
11100b57cec5SDimitry Andric ///
11110b57cec5SDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo
11120b57cec5SDimitry Andric /// field. TiedTo can have these values:
11130b57cec5SDimitry Andric ///
11140b57cec5SDimitry Andric /// 0:              Operand is not tied to anything.
11150b57cec5SDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1).
11160b57cec5SDimitry Andric /// TiedMax:        Tied to an operand >= TiedMax-1.
11170b57cec5SDimitry Andric ///
11180b57cec5SDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal
11190b57cec5SDimitry Andric /// instruction. INLINEASM instructions allow more tied defs.
11200b57cec5SDimitry Andric ///
tieOperands(unsigned DefIdx,unsigned UseIdx)11210b57cec5SDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) {
11220b57cec5SDimitry Andric   MachineOperand &DefMO = getOperand(DefIdx);
11230b57cec5SDimitry Andric   MachineOperand &UseMO = getOperand(UseIdx);
11240b57cec5SDimitry Andric   assert(DefMO.isDef() && "DefIdx must be a def operand");
11250b57cec5SDimitry Andric   assert(UseMO.isUse() && "UseIdx must be a use operand");
11260b57cec5SDimitry Andric   assert(!DefMO.isTied() && "Def is already tied to another use");
11270b57cec5SDimitry Andric   assert(!UseMO.isTied() && "Use is already tied to another def");
11280b57cec5SDimitry Andric 
11290b57cec5SDimitry Andric   if (DefIdx < TiedMax)
11300b57cec5SDimitry Andric     UseMO.TiedTo = DefIdx + 1;
11310b57cec5SDimitry Andric   else {
1132e8d8bef9SDimitry Andric     // Inline asm can use the group descriptors to find tied operands,
1133e8d8bef9SDimitry Andric     // statepoint tied operands are trivial to match (1-1 reg def with reg use),
1134e8d8bef9SDimitry Andric     // but on normal instruction, the tied def must be within the first TiedMax
11350b57cec5SDimitry Andric     // operands.
1136e8d8bef9SDimitry Andric     assert((isInlineAsm() || getOpcode() == TargetOpcode::STATEPOINT) &&
1137e8d8bef9SDimitry Andric            "DefIdx out of range");
11380b57cec5SDimitry Andric     UseMO.TiedTo = TiedMax;
11390b57cec5SDimitry Andric   }
11400b57cec5SDimitry Andric 
11410b57cec5SDimitry Andric   // UseIdx can be out of range, we'll search for it in findTiedOperandIdx().
11420b57cec5SDimitry Andric   DefMO.TiedTo = std::min(UseIdx + 1, TiedMax);
11430b57cec5SDimitry Andric }
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to.
11460b57cec5SDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand
11470b57cec5SDimitry Andric /// which must exist.
findTiedOperandIdx(unsigned OpIdx) const11480b57cec5SDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const {
11490b57cec5SDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
11500b57cec5SDimitry Andric   assert(MO.isTied() && "Operand isn't tied");
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric   // Normally TiedTo is in range.
11530b57cec5SDimitry Andric   if (MO.TiedTo < TiedMax)
11540b57cec5SDimitry Andric     return MO.TiedTo - 1;
11550b57cec5SDimitry Andric 
11560b57cec5SDimitry Andric   // Uses on normal instructions can be out of range.
1157e8d8bef9SDimitry Andric   if (!isInlineAsm() && getOpcode() != TargetOpcode::STATEPOINT) {
11580b57cec5SDimitry Andric     // Normal tied defs must be in the 0..TiedMax-1 range.
11590b57cec5SDimitry Andric     if (MO.isUse())
11600b57cec5SDimitry Andric       return TiedMax - 1;
11610b57cec5SDimitry Andric     // MO is a def. Search for the tied use.
11620b57cec5SDimitry Andric     for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) {
11630b57cec5SDimitry Andric       const MachineOperand &UseMO = getOperand(i);
11640b57cec5SDimitry Andric       if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1)
11650b57cec5SDimitry Andric         return i;
11660b57cec5SDimitry Andric     }
11670b57cec5SDimitry Andric     llvm_unreachable("Can't find tied use");
11680b57cec5SDimitry Andric   }
11690b57cec5SDimitry Andric 
1170e8d8bef9SDimitry Andric   if (getOpcode() == TargetOpcode::STATEPOINT) {
1171e8d8bef9SDimitry Andric     // In STATEPOINT defs correspond 1-1 to GC pointer operands passed
1172e8d8bef9SDimitry Andric     // on registers.
1173e8d8bef9SDimitry Andric     StatepointOpers SO(this);
1174e8d8bef9SDimitry Andric     unsigned CurUseIdx = SO.getFirstGCPtrIdx();
1175e8d8bef9SDimitry Andric     assert(CurUseIdx != -1U && "only gc pointer statepoint operands can be tied");
1176e8d8bef9SDimitry Andric     unsigned NumDefs = getNumDefs();
1177e8d8bef9SDimitry Andric     for (unsigned CurDefIdx = 0; CurDefIdx < NumDefs; ++CurDefIdx) {
1178e8d8bef9SDimitry Andric       while (!getOperand(CurUseIdx).isReg())
1179e8d8bef9SDimitry Andric         CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx);
1180e8d8bef9SDimitry Andric       if (OpIdx == CurDefIdx)
1181e8d8bef9SDimitry Andric         return CurUseIdx;
1182e8d8bef9SDimitry Andric       if (OpIdx == CurUseIdx)
1183e8d8bef9SDimitry Andric         return CurDefIdx;
1184e8d8bef9SDimitry Andric       CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx);
1185e8d8bef9SDimitry Andric     }
1186e8d8bef9SDimitry Andric     llvm_unreachable("Can't find tied use");
1187e8d8bef9SDimitry Andric   }
1188e8d8bef9SDimitry Andric 
11890b57cec5SDimitry Andric   // Now deal with inline asm by parsing the operand group descriptor flags.
11900b57cec5SDimitry Andric   // Find the beginning of each operand group.
11910b57cec5SDimitry Andric   SmallVector<unsigned, 8> GroupIdx;
11920b57cec5SDimitry Andric   unsigned OpIdxGroup = ~0u;
11930b57cec5SDimitry Andric   unsigned NumOps;
11940b57cec5SDimitry Andric   for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e;
11950b57cec5SDimitry Andric        i += NumOps) {
11960b57cec5SDimitry Andric     const MachineOperand &FlagMO = getOperand(i);
11970b57cec5SDimitry Andric     assert(FlagMO.isImm() && "Invalid tied operand on inline asm");
11980b57cec5SDimitry Andric     unsigned CurGroup = GroupIdx.size();
11990b57cec5SDimitry Andric     GroupIdx.push_back(i);
1200*c9157d92SDimitry Andric     const InlineAsm::Flag F(FlagMO.getImm());
1201*c9157d92SDimitry Andric     NumOps = 1 + F.getNumOperandRegisters();
12020b57cec5SDimitry Andric     // OpIdx belongs to this operand group.
12030b57cec5SDimitry Andric     if (OpIdx > i && OpIdx < i + NumOps)
12040b57cec5SDimitry Andric       OpIdxGroup = CurGroup;
12050b57cec5SDimitry Andric     unsigned TiedGroup;
1206*c9157d92SDimitry Andric     if (!F.isUseOperandTiedToDef(TiedGroup))
12070b57cec5SDimitry Andric       continue;
12080b57cec5SDimitry Andric     // Operands in this group are tied to operands in TiedGroup which must be
12090b57cec5SDimitry Andric     // earlier. Find the number of operands between the two groups.
12100b57cec5SDimitry Andric     unsigned Delta = i - GroupIdx[TiedGroup];
12110b57cec5SDimitry Andric 
12120b57cec5SDimitry Andric     // OpIdx is a use tied to TiedGroup.
12130b57cec5SDimitry Andric     if (OpIdxGroup == CurGroup)
12140b57cec5SDimitry Andric       return OpIdx - Delta;
12150b57cec5SDimitry Andric 
12160b57cec5SDimitry Andric     // OpIdx is a def tied to this use group.
12170b57cec5SDimitry Andric     if (OpIdxGroup == TiedGroup)
12180b57cec5SDimitry Andric       return OpIdx + Delta;
12190b57cec5SDimitry Andric   }
12200b57cec5SDimitry Andric   llvm_unreachable("Invalid tied operand on inline asm");
12210b57cec5SDimitry Andric }
12220b57cec5SDimitry Andric 
12230b57cec5SDimitry Andric /// clearKillInfo - Clears kill flags on all operands.
12240b57cec5SDimitry Andric ///
clearKillInfo()12250b57cec5SDimitry Andric void MachineInstr::clearKillInfo() {
12260b57cec5SDimitry Andric   for (MachineOperand &MO : operands()) {
12270b57cec5SDimitry Andric     if (MO.isReg() && MO.isUse())
12280b57cec5SDimitry Andric       MO.setIsKill(false);
12290b57cec5SDimitry Andric   }
12300b57cec5SDimitry Andric }
12310b57cec5SDimitry Andric 
substituteRegister(Register FromReg,Register ToReg,unsigned SubIdx,const TargetRegisterInfo & RegInfo)12328bcb0991SDimitry Andric void MachineInstr::substituteRegister(Register FromReg, Register ToReg,
12330b57cec5SDimitry Andric                                       unsigned SubIdx,
12340b57cec5SDimitry Andric                                       const TargetRegisterInfo &RegInfo) {
1235bdd1243dSDimitry Andric   if (ToReg.isPhysical()) {
12360b57cec5SDimitry Andric     if (SubIdx)
12370b57cec5SDimitry Andric       ToReg = RegInfo.getSubReg(ToReg, SubIdx);
12380b57cec5SDimitry Andric     for (MachineOperand &MO : operands()) {
12390b57cec5SDimitry Andric       if (!MO.isReg() || MO.getReg() != FromReg)
12400b57cec5SDimitry Andric         continue;
12410b57cec5SDimitry Andric       MO.substPhysReg(ToReg, RegInfo);
12420b57cec5SDimitry Andric     }
12430b57cec5SDimitry Andric   } else {
12440b57cec5SDimitry Andric     for (MachineOperand &MO : operands()) {
12450b57cec5SDimitry Andric       if (!MO.isReg() || MO.getReg() != FromReg)
12460b57cec5SDimitry Andric         continue;
12470b57cec5SDimitry Andric       MO.substVirtReg(ToReg, SubIdx, RegInfo);
12480b57cec5SDimitry Andric     }
12490b57cec5SDimitry Andric   }
12500b57cec5SDimitry Andric }
12510b57cec5SDimitry Andric 
12520b57cec5SDimitry Andric /// isSafeToMove - Return true if it is safe to move this instruction. If
12530b57cec5SDimitry Andric /// SawStore is set to true, it means that there is a store (or call) between
12540b57cec5SDimitry Andric /// the instruction's location and its intended destination.
isSafeToMove(AAResults * AA,bool & SawStore) const12558bcb0991SDimitry Andric bool MachineInstr::isSafeToMove(AAResults *AA, bool &SawStore) const {
12560b57cec5SDimitry Andric   // Ignore stuff that we obviously can't move.
12570b57cec5SDimitry Andric   //
12580b57cec5SDimitry Andric   // Treat volatile loads as stores. This is not strictly necessary for
12590b57cec5SDimitry Andric   // volatiles, but it is required for atomic loads. It is not allowed to move
12600b57cec5SDimitry Andric   // a load across an atomic load with Ordering > Monotonic.
12610b57cec5SDimitry Andric   if (mayStore() || isCall() || isPHI() ||
12620b57cec5SDimitry Andric       (mayLoad() && hasOrderedMemoryRef())) {
12630b57cec5SDimitry Andric     SawStore = true;
12640b57cec5SDimitry Andric     return false;
12650b57cec5SDimitry Andric   }
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric   if (isPosition() || isDebugInstr() || isTerminator() ||
1268*c9157d92SDimitry Andric       mayRaiseFPException() || hasUnmodeledSideEffects() ||
1269*c9157d92SDimitry Andric       isJumpTableDebugInfo())
12700b57cec5SDimitry Andric     return false;
12710b57cec5SDimitry Andric 
12720b57cec5SDimitry Andric   // See if this instruction does a load.  If so, we have to guarantee that the
12730b57cec5SDimitry Andric   // loaded value doesn't change between the load and the its intended
1274e8d8bef9SDimitry Andric   // destination. The check for isInvariantLoad gives the target the chance to
12750b57cec5SDimitry Andric   // classify the load as always returning a constant, e.g. a constant pool
12760b57cec5SDimitry Andric   // load.
1277fcaf7f86SDimitry Andric   if (mayLoad() && !isDereferenceableInvariantLoad())
12780b57cec5SDimitry Andric     // Otherwise, this is a real load.  If there is a store between the load and
12790b57cec5SDimitry Andric     // end of block, we can't move it.
12800b57cec5SDimitry Andric     return !SawStore;
12810b57cec5SDimitry Andric 
12820b57cec5SDimitry Andric   return true;
12830b57cec5SDimitry Andric }
12840b57cec5SDimitry Andric 
MemOperandsHaveAlias(const MachineFrameInfo & MFI,AAResults * AA,bool UseTBAA,const MachineMemOperand * MMOa,const MachineMemOperand * MMOb)1285e8d8bef9SDimitry Andric static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA,
1286e8d8bef9SDimitry Andric                                  bool UseTBAA, const MachineMemOperand *MMOa,
1287e8d8bef9SDimitry Andric                                  const MachineMemOperand *MMOb) {
1288e8d8bef9SDimitry Andric   // The following interface to AA is fashioned after DAGCombiner::isAlias and
1289e8d8bef9SDimitry Andric   // operates with MachineMemOperand offset with some important assumptions:
12900b57cec5SDimitry Andric   //   - LLVM fundamentally assumes flat address spaces.
1291e8d8bef9SDimitry Andric   //   - MachineOperand offset can *only* result from legalization and cannot
1292e8d8bef9SDimitry Andric   //     affect queries other than the trivial case of overlap checking.
1293e8d8bef9SDimitry Andric   //   - These offsets never wrap and never step outside of allocated objects.
12940b57cec5SDimitry Andric   //   - There should never be any negative offsets here.
12950b57cec5SDimitry Andric   //
12960b57cec5SDimitry Andric   // FIXME: Modify API to hide this math from "user"
1297e8d8bef9SDimitry Andric   // Even before we go to AA we can reason locally about some memory objects. It
1298e8d8bef9SDimitry Andric   // can save compile time, and possibly catch some corner cases not currently
1299e8d8bef9SDimitry Andric   // covered.
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric   int64_t OffsetA = MMOa->getOffset();
13020b57cec5SDimitry Andric   int64_t OffsetB = MMOb->getOffset();
13030b57cec5SDimitry Andric   int64_t MinOffset = std::min(OffsetA, OffsetB);
13040b57cec5SDimitry Andric 
13050b57cec5SDimitry Andric   uint64_t WidthA = MMOa->getSize();
13060b57cec5SDimitry Andric   uint64_t WidthB = MMOb->getSize();
13070b57cec5SDimitry Andric   bool KnownWidthA = WidthA != MemoryLocation::UnknownSize;
13080b57cec5SDimitry Andric   bool KnownWidthB = WidthB != MemoryLocation::UnknownSize;
13090b57cec5SDimitry Andric 
13100b57cec5SDimitry Andric   const Value *ValA = MMOa->getValue();
13110b57cec5SDimitry Andric   const Value *ValB = MMOb->getValue();
13120b57cec5SDimitry Andric   bool SameVal = (ValA && ValB && (ValA == ValB));
13130b57cec5SDimitry Andric   if (!SameVal) {
13140b57cec5SDimitry Andric     const PseudoSourceValue *PSVa = MMOa->getPseudoValue();
13150b57cec5SDimitry Andric     const PseudoSourceValue *PSVb = MMOb->getPseudoValue();
13160b57cec5SDimitry Andric     if (PSVa && ValB && !PSVa->mayAlias(&MFI))
13170b57cec5SDimitry Andric       return false;
13180b57cec5SDimitry Andric     if (PSVb && ValA && !PSVb->mayAlias(&MFI))
13190b57cec5SDimitry Andric       return false;
13200b57cec5SDimitry Andric     if (PSVa && PSVb && (PSVa == PSVb))
13210b57cec5SDimitry Andric       SameVal = true;
13220b57cec5SDimitry Andric   }
13230b57cec5SDimitry Andric 
13240b57cec5SDimitry Andric   if (SameVal) {
13250b57cec5SDimitry Andric     if (!KnownWidthA || !KnownWidthB)
13260b57cec5SDimitry Andric       return true;
13270b57cec5SDimitry Andric     int64_t MaxOffset = std::max(OffsetA, OffsetB);
13280b57cec5SDimitry Andric     int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB;
13290b57cec5SDimitry Andric     return (MinOffset + LowWidth > MaxOffset);
13300b57cec5SDimitry Andric   }
13310b57cec5SDimitry Andric 
13320b57cec5SDimitry Andric   if (!AA)
13330b57cec5SDimitry Andric     return true;
13340b57cec5SDimitry Andric 
13350b57cec5SDimitry Andric   if (!ValA || !ValB)
13360b57cec5SDimitry Andric     return true;
13370b57cec5SDimitry Andric 
13380b57cec5SDimitry Andric   assert((OffsetA >= 0) && "Negative MachineMemOperand offset");
13390b57cec5SDimitry Andric   assert((OffsetB >= 0) && "Negative MachineMemOperand offset");
13400b57cec5SDimitry Andric 
1341e8d8bef9SDimitry Andric   int64_t OverlapA =
1342e8d8bef9SDimitry Andric       KnownWidthA ? WidthA + OffsetA - MinOffset : MemoryLocation::UnknownSize;
1343e8d8bef9SDimitry Andric   int64_t OverlapB =
1344e8d8bef9SDimitry Andric       KnownWidthB ? WidthB + OffsetB - MinOffset : MemoryLocation::UnknownSize;
13450b57cec5SDimitry Andric 
1346fe6060f1SDimitry Andric   return !AA->isNoAlias(
1347e8d8bef9SDimitry Andric       MemoryLocation(ValA, OverlapA, UseTBAA ? MMOa->getAAInfo() : AAMDNodes()),
13480b57cec5SDimitry Andric       MemoryLocation(ValB, OverlapB,
13490b57cec5SDimitry Andric                      UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));
13500b57cec5SDimitry Andric }
13510b57cec5SDimitry Andric 
mayAlias(AAResults * AA,const MachineInstr & Other,bool UseTBAA) const1352e8d8bef9SDimitry Andric bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
1353e8d8bef9SDimitry Andric                             bool UseTBAA) const {
1354e8d8bef9SDimitry Andric   const MachineFunction *MF = getMF();
1355e8d8bef9SDimitry Andric   const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
1356e8d8bef9SDimitry Andric   const MachineFrameInfo &MFI = MF->getFrameInfo();
1357e8d8bef9SDimitry Andric 
1358e8d8bef9SDimitry Andric   // Exclude call instruction which may alter the memory but can not be handled
1359e8d8bef9SDimitry Andric   // by this function.
1360e8d8bef9SDimitry Andric   if (isCall() || Other.isCall())
1361e8d8bef9SDimitry Andric     return true;
1362e8d8bef9SDimitry Andric 
1363e8d8bef9SDimitry Andric   // If neither instruction stores to memory, they can't alias in any
1364e8d8bef9SDimitry Andric   // meaningful way, even if they read from the same address.
1365e8d8bef9SDimitry Andric   if (!mayStore() && !Other.mayStore())
1366e8d8bef9SDimitry Andric     return false;
1367e8d8bef9SDimitry Andric 
1368e8d8bef9SDimitry Andric   // Both instructions must be memory operations to be able to alias.
1369e8d8bef9SDimitry Andric   if (!mayLoadOrStore() || !Other.mayLoadOrStore())
1370e8d8bef9SDimitry Andric     return false;
1371e8d8bef9SDimitry Andric 
1372e8d8bef9SDimitry Andric   // Let the target decide if memory accesses cannot possibly overlap.
1373e8d8bef9SDimitry Andric   if (TII->areMemAccessesTriviallyDisjoint(*this, Other))
1374e8d8bef9SDimitry Andric     return false;
1375e8d8bef9SDimitry Andric 
1376e8d8bef9SDimitry Andric   // Memory operations without memory operands may access anything. Be
1377e8d8bef9SDimitry Andric   // conservative and assume `MayAlias`.
1378e8d8bef9SDimitry Andric   if (memoperands_empty() || Other.memoperands_empty())
1379e8d8bef9SDimitry Andric     return true;
1380e8d8bef9SDimitry Andric 
1381e8d8bef9SDimitry Andric   // Skip if there are too many memory operands.
1382e8d8bef9SDimitry Andric   auto NumChecks = getNumMemOperands() * Other.getNumMemOperands();
1383e8d8bef9SDimitry Andric   if (NumChecks > TII->getMemOperandAACheckLimit())
1384e8d8bef9SDimitry Andric     return true;
1385e8d8bef9SDimitry Andric 
1386e8d8bef9SDimitry Andric   // Check each pair of memory operands from both instructions, which can't
1387e8d8bef9SDimitry Andric   // alias only if all pairs won't alias.
1388e8d8bef9SDimitry Andric   for (auto *MMOa : memoperands())
1389e8d8bef9SDimitry Andric     for (auto *MMOb : Other.memoperands())
1390e8d8bef9SDimitry Andric       if (MemOperandsHaveAlias(MFI, AA, UseTBAA, MMOa, MMOb))
1391e8d8bef9SDimitry Andric         return true;
1392e8d8bef9SDimitry Andric 
1393e8d8bef9SDimitry Andric   return false;
1394e8d8bef9SDimitry Andric }
1395e8d8bef9SDimitry Andric 
13960b57cec5SDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered
13970b57cec5SDimitry Andric /// or volatile memory reference, or if the information describing the memory
13980b57cec5SDimitry Andric /// reference is not available. Return false if it is known to have no ordered
13990b57cec5SDimitry Andric /// memory references.
hasOrderedMemoryRef() const14000b57cec5SDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const {
14010b57cec5SDimitry Andric   // An instruction known never to access memory won't have a volatile access.
14020b57cec5SDimitry Andric   if (!mayStore() &&
14030b57cec5SDimitry Andric       !mayLoad() &&
14040b57cec5SDimitry Andric       !isCall() &&
14050b57cec5SDimitry Andric       !hasUnmodeledSideEffects())
14060b57cec5SDimitry Andric     return false;
14070b57cec5SDimitry Andric 
14080b57cec5SDimitry Andric   // Otherwise, if the instruction has no memory reference information,
14090b57cec5SDimitry Andric   // conservatively assume it wasn't preserved.
14100b57cec5SDimitry Andric   if (memoperands_empty())
14110b57cec5SDimitry Andric     return true;
14120b57cec5SDimitry Andric 
14130b57cec5SDimitry Andric   // Check if any of our memory operands are ordered.
14140b57cec5SDimitry Andric   return llvm::any_of(memoperands(), [](const MachineMemOperand *MMO) {
14150b57cec5SDimitry Andric     return !MMO->isUnordered();
14160b57cec5SDimitry Andric   });
14170b57cec5SDimitry Andric }
14180b57cec5SDimitry Andric 
14190b57cec5SDimitry Andric /// isDereferenceableInvariantLoad - Return true if this instruction will never
14200b57cec5SDimitry Andric /// trap and is loading from a location whose value is invariant across a run of
14210b57cec5SDimitry Andric /// this function.
isDereferenceableInvariantLoad() const1422fcaf7f86SDimitry Andric bool MachineInstr::isDereferenceableInvariantLoad() const {
14230b57cec5SDimitry Andric   // If the instruction doesn't load at all, it isn't an invariant load.
14240b57cec5SDimitry Andric   if (!mayLoad())
14250b57cec5SDimitry Andric     return false;
14260b57cec5SDimitry Andric 
14270b57cec5SDimitry Andric   // If the instruction has lost its memoperands, conservatively assume that
14280b57cec5SDimitry Andric   // it may not be an invariant load.
14290b57cec5SDimitry Andric   if (memoperands_empty())
14300b57cec5SDimitry Andric     return false;
14310b57cec5SDimitry Andric 
14320b57cec5SDimitry Andric   const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo();
14330b57cec5SDimitry Andric 
14340b57cec5SDimitry Andric   for (MachineMemOperand *MMO : memoperands()) {
14350b57cec5SDimitry Andric     if (!MMO->isUnordered())
14360b57cec5SDimitry Andric       // If the memory operand has ordering side effects, we can't move the
14370b57cec5SDimitry Andric       // instruction.  Such an instruction is technically an invariant load,
14380b57cec5SDimitry Andric       // but the caller code would need updated to expect that.
14390b57cec5SDimitry Andric       return false;
14400b57cec5SDimitry Andric     if (MMO->isStore()) return false;
14410b57cec5SDimitry Andric     if (MMO->isInvariant() && MMO->isDereferenceable())
14420b57cec5SDimitry Andric       continue;
14430b57cec5SDimitry Andric 
14440b57cec5SDimitry Andric     // A load from a constant PseudoSourceValue is invariant.
144581ad6265SDimitry Andric     if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) {
14460b57cec5SDimitry Andric       if (PSV->isConstant(&MFI))
14470b57cec5SDimitry Andric         continue;
14480b57cec5SDimitry Andric     }
14490b57cec5SDimitry Andric 
14500b57cec5SDimitry Andric     // Otherwise assume conservatively.
14510b57cec5SDimitry Andric     return false;
14520b57cec5SDimitry Andric   }
14530b57cec5SDimitry Andric 
14540b57cec5SDimitry Andric   // Everything checks out.
14550b57cec5SDimitry Andric   return true;
14560b57cec5SDimitry Andric }
14570b57cec5SDimitry Andric 
14580b57cec5SDimitry Andric /// isConstantValuePHI - If the specified instruction is a PHI that always
14590b57cec5SDimitry Andric /// merges together the same virtual register, return the register, otherwise
14600b57cec5SDimitry Andric /// return 0.
isConstantValuePHI() const14610b57cec5SDimitry Andric unsigned MachineInstr::isConstantValuePHI() const {
14620b57cec5SDimitry Andric   if (!isPHI())
14630b57cec5SDimitry Andric     return 0;
14640b57cec5SDimitry Andric   assert(getNumOperands() >= 3 &&
14650b57cec5SDimitry Andric          "It's illegal to have a PHI without source operands");
14660b57cec5SDimitry Andric 
14678bcb0991SDimitry Andric   Register Reg = getOperand(1).getReg();
14680b57cec5SDimitry Andric   for (unsigned i = 3, e = getNumOperands(); i < e; i += 2)
14690b57cec5SDimitry Andric     if (getOperand(i).getReg() != Reg)
14700b57cec5SDimitry Andric       return 0;
14710b57cec5SDimitry Andric   return Reg;
14720b57cec5SDimitry Andric }
14730b57cec5SDimitry Andric 
hasUnmodeledSideEffects() const14740b57cec5SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const {
14750b57cec5SDimitry Andric   if (hasProperty(MCID::UnmodeledSideEffects))
14760b57cec5SDimitry Andric     return true;
14770b57cec5SDimitry Andric   if (isInlineAsm()) {
14780b57cec5SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
14790b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
14800b57cec5SDimitry Andric       return true;
14810b57cec5SDimitry Andric   }
14820b57cec5SDimitry Andric 
14830b57cec5SDimitry Andric   return false;
14840b57cec5SDimitry Andric }
14850b57cec5SDimitry Andric 
isLoadFoldBarrier() const14860b57cec5SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const {
1487d409305fSDimitry Andric   return mayStore() || isCall() ||
1488d409305fSDimitry Andric          (hasUnmodeledSideEffects() && !isPseudoProbe());
14890b57cec5SDimitry Andric }
14900b57cec5SDimitry Andric 
14910b57cec5SDimitry Andric /// allDefsAreDead - Return true if all the defs of this instruction are dead.
14920b57cec5SDimitry Andric ///
allDefsAreDead() const14930b57cec5SDimitry Andric bool MachineInstr::allDefsAreDead() const {
14940b57cec5SDimitry Andric   for (const MachineOperand &MO : operands()) {
14950b57cec5SDimitry Andric     if (!MO.isReg() || MO.isUse())
14960b57cec5SDimitry Andric       continue;
14970b57cec5SDimitry Andric     if (!MO.isDead())
14980b57cec5SDimitry Andric       return false;
14990b57cec5SDimitry Andric   }
15000b57cec5SDimitry Andric   return true;
15010b57cec5SDimitry Andric }
15020b57cec5SDimitry Andric 
allImplicitDefsAreDead() const1503*c9157d92SDimitry Andric bool MachineInstr::allImplicitDefsAreDead() const {
1504*c9157d92SDimitry Andric   for (const MachineOperand &MO : implicit_operands()) {
1505*c9157d92SDimitry Andric     if (!MO.isReg() || MO.isUse())
1506*c9157d92SDimitry Andric       continue;
1507*c9157d92SDimitry Andric     if (!MO.isDead())
1508*c9157d92SDimitry Andric       return false;
1509*c9157d92SDimitry Andric   }
1510*c9157d92SDimitry Andric   return true;
1511*c9157d92SDimitry Andric }
1512*c9157d92SDimitry Andric 
15130b57cec5SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified
15140b57cec5SDimitry Andric /// instruction to this instruction.
copyImplicitOps(MachineFunction & MF,const MachineInstr & MI)15150b57cec5SDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF,
15160b57cec5SDimitry Andric                                    const MachineInstr &MI) {
15174824e7fdSDimitry Andric   for (const MachineOperand &MO :
15184824e7fdSDimitry Andric        llvm::drop_begin(MI.operands(), MI.getDesc().getNumOperands()))
15190b57cec5SDimitry Andric     if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask())
15200b57cec5SDimitry Andric       addOperand(MF, MO);
15210b57cec5SDimitry Andric }
15220b57cec5SDimitry Andric 
hasComplexRegisterTies() const15230b57cec5SDimitry Andric bool MachineInstr::hasComplexRegisterTies() const {
15240b57cec5SDimitry Andric   const MCInstrDesc &MCID = getDesc();
1525e8d8bef9SDimitry Andric   if (MCID.Opcode == TargetOpcode::STATEPOINT)
1526e8d8bef9SDimitry Andric     return true;
15270b57cec5SDimitry Andric   for (unsigned I = 0, E = getNumOperands(); I < E; ++I) {
15280b57cec5SDimitry Andric     const auto &Operand = getOperand(I);
15290b57cec5SDimitry Andric     if (!Operand.isReg() || Operand.isDef())
15300b57cec5SDimitry Andric       // Ignore the defined registers as MCID marks only the uses as tied.
15310b57cec5SDimitry Andric       continue;
15320b57cec5SDimitry Andric     int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO);
15330b57cec5SDimitry Andric     int TiedIdx = Operand.isTied() ? int(findTiedOperandIdx(I)) : -1;
15340b57cec5SDimitry Andric     if (ExpectedTiedIdx != TiedIdx)
15350b57cec5SDimitry Andric       return true;
15360b57cec5SDimitry Andric   }
15370b57cec5SDimitry Andric   return false;
15380b57cec5SDimitry Andric }
15390b57cec5SDimitry Andric 
getTypeToPrint(unsigned OpIdx,SmallBitVector & PrintedTypes,const MachineRegisterInfo & MRI) const15400b57cec5SDimitry Andric LLT MachineInstr::getTypeToPrint(unsigned OpIdx, SmallBitVector &PrintedTypes,
15410b57cec5SDimitry Andric                                  const MachineRegisterInfo &MRI) const {
15420b57cec5SDimitry Andric   const MachineOperand &Op = getOperand(OpIdx);
15430b57cec5SDimitry Andric   if (!Op.isReg())
15440b57cec5SDimitry Andric     return LLT{};
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric   if (isVariadic() || OpIdx >= getNumExplicitOperands())
15470b57cec5SDimitry Andric     return MRI.getType(Op.getReg());
15480b57cec5SDimitry Andric 
1549bdd1243dSDimitry Andric   auto &OpInfo = getDesc().operands()[OpIdx];
15500b57cec5SDimitry Andric   if (!OpInfo.isGenericType())
15510b57cec5SDimitry Andric     return MRI.getType(Op.getReg());
15520b57cec5SDimitry Andric 
15530b57cec5SDimitry Andric   if (PrintedTypes[OpInfo.getGenericTypeIndex()])
15540b57cec5SDimitry Andric     return LLT{};
15550b57cec5SDimitry Andric 
15560b57cec5SDimitry Andric   LLT TypeToPrint = MRI.getType(Op.getReg());
15570b57cec5SDimitry Andric   // Don't mark the type index printed if it wasn't actually printed: maybe
15580b57cec5SDimitry Andric   // another operand with the same type index has an actual type attached:
15590b57cec5SDimitry Andric   if (TypeToPrint.isValid())
15600b57cec5SDimitry Andric     PrintedTypes.set(OpInfo.getGenericTypeIndex());
15610b57cec5SDimitry Andric   return TypeToPrint;
15620b57cec5SDimitry Andric }
15630b57cec5SDimitry Andric 
15640b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const15650b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dump() const {
15660b57cec5SDimitry Andric   dbgs() << "  ";
15670b57cec5SDimitry Andric   print(dbgs());
15680b57cec5SDimitry Andric }
15695ffd83dbSDimitry Andric 
dumprImpl(const MachineRegisterInfo & MRI,unsigned Depth,unsigned MaxDepth,SmallPtrSetImpl<const MachineInstr * > & AlreadySeenInstrs) const15705ffd83dbSDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dumprImpl(
15715ffd83dbSDimitry Andric     const MachineRegisterInfo &MRI, unsigned Depth, unsigned MaxDepth,
15725ffd83dbSDimitry Andric     SmallPtrSetImpl<const MachineInstr *> &AlreadySeenInstrs) const {
15735ffd83dbSDimitry Andric   if (Depth >= MaxDepth)
15745ffd83dbSDimitry Andric     return;
15755ffd83dbSDimitry Andric   if (!AlreadySeenInstrs.insert(this).second)
15765ffd83dbSDimitry Andric     return;
15775ffd83dbSDimitry Andric   // PadToColumn always inserts at least one space.
15785ffd83dbSDimitry Andric   // Don't mess up the alignment if we don't want any space.
15795ffd83dbSDimitry Andric   if (Depth)
15805ffd83dbSDimitry Andric     fdbgs().PadToColumn(Depth * 2);
15815ffd83dbSDimitry Andric   print(fdbgs());
15825ffd83dbSDimitry Andric   for (const MachineOperand &MO : operands()) {
15835ffd83dbSDimitry Andric     if (!MO.isReg() || MO.isDef())
15845ffd83dbSDimitry Andric       continue;
15855ffd83dbSDimitry Andric     Register Reg = MO.getReg();
15865ffd83dbSDimitry Andric     if (Reg.isPhysical())
15875ffd83dbSDimitry Andric       continue;
15885ffd83dbSDimitry Andric     const MachineInstr *NewMI = MRI.getUniqueVRegDef(Reg);
15895ffd83dbSDimitry Andric     if (NewMI == nullptr)
15905ffd83dbSDimitry Andric       continue;
15915ffd83dbSDimitry Andric     NewMI->dumprImpl(MRI, Depth + 1, MaxDepth, AlreadySeenInstrs);
15925ffd83dbSDimitry Andric   }
15935ffd83dbSDimitry Andric }
15945ffd83dbSDimitry Andric 
dumpr(const MachineRegisterInfo & MRI,unsigned MaxDepth) const15955ffd83dbSDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dumpr(const MachineRegisterInfo &MRI,
15965ffd83dbSDimitry Andric                                           unsigned MaxDepth) const {
15975ffd83dbSDimitry Andric   SmallPtrSet<const MachineInstr *, 16> AlreadySeenInstrs;
15985ffd83dbSDimitry Andric   dumprImpl(MRI, 0, MaxDepth, AlreadySeenInstrs);
15995ffd83dbSDimitry Andric }
16000b57cec5SDimitry Andric #endif
16010b57cec5SDimitry Andric 
print(raw_ostream & OS,bool IsStandalone,bool SkipOpers,bool SkipDebugLoc,bool AddNewLine,const TargetInstrInfo * TII) const16020b57cec5SDimitry Andric void MachineInstr::print(raw_ostream &OS, bool IsStandalone, bool SkipOpers,
16030b57cec5SDimitry Andric                          bool SkipDebugLoc, bool AddNewLine,
16040b57cec5SDimitry Andric                          const TargetInstrInfo *TII) const {
16050b57cec5SDimitry Andric   const Module *M = nullptr;
16060b57cec5SDimitry Andric   const Function *F = nullptr;
16070b57cec5SDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(*this)) {
16080b57cec5SDimitry Andric     F = &MF->getFunction();
16090b57cec5SDimitry Andric     M = F->getParent();
16100b57cec5SDimitry Andric     if (!TII)
16110b57cec5SDimitry Andric       TII = MF->getSubtarget().getInstrInfo();
16120b57cec5SDimitry Andric   }
16130b57cec5SDimitry Andric 
16140b57cec5SDimitry Andric   ModuleSlotTracker MST(M);
16150b57cec5SDimitry Andric   if (F)
16160b57cec5SDimitry Andric     MST.incorporateFunction(*F);
16170b57cec5SDimitry Andric   print(OS, MST, IsStandalone, SkipOpers, SkipDebugLoc, AddNewLine, TII);
16180b57cec5SDimitry Andric }
16190b57cec5SDimitry Andric 
print(raw_ostream & OS,ModuleSlotTracker & MST,bool IsStandalone,bool SkipOpers,bool SkipDebugLoc,bool AddNewLine,const TargetInstrInfo * TII) const16200b57cec5SDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
16210b57cec5SDimitry Andric                          bool IsStandalone, bool SkipOpers, bool SkipDebugLoc,
16220b57cec5SDimitry Andric                          bool AddNewLine, const TargetInstrInfo *TII) const {
16230b57cec5SDimitry Andric   // We can be a bit tidier if we know the MachineFunction.
16240b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = nullptr;
16250b57cec5SDimitry Andric   const MachineRegisterInfo *MRI = nullptr;
16260b57cec5SDimitry Andric   const TargetIntrinsicInfo *IntrinsicInfo = nullptr;
16270b57cec5SDimitry Andric   tryToGetTargetInfo(*this, TRI, MRI, IntrinsicInfo, TII);
16280b57cec5SDimitry Andric 
16290b57cec5SDimitry Andric   if (isCFIInstruction())
16300b57cec5SDimitry Andric     assert(getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
16310b57cec5SDimitry Andric 
16320b57cec5SDimitry Andric   SmallBitVector PrintedTypes(8);
16330b57cec5SDimitry Andric   bool ShouldPrintRegisterTies = IsStandalone || hasComplexRegisterTies();
16340b57cec5SDimitry Andric   auto getTiedOperandIdx = [&](unsigned OpIdx) {
16350b57cec5SDimitry Andric     if (!ShouldPrintRegisterTies)
16360b57cec5SDimitry Andric       return 0U;
16370b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(OpIdx);
16380b57cec5SDimitry Andric     if (MO.isReg() && MO.isTied() && !MO.isDef())
16390b57cec5SDimitry Andric       return findTiedOperandIdx(OpIdx);
16400b57cec5SDimitry Andric     return 0U;
16410b57cec5SDimitry Andric   };
16420b57cec5SDimitry Andric   unsigned StartOp = 0;
16430b57cec5SDimitry Andric   unsigned e = getNumOperands();
16440b57cec5SDimitry Andric 
16450b57cec5SDimitry Andric   // Print explicitly defined operands on the left of an assignment syntax.
16460b57cec5SDimitry Andric   while (StartOp < e) {
16470b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(StartOp);
16480b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
16490b57cec5SDimitry Andric       break;
16500b57cec5SDimitry Andric 
16510b57cec5SDimitry Andric     if (StartOp != 0)
16520b57cec5SDimitry Andric       OS << ", ";
16530b57cec5SDimitry Andric 
16540b57cec5SDimitry Andric     LLT TypeToPrint = MRI ? getTypeToPrint(StartOp, PrintedTypes, *MRI) : LLT{};
16550b57cec5SDimitry Andric     unsigned TiedOperandIdx = getTiedOperandIdx(StartOp);
1656480093f4SDimitry Andric     MO.print(OS, MST, TypeToPrint, StartOp, /*PrintDef=*/false, IsStandalone,
16570b57cec5SDimitry Andric              ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
16580b57cec5SDimitry Andric     ++StartOp;
16590b57cec5SDimitry Andric   }
16600b57cec5SDimitry Andric 
16610b57cec5SDimitry Andric   if (StartOp != 0)
16620b57cec5SDimitry Andric     OS << " = ";
16630b57cec5SDimitry Andric 
16640b57cec5SDimitry Andric   if (getFlag(MachineInstr::FrameSetup))
16650b57cec5SDimitry Andric     OS << "frame-setup ";
16660b57cec5SDimitry Andric   if (getFlag(MachineInstr::FrameDestroy))
16670b57cec5SDimitry Andric     OS << "frame-destroy ";
16680b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmNoNans))
16690b57cec5SDimitry Andric     OS << "nnan ";
16700b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmNoInfs))
16710b57cec5SDimitry Andric     OS << "ninf ";
16720b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmNsz))
16730b57cec5SDimitry Andric     OS << "nsz ";
16740b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmArcp))
16750b57cec5SDimitry Andric     OS << "arcp ";
16760b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmContract))
16770b57cec5SDimitry Andric     OS << "contract ";
16780b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmAfn))
16790b57cec5SDimitry Andric     OS << "afn ";
16800b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmReassoc))
16810b57cec5SDimitry Andric     OS << "reassoc ";
16820b57cec5SDimitry Andric   if (getFlag(MachineInstr::NoUWrap))
16830b57cec5SDimitry Andric     OS << "nuw ";
16840b57cec5SDimitry Andric   if (getFlag(MachineInstr::NoSWrap))
16850b57cec5SDimitry Andric     OS << "nsw ";
16860b57cec5SDimitry Andric   if (getFlag(MachineInstr::IsExact))
16870b57cec5SDimitry Andric     OS << "exact ";
1688480093f4SDimitry Andric   if (getFlag(MachineInstr::NoFPExcept))
1689480093f4SDimitry Andric     OS << "nofpexcept ";
16905ffd83dbSDimitry Andric   if (getFlag(MachineInstr::NoMerge))
16915ffd83dbSDimitry Andric     OS << "nomerge ";
16920b57cec5SDimitry Andric 
16930b57cec5SDimitry Andric   // Print the opcode name.
16940b57cec5SDimitry Andric   if (TII)
16950b57cec5SDimitry Andric     OS << TII->getName(getOpcode());
16960b57cec5SDimitry Andric   else
16970b57cec5SDimitry Andric     OS << "UNKNOWN";
16980b57cec5SDimitry Andric 
16990b57cec5SDimitry Andric   if (SkipOpers)
17000b57cec5SDimitry Andric     return;
17010b57cec5SDimitry Andric 
17020b57cec5SDimitry Andric   // Print the rest of the operands.
17030b57cec5SDimitry Andric   bool FirstOp = true;
17040b57cec5SDimitry Andric   unsigned AsmDescOp = ~0u;
17050b57cec5SDimitry Andric   unsigned AsmOpCount = 0;
17060b57cec5SDimitry Andric 
17070b57cec5SDimitry Andric   if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) {
17080b57cec5SDimitry Andric     // Print asm string.
17090b57cec5SDimitry Andric     OS << " ";
17100b57cec5SDimitry Andric     const unsigned OpIdx = InlineAsm::MIOp_AsmString;
17110b57cec5SDimitry Andric     LLT TypeToPrint = MRI ? getTypeToPrint(OpIdx, PrintedTypes, *MRI) : LLT{};
17120b57cec5SDimitry Andric     unsigned TiedOperandIdx = getTiedOperandIdx(OpIdx);
1713480093f4SDimitry Andric     getOperand(OpIdx).print(OS, MST, TypeToPrint, OpIdx, /*PrintDef=*/true, IsStandalone,
17140b57cec5SDimitry Andric                             ShouldPrintRegisterTies, TiedOperandIdx, TRI,
17150b57cec5SDimitry Andric                             IntrinsicInfo);
17160b57cec5SDimitry Andric 
17170b57cec5SDimitry Andric     // Print HasSideEffects, MayLoad, MayStore, IsAlignStack
17180b57cec5SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
17190b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
17200b57cec5SDimitry Andric       OS << " [sideeffect]";
17210b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_MayLoad)
17220b57cec5SDimitry Andric       OS << " [mayload]";
17230b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_MayStore)
17240b57cec5SDimitry Andric       OS << " [maystore]";
17250b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsConvergent)
17260b57cec5SDimitry Andric       OS << " [isconvergent]";
17270b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
17280b57cec5SDimitry Andric       OS << " [alignstack]";
17290b57cec5SDimitry Andric     if (getInlineAsmDialect() == InlineAsm::AD_ATT)
17300b57cec5SDimitry Andric       OS << " [attdialect]";
17310b57cec5SDimitry Andric     if (getInlineAsmDialect() == InlineAsm::AD_Intel)
17320b57cec5SDimitry Andric       OS << " [inteldialect]";
17330b57cec5SDimitry Andric 
17340b57cec5SDimitry Andric     StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand;
17350b57cec5SDimitry Andric     FirstOp = false;
17360b57cec5SDimitry Andric   }
17370b57cec5SDimitry Andric 
17380b57cec5SDimitry Andric   for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
17390b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
17400b57cec5SDimitry Andric 
17410b57cec5SDimitry Andric     if (FirstOp) FirstOp = false; else OS << ",";
17420b57cec5SDimitry Andric     OS << " ";
17430b57cec5SDimitry Andric 
1744fe013be4SDimitry Andric     if (isDebugValueLike() && MO.isMetadata()) {
1745fe6060f1SDimitry Andric       // Pretty print DBG_VALUE* instructions.
17460b57cec5SDimitry Andric       auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata());
17470b57cec5SDimitry Andric       if (DIV && !DIV->getName().empty())
17480b57cec5SDimitry Andric         OS << "!\"" << DIV->getName() << '\"';
17490b57cec5SDimitry Andric       else {
17500b57cec5SDimitry Andric         LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
17510b57cec5SDimitry Andric         unsigned TiedOperandIdx = getTiedOperandIdx(i);
1752480093f4SDimitry Andric         MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone,
17530b57cec5SDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
17540b57cec5SDimitry Andric       }
17550b57cec5SDimitry Andric     } else if (isDebugLabel() && MO.isMetadata()) {
17560b57cec5SDimitry Andric       // Pretty print DBG_LABEL instructions.
17570b57cec5SDimitry Andric       auto *DIL = dyn_cast<DILabel>(MO.getMetadata());
17580b57cec5SDimitry Andric       if (DIL && !DIL->getName().empty())
17590b57cec5SDimitry Andric         OS << "\"" << DIL->getName() << '\"';
17600b57cec5SDimitry Andric       else {
17610b57cec5SDimitry Andric         LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
17620b57cec5SDimitry Andric         unsigned TiedOperandIdx = getTiedOperandIdx(i);
1763480093f4SDimitry Andric         MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone,
17640b57cec5SDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
17650b57cec5SDimitry Andric       }
17660b57cec5SDimitry Andric     } else if (i == AsmDescOp && MO.isImm()) {
17670b57cec5SDimitry Andric       // Pretty print the inline asm operand descriptor.
17680b57cec5SDimitry Andric       OS << '$' << AsmOpCount++;
17690b57cec5SDimitry Andric       unsigned Flag = MO.getImm();
1770*c9157d92SDimitry Andric       const InlineAsm::Flag F(Flag);
17715ffd83dbSDimitry Andric       OS << ":[";
1772*c9157d92SDimitry Andric       OS << F.getKindName();
17730b57cec5SDimitry Andric 
1774*c9157d92SDimitry Andric       unsigned RCID;
1775*c9157d92SDimitry Andric       if (!F.isImmKind() && !F.isMemKind() && F.hasRegClassConstraint(RCID)) {
17760b57cec5SDimitry Andric         if (TRI) {
17770b57cec5SDimitry Andric           OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID));
17780b57cec5SDimitry Andric         } else
17790b57cec5SDimitry Andric           OS << ":RC" << RCID;
17800b57cec5SDimitry Andric       }
17810b57cec5SDimitry Andric 
1782*c9157d92SDimitry Andric       if (F.isMemKind()) {
1783*c9157d92SDimitry Andric         const InlineAsm::ConstraintCode MCID = F.getMemoryConstraintID();
17845ffd83dbSDimitry Andric         OS << ":" << InlineAsm::getMemConstraintName(MCID);
17850b57cec5SDimitry Andric       }
17860b57cec5SDimitry Andric 
1787*c9157d92SDimitry Andric       unsigned TiedTo;
1788*c9157d92SDimitry Andric       if (F.isUseOperandTiedToDef(TiedTo))
17890b57cec5SDimitry Andric         OS << " tiedto:$" << TiedTo;
17900b57cec5SDimitry Andric 
1791*c9157d92SDimitry Andric       if ((F.isRegDefKind() || F.isRegDefEarlyClobberKind() ||
1792*c9157d92SDimitry Andric            F.isRegUseKind()) &&
1793*c9157d92SDimitry Andric           F.getRegMayBeFolded()) {
1794*c9157d92SDimitry Andric         OS << " foldable";
1795*c9157d92SDimitry Andric       }
1796*c9157d92SDimitry Andric 
17970b57cec5SDimitry Andric       OS << ']';
17980b57cec5SDimitry Andric 
17990b57cec5SDimitry Andric       // Compute the index of the next operand descriptor.
1800*c9157d92SDimitry Andric       AsmDescOp += 1 + F.getNumOperandRegisters();
18010b57cec5SDimitry Andric     } else {
18020b57cec5SDimitry Andric       LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
18030b57cec5SDimitry Andric       unsigned TiedOperandIdx = getTiedOperandIdx(i);
18040b57cec5SDimitry Andric       if (MO.isImm() && isOperandSubregIdx(i))
18050b57cec5SDimitry Andric         MachineOperand::printSubRegIdx(OS, MO.getImm(), TRI);
18060b57cec5SDimitry Andric       else
1807480093f4SDimitry Andric         MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone,
18080b57cec5SDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
18090b57cec5SDimitry Andric     }
18100b57cec5SDimitry Andric   }
18110b57cec5SDimitry Andric 
18120b57cec5SDimitry Andric   // Print any optional symbols attached to this instruction as-if they were
18130b57cec5SDimitry Andric   // operands.
18140b57cec5SDimitry Andric   if (MCSymbol *PreInstrSymbol = getPreInstrSymbol()) {
18150b57cec5SDimitry Andric     if (!FirstOp) {
18160b57cec5SDimitry Andric       FirstOp = false;
18170b57cec5SDimitry Andric       OS << ',';
18180b57cec5SDimitry Andric     }
18190b57cec5SDimitry Andric     OS << " pre-instr-symbol ";
18200b57cec5SDimitry Andric     MachineOperand::printSymbol(OS, *PreInstrSymbol);
18210b57cec5SDimitry Andric   }
18220b57cec5SDimitry Andric   if (MCSymbol *PostInstrSymbol = getPostInstrSymbol()) {
18230b57cec5SDimitry Andric     if (!FirstOp) {
18240b57cec5SDimitry Andric       FirstOp = false;
18250b57cec5SDimitry Andric       OS << ',';
18260b57cec5SDimitry Andric     }
18270b57cec5SDimitry Andric     OS << " post-instr-symbol ";
18280b57cec5SDimitry Andric     MachineOperand::printSymbol(OS, *PostInstrSymbol);
18290b57cec5SDimitry Andric   }
1830c14a5a88SDimitry Andric   if (MDNode *HeapAllocMarker = getHeapAllocMarker()) {
1831c14a5a88SDimitry Andric     if (!FirstOp) {
1832c14a5a88SDimitry Andric       FirstOp = false;
1833c14a5a88SDimitry Andric       OS << ',';
1834c14a5a88SDimitry Andric     }
1835c14a5a88SDimitry Andric     OS << " heap-alloc-marker ";
1836480093f4SDimitry Andric     HeapAllocMarker->printAsOperand(OS, MST);
1837c14a5a88SDimitry Andric   }
1838bdd1243dSDimitry Andric   if (MDNode *PCSections = getPCSections()) {
1839bdd1243dSDimitry Andric     if (!FirstOp) {
1840bdd1243dSDimitry Andric       FirstOp = false;
1841bdd1243dSDimitry Andric       OS << ',';
1842bdd1243dSDimitry Andric     }
1843bdd1243dSDimitry Andric     OS << " pcsections ";
1844bdd1243dSDimitry Andric     PCSections->printAsOperand(OS, MST);
1845bdd1243dSDimitry Andric   }
1846bdd1243dSDimitry Andric   if (uint32_t CFIType = getCFIType()) {
1847bdd1243dSDimitry Andric     if (!FirstOp)
1848bdd1243dSDimitry Andric       OS << ',';
1849bdd1243dSDimitry Andric     OS << " cfi-type " << CFIType;
1850bdd1243dSDimitry Andric   }
18510b57cec5SDimitry Andric 
1852e8d8bef9SDimitry Andric   if (DebugInstrNum) {
1853e8d8bef9SDimitry Andric     if (!FirstOp)
1854e8d8bef9SDimitry Andric       OS << ",";
1855e8d8bef9SDimitry Andric     OS << " debug-instr-number " << DebugInstrNum;
1856e8d8bef9SDimitry Andric   }
1857e8d8bef9SDimitry Andric 
18580b57cec5SDimitry Andric   if (!SkipDebugLoc) {
18590b57cec5SDimitry Andric     if (const DebugLoc &DL = getDebugLoc()) {
18600b57cec5SDimitry Andric       if (!FirstOp)
18610b57cec5SDimitry Andric         OS << ',';
18620b57cec5SDimitry Andric       OS << " debug-location ";
18630b57cec5SDimitry Andric       DL->printAsOperand(OS, MST);
18640b57cec5SDimitry Andric     }
18650b57cec5SDimitry Andric   }
18660b57cec5SDimitry Andric 
18670b57cec5SDimitry Andric   if (!memoperands_empty()) {
18680b57cec5SDimitry Andric     SmallVector<StringRef, 0> SSNs;
18690b57cec5SDimitry Andric     const LLVMContext *Context = nullptr;
18700b57cec5SDimitry Andric     std::unique_ptr<LLVMContext> CtxPtr;
18710b57cec5SDimitry Andric     const MachineFrameInfo *MFI = nullptr;
18720b57cec5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
18730b57cec5SDimitry Andric       MFI = &MF->getFrameInfo();
18740b57cec5SDimitry Andric       Context = &MF->getFunction().getContext();
18750b57cec5SDimitry Andric     } else {
18768bcb0991SDimitry Andric       CtxPtr = std::make_unique<LLVMContext>();
18770b57cec5SDimitry Andric       Context = CtxPtr.get();
18780b57cec5SDimitry Andric     }
18790b57cec5SDimitry Andric 
18800b57cec5SDimitry Andric     OS << " :: ";
18810b57cec5SDimitry Andric     bool NeedComma = false;
18820b57cec5SDimitry Andric     for (const MachineMemOperand *Op : memoperands()) {
18830b57cec5SDimitry Andric       if (NeedComma)
18840b57cec5SDimitry Andric         OS << ", ";
18850b57cec5SDimitry Andric       Op->print(OS, MST, SSNs, *Context, MFI, TII);
18860b57cec5SDimitry Andric       NeedComma = true;
18870b57cec5SDimitry Andric     }
18880b57cec5SDimitry Andric   }
18890b57cec5SDimitry Andric 
18900b57cec5SDimitry Andric   if (SkipDebugLoc)
18910b57cec5SDimitry Andric     return;
18920b57cec5SDimitry Andric 
18930b57cec5SDimitry Andric   bool HaveSemi = false;
18940b57cec5SDimitry Andric 
18950b57cec5SDimitry Andric   // Print debug location information.
18960b57cec5SDimitry Andric   if (const DebugLoc &DL = getDebugLoc()) {
18970b57cec5SDimitry Andric     if (!HaveSemi) {
18980b57cec5SDimitry Andric       OS << ';';
18990b57cec5SDimitry Andric       HaveSemi = true;
19000b57cec5SDimitry Andric     }
19010b57cec5SDimitry Andric     OS << ' ';
19020b57cec5SDimitry Andric     DL.print(OS);
19030b57cec5SDimitry Andric   }
19040b57cec5SDimitry Andric 
1905*c9157d92SDimitry Andric   // Print extra comments for DEBUG_VALUE and friends if they are well-formed.
1906*c9157d92SDimitry Andric   if ((isNonListDebugValue() && getNumOperands() >= 4) ||
1907*c9157d92SDimitry Andric       (isDebugValueList() && getNumOperands() >= 2) ||
1908*c9157d92SDimitry Andric       (isDebugRef() && getNumOperands() >= 3)) {
1909*c9157d92SDimitry Andric     if (getDebugVariableOp().isMetadata()) {
19100b57cec5SDimitry Andric       if (!HaveSemi) {
19110b57cec5SDimitry Andric         OS << ";";
19120b57cec5SDimitry Andric         HaveSemi = true;
19130b57cec5SDimitry Andric       }
19145ffd83dbSDimitry Andric       auto *DV = getDebugVariable();
19150b57cec5SDimitry Andric       OS << " line no:" << DV->getLine();
19160b57cec5SDimitry Andric       if (isIndirectDebugValue())
19170b57cec5SDimitry Andric         OS << " indirect";
19180b57cec5SDimitry Andric     }
1919*c9157d92SDimitry Andric   }
19200b57cec5SDimitry Andric   // TODO: DBG_LABEL
19210b57cec5SDimitry Andric 
19220b57cec5SDimitry Andric   if (AddNewLine)
19230b57cec5SDimitry Andric     OS << '\n';
19240b57cec5SDimitry Andric }
19250b57cec5SDimitry Andric 
addRegisterKilled(Register IncomingReg,const TargetRegisterInfo * RegInfo,bool AddIfNotFound)19268bcb0991SDimitry Andric bool MachineInstr::addRegisterKilled(Register IncomingReg,
19270b57cec5SDimitry Andric                                      const TargetRegisterInfo *RegInfo,
19280b57cec5SDimitry Andric                                      bool AddIfNotFound) {
1929bdd1243dSDimitry Andric   bool isPhysReg = IncomingReg.isPhysical();
19300b57cec5SDimitry Andric   bool hasAliases = isPhysReg &&
19310b57cec5SDimitry Andric     MCRegAliasIterator(IncomingReg, RegInfo, false).isValid();
19320b57cec5SDimitry Andric   bool Found = false;
19330b57cec5SDimitry Andric   SmallVector<unsigned,4> DeadOps;
19340b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
19350b57cec5SDimitry Andric     MachineOperand &MO = getOperand(i);
19360b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isUse() || MO.isUndef())
19370b57cec5SDimitry Andric       continue;
19380b57cec5SDimitry Andric 
19390b57cec5SDimitry Andric     // DEBUG_VALUE nodes do not contribute to code generation and should
19400b57cec5SDimitry Andric     // always be ignored. Failure to do so may result in trying to modify
19410b57cec5SDimitry Andric     // KILL flags on DEBUG_VALUE nodes.
19420b57cec5SDimitry Andric     if (MO.isDebug())
19430b57cec5SDimitry Andric       continue;
19440b57cec5SDimitry Andric 
19458bcb0991SDimitry Andric     Register Reg = MO.getReg();
19460b57cec5SDimitry Andric     if (!Reg)
19470b57cec5SDimitry Andric       continue;
19480b57cec5SDimitry Andric 
19490b57cec5SDimitry Andric     if (Reg == IncomingReg) {
19500b57cec5SDimitry Andric       if (!Found) {
19510b57cec5SDimitry Andric         if (MO.isKill())
19520b57cec5SDimitry Andric           // The register is already marked kill.
19530b57cec5SDimitry Andric           return true;
19540b57cec5SDimitry Andric         if (isPhysReg && isRegTiedToDefOperand(i))
19550b57cec5SDimitry Andric           // Two-address uses of physregs must not be marked kill.
19560b57cec5SDimitry Andric           return true;
19570b57cec5SDimitry Andric         MO.setIsKill();
19580b57cec5SDimitry Andric         Found = true;
19590b57cec5SDimitry Andric       }
1960bdd1243dSDimitry Andric     } else if (hasAliases && MO.isKill() && Reg.isPhysical()) {
19610b57cec5SDimitry Andric       // A super-register kill already exists.
19620b57cec5SDimitry Andric       if (RegInfo->isSuperRegister(IncomingReg, Reg))
19630b57cec5SDimitry Andric         return true;
19640b57cec5SDimitry Andric       if (RegInfo->isSubRegister(IncomingReg, Reg))
19650b57cec5SDimitry Andric         DeadOps.push_back(i);
19660b57cec5SDimitry Andric     }
19670b57cec5SDimitry Andric   }
19680b57cec5SDimitry Andric 
19690b57cec5SDimitry Andric   // Trim unneeded kill operands.
19700b57cec5SDimitry Andric   while (!DeadOps.empty()) {
19710b57cec5SDimitry Andric     unsigned OpIdx = DeadOps.back();
19720b57cec5SDimitry Andric     if (getOperand(OpIdx).isImplicit() &&
19730b57cec5SDimitry Andric         (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0))
197481ad6265SDimitry Andric       removeOperand(OpIdx);
19750b57cec5SDimitry Andric     else
19760b57cec5SDimitry Andric       getOperand(OpIdx).setIsKill(false);
19770b57cec5SDimitry Andric     DeadOps.pop_back();
19780b57cec5SDimitry Andric   }
19790b57cec5SDimitry Andric 
19800b57cec5SDimitry Andric   // If not found, this means an alias of one of the operands is killed. Add a
19810b57cec5SDimitry Andric   // new implicit operand if required.
19820b57cec5SDimitry Andric   if (!Found && AddIfNotFound) {
19830b57cec5SDimitry Andric     addOperand(MachineOperand::CreateReg(IncomingReg,
19840b57cec5SDimitry Andric                                          false /*IsDef*/,
19850b57cec5SDimitry Andric                                          true  /*IsImp*/,
19860b57cec5SDimitry Andric                                          true  /*IsKill*/));
19870b57cec5SDimitry Andric     return true;
19880b57cec5SDimitry Andric   }
19890b57cec5SDimitry Andric   return Found;
19900b57cec5SDimitry Andric }
19910b57cec5SDimitry Andric 
clearRegisterKills(Register Reg,const TargetRegisterInfo * RegInfo)19928bcb0991SDimitry Andric void MachineInstr::clearRegisterKills(Register Reg,
19930b57cec5SDimitry Andric                                       const TargetRegisterInfo *RegInfo) {
1994bdd1243dSDimitry Andric   if (!Reg.isPhysical())
19950b57cec5SDimitry Andric     RegInfo = nullptr;
19960b57cec5SDimitry Andric   for (MachineOperand &MO : operands()) {
19970b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isUse() || !MO.isKill())
19980b57cec5SDimitry Andric       continue;
19998bcb0991SDimitry Andric     Register OpReg = MO.getReg();
20000b57cec5SDimitry Andric     if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg)
20010b57cec5SDimitry Andric       MO.setIsKill(false);
20020b57cec5SDimitry Andric   }
20030b57cec5SDimitry Andric }
20040b57cec5SDimitry Andric 
addRegisterDead(Register Reg,const TargetRegisterInfo * RegInfo,bool AddIfNotFound)20058bcb0991SDimitry Andric bool MachineInstr::addRegisterDead(Register Reg,
20060b57cec5SDimitry Andric                                    const TargetRegisterInfo *RegInfo,
20070b57cec5SDimitry Andric                                    bool AddIfNotFound) {
2008bdd1243dSDimitry Andric   bool isPhysReg = Reg.isPhysical();
20090b57cec5SDimitry Andric   bool hasAliases = isPhysReg &&
20100b57cec5SDimitry Andric     MCRegAliasIterator(Reg, RegInfo, false).isValid();
20110b57cec5SDimitry Andric   bool Found = false;
20120b57cec5SDimitry Andric   SmallVector<unsigned,4> DeadOps;
20130b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
20140b57cec5SDimitry Andric     MachineOperand &MO = getOperand(i);
20150b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef())
20160b57cec5SDimitry Andric       continue;
20178bcb0991SDimitry Andric     Register MOReg = MO.getReg();
20180b57cec5SDimitry Andric     if (!MOReg)
20190b57cec5SDimitry Andric       continue;
20200b57cec5SDimitry Andric 
20210b57cec5SDimitry Andric     if (MOReg == Reg) {
20220b57cec5SDimitry Andric       MO.setIsDead();
20230b57cec5SDimitry Andric       Found = true;
2024bdd1243dSDimitry Andric     } else if (hasAliases && MO.isDead() && MOReg.isPhysical()) {
20250b57cec5SDimitry Andric       // There exists a super-register that's marked dead.
20260b57cec5SDimitry Andric       if (RegInfo->isSuperRegister(Reg, MOReg))
20270b57cec5SDimitry Andric         return true;
20280b57cec5SDimitry Andric       if (RegInfo->isSubRegister(Reg, MOReg))
20290b57cec5SDimitry Andric         DeadOps.push_back(i);
20300b57cec5SDimitry Andric     }
20310b57cec5SDimitry Andric   }
20320b57cec5SDimitry Andric 
20330b57cec5SDimitry Andric   // Trim unneeded dead operands.
20340b57cec5SDimitry Andric   while (!DeadOps.empty()) {
20350b57cec5SDimitry Andric     unsigned OpIdx = DeadOps.back();
20360b57cec5SDimitry Andric     if (getOperand(OpIdx).isImplicit() &&
20370b57cec5SDimitry Andric         (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0))
203881ad6265SDimitry Andric       removeOperand(OpIdx);
20390b57cec5SDimitry Andric     else
20400b57cec5SDimitry Andric       getOperand(OpIdx).setIsDead(false);
20410b57cec5SDimitry Andric     DeadOps.pop_back();
20420b57cec5SDimitry Andric   }
20430b57cec5SDimitry Andric 
20440b57cec5SDimitry Andric   // If not found, this means an alias of one of the operands is dead. Add a
20450b57cec5SDimitry Andric   // new implicit operand if required.
20460b57cec5SDimitry Andric   if (Found || !AddIfNotFound)
20470b57cec5SDimitry Andric     return Found;
20480b57cec5SDimitry Andric 
20490b57cec5SDimitry Andric   addOperand(MachineOperand::CreateReg(Reg,
20500b57cec5SDimitry Andric                                        true  /*IsDef*/,
20510b57cec5SDimitry Andric                                        true  /*IsImp*/,
20520b57cec5SDimitry Andric                                        false /*IsKill*/,
20530b57cec5SDimitry Andric                                        true  /*IsDead*/));
20540b57cec5SDimitry Andric   return true;
20550b57cec5SDimitry Andric }
20560b57cec5SDimitry Andric 
clearRegisterDeads(Register Reg)20578bcb0991SDimitry Andric void MachineInstr::clearRegisterDeads(Register Reg) {
20580b57cec5SDimitry Andric   for (MachineOperand &MO : operands()) {
20590b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg)
20600b57cec5SDimitry Andric       continue;
20610b57cec5SDimitry Andric     MO.setIsDead(false);
20620b57cec5SDimitry Andric   }
20630b57cec5SDimitry Andric }
20640b57cec5SDimitry Andric 
setRegisterDefReadUndef(Register Reg,bool IsUndef)20658bcb0991SDimitry Andric void MachineInstr::setRegisterDefReadUndef(Register Reg, bool IsUndef) {
20660b57cec5SDimitry Andric   for (MachineOperand &MO : operands()) {
20670b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0)
20680b57cec5SDimitry Andric       continue;
20690b57cec5SDimitry Andric     MO.setIsUndef(IsUndef);
20700b57cec5SDimitry Andric   }
20710b57cec5SDimitry Andric }
20720b57cec5SDimitry Andric 
addRegisterDefined(Register Reg,const TargetRegisterInfo * RegInfo)20738bcb0991SDimitry Andric void MachineInstr::addRegisterDefined(Register Reg,
20740b57cec5SDimitry Andric                                       const TargetRegisterInfo *RegInfo) {
2075bdd1243dSDimitry Andric   if (Reg.isPhysical()) {
20760b57cec5SDimitry Andric     MachineOperand *MO = findRegisterDefOperand(Reg, false, false, RegInfo);
20770b57cec5SDimitry Andric     if (MO)
20780b57cec5SDimitry Andric       return;
20790b57cec5SDimitry Andric   } else {
20800b57cec5SDimitry Andric     for (const MachineOperand &MO : operands()) {
20810b57cec5SDimitry Andric       if (MO.isReg() && MO.getReg() == Reg && MO.isDef() &&
20820b57cec5SDimitry Andric           MO.getSubReg() == 0)
20830b57cec5SDimitry Andric         return;
20840b57cec5SDimitry Andric     }
20850b57cec5SDimitry Andric   }
20860b57cec5SDimitry Andric   addOperand(MachineOperand::CreateReg(Reg,
20870b57cec5SDimitry Andric                                        true  /*IsDef*/,
20880b57cec5SDimitry Andric                                        true  /*IsImp*/));
20890b57cec5SDimitry Andric }
20900b57cec5SDimitry Andric 
setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs,const TargetRegisterInfo & TRI)20918bcb0991SDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs,
20920b57cec5SDimitry Andric                                          const TargetRegisterInfo &TRI) {
20930b57cec5SDimitry Andric   bool HasRegMask = false;
20940b57cec5SDimitry Andric   for (MachineOperand &MO : operands()) {
20950b57cec5SDimitry Andric     if (MO.isRegMask()) {
20960b57cec5SDimitry Andric       HasRegMask = true;
20970b57cec5SDimitry Andric       continue;
20980b57cec5SDimitry Andric     }
20990b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef()) continue;
21008bcb0991SDimitry Andric     Register Reg = MO.getReg();
21018bcb0991SDimitry Andric     if (!Reg.isPhysical())
21028bcb0991SDimitry Andric       continue;
21030b57cec5SDimitry Andric     // If there are no uses, including partial uses, the def is dead.
21040b57cec5SDimitry Andric     if (llvm::none_of(UsedRegs,
21058bcb0991SDimitry Andric                       [&](MCRegister Use) { return TRI.regsOverlap(Use, Reg); }))
21060b57cec5SDimitry Andric       MO.setIsDead();
21070b57cec5SDimitry Andric   }
21080b57cec5SDimitry Andric 
21090b57cec5SDimitry Andric   // This is a call with a register mask operand.
21100b57cec5SDimitry Andric   // Mask clobbers are always dead, so add defs for the non-dead defines.
21110b57cec5SDimitry Andric   if (HasRegMask)
2112fe6060f1SDimitry Andric     for (const Register &UsedReg : UsedRegs)
2113fe6060f1SDimitry Andric       addRegisterDefined(UsedReg, &TRI);
21140b57cec5SDimitry Andric }
21150b57cec5SDimitry Andric 
21160b57cec5SDimitry Andric unsigned
getHashValue(const MachineInstr * const & MI)21170b57cec5SDimitry Andric MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) {
21180b57cec5SDimitry Andric   // Build up a buffer of hash code components.
2119480093f4SDimitry Andric   SmallVector<size_t, 16> HashComponents;
21200b57cec5SDimitry Andric   HashComponents.reserve(MI->getNumOperands() + 1);
21210b57cec5SDimitry Andric   HashComponents.push_back(MI->getOpcode());
21220b57cec5SDimitry Andric   for (const MachineOperand &MO : MI->operands()) {
2123bdd1243dSDimitry Andric     if (MO.isReg() && MO.isDef() && MO.getReg().isVirtual())
21240b57cec5SDimitry Andric       continue;  // Skip virtual register defs.
21250b57cec5SDimitry Andric 
21260b57cec5SDimitry Andric     HashComponents.push_back(hash_value(MO));
21270b57cec5SDimitry Andric   }
21280b57cec5SDimitry Andric   return hash_combine_range(HashComponents.begin(), HashComponents.end());
21290b57cec5SDimitry Andric }
21300b57cec5SDimitry Andric 
emitError(StringRef Msg) const21310b57cec5SDimitry Andric void MachineInstr::emitError(StringRef Msg) const {
21320b57cec5SDimitry Andric   // Find the source location cookie.
2133fe6060f1SDimitry Andric   uint64_t LocCookie = 0;
21340b57cec5SDimitry Andric   const MDNode *LocMD = nullptr;
21350b57cec5SDimitry Andric   for (unsigned i = getNumOperands(); i != 0; --i) {
21360b57cec5SDimitry Andric     if (getOperand(i-1).isMetadata() &&
21370b57cec5SDimitry Andric         (LocMD = getOperand(i-1).getMetadata()) &&
21380b57cec5SDimitry Andric         LocMD->getNumOperands() != 0) {
21390b57cec5SDimitry Andric       if (const ConstantInt *CI =
21400b57cec5SDimitry Andric               mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) {
21410b57cec5SDimitry Andric         LocCookie = CI->getZExtValue();
21420b57cec5SDimitry Andric         break;
21430b57cec5SDimitry Andric       }
21440b57cec5SDimitry Andric     }
21450b57cec5SDimitry Andric   }
21460b57cec5SDimitry Andric 
21470b57cec5SDimitry Andric   if (const MachineBasicBlock *MBB = getParent())
21480b57cec5SDimitry Andric     if (const MachineFunction *MF = MBB->getParent())
21490b57cec5SDimitry Andric       return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg);
21500b57cec5SDimitry Andric   report_fatal_error(Msg);
21510b57cec5SDimitry Andric }
21520b57cec5SDimitry Andric 
BuildMI(MachineFunction & MF,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,Register Reg,const MDNode * Variable,const MDNode * Expr)21530b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
21540b57cec5SDimitry Andric                                   const MCInstrDesc &MCID, bool IsIndirect,
21558bcb0991SDimitry Andric                                   Register Reg, const MDNode *Variable,
21560b57cec5SDimitry Andric                                   const MDNode *Expr) {
21570b57cec5SDimitry Andric   assert(isa<DILocalVariable>(Variable) && "not a variable");
21580b57cec5SDimitry Andric   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
21590b57cec5SDimitry Andric   assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
21600b57cec5SDimitry Andric          "Expected inlined-at fields to agree");
2161349cc55cSDimitry Andric   auto MIB = BuildMI(MF, DL, MCID).addReg(Reg);
21620b57cec5SDimitry Andric   if (IsIndirect)
21630b57cec5SDimitry Andric     MIB.addImm(0U);
21640b57cec5SDimitry Andric   else
2165349cc55cSDimitry Andric     MIB.addReg(0U);
21660b57cec5SDimitry Andric   return MIB.addMetadata(Variable).addMetadata(Expr);
21670b57cec5SDimitry Andric }
21680b57cec5SDimitry Andric 
BuildMI(MachineFunction & MF,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,ArrayRef<MachineOperand> DebugOps,const MDNode * Variable,const MDNode * Expr)21690b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
21700b57cec5SDimitry Andric                                   const MCInstrDesc &MCID, bool IsIndirect,
2171bdd1243dSDimitry Andric                                   ArrayRef<MachineOperand> DebugOps,
2172fe6060f1SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
21730b57cec5SDimitry Andric   assert(isa<DILocalVariable>(Variable) && "not a variable");
21740b57cec5SDimitry Andric   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
21750b57cec5SDimitry Andric   assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
21760b57cec5SDimitry Andric          "Expected inlined-at fields to agree");
2177bdd1243dSDimitry Andric   if (MCID.Opcode == TargetOpcode::DBG_VALUE) {
2178bdd1243dSDimitry Andric     assert(DebugOps.size() == 1 &&
2179bdd1243dSDimitry Andric            "DBG_VALUE must contain exactly one debug operand");
2180bdd1243dSDimitry Andric     MachineOperand DebugOp = DebugOps[0];
2181bdd1243dSDimitry Andric     if (DebugOp.isReg())
2182bdd1243dSDimitry Andric       return BuildMI(MF, DL, MCID, IsIndirect, DebugOp.getReg(), Variable,
2183bdd1243dSDimitry Andric                      Expr);
21840b57cec5SDimitry Andric 
2185bdd1243dSDimitry Andric     auto MIB = BuildMI(MF, DL, MCID).add(DebugOp);
21860b57cec5SDimitry Andric     if (IsIndirect)
21870b57cec5SDimitry Andric       MIB.addImm(0U);
21880b57cec5SDimitry Andric     else
2189349cc55cSDimitry Andric       MIB.addReg(0U);
21900b57cec5SDimitry Andric     return MIB.addMetadata(Variable).addMetadata(Expr);
21910b57cec5SDimitry Andric   }
21920b57cec5SDimitry Andric 
2193fe6060f1SDimitry Andric   auto MIB = BuildMI(MF, DL, MCID);
2194fe6060f1SDimitry Andric   MIB.addMetadata(Variable).addMetadata(Expr);
2195bdd1243dSDimitry Andric   for (const MachineOperand &DebugOp : DebugOps)
2196bdd1243dSDimitry Andric     if (DebugOp.isReg())
2197bdd1243dSDimitry Andric       MIB.addReg(DebugOp.getReg());
2198fe6060f1SDimitry Andric     else
2199bdd1243dSDimitry Andric       MIB.add(DebugOp);
2200fe6060f1SDimitry Andric   return MIB;
2201fe6060f1SDimitry Andric }
2202fe6060f1SDimitry Andric 
BuildMI(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,Register Reg,const MDNode * Variable,const MDNode * Expr)22030b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
22040b57cec5SDimitry Andric                                   MachineBasicBlock::iterator I,
22050b57cec5SDimitry Andric                                   const DebugLoc &DL, const MCInstrDesc &MCID,
22068bcb0991SDimitry Andric                                   bool IsIndirect, Register Reg,
22070b57cec5SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
22080b57cec5SDimitry Andric   MachineFunction &MF = *BB.getParent();
22090b57cec5SDimitry Andric   MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Variable, Expr);
22100b57cec5SDimitry Andric   BB.insert(I, MI);
22110b57cec5SDimitry Andric   return MachineInstrBuilder(MF, MI);
22120b57cec5SDimitry Andric }
22130b57cec5SDimitry Andric 
BuildMI(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,ArrayRef<MachineOperand> DebugOps,const MDNode * Variable,const MDNode * Expr)22140b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
22150b57cec5SDimitry Andric                                   MachineBasicBlock::iterator I,
22160b57cec5SDimitry Andric                                   const DebugLoc &DL, const MCInstrDesc &MCID,
2217bdd1243dSDimitry Andric                                   bool IsIndirect,
2218bdd1243dSDimitry Andric                                   ArrayRef<MachineOperand> DebugOps,
22190b57cec5SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
22200b57cec5SDimitry Andric   MachineFunction &MF = *BB.getParent();
2221bdd1243dSDimitry Andric   MachineInstr *MI =
2222bdd1243dSDimitry Andric       BuildMI(MF, DL, MCID, IsIndirect, DebugOps, Variable, Expr);
2223fe6060f1SDimitry Andric   BB.insert(I, MI);
2224fe6060f1SDimitry Andric   return MachineInstrBuilder(MF, *MI);
2225fe6060f1SDimitry Andric }
2226fe6060f1SDimitry Andric 
22270b57cec5SDimitry Andric /// Compute the new DIExpression to use with a DBG_VALUE for a spill slot.
22280b57cec5SDimitry Andric /// This prepends DW_OP_deref when spilling an indirect DBG_VALUE.
2229fe6060f1SDimitry Andric static const DIExpression *
computeExprForSpill(const MachineInstr & MI,SmallVectorImpl<const MachineOperand * > & SpilledOperands)2230fe6060f1SDimitry Andric computeExprForSpill(const MachineInstr &MI,
2231fe6060f1SDimitry Andric                     SmallVectorImpl<const MachineOperand *> &SpilledOperands) {
22320b57cec5SDimitry Andric   assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
22330b57cec5SDimitry Andric          "Expected inlined-at fields to agree");
22340b57cec5SDimitry Andric 
22350b57cec5SDimitry Andric   const DIExpression *Expr = MI.getDebugExpression();
22360b57cec5SDimitry Andric   if (MI.isIndirectDebugValue()) {
22375ffd83dbSDimitry Andric     assert(MI.getDebugOffset().getImm() == 0 &&
22385ffd83dbSDimitry Andric            "DBG_VALUE with nonzero offset");
22390b57cec5SDimitry Andric     Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore);
2240fe6060f1SDimitry Andric   } else if (MI.isDebugValueList()) {
2241fe6060f1SDimitry Andric     // We will replace the spilled register with a frame index, so
2242fe6060f1SDimitry Andric     // immediately deref all references to the spilled register.
2243fe6060f1SDimitry Andric     std::array<uint64_t, 1> Ops{{dwarf::DW_OP_deref}};
2244fe6060f1SDimitry Andric     for (const MachineOperand *Op : SpilledOperands) {
2245fe6060f1SDimitry Andric       unsigned OpIdx = MI.getDebugOperandIndex(Op);
2246fe6060f1SDimitry Andric       Expr = DIExpression::appendOpsToArg(Expr, Ops, OpIdx);
2247fe6060f1SDimitry Andric     }
22480b57cec5SDimitry Andric   }
22490b57cec5SDimitry Andric   return Expr;
22500b57cec5SDimitry Andric }
computeExprForSpill(const MachineInstr & MI,Register SpillReg)2251fe6060f1SDimitry Andric static const DIExpression *computeExprForSpill(const MachineInstr &MI,
2252fe6060f1SDimitry Andric                                                Register SpillReg) {
2253fe6060f1SDimitry Andric   assert(MI.hasDebugOperandForReg(SpillReg) && "Spill Reg is not used in MI.");
2254fe6060f1SDimitry Andric   SmallVector<const MachineOperand *> SpillOperands;
2255fe6060f1SDimitry Andric   for (const MachineOperand &Op : MI.getDebugOperandsForReg(SpillReg))
2256fe6060f1SDimitry Andric     SpillOperands.push_back(&Op);
2257fe6060f1SDimitry Andric   return computeExprForSpill(MI, SpillOperands);
2258fe6060f1SDimitry Andric }
22590b57cec5SDimitry Andric 
buildDbgValueForSpill(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const MachineInstr & Orig,int FrameIndex,Register SpillReg)22600b57cec5SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB,
22610b57cec5SDimitry Andric                                           MachineBasicBlock::iterator I,
22620b57cec5SDimitry Andric                                           const MachineInstr &Orig,
2263fe6060f1SDimitry Andric                                           int FrameIndex, Register SpillReg) {
2264bdd1243dSDimitry Andric   assert(!Orig.isDebugRef() &&
2265bdd1243dSDimitry Andric          "DBG_INSTR_REF should not reference a virtual register.");
2266fe6060f1SDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig, SpillReg);
2267fe6060f1SDimitry Andric   MachineInstrBuilder NewMI =
2268fe6060f1SDimitry Andric       BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc());
2269fe6060f1SDimitry Andric   // Non-Variadic Operands: Location, Offset, Variable, Expression
2270fe6060f1SDimitry Andric   // Variadic Operands:     Variable, Expression, Locations...
2271fe6060f1SDimitry Andric   if (Orig.isNonListDebugValue())
2272fe6060f1SDimitry Andric     NewMI.addFrameIndex(FrameIndex).addImm(0U);
2273fe6060f1SDimitry Andric   NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr);
2274fe6060f1SDimitry Andric   if (Orig.isDebugValueList()) {
2275fe6060f1SDimitry Andric     for (const MachineOperand &Op : Orig.debug_operands())
2276fe6060f1SDimitry Andric       if (Op.isReg() && Op.getReg() == SpillReg)
2277fe6060f1SDimitry Andric         NewMI.addFrameIndex(FrameIndex);
2278fe6060f1SDimitry Andric       else
2279fe6060f1SDimitry Andric         NewMI.add(MachineOperand(Op));
2280fe6060f1SDimitry Andric   }
2281fe6060f1SDimitry Andric   return NewMI;
2282fe6060f1SDimitry Andric }
buildDbgValueForSpill(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const MachineInstr & Orig,int FrameIndex,SmallVectorImpl<const MachineOperand * > & SpilledOperands)2283fe6060f1SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(
2284fe6060f1SDimitry Andric     MachineBasicBlock &BB, MachineBasicBlock::iterator I,
2285fe6060f1SDimitry Andric     const MachineInstr &Orig, int FrameIndex,
2286fe6060f1SDimitry Andric     SmallVectorImpl<const MachineOperand *> &SpilledOperands) {
2287fe6060f1SDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig, SpilledOperands);
2288fe6060f1SDimitry Andric   MachineInstrBuilder NewMI =
2289fe6060f1SDimitry Andric       BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc());
2290fe6060f1SDimitry Andric   // Non-Variadic Operands: Location, Offset, Variable, Expression
2291fe6060f1SDimitry Andric   // Variadic Operands:     Variable, Expression, Locations...
2292fe6060f1SDimitry Andric   if (Orig.isNonListDebugValue())
2293fe6060f1SDimitry Andric     NewMI.addFrameIndex(FrameIndex).addImm(0U);
2294fe6060f1SDimitry Andric   NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr);
2295fe6060f1SDimitry Andric   if (Orig.isDebugValueList()) {
2296fe6060f1SDimitry Andric     for (const MachineOperand &Op : Orig.debug_operands())
2297fe6060f1SDimitry Andric       if (is_contained(SpilledOperands, &Op))
2298fe6060f1SDimitry Andric         NewMI.addFrameIndex(FrameIndex);
2299fe6060f1SDimitry Andric       else
2300fe6060f1SDimitry Andric         NewMI.add(MachineOperand(Op));
2301fe6060f1SDimitry Andric   }
2302fe6060f1SDimitry Andric   return NewMI;
23030b57cec5SDimitry Andric }
23040b57cec5SDimitry Andric 
updateDbgValueForSpill(MachineInstr & Orig,int FrameIndex,Register Reg)2305fe6060f1SDimitry Andric void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex,
2306fe6060f1SDimitry Andric                                   Register Reg) {
2307fe6060f1SDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig, Reg);
2308fe6060f1SDimitry Andric   if (Orig.isNonListDebugValue())
23095ffd83dbSDimitry Andric     Orig.getDebugOffset().ChangeToImmediate(0U);
2310fe6060f1SDimitry Andric   for (MachineOperand &Op : Orig.getDebugOperandsForReg(Reg))
2311fe6060f1SDimitry Andric     Op.ChangeToFrameIndex(FrameIndex);
23125ffd83dbSDimitry Andric   Orig.getDebugExpressionOp().setMetadata(Expr);
23130b57cec5SDimitry Andric }
23140b57cec5SDimitry Andric 
collectDebugValues(SmallVectorImpl<MachineInstr * > & DbgValues)23150b57cec5SDimitry Andric void MachineInstr::collectDebugValues(
23160b57cec5SDimitry Andric                                 SmallVectorImpl<MachineInstr *> &DbgValues) {
23170b57cec5SDimitry Andric   MachineInstr &MI = *this;
23180b57cec5SDimitry Andric   if (!MI.getOperand(0).isReg())
23190b57cec5SDimitry Andric     return;
23200b57cec5SDimitry Andric 
23210b57cec5SDimitry Andric   MachineBasicBlock::iterator DI = MI; ++DI;
23220b57cec5SDimitry Andric   for (MachineBasicBlock::iterator DE = MI.getParent()->end();
23230b57cec5SDimitry Andric        DI != DE; ++DI) {
23240b57cec5SDimitry Andric     if (!DI->isDebugValue())
23250b57cec5SDimitry Andric       return;
2326fe6060f1SDimitry Andric     if (DI->hasDebugOperandForReg(MI.getOperand(0).getReg()))
23270b57cec5SDimitry Andric       DbgValues.push_back(&*DI);
23280b57cec5SDimitry Andric   }
23290b57cec5SDimitry Andric }
23300b57cec5SDimitry Andric 
changeDebugValuesDefReg(Register Reg)23318bcb0991SDimitry Andric void MachineInstr::changeDebugValuesDefReg(Register Reg) {
23320b57cec5SDimitry Andric   // Collect matching debug values.
23330b57cec5SDimitry Andric   SmallVector<MachineInstr *, 2> DbgValues;
23348bcb0991SDimitry Andric 
23358bcb0991SDimitry Andric   if (!getOperand(0).isReg())
23368bcb0991SDimitry Andric     return;
23378bcb0991SDimitry Andric 
23385ffd83dbSDimitry Andric   Register DefReg = getOperand(0).getReg();
23398bcb0991SDimitry Andric   auto *MRI = getRegInfo();
23408bcb0991SDimitry Andric   for (auto &MO : MRI->use_operands(DefReg)) {
23418bcb0991SDimitry Andric     auto *DI = MO.getParent();
23428bcb0991SDimitry Andric     if (!DI->isDebugValue())
23438bcb0991SDimitry Andric       continue;
2344fe6060f1SDimitry Andric     if (DI->hasDebugOperandForReg(DefReg)) {
23458bcb0991SDimitry Andric       DbgValues.push_back(DI);
23468bcb0991SDimitry Andric     }
23478bcb0991SDimitry Andric   }
23480b57cec5SDimitry Andric 
23490b57cec5SDimitry Andric   // Propagate Reg to debug value instructions.
23500b57cec5SDimitry Andric   for (auto *DBI : DbgValues)
2351fe6060f1SDimitry Andric     for (MachineOperand &Op : DBI->getDebugOperandsForReg(DefReg))
2352fe6060f1SDimitry Andric       Op.setReg(Reg);
23530b57cec5SDimitry Andric }
23540b57cec5SDimitry Andric 
23550b57cec5SDimitry Andric using MMOList = SmallVector<const MachineMemOperand *, 2>;
23560b57cec5SDimitry Andric 
getSpillSlotSize(const MMOList & Accesses,const MachineFrameInfo & MFI)23575ffd83dbSDimitry Andric static unsigned getSpillSlotSize(const MMOList &Accesses,
23580b57cec5SDimitry Andric                                  const MachineFrameInfo &MFI) {
23590b57cec5SDimitry Andric   unsigned Size = 0;
2360fcaf7f86SDimitry Andric   for (const auto *A : Accesses)
23610b57cec5SDimitry Andric     if (MFI.isSpillSlotObjectIndex(
23620b57cec5SDimitry Andric             cast<FixedStackPseudoSourceValue>(A->getPseudoValue())
23630b57cec5SDimitry Andric                 ->getFrameIndex()))
23640b57cec5SDimitry Andric       Size += A->getSize();
23650b57cec5SDimitry Andric   return Size;
23660b57cec5SDimitry Andric }
23670b57cec5SDimitry Andric 
2368bdd1243dSDimitry Andric std::optional<unsigned>
getSpillSize(const TargetInstrInfo * TII) const23690b57cec5SDimitry Andric MachineInstr::getSpillSize(const TargetInstrInfo *TII) const {
23700b57cec5SDimitry Andric   int FI;
23710b57cec5SDimitry Andric   if (TII->isStoreToStackSlotPostFE(*this, FI)) {
23720b57cec5SDimitry Andric     const MachineFrameInfo &MFI = getMF()->getFrameInfo();
23730b57cec5SDimitry Andric     if (MFI.isSpillSlotObjectIndex(FI))
23740b57cec5SDimitry Andric       return (*memoperands_begin())->getSize();
23750b57cec5SDimitry Andric   }
2376bdd1243dSDimitry Andric   return std::nullopt;
23770b57cec5SDimitry Andric }
23780b57cec5SDimitry Andric 
2379bdd1243dSDimitry Andric std::optional<unsigned>
getFoldedSpillSize(const TargetInstrInfo * TII) const23800b57cec5SDimitry Andric MachineInstr::getFoldedSpillSize(const TargetInstrInfo *TII) const {
23810b57cec5SDimitry Andric   MMOList Accesses;
23820b57cec5SDimitry Andric   if (TII->hasStoreToStackSlot(*this, Accesses))
23830b57cec5SDimitry Andric     return getSpillSlotSize(Accesses, getMF()->getFrameInfo());
2384bdd1243dSDimitry Andric   return std::nullopt;
23850b57cec5SDimitry Andric }
23860b57cec5SDimitry Andric 
2387bdd1243dSDimitry Andric std::optional<unsigned>
getRestoreSize(const TargetInstrInfo * TII) const23880b57cec5SDimitry Andric MachineInstr::getRestoreSize(const TargetInstrInfo *TII) const {
23890b57cec5SDimitry Andric   int FI;
23900b57cec5SDimitry Andric   if (TII->isLoadFromStackSlotPostFE(*this, FI)) {
23910b57cec5SDimitry Andric     const MachineFrameInfo &MFI = getMF()->getFrameInfo();
23920b57cec5SDimitry Andric     if (MFI.isSpillSlotObjectIndex(FI))
23930b57cec5SDimitry Andric       return (*memoperands_begin())->getSize();
23940b57cec5SDimitry Andric   }
2395bdd1243dSDimitry Andric   return std::nullopt;
23960b57cec5SDimitry Andric }
23970b57cec5SDimitry Andric 
2398bdd1243dSDimitry Andric std::optional<unsigned>
getFoldedRestoreSize(const TargetInstrInfo * TII) const23990b57cec5SDimitry Andric MachineInstr::getFoldedRestoreSize(const TargetInstrInfo *TII) const {
24000b57cec5SDimitry Andric   MMOList Accesses;
24010b57cec5SDimitry Andric   if (TII->hasLoadFromStackSlot(*this, Accesses))
24020b57cec5SDimitry Andric     return getSpillSlotSize(Accesses, getMF()->getFrameInfo());
2403bdd1243dSDimitry Andric   return std::nullopt;
24040b57cec5SDimitry Andric }
2405e8d8bef9SDimitry Andric 
getDebugInstrNum()2406e8d8bef9SDimitry Andric unsigned MachineInstr::getDebugInstrNum() {
2407e8d8bef9SDimitry Andric   if (DebugInstrNum == 0)
2408e8d8bef9SDimitry Andric     DebugInstrNum = getParent()->getParent()->getNewDebugInstrNum();
2409e8d8bef9SDimitry Andric   return DebugInstrNum;
2410e8d8bef9SDimitry Andric }
2411fe6060f1SDimitry Andric 
getDebugInstrNum(MachineFunction & MF)2412fe6060f1SDimitry Andric unsigned MachineInstr::getDebugInstrNum(MachineFunction &MF) {
2413fe6060f1SDimitry Andric   if (DebugInstrNum == 0)
2414fe6060f1SDimitry Andric     DebugInstrNum = MF.getNewDebugInstrNum();
2415fe6060f1SDimitry Andric   return DebugInstrNum;
2416fe6060f1SDimitry Andric }
2417fe013be4SDimitry Andric 
getFirst2LLTs() const2418fe013be4SDimitry Andric std::tuple<LLT, LLT> MachineInstr::getFirst2LLTs() const {
2419fe013be4SDimitry Andric   return std::tuple(getRegInfo()->getType(getOperand(0).getReg()),
2420fe013be4SDimitry Andric                     getRegInfo()->getType(getOperand(1).getReg()));
2421fe013be4SDimitry Andric }
2422fe013be4SDimitry Andric 
getFirst3LLTs() const2423fe013be4SDimitry Andric std::tuple<LLT, LLT, LLT> MachineInstr::getFirst3LLTs() const {
2424fe013be4SDimitry Andric   return std::tuple(getRegInfo()->getType(getOperand(0).getReg()),
2425fe013be4SDimitry Andric                     getRegInfo()->getType(getOperand(1).getReg()),
2426fe013be4SDimitry Andric                     getRegInfo()->getType(getOperand(2).getReg()));
2427fe013be4SDimitry Andric }
2428fe013be4SDimitry Andric 
getFirst4LLTs() const2429fe013be4SDimitry Andric std::tuple<LLT, LLT, LLT, LLT> MachineInstr::getFirst4LLTs() const {
2430fe013be4SDimitry Andric   return std::tuple(getRegInfo()->getType(getOperand(0).getReg()),
2431fe013be4SDimitry Andric                     getRegInfo()->getType(getOperand(1).getReg()),
2432fe013be4SDimitry Andric                     getRegInfo()->getType(getOperand(2).getReg()),
2433fe013be4SDimitry Andric                     getRegInfo()->getType(getOperand(3).getReg()));
2434fe013be4SDimitry Andric }
2435fe013be4SDimitry Andric 
getFirst5LLTs() const2436fe013be4SDimitry Andric std::tuple<LLT, LLT, LLT, LLT, LLT> MachineInstr::getFirst5LLTs() const {
2437fe013be4SDimitry Andric   return std::tuple(getRegInfo()->getType(getOperand(0).getReg()),
2438fe013be4SDimitry Andric                     getRegInfo()->getType(getOperand(1).getReg()),
2439fe013be4SDimitry Andric                     getRegInfo()->getType(getOperand(2).getReg()),
2440fe013be4SDimitry Andric                     getRegInfo()->getType(getOperand(3).getReg()),
2441fe013be4SDimitry Andric                     getRegInfo()->getType(getOperand(4).getReg()));
2442fe013be4SDimitry Andric }
2443fe013be4SDimitry Andric 
2444fe013be4SDimitry Andric std::tuple<Register, LLT, Register, LLT>
getFirst2RegLLTs() const2445fe013be4SDimitry Andric MachineInstr::getFirst2RegLLTs() const {
2446fe013be4SDimitry Andric   Register Reg0 = getOperand(0).getReg();
2447fe013be4SDimitry Andric   Register Reg1 = getOperand(1).getReg();
2448fe013be4SDimitry Andric   return std::tuple(Reg0, getRegInfo()->getType(Reg0), Reg1,
2449fe013be4SDimitry Andric                     getRegInfo()->getType(Reg1));
2450fe013be4SDimitry Andric }
2451fe013be4SDimitry Andric 
2452fe013be4SDimitry Andric std::tuple<Register, LLT, Register, LLT, Register, LLT>
getFirst3RegLLTs() const2453fe013be4SDimitry Andric MachineInstr::getFirst3RegLLTs() const {
2454fe013be4SDimitry Andric   Register Reg0 = getOperand(0).getReg();
2455fe013be4SDimitry Andric   Register Reg1 = getOperand(1).getReg();
2456fe013be4SDimitry Andric   Register Reg2 = getOperand(2).getReg();
2457fe013be4SDimitry Andric   return std::tuple(Reg0, getRegInfo()->getType(Reg0), Reg1,
2458fe013be4SDimitry Andric                     getRegInfo()->getType(Reg1), Reg2,
2459fe013be4SDimitry Andric                     getRegInfo()->getType(Reg2));
2460fe013be4SDimitry Andric }
2461fe013be4SDimitry Andric 
2462fe013be4SDimitry Andric std::tuple<Register, LLT, Register, LLT, Register, LLT, Register, LLT>
getFirst4RegLLTs() const2463fe013be4SDimitry Andric MachineInstr::getFirst4RegLLTs() const {
2464fe013be4SDimitry Andric   Register Reg0 = getOperand(0).getReg();
2465fe013be4SDimitry Andric   Register Reg1 = getOperand(1).getReg();
2466fe013be4SDimitry Andric   Register Reg2 = getOperand(2).getReg();
2467fe013be4SDimitry Andric   Register Reg3 = getOperand(3).getReg();
2468fe013be4SDimitry Andric   return std::tuple(
2469fe013be4SDimitry Andric       Reg0, getRegInfo()->getType(Reg0), Reg1, getRegInfo()->getType(Reg1),
2470fe013be4SDimitry Andric       Reg2, getRegInfo()->getType(Reg2), Reg3, getRegInfo()->getType(Reg3));
2471fe013be4SDimitry Andric }
2472fe013be4SDimitry Andric 
2473fe013be4SDimitry Andric std::tuple<Register, LLT, Register, LLT, Register, LLT, Register, LLT, Register,
2474fe013be4SDimitry Andric            LLT>
getFirst5RegLLTs() const2475fe013be4SDimitry Andric MachineInstr::getFirst5RegLLTs() const {
2476fe013be4SDimitry Andric   Register Reg0 = getOperand(0).getReg();
2477fe013be4SDimitry Andric   Register Reg1 = getOperand(1).getReg();
2478fe013be4SDimitry Andric   Register Reg2 = getOperand(2).getReg();
2479fe013be4SDimitry Andric   Register Reg3 = getOperand(3).getReg();
2480fe013be4SDimitry Andric   Register Reg4 = getOperand(4).getReg();
2481fe013be4SDimitry Andric   return std::tuple(
2482fe013be4SDimitry Andric       Reg0, getRegInfo()->getType(Reg0), Reg1, getRegInfo()->getType(Reg1),
2483fe013be4SDimitry Andric       Reg2, getRegInfo()->getType(Reg2), Reg3, getRegInfo()->getType(Reg3),
2484fe013be4SDimitry Andric       Reg4, getRegInfo()->getType(Reg4));
2485fe013be4SDimitry Andric }
2486*c9157d92SDimitry Andric 
insert(mop_iterator InsertBefore,ArrayRef<MachineOperand> Ops)2487*c9157d92SDimitry Andric void MachineInstr::insert(mop_iterator InsertBefore,
2488*c9157d92SDimitry Andric                           ArrayRef<MachineOperand> Ops) {
2489*c9157d92SDimitry Andric   assert(InsertBefore != nullptr && "invalid iterator");
2490*c9157d92SDimitry Andric   assert(InsertBefore->getParent() == this &&
2491*c9157d92SDimitry Andric          "iterator points to operand of other inst");
2492*c9157d92SDimitry Andric   if (Ops.empty())
2493*c9157d92SDimitry Andric     return;
2494*c9157d92SDimitry Andric 
2495*c9157d92SDimitry Andric   // Do one pass to untie operands.
2496*c9157d92SDimitry Andric   SmallDenseMap<unsigned, unsigned> TiedOpIndices;
2497*c9157d92SDimitry Andric   for (const MachineOperand &MO : operands()) {
2498*c9157d92SDimitry Andric     if (MO.isReg() && MO.isTied()) {
2499*c9157d92SDimitry Andric       unsigned OpNo = getOperandNo(&MO);
2500*c9157d92SDimitry Andric       unsigned TiedTo = findTiedOperandIdx(OpNo);
2501*c9157d92SDimitry Andric       TiedOpIndices[OpNo] = TiedTo;
2502*c9157d92SDimitry Andric       untieRegOperand(OpNo);
2503*c9157d92SDimitry Andric     }
2504*c9157d92SDimitry Andric   }
2505*c9157d92SDimitry Andric 
2506*c9157d92SDimitry Andric   unsigned OpIdx = getOperandNo(InsertBefore);
2507*c9157d92SDimitry Andric   unsigned NumOperands = getNumOperands();
2508*c9157d92SDimitry Andric   unsigned OpsToMove = NumOperands - OpIdx;
2509*c9157d92SDimitry Andric 
2510*c9157d92SDimitry Andric   SmallVector<MachineOperand> MovingOps;
2511*c9157d92SDimitry Andric   MovingOps.reserve(OpsToMove);
2512*c9157d92SDimitry Andric 
2513*c9157d92SDimitry Andric   for (unsigned I = 0; I < OpsToMove; ++I) {
2514*c9157d92SDimitry Andric     MovingOps.emplace_back(getOperand(OpIdx));
2515*c9157d92SDimitry Andric     removeOperand(OpIdx);
2516*c9157d92SDimitry Andric   }
2517*c9157d92SDimitry Andric   for (const MachineOperand &MO : Ops)
2518*c9157d92SDimitry Andric     addOperand(MO);
2519*c9157d92SDimitry Andric   for (const MachineOperand &OpMoved : MovingOps)
2520*c9157d92SDimitry Andric     addOperand(OpMoved);
2521*c9157d92SDimitry Andric 
2522*c9157d92SDimitry Andric   // Re-tie operands.
2523*c9157d92SDimitry Andric   for (auto [Tie1, Tie2] : TiedOpIndices) {
2524*c9157d92SDimitry Andric     if (Tie1 >= OpIdx)
2525*c9157d92SDimitry Andric       Tie1 += Ops.size();
2526*c9157d92SDimitry Andric     if (Tie2 >= OpIdx)
2527*c9157d92SDimitry Andric       Tie2 += Ops.size();
2528*c9157d92SDimitry Andric     tieOperands(Tie1, Tie2);
2529*c9157d92SDimitry Andric   }
2530*c9157d92SDimitry Andric }
2531*c9157d92SDimitry Andric 
mayFoldInlineAsmRegOp(unsigned OpId) const2532*c9157d92SDimitry Andric bool MachineInstr::mayFoldInlineAsmRegOp(unsigned OpId) const {
2533*c9157d92SDimitry Andric   assert(OpId && "expected non-zero operand id");
2534*c9157d92SDimitry Andric   assert(isInlineAsm() && "should only be used on inline asm");
2535*c9157d92SDimitry Andric 
2536*c9157d92SDimitry Andric   if (!getOperand(OpId).isReg())
2537*c9157d92SDimitry Andric     return false;
2538*c9157d92SDimitry Andric 
2539*c9157d92SDimitry Andric   const MachineOperand &MD = getOperand(OpId - 1);
2540*c9157d92SDimitry Andric   if (!MD.isImm())
2541*c9157d92SDimitry Andric     return false;
2542*c9157d92SDimitry Andric 
2543*c9157d92SDimitry Andric   InlineAsm::Flag F(MD.getImm());
2544*c9157d92SDimitry Andric   if (F.isRegUseKind() || F.isRegDefKind() || F.isRegDefEarlyClobberKind())
2545*c9157d92SDimitry Andric     return F.getRegMayBeFolded();
2546*c9157d92SDimitry Andric   return false;
2547*c9157d92SDimitry Andric }
2548