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