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/APFloat.h"
150b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
160b57cec5SDimitry Andric #include "llvm/ADT/FoldingSet.h"
170b57cec5SDimitry Andric #include "llvm/ADT/Hashing.h"
180b57cec5SDimitry Andric #include "llvm/ADT/None.h"
190b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallBitVector.h"
210b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
220b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
230b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
240b57cec5SDimitry Andric #include "llvm/Analysis/Loads.h"
250b57cec5SDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h"
37af732203SDimitry Andric #include "llvm/CodeGen/StackMaps.h"
380b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
390b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
400b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
410b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
420b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
430b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
440b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
450b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
460b57cec5SDimitry Andric #include "llvm/IR/Function.h"
470b57cec5SDimitry Andric #include "llvm/IR/InlineAsm.h"
480b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
490b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
500b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
510b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
520b57cec5SDimitry Andric #include "llvm/IR/Module.h"
530b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
540b57cec5SDimitry Andric #include "llvm/IR/Operator.h"
550b57cec5SDimitry Andric #include "llvm/IR/Type.h"
560b57cec5SDimitry Andric #include "llvm/IR/Value.h"
570b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
580b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
590b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
600b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
610b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
620b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
630b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
640b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
655ffd83dbSDimitry Andric #include "llvm/Support/FormattedStream.h"
660b57cec5SDimitry Andric #include "llvm/Support/LowLevelTypeImpl.h"
670b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
680b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
690b57cec5SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
700b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
710b57cec5SDimitry Andric #include <algorithm>
720b57cec5SDimitry Andric #include <cassert>
730b57cec5SDimitry Andric #include <cstddef>
740b57cec5SDimitry Andric #include <cstdint>
750b57cec5SDimitry Andric #include <cstring>
760b57cec5SDimitry Andric #include <iterator>
770b57cec5SDimitry Andric #include <utility>
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric using namespace llvm;
800b57cec5SDimitry Andric 
getMFIfAvailable(const MachineInstr & MI)810b57cec5SDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineInstr &MI) {
820b57cec5SDimitry Andric   if (const MachineBasicBlock *MBB = MI.getParent())
830b57cec5SDimitry Andric     if (const MachineFunction *MF = MBB->getParent())
840b57cec5SDimitry Andric       return MF;
850b57cec5SDimitry Andric   return nullptr;
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from
890b57cec5SDimitry Andric // it.
tryToGetTargetInfo(const MachineInstr & MI,const TargetRegisterInfo * & TRI,const MachineRegisterInfo * & MRI,const TargetIntrinsicInfo * & IntrinsicInfo,const TargetInstrInfo * & TII)900b57cec5SDimitry Andric static void tryToGetTargetInfo(const MachineInstr &MI,
910b57cec5SDimitry Andric                                const TargetRegisterInfo *&TRI,
920b57cec5SDimitry Andric                                const MachineRegisterInfo *&MRI,
930b57cec5SDimitry Andric                                const TargetIntrinsicInfo *&IntrinsicInfo,
940b57cec5SDimitry Andric                                const TargetInstrInfo *&TII) {
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(MI)) {
970b57cec5SDimitry Andric     TRI = MF->getSubtarget().getRegisterInfo();
980b57cec5SDimitry Andric     MRI = &MF->getRegInfo();
990b57cec5SDimitry Andric     IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
1000b57cec5SDimitry Andric     TII = MF->getSubtarget().getInstrInfo();
1010b57cec5SDimitry Andric   }
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
addImplicitDefUseOperands(MachineFunction & MF)1040b57cec5SDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) {
1050b57cec5SDimitry Andric   if (MCID->ImplicitDefs)
1060b57cec5SDimitry Andric     for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs;
1070b57cec5SDimitry Andric            ++ImpDefs)
1080b57cec5SDimitry Andric       addOperand(MF, MachineOperand::CreateReg(*ImpDefs, true, true));
1090b57cec5SDimitry Andric   if (MCID->ImplicitUses)
1100b57cec5SDimitry Andric     for (const MCPhysReg *ImpUses = MCID->getImplicitUses(); *ImpUses;
1110b57cec5SDimitry Andric            ++ImpUses)
1120b57cec5SDimitry Andric       addOperand(MF, MachineOperand::CreateReg(*ImpUses, false, true));
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric /// MachineInstr ctor - This constructor creates a MachineInstr and adds the
1160b57cec5SDimitry Andric /// implicit operands. It reserves space for the number of operands specified by
1170b57cec5SDimitry Andric /// the MCInstrDesc.
MachineInstr(MachineFunction & MF,const MCInstrDesc & tid,DebugLoc dl,bool NoImp)1180b57cec5SDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,
1190b57cec5SDimitry Andric                            DebugLoc dl, bool NoImp)
120af732203SDimitry Andric     : MCID(&tid), debugLoc(std::move(dl)), DebugInstrNum(0) {
1210b57cec5SDimitry Andric   assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   // Reserve space for the expected number of operands.
1240b57cec5SDimitry Andric   if (unsigned NumOps = MCID->getNumOperands() +
1250b57cec5SDimitry Andric     MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) {
1260b57cec5SDimitry Andric     CapOperands = OperandCapacity::get(NumOps);
1270b57cec5SDimitry Andric     Operands = MF.allocateOperandArray(CapOperands);
1280b57cec5SDimitry Andric   }
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   if (!NoImp)
1310b57cec5SDimitry Andric     addImplicitDefUseOperands(MF);
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
134af732203SDimitry Andric /// MachineInstr ctor - Copies MachineInstr arg exactly.
135af732203SDimitry Andric /// Does not copy the number from debug instruction numbering, to preserve
136af732203SDimitry Andric /// uniqueness.
MachineInstr(MachineFunction & MF,const MachineInstr & MI)1370b57cec5SDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
138af732203SDimitry Andric     : MCID(&MI.getDesc()), Info(MI.Info), debugLoc(MI.getDebugLoc()),
139af732203SDimitry Andric       DebugInstrNum(0) {
1400b57cec5SDimitry Andric   assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   CapOperands = OperandCapacity::get(MI.getNumOperands());
1430b57cec5SDimitry Andric   Operands = MF.allocateOperandArray(CapOperands);
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   // Copy operands.
1460b57cec5SDimitry Andric   for (const MachineOperand &MO : MI.operands())
1470b57cec5SDimitry Andric     addOperand(MF, MO);
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   // Copy all the sensible flags.
1500b57cec5SDimitry Andric   setFlags(MI.Flags);
1510b57cec5SDimitry Andric }
1520b57cec5SDimitry Andric 
moveBefore(MachineInstr * MovePos)153af732203SDimitry Andric void MachineInstr::moveBefore(MachineInstr *MovePos) {
154af732203SDimitry Andric   MovePos->getParent()->splice(MovePos, getParent(), getIterator());
155af732203SDimitry Andric }
156af732203SDimitry Andric 
1570b57cec5SDimitry Andric /// getRegInfo - If this instruction is embedded into a MachineFunction,
1580b57cec5SDimitry Andric /// return the MachineRegisterInfo object for the current function, otherwise
1590b57cec5SDimitry Andric /// return null.
getRegInfo()1600b57cec5SDimitry Andric MachineRegisterInfo *MachineInstr::getRegInfo() {
1610b57cec5SDimitry Andric   if (MachineBasicBlock *MBB = getParent())
1620b57cec5SDimitry Andric     return &MBB->getParent()->getRegInfo();
1630b57cec5SDimitry Andric   return nullptr;
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in
1670b57cec5SDimitry Andric /// this instruction from their respective use lists.  This requires that the
1680b57cec5SDimitry Andric /// operands already be on their use lists.
RemoveRegOperandsFromUseLists(MachineRegisterInfo & MRI)1690b57cec5SDimitry 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 
1750b57cec5SDimitry Andric /// AddRegOperandsToUseLists - Add all of the register operands in
1760b57cec5SDimitry Andric /// this instruction from their respective use lists.  This requires that the
1770b57cec5SDimitry Andric /// operands not be on their use lists yet.
AddRegOperandsToUseLists(MachineRegisterInfo & MRI)1780b57cec5SDimitry Andric void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) {
1790b57cec5SDimitry Andric   for (MachineOperand &MO : operands())
1800b57cec5SDimitry Andric     if (MO.isReg())
1810b57cec5SDimitry Andric       MRI.addRegOperandToUseList(&MO);
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric 
addOperand(const MachineOperand & Op)1840b57cec5SDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) {
1850b57cec5SDimitry Andric   MachineBasicBlock *MBB = getParent();
1860b57cec5SDimitry Andric   assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs");
1870b57cec5SDimitry Andric   MachineFunction *MF = MBB->getParent();
1880b57cec5SDimitry Andric   assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs");
1890b57cec5SDimitry Andric   addOperand(*MF, Op);
1900b57cec5SDimitry Andric }
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping
1930b57cec5SDimitry Andric /// ranges. If MRI is non-null also update use-def chains.
moveOperands(MachineOperand * Dst,MachineOperand * Src,unsigned NumOps,MachineRegisterInfo * MRI)1940b57cec5SDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src,
1950b57cec5SDimitry Andric                          unsigned NumOps, MachineRegisterInfo *MRI) {
1960b57cec5SDimitry Andric   if (MRI)
1970b57cec5SDimitry Andric     return MRI->moveOperands(Dst, Src, NumOps);
1980b57cec5SDimitry Andric   // MachineOperand is a trivially copyable type so we can just use memmove.
199480093f4SDimitry Andric   assert(Dst && Src && "Unknown operands");
2000b57cec5SDimitry Andric   std::memmove(Dst, Src, NumOps * sizeof(MachineOperand));
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric /// addOperand - Add the specified operand to the instruction.  If it is an
2040b57cec5SDimitry Andric /// implicit operand, it is added to the end of the operand list.  If it is
2050b57cec5SDimitry Andric /// an explicit operand it is added at the end of the explicit operand list
2060b57cec5SDimitry Andric /// (before the first implicit operand).
addOperand(MachineFunction & MF,const MachineOperand & Op)2070b57cec5SDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) {
2080b57cec5SDimitry Andric   assert(MCID && "Cannot add operands before providing an instr descriptor");
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric   // Check if we're adding one of our existing operands.
2110b57cec5SDimitry Andric   if (&Op >= Operands && &Op < Operands + NumOperands) {
2120b57cec5SDimitry Andric     // This is unusual: MI->addOperand(MI->getOperand(i)).
2130b57cec5SDimitry Andric     // If adding Op requires reallocating or moving existing operands around,
2140b57cec5SDimitry Andric     // the Op reference could go stale. Support it by copying Op.
2150b57cec5SDimitry Andric     MachineOperand CopyOp(Op);
2160b57cec5SDimitry Andric     return addOperand(MF, CopyOp);
2170b57cec5SDimitry Andric   }
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   // Find the insert location for the new operand.  Implicit registers go at
2200b57cec5SDimitry Andric   // the end, everything else goes before the implicit regs.
2210b57cec5SDimitry Andric   //
2220b57cec5SDimitry Andric   // FIXME: Allow mixed explicit and implicit operands on inline asm.
2230b57cec5SDimitry Andric   // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as
2240b57cec5SDimitry Andric   // implicit-defs, but they must not be moved around.  See the FIXME in
2250b57cec5SDimitry Andric   // InstrEmitter.cpp.
2260b57cec5SDimitry Andric   unsigned OpNo = getNumOperands();
2270b57cec5SDimitry Andric   bool isImpReg = Op.isReg() && Op.isImplicit();
2280b57cec5SDimitry Andric   if (!isImpReg && !isInlineAsm()) {
2290b57cec5SDimitry Andric     while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) {
2300b57cec5SDimitry Andric       --OpNo;
2310b57cec5SDimitry Andric       assert(!Operands[OpNo].isTied() && "Cannot move tied operands");
2320b57cec5SDimitry Andric     }
2330b57cec5SDimitry Andric   }
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric #ifndef NDEBUG
2360b57cec5SDimitry Andric   bool isDebugOp = Op.getType() == MachineOperand::MO_Metadata ||
2370b57cec5SDimitry Andric                    Op.getType() == MachineOperand::MO_MCSymbol;
2380b57cec5SDimitry Andric   // OpNo now points as the desired insertion point.  Unless this is a variadic
2390b57cec5SDimitry Andric   // instruction, only implicit regs are allowed beyond MCID->getNumOperands().
2400b57cec5SDimitry Andric   // RegMask operands go between the explicit and implicit operands.
2410b57cec5SDimitry Andric   assert((isImpReg || Op.isRegMask() || MCID->isVariadic() ||
2420b57cec5SDimitry Andric           OpNo < MCID->getNumOperands() || isDebugOp) &&
2430b57cec5SDimitry Andric          "Trying to add an operand to a machine instr that is already done!");
2440b57cec5SDimitry Andric #endif
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric   MachineRegisterInfo *MRI = getRegInfo();
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   // Determine if the Operands array needs to be reallocated.
2490b57cec5SDimitry Andric   // Save the old capacity and operand array.
2500b57cec5SDimitry Andric   OperandCapacity OldCap = CapOperands;
2510b57cec5SDimitry Andric   MachineOperand *OldOperands = Operands;
2520b57cec5SDimitry Andric   if (!OldOperands || OldCap.getSize() == getNumOperands()) {
2530b57cec5SDimitry Andric     CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1);
2540b57cec5SDimitry Andric     Operands = MF.allocateOperandArray(CapOperands);
2550b57cec5SDimitry Andric     // Move the operands before the insertion point.
2560b57cec5SDimitry Andric     if (OpNo)
2570b57cec5SDimitry Andric       moveOperands(Operands, OldOperands, OpNo, MRI);
2580b57cec5SDimitry Andric   }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   // Move the operands following the insertion point.
2610b57cec5SDimitry Andric   if (OpNo != NumOperands)
2620b57cec5SDimitry Andric     moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo,
2630b57cec5SDimitry Andric                  MRI);
2640b57cec5SDimitry Andric   ++NumOperands;
2650b57cec5SDimitry Andric 
2660b57cec5SDimitry Andric   // Deallocate the old operand array.
2670b57cec5SDimitry Andric   if (OldOperands != Operands && OldOperands)
2680b57cec5SDimitry Andric     MF.deallocateOperandArray(OldCap, OldOperands);
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric   // Copy Op into place. It still needs to be inserted into the MRI use lists.
2710b57cec5SDimitry Andric   MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op);
2720b57cec5SDimitry Andric   NewMO->ParentMI = this;
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric   // When adding a register operand, tell MRI about it.
2750b57cec5SDimitry Andric   if (NewMO->isReg()) {
2760b57cec5SDimitry Andric     // Ensure isOnRegUseList() returns false, regardless of Op's status.
2770b57cec5SDimitry Andric     NewMO->Contents.Reg.Prev = nullptr;
2780b57cec5SDimitry Andric     // Ignore existing ties. This is not a property that can be copied.
2790b57cec5SDimitry Andric     NewMO->TiedTo = 0;
2800b57cec5SDimitry Andric     // Add the new operand to MRI, but only for instructions in an MBB.
2810b57cec5SDimitry Andric     if (MRI)
2820b57cec5SDimitry Andric       MRI->addRegOperandToUseList(NewMO);
2830b57cec5SDimitry Andric     // The MCID operand information isn't accurate until we start adding
2840b57cec5SDimitry Andric     // explicit operands. The implicit operands are added first, then the
2850b57cec5SDimitry Andric     // explicits are inserted before them.
2860b57cec5SDimitry Andric     if (!isImpReg) {
2870b57cec5SDimitry Andric       // Tie uses to defs as indicated in MCInstrDesc.
2880b57cec5SDimitry Andric       if (NewMO->isUse()) {
2890b57cec5SDimitry Andric         int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO);
2900b57cec5SDimitry Andric         if (DefIdx != -1)
2910b57cec5SDimitry Andric           tieOperands(DefIdx, OpNo);
2920b57cec5SDimitry Andric       }
2930b57cec5SDimitry Andric       // If the register operand is flagged as early, mark the operand as such.
2940b57cec5SDimitry Andric       if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1)
2950b57cec5SDimitry Andric         NewMO->setIsEarlyClobber(true);
2960b57cec5SDimitry Andric     }
2970b57cec5SDimitry Andric   }
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric /// RemoveOperand - Erase an operand  from an instruction, leaving it with one
3010b57cec5SDimitry Andric /// fewer operand than it started with.
3020b57cec5SDimitry Andric ///
RemoveOperand(unsigned OpNo)3030b57cec5SDimitry Andric void MachineInstr::RemoveOperand(unsigned OpNo) {
3040b57cec5SDimitry Andric   assert(OpNo < getNumOperands() && "Invalid operand number");
3050b57cec5SDimitry Andric   untieRegOperand(OpNo);
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric #ifndef NDEBUG
3080b57cec5SDimitry Andric   // Moving tied operands would break the ties.
3090b57cec5SDimitry Andric   for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i)
3100b57cec5SDimitry Andric     if (Operands[i].isReg())
3110b57cec5SDimitry Andric       assert(!Operands[i].isTied() && "Cannot move tied operands");
3120b57cec5SDimitry Andric #endif
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   MachineRegisterInfo *MRI = getRegInfo();
3150b57cec5SDimitry Andric   if (MRI && Operands[OpNo].isReg())
3160b57cec5SDimitry Andric     MRI->removeRegOperandFromUseList(Operands + OpNo);
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric   // Don't call the MachineOperand destructor. A lot of this code depends on
3190b57cec5SDimitry Andric   // MachineOperand having a trivial destructor anyway, and adding a call here
3200b57cec5SDimitry Andric   // wouldn't make it 'destructor-correct'.
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   if (unsigned N = NumOperands - 1 - OpNo)
3230b57cec5SDimitry Andric     moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI);
3240b57cec5SDimitry Andric   --NumOperands;
3250b57cec5SDimitry Andric }
3260b57cec5SDimitry Andric 
setExtraInfo(MachineFunction & MF,ArrayRef<MachineMemOperand * > MMOs,MCSymbol * PreInstrSymbol,MCSymbol * PostInstrSymbol,MDNode * HeapAllocMarker)327c14a5a88SDimitry Andric void MachineInstr::setExtraInfo(MachineFunction &MF,
328c14a5a88SDimitry Andric                                 ArrayRef<MachineMemOperand *> MMOs,
329c14a5a88SDimitry Andric                                 MCSymbol *PreInstrSymbol,
330c14a5a88SDimitry Andric                                 MCSymbol *PostInstrSymbol,
331c14a5a88SDimitry Andric                                 MDNode *HeapAllocMarker) {
332c14a5a88SDimitry Andric   bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
333c14a5a88SDimitry Andric   bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
334c14a5a88SDimitry Andric   bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
335c14a5a88SDimitry Andric   int NumPointers =
336c14a5a88SDimitry Andric       MMOs.size() + HasPreInstrSymbol + HasPostInstrSymbol + HasHeapAllocMarker;
337c14a5a88SDimitry Andric 
338c14a5a88SDimitry Andric   // Drop all extra info if there is none.
339c14a5a88SDimitry Andric   if (NumPointers <= 0) {
340c14a5a88SDimitry Andric     Info.clear();
341c14a5a88SDimitry Andric     return;
342c14a5a88SDimitry Andric   }
343c14a5a88SDimitry Andric 
344c14a5a88SDimitry Andric   // If more than one pointer, then store out of line. Store heap alloc markers
345c14a5a88SDimitry Andric   // out of line because PointerSumType cannot hold more than 4 tag types with
346c14a5a88SDimitry Andric   // 32-bit pointers.
347c14a5a88SDimitry Andric   // FIXME: Maybe we should make the symbols in the extra info mutable?
348c14a5a88SDimitry Andric   else if (NumPointers > 1 || HasHeapAllocMarker) {
349480093f4SDimitry Andric     Info.set<EIIK_OutOfLine>(MF.createMIExtraInfo(
350c14a5a88SDimitry Andric         MMOs, PreInstrSymbol, PostInstrSymbol, HeapAllocMarker));
351c14a5a88SDimitry Andric     return;
352c14a5a88SDimitry Andric   }
353c14a5a88SDimitry Andric 
354c14a5a88SDimitry Andric   // Otherwise store the single pointer inline.
355c14a5a88SDimitry Andric   if (HasPreInstrSymbol)
356c14a5a88SDimitry Andric     Info.set<EIIK_PreInstrSymbol>(PreInstrSymbol);
357c14a5a88SDimitry Andric   else if (HasPostInstrSymbol)
358c14a5a88SDimitry Andric     Info.set<EIIK_PostInstrSymbol>(PostInstrSymbol);
359c14a5a88SDimitry Andric   else
360c14a5a88SDimitry Andric     Info.set<EIIK_MMO>(MMOs[0]);
361c14a5a88SDimitry Andric }
362c14a5a88SDimitry Andric 
dropMemRefs(MachineFunction & MF)3630b57cec5SDimitry Andric void MachineInstr::dropMemRefs(MachineFunction &MF) {
3640b57cec5SDimitry Andric   if (memoperands_empty())
3650b57cec5SDimitry Andric     return;
3660b57cec5SDimitry Andric 
367c14a5a88SDimitry Andric   setExtraInfo(MF, {}, getPreInstrSymbol(), getPostInstrSymbol(),
368c14a5a88SDimitry Andric                getHeapAllocMarker());
3690b57cec5SDimitry Andric }
3700b57cec5SDimitry Andric 
setMemRefs(MachineFunction & MF,ArrayRef<MachineMemOperand * > MMOs)3710b57cec5SDimitry Andric void MachineInstr::setMemRefs(MachineFunction &MF,
3720b57cec5SDimitry Andric                               ArrayRef<MachineMemOperand *> MMOs) {
3730b57cec5SDimitry Andric   if (MMOs.empty()) {
3740b57cec5SDimitry Andric     dropMemRefs(MF);
3750b57cec5SDimitry Andric     return;
3760b57cec5SDimitry Andric   }
3770b57cec5SDimitry Andric 
378c14a5a88SDimitry Andric   setExtraInfo(MF, MMOs, getPreInstrSymbol(), getPostInstrSymbol(),
379c14a5a88SDimitry Andric                getHeapAllocMarker());
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric 
addMemOperand(MachineFunction & MF,MachineMemOperand * MO)3820b57cec5SDimitry Andric void MachineInstr::addMemOperand(MachineFunction &MF,
3830b57cec5SDimitry Andric                                  MachineMemOperand *MO) {
3840b57cec5SDimitry Andric   SmallVector<MachineMemOperand *, 2> MMOs;
3850b57cec5SDimitry Andric   MMOs.append(memoperands_begin(), memoperands_end());
3860b57cec5SDimitry Andric   MMOs.push_back(MO);
3870b57cec5SDimitry Andric   setMemRefs(MF, MMOs);
3880b57cec5SDimitry Andric }
3890b57cec5SDimitry Andric 
cloneMemRefs(MachineFunction & MF,const MachineInstr & MI)3900b57cec5SDimitry Andric void MachineInstr::cloneMemRefs(MachineFunction &MF, const MachineInstr &MI) {
3910b57cec5SDimitry Andric   if (this == &MI)
3920b57cec5SDimitry Andric     // Nothing to do for a self-clone!
3930b57cec5SDimitry Andric     return;
3940b57cec5SDimitry Andric 
3950b57cec5SDimitry Andric   assert(&MF == MI.getMF() &&
3960b57cec5SDimitry Andric          "Invalid machine functions when cloning memory refrences!");
3970b57cec5SDimitry Andric   // See if we can just steal the extra info already allocated for the
3980b57cec5SDimitry Andric   // instruction. We can do this whenever the pre- and post-instruction symbols
3990b57cec5SDimitry Andric   // are the same (including null).
4000b57cec5SDimitry Andric   if (getPreInstrSymbol() == MI.getPreInstrSymbol() &&
401c14a5a88SDimitry Andric       getPostInstrSymbol() == MI.getPostInstrSymbol() &&
402c14a5a88SDimitry Andric       getHeapAllocMarker() == MI.getHeapAllocMarker()) {
4030b57cec5SDimitry Andric     Info = MI.Info;
4040b57cec5SDimitry Andric     return;
4050b57cec5SDimitry Andric   }
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric   // Otherwise, fall back on a copy-based clone.
4080b57cec5SDimitry Andric   setMemRefs(MF, MI.memoperands());
4090b57cec5SDimitry Andric }
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric /// Check to see if the MMOs pointed to by the two MemRefs arrays are
4120b57cec5SDimitry Andric /// identical.
hasIdenticalMMOs(ArrayRef<MachineMemOperand * > LHS,ArrayRef<MachineMemOperand * > RHS)4130b57cec5SDimitry Andric static bool hasIdenticalMMOs(ArrayRef<MachineMemOperand *> LHS,
4140b57cec5SDimitry Andric                              ArrayRef<MachineMemOperand *> RHS) {
4150b57cec5SDimitry Andric   if (LHS.size() != RHS.size())
4160b57cec5SDimitry Andric     return false;
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   auto LHSPointees = make_pointee_range(LHS);
4190b57cec5SDimitry Andric   auto RHSPointees = make_pointee_range(RHS);
4200b57cec5SDimitry Andric   return std::equal(LHSPointees.begin(), LHSPointees.end(),
4210b57cec5SDimitry Andric                     RHSPointees.begin());
4220b57cec5SDimitry Andric }
4230b57cec5SDimitry Andric 
cloneMergedMemRefs(MachineFunction & MF,ArrayRef<const MachineInstr * > MIs)4240b57cec5SDimitry Andric void MachineInstr::cloneMergedMemRefs(MachineFunction &MF,
4250b57cec5SDimitry Andric                                       ArrayRef<const MachineInstr *> MIs) {
4260b57cec5SDimitry Andric   // Try handling easy numbers of MIs with simpler mechanisms.
4270b57cec5SDimitry Andric   if (MIs.empty()) {
4280b57cec5SDimitry Andric     dropMemRefs(MF);
4290b57cec5SDimitry Andric     return;
4300b57cec5SDimitry Andric   }
4310b57cec5SDimitry Andric   if (MIs.size() == 1) {
4320b57cec5SDimitry Andric     cloneMemRefs(MF, *MIs[0]);
4330b57cec5SDimitry Andric     return;
4340b57cec5SDimitry Andric   }
4350b57cec5SDimitry Andric   // Because an empty memoperands list provides *no* information and must be
4360b57cec5SDimitry Andric   // handled conservatively (assuming the instruction can do anything), the only
4370b57cec5SDimitry Andric   // way to merge with it is to drop all other memoperands.
4380b57cec5SDimitry Andric   if (MIs[0]->memoperands_empty()) {
4390b57cec5SDimitry Andric     dropMemRefs(MF);
4400b57cec5SDimitry Andric     return;
4410b57cec5SDimitry Andric   }
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric   // Handle the general case.
4440b57cec5SDimitry Andric   SmallVector<MachineMemOperand *, 2> MergedMMOs;
4450b57cec5SDimitry Andric   // Start with the first instruction.
4460b57cec5SDimitry Andric   assert(&MF == MIs[0]->getMF() &&
4470b57cec5SDimitry Andric          "Invalid machine functions when cloning memory references!");
4480b57cec5SDimitry Andric   MergedMMOs.append(MIs[0]->memoperands_begin(), MIs[0]->memoperands_end());
4490b57cec5SDimitry Andric   // Now walk all the other instructions and accumulate any different MMOs.
4500b57cec5SDimitry Andric   for (const MachineInstr &MI : make_pointee_range(MIs.slice(1))) {
4510b57cec5SDimitry Andric     assert(&MF == MI.getMF() &&
4520b57cec5SDimitry Andric            "Invalid machine functions when cloning memory references!");
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric     // Skip MIs with identical operands to the first. This is a somewhat
4550b57cec5SDimitry Andric     // arbitrary hack but will catch common cases without being quadratic.
4560b57cec5SDimitry Andric     // TODO: We could fully implement merge semantics here if needed.
4570b57cec5SDimitry Andric     if (hasIdenticalMMOs(MIs[0]->memoperands(), MI.memoperands()))
4580b57cec5SDimitry Andric       continue;
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric     // Because an empty memoperands list provides *no* information and must be
4610b57cec5SDimitry Andric     // handled conservatively (assuming the instruction can do anything), the
4620b57cec5SDimitry Andric     // only way to merge with it is to drop all other memoperands.
4630b57cec5SDimitry Andric     if (MI.memoperands_empty()) {
4640b57cec5SDimitry Andric       dropMemRefs(MF);
4650b57cec5SDimitry Andric       return;
4660b57cec5SDimitry Andric     }
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric     // Otherwise accumulate these into our temporary buffer of the merged state.
4690b57cec5SDimitry Andric     MergedMMOs.append(MI.memoperands_begin(), MI.memoperands_end());
4700b57cec5SDimitry Andric   }
4710b57cec5SDimitry Andric 
4720b57cec5SDimitry Andric   setMemRefs(MF, MergedMMOs);
4730b57cec5SDimitry Andric }
4740b57cec5SDimitry Andric 
setPreInstrSymbol(MachineFunction & MF,MCSymbol * Symbol)4750b57cec5SDimitry Andric void MachineInstr::setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
476c14a5a88SDimitry Andric   // Do nothing if old and new symbols are the same.
477c14a5a88SDimitry Andric   if (Symbol == getPreInstrSymbol())
4780b57cec5SDimitry Andric     return;
479c14a5a88SDimitry Andric 
480c14a5a88SDimitry Andric   // If there was only one symbol and we're removing it, just clear info.
481c14a5a88SDimitry Andric   if (!Symbol && Info.is<EIIK_PreInstrSymbol>()) {
4820b57cec5SDimitry Andric     Info.clear();
4830b57cec5SDimitry Andric     return;
4840b57cec5SDimitry Andric   }
4850b57cec5SDimitry Andric 
486c14a5a88SDimitry Andric   setExtraInfo(MF, memoperands(), Symbol, getPostInstrSymbol(),
487c14a5a88SDimitry Andric                getHeapAllocMarker());
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric 
setPostInstrSymbol(MachineFunction & MF,MCSymbol * Symbol)4900b57cec5SDimitry Andric void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
491c14a5a88SDimitry Andric   // Do nothing if old and new symbols are the same.
492c14a5a88SDimitry Andric   if (Symbol == getPostInstrSymbol())
4930b57cec5SDimitry Andric     return;
494c14a5a88SDimitry Andric 
495c14a5a88SDimitry Andric   // If there was only one symbol and we're removing it, just clear info.
496c14a5a88SDimitry Andric   if (!Symbol && Info.is<EIIK_PostInstrSymbol>()) {
4970b57cec5SDimitry Andric     Info.clear();
4980b57cec5SDimitry Andric     return;
4990b57cec5SDimitry Andric   }
5000b57cec5SDimitry Andric 
501c14a5a88SDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), Symbol,
502c14a5a88SDimitry Andric                getHeapAllocMarker());
5030b57cec5SDimitry Andric }
5040b57cec5SDimitry Andric 
setHeapAllocMarker(MachineFunction & MF,MDNode * Marker)505c14a5a88SDimitry Andric void MachineInstr::setHeapAllocMarker(MachineFunction &MF, MDNode *Marker) {
506c14a5a88SDimitry Andric   // Do nothing if old and new symbols are the same.
507c14a5a88SDimitry Andric   if (Marker == getHeapAllocMarker())
5080b57cec5SDimitry Andric     return;
5090b57cec5SDimitry Andric 
510c14a5a88SDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(),
511c14a5a88SDimitry Andric                Marker);
5120b57cec5SDimitry Andric }
5130b57cec5SDimitry Andric 
cloneInstrSymbols(MachineFunction & MF,const MachineInstr & MI)5140b57cec5SDimitry Andric void MachineInstr::cloneInstrSymbols(MachineFunction &MF,
5150b57cec5SDimitry Andric                                      const MachineInstr &MI) {
5160b57cec5SDimitry Andric   if (this == &MI)
5170b57cec5SDimitry Andric     // Nothing to do for a self-clone!
5180b57cec5SDimitry Andric     return;
5190b57cec5SDimitry Andric 
5200b57cec5SDimitry Andric   assert(&MF == MI.getMF() &&
5210b57cec5SDimitry Andric          "Invalid machine functions when cloning instruction symbols!");
5220b57cec5SDimitry Andric 
5230b57cec5SDimitry Andric   setPreInstrSymbol(MF, MI.getPreInstrSymbol());
5240b57cec5SDimitry Andric   setPostInstrSymbol(MF, MI.getPostInstrSymbol());
525c14a5a88SDimitry Andric   setHeapAllocMarker(MF, MI.getHeapAllocMarker());
5260b57cec5SDimitry Andric }
5270b57cec5SDimitry Andric 
mergeFlagsWith(const MachineInstr & Other) const5280b57cec5SDimitry Andric uint16_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const {
5290b57cec5SDimitry Andric   // For now, the just return the union of the flags. If the flags get more
5300b57cec5SDimitry Andric   // complicated over time, we might need more logic here.
5310b57cec5SDimitry Andric   return getFlags() | Other.getFlags();
5320b57cec5SDimitry Andric }
5330b57cec5SDimitry Andric 
copyFlagsFromInstruction(const Instruction & I)5340b57cec5SDimitry Andric uint16_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) {
5350b57cec5SDimitry Andric   uint16_t MIFlags = 0;
5360b57cec5SDimitry Andric   // Copy the wrapping flags.
5370b57cec5SDimitry Andric   if (const OverflowingBinaryOperator *OB =
5380b57cec5SDimitry Andric           dyn_cast<OverflowingBinaryOperator>(&I)) {
5390b57cec5SDimitry Andric     if (OB->hasNoSignedWrap())
5400b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::NoSWrap;
5410b57cec5SDimitry Andric     if (OB->hasNoUnsignedWrap())
5420b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::NoUWrap;
5430b57cec5SDimitry Andric   }
5440b57cec5SDimitry Andric 
5450b57cec5SDimitry Andric   // Copy the exact flag.
5460b57cec5SDimitry Andric   if (const PossiblyExactOperator *PE = dyn_cast<PossiblyExactOperator>(&I))
5470b57cec5SDimitry Andric     if (PE->isExact())
5480b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::IsExact;
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric   // Copy the fast-math flags.
5510b57cec5SDimitry Andric   if (const FPMathOperator *FP = dyn_cast<FPMathOperator>(&I)) {
5520b57cec5SDimitry Andric     const FastMathFlags Flags = FP->getFastMathFlags();
5530b57cec5SDimitry Andric     if (Flags.noNaNs())
5540b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmNoNans;
5550b57cec5SDimitry Andric     if (Flags.noInfs())
5560b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmNoInfs;
5570b57cec5SDimitry Andric     if (Flags.noSignedZeros())
5580b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmNsz;
5590b57cec5SDimitry Andric     if (Flags.allowReciprocal())
5600b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmArcp;
5610b57cec5SDimitry Andric     if (Flags.allowContract())
5620b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmContract;
5630b57cec5SDimitry Andric     if (Flags.approxFunc())
5640b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmAfn;
5650b57cec5SDimitry Andric     if (Flags.allowReassoc())
5660b57cec5SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmReassoc;
5670b57cec5SDimitry Andric   }
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric   return MIFlags;
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric 
copyIRFlags(const Instruction & I)5720b57cec5SDimitry Andric void MachineInstr::copyIRFlags(const Instruction &I) {
5730b57cec5SDimitry Andric   Flags = copyFlagsFromInstruction(I);
5740b57cec5SDimitry Andric }
5750b57cec5SDimitry Andric 
hasPropertyInBundle(uint64_t Mask,QueryType Type) const5760b57cec5SDimitry Andric bool MachineInstr::hasPropertyInBundle(uint64_t Mask, QueryType Type) const {
5770b57cec5SDimitry Andric   assert(!isBundledWithPred() && "Must be called on bundle header");
5780b57cec5SDimitry Andric   for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) {
5790b57cec5SDimitry Andric     if (MII->getDesc().getFlags() & Mask) {
5800b57cec5SDimitry Andric       if (Type == AnyInBundle)
5810b57cec5SDimitry Andric         return true;
5820b57cec5SDimitry Andric     } else {
5830b57cec5SDimitry Andric       if (Type == AllInBundle && !MII->isBundle())
5840b57cec5SDimitry Andric         return false;
5850b57cec5SDimitry Andric     }
5860b57cec5SDimitry Andric     // This was the last instruction in the bundle.
5870b57cec5SDimitry Andric     if (!MII->isBundledWithSucc())
5880b57cec5SDimitry Andric       return Type == AllInBundle;
5890b57cec5SDimitry Andric   }
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric 
isIdenticalTo(const MachineInstr & Other,MICheckType Check) const5920b57cec5SDimitry Andric bool MachineInstr::isIdenticalTo(const MachineInstr &Other,
5930b57cec5SDimitry Andric                                  MICheckType Check) const {
5940b57cec5SDimitry Andric   // If opcodes or number of operands are not the same then the two
5950b57cec5SDimitry Andric   // instructions are obviously not identical.
5960b57cec5SDimitry Andric   if (Other.getOpcode() != getOpcode() ||
5970b57cec5SDimitry Andric       Other.getNumOperands() != getNumOperands())
5980b57cec5SDimitry Andric     return false;
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric   if (isBundle()) {
6010b57cec5SDimitry Andric     // We have passed the test above that both instructions have the same
6020b57cec5SDimitry Andric     // opcode, so we know that both instructions are bundles here. Let's compare
6030b57cec5SDimitry Andric     // MIs inside the bundle.
6040b57cec5SDimitry Andric     assert(Other.isBundle() && "Expected that both instructions are bundles.");
6050b57cec5SDimitry Andric     MachineBasicBlock::const_instr_iterator I1 = getIterator();
6060b57cec5SDimitry Andric     MachineBasicBlock::const_instr_iterator I2 = Other.getIterator();
6070b57cec5SDimitry Andric     // Loop until we analysed the last intruction inside at least one of the
6080b57cec5SDimitry Andric     // bundles.
6090b57cec5SDimitry Andric     while (I1->isBundledWithSucc() && I2->isBundledWithSucc()) {
6100b57cec5SDimitry Andric       ++I1;
6110b57cec5SDimitry Andric       ++I2;
6120b57cec5SDimitry Andric       if (!I1->isIdenticalTo(*I2, Check))
6130b57cec5SDimitry Andric         return false;
6140b57cec5SDimitry Andric     }
6150b57cec5SDimitry Andric     // If we've reached the end of just one of the two bundles, but not both,
6160b57cec5SDimitry Andric     // the instructions are not identical.
6170b57cec5SDimitry Andric     if (I1->isBundledWithSucc() || I2->isBundledWithSucc())
6180b57cec5SDimitry Andric       return false;
6190b57cec5SDimitry Andric   }
6200b57cec5SDimitry Andric 
6210b57cec5SDimitry Andric   // Check operands to make sure they match.
6220b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
6230b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
6240b57cec5SDimitry Andric     const MachineOperand &OMO = Other.getOperand(i);
6250b57cec5SDimitry Andric     if (!MO.isReg()) {
6260b57cec5SDimitry Andric       if (!MO.isIdenticalTo(OMO))
6270b57cec5SDimitry Andric         return false;
6280b57cec5SDimitry Andric       continue;
6290b57cec5SDimitry Andric     }
6300b57cec5SDimitry Andric 
6310b57cec5SDimitry Andric     // Clients may or may not want to ignore defs when testing for equality.
6320b57cec5SDimitry Andric     // For example, machine CSE pass only cares about finding common
6330b57cec5SDimitry Andric     // subexpressions, so it's safe to ignore virtual register defs.
6340b57cec5SDimitry Andric     if (MO.isDef()) {
6350b57cec5SDimitry Andric       if (Check == IgnoreDefs)
6360b57cec5SDimitry Andric         continue;
6370b57cec5SDimitry Andric       else if (Check == IgnoreVRegDefs) {
6388bcb0991SDimitry Andric         if (!Register::isVirtualRegister(MO.getReg()) ||
6398bcb0991SDimitry Andric             !Register::isVirtualRegister(OMO.getReg()))
6400b57cec5SDimitry Andric           if (!MO.isIdenticalTo(OMO))
6410b57cec5SDimitry Andric             return false;
6420b57cec5SDimitry Andric       } else {
6430b57cec5SDimitry Andric         if (!MO.isIdenticalTo(OMO))
6440b57cec5SDimitry Andric           return false;
6450b57cec5SDimitry Andric         if (Check == CheckKillDead && MO.isDead() != OMO.isDead())
6460b57cec5SDimitry Andric           return false;
6470b57cec5SDimitry Andric       }
6480b57cec5SDimitry Andric     } else {
6490b57cec5SDimitry Andric       if (!MO.isIdenticalTo(OMO))
6500b57cec5SDimitry Andric         return false;
6510b57cec5SDimitry Andric       if (Check == CheckKillDead && MO.isKill() != OMO.isKill())
6520b57cec5SDimitry Andric         return false;
6530b57cec5SDimitry Andric     }
6540b57cec5SDimitry Andric   }
6550b57cec5SDimitry Andric   // If DebugLoc does not match then two debug instructions are not identical.
6560b57cec5SDimitry Andric   if (isDebugInstr())
6570b57cec5SDimitry Andric     if (getDebugLoc() && Other.getDebugLoc() &&
6580b57cec5SDimitry Andric         getDebugLoc() != Other.getDebugLoc())
6590b57cec5SDimitry Andric       return false;
6600b57cec5SDimitry Andric   return true;
6610b57cec5SDimitry Andric }
6620b57cec5SDimitry Andric 
getMF() const6630b57cec5SDimitry Andric const MachineFunction *MachineInstr::getMF() const {
6640b57cec5SDimitry Andric   return getParent()->getParent();
6650b57cec5SDimitry Andric }
6660b57cec5SDimitry Andric 
removeFromParent()6670b57cec5SDimitry Andric MachineInstr *MachineInstr::removeFromParent() {
6680b57cec5SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
6690b57cec5SDimitry Andric   return getParent()->remove(this);
6700b57cec5SDimitry Andric }
6710b57cec5SDimitry Andric 
removeFromBundle()6720b57cec5SDimitry Andric MachineInstr *MachineInstr::removeFromBundle() {
6730b57cec5SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
6740b57cec5SDimitry Andric   return getParent()->remove_instr(this);
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric 
eraseFromParent()6770b57cec5SDimitry Andric void MachineInstr::eraseFromParent() {
6780b57cec5SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
6790b57cec5SDimitry Andric   getParent()->erase(this);
6800b57cec5SDimitry Andric }
6810b57cec5SDimitry Andric 
eraseFromParentAndMarkDBGValuesForRemoval()6820b57cec5SDimitry Andric void MachineInstr::eraseFromParentAndMarkDBGValuesForRemoval() {
6830b57cec5SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
6840b57cec5SDimitry Andric   MachineBasicBlock *MBB = getParent();
6850b57cec5SDimitry Andric   MachineFunction *MF = MBB->getParent();
6860b57cec5SDimitry Andric   assert(MF && "Not embedded in a function!");
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   MachineInstr *MI = (MachineInstr *)this;
6890b57cec5SDimitry Andric   MachineRegisterInfo &MRI = MF->getRegInfo();
6900b57cec5SDimitry Andric 
6910b57cec5SDimitry Andric   for (const MachineOperand &MO : MI->operands()) {
6920b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef())
6930b57cec5SDimitry Andric       continue;
6948bcb0991SDimitry Andric     Register Reg = MO.getReg();
6958bcb0991SDimitry Andric     if (!Reg.isVirtual())
6960b57cec5SDimitry Andric       continue;
6970b57cec5SDimitry Andric     MRI.markUsesInDebugValueAsUndef(Reg);
6980b57cec5SDimitry Andric   }
6990b57cec5SDimitry Andric   MI->eraseFromParent();
7000b57cec5SDimitry Andric }
7010b57cec5SDimitry Andric 
eraseFromBundle()7020b57cec5SDimitry Andric void MachineInstr::eraseFromBundle() {
7030b57cec5SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
7040b57cec5SDimitry Andric   getParent()->erase_instr(this);
7050b57cec5SDimitry Andric }
7060b57cec5SDimitry Andric 
isCandidateForCallSiteEntry(QueryType Type) const7075ffd83dbSDimitry Andric bool MachineInstr::isCandidateForCallSiteEntry(QueryType Type) const {
7085ffd83dbSDimitry Andric   if (!isCall(Type))
7095ffd83dbSDimitry Andric     return false;
7105ffd83dbSDimitry Andric   switch (getOpcode()) {
7115ffd83dbSDimitry Andric   case TargetOpcode::PATCHPOINT:
7125ffd83dbSDimitry Andric   case TargetOpcode::STACKMAP:
7135ffd83dbSDimitry Andric   case TargetOpcode::STATEPOINT:
714af732203SDimitry Andric   case TargetOpcode::FENTRY_CALL:
7155ffd83dbSDimitry Andric     return false;
7165ffd83dbSDimitry Andric   }
7175ffd83dbSDimitry Andric   return true;
7185ffd83dbSDimitry Andric }
7195ffd83dbSDimitry Andric 
shouldUpdateCallSiteInfo() const7205ffd83dbSDimitry Andric bool MachineInstr::shouldUpdateCallSiteInfo() const {
7215ffd83dbSDimitry Andric   if (isBundle())
7225ffd83dbSDimitry Andric     return isCandidateForCallSiteEntry(MachineInstr::AnyInBundle);
7235ffd83dbSDimitry Andric   return isCandidateForCallSiteEntry();
7245ffd83dbSDimitry Andric }
7255ffd83dbSDimitry Andric 
getNumExplicitOperands() const7260b57cec5SDimitry Andric unsigned MachineInstr::getNumExplicitOperands() const {
7270b57cec5SDimitry Andric   unsigned NumOperands = MCID->getNumOperands();
7280b57cec5SDimitry Andric   if (!MCID->isVariadic())
7290b57cec5SDimitry Andric     return NumOperands;
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric   for (unsigned I = NumOperands, E = getNumOperands(); I != E; ++I) {
7320b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(I);
7330b57cec5SDimitry Andric     // The operands must always be in the following order:
7340b57cec5SDimitry Andric     // - explicit reg defs,
7350b57cec5SDimitry Andric     // - other explicit operands (reg uses, immediates, etc.),
7360b57cec5SDimitry Andric     // - implicit reg defs
7370b57cec5SDimitry Andric     // - implicit reg uses
7380b57cec5SDimitry Andric     if (MO.isReg() && MO.isImplicit())
7390b57cec5SDimitry Andric       break;
7400b57cec5SDimitry Andric     ++NumOperands;
7410b57cec5SDimitry Andric   }
7420b57cec5SDimitry Andric   return NumOperands;
7430b57cec5SDimitry Andric }
7440b57cec5SDimitry Andric 
getNumExplicitDefs() const7450b57cec5SDimitry Andric unsigned MachineInstr::getNumExplicitDefs() const {
7460b57cec5SDimitry Andric   unsigned NumDefs = MCID->getNumDefs();
7470b57cec5SDimitry Andric   if (!MCID->isVariadic())
7480b57cec5SDimitry Andric     return NumDefs;
7490b57cec5SDimitry Andric 
7500b57cec5SDimitry Andric   for (unsigned I = NumDefs, E = getNumOperands(); I != E; ++I) {
7510b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(I);
7520b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
7530b57cec5SDimitry Andric       break;
7540b57cec5SDimitry Andric     ++NumDefs;
7550b57cec5SDimitry Andric   }
7560b57cec5SDimitry Andric   return NumDefs;
7570b57cec5SDimitry Andric }
7580b57cec5SDimitry Andric 
bundleWithPred()7590b57cec5SDimitry Andric void MachineInstr::bundleWithPred() {
7600b57cec5SDimitry Andric   assert(!isBundledWithPred() && "MI is already bundled with its predecessor");
7610b57cec5SDimitry Andric   setFlag(BundledPred);
7620b57cec5SDimitry Andric   MachineBasicBlock::instr_iterator Pred = getIterator();
7630b57cec5SDimitry Andric   --Pred;
7640b57cec5SDimitry Andric   assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags");
7650b57cec5SDimitry Andric   Pred->setFlag(BundledSucc);
7660b57cec5SDimitry Andric }
7670b57cec5SDimitry Andric 
bundleWithSucc()7680b57cec5SDimitry Andric void MachineInstr::bundleWithSucc() {
7690b57cec5SDimitry Andric   assert(!isBundledWithSucc() && "MI is already bundled with its successor");
7700b57cec5SDimitry Andric   setFlag(BundledSucc);
7710b57cec5SDimitry Andric   MachineBasicBlock::instr_iterator Succ = getIterator();
7720b57cec5SDimitry Andric   ++Succ;
7730b57cec5SDimitry Andric   assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags");
7740b57cec5SDimitry Andric   Succ->setFlag(BundledPred);
7750b57cec5SDimitry Andric }
7760b57cec5SDimitry Andric 
unbundleFromPred()7770b57cec5SDimitry Andric void MachineInstr::unbundleFromPred() {
7780b57cec5SDimitry Andric   assert(isBundledWithPred() && "MI isn't bundled with its predecessor");
7790b57cec5SDimitry Andric   clearFlag(BundledPred);
7800b57cec5SDimitry Andric   MachineBasicBlock::instr_iterator Pred = getIterator();
7810b57cec5SDimitry Andric   --Pred;
7820b57cec5SDimitry Andric   assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags");
7830b57cec5SDimitry Andric   Pred->clearFlag(BundledSucc);
7840b57cec5SDimitry Andric }
7850b57cec5SDimitry Andric 
unbundleFromSucc()7860b57cec5SDimitry Andric void MachineInstr::unbundleFromSucc() {
7870b57cec5SDimitry Andric   assert(isBundledWithSucc() && "MI isn't bundled with its successor");
7880b57cec5SDimitry Andric   clearFlag(BundledSucc);
7890b57cec5SDimitry Andric   MachineBasicBlock::instr_iterator Succ = getIterator();
7900b57cec5SDimitry Andric   ++Succ;
7910b57cec5SDimitry Andric   assert(Succ->isBundledWithPred() && "Inconsistent bundle flags");
7920b57cec5SDimitry Andric   Succ->clearFlag(BundledPred);
7930b57cec5SDimitry Andric }
7940b57cec5SDimitry Andric 
isStackAligningInlineAsm() const7950b57cec5SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const {
7960b57cec5SDimitry Andric   if (isInlineAsm()) {
7970b57cec5SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
7980b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
7990b57cec5SDimitry Andric       return true;
8000b57cec5SDimitry Andric   }
8010b57cec5SDimitry Andric   return false;
8020b57cec5SDimitry Andric }
8030b57cec5SDimitry Andric 
getInlineAsmDialect() const8040b57cec5SDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const {
8050b57cec5SDimitry Andric   assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!");
8060b57cec5SDimitry Andric   unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
8070b57cec5SDimitry Andric   return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0);
8080b57cec5SDimitry Andric }
8090b57cec5SDimitry Andric 
findInlineAsmFlagIdx(unsigned OpIdx,unsigned * GroupNo) const8100b57cec5SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx,
8110b57cec5SDimitry Andric                                        unsigned *GroupNo) const {
8120b57cec5SDimitry Andric   assert(isInlineAsm() && "Expected an inline asm instruction");
8130b57cec5SDimitry Andric   assert(OpIdx < getNumOperands() && "OpIdx out of range");
8140b57cec5SDimitry Andric 
8150b57cec5SDimitry Andric   // Ignore queries about the initial operands.
8160b57cec5SDimitry Andric   if (OpIdx < InlineAsm::MIOp_FirstOperand)
8170b57cec5SDimitry Andric     return -1;
8180b57cec5SDimitry Andric 
8190b57cec5SDimitry Andric   unsigned Group = 0;
8200b57cec5SDimitry Andric   unsigned NumOps;
8210b57cec5SDimitry Andric   for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e;
8220b57cec5SDimitry Andric        i += NumOps) {
8230b57cec5SDimitry Andric     const MachineOperand &FlagMO = getOperand(i);
8240b57cec5SDimitry Andric     // If we reach the implicit register operands, stop looking.
8250b57cec5SDimitry Andric     if (!FlagMO.isImm())
8260b57cec5SDimitry Andric       return -1;
8270b57cec5SDimitry Andric     NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm());
8280b57cec5SDimitry Andric     if (i + NumOps > OpIdx) {
8290b57cec5SDimitry Andric       if (GroupNo)
8300b57cec5SDimitry Andric         *GroupNo = Group;
8310b57cec5SDimitry Andric       return i;
8320b57cec5SDimitry Andric     }
8330b57cec5SDimitry Andric     ++Group;
8340b57cec5SDimitry Andric   }
8350b57cec5SDimitry Andric   return -1;
8360b57cec5SDimitry Andric }
8370b57cec5SDimitry Andric 
getDebugLabel() const8380b57cec5SDimitry Andric const DILabel *MachineInstr::getDebugLabel() const {
8390b57cec5SDimitry Andric   assert(isDebugLabel() && "not a DBG_LABEL");
8400b57cec5SDimitry Andric   return cast<DILabel>(getOperand(0).getMetadata());
8410b57cec5SDimitry Andric }
8420b57cec5SDimitry Andric 
getDebugVariableOp() const8435ffd83dbSDimitry Andric const MachineOperand &MachineInstr::getDebugVariableOp() const {
844*5f7ddb14SDimitry Andric   assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*");
845*5f7ddb14SDimitry Andric   unsigned VariableOp = isDebugValueList() ? 0 : 2;
846*5f7ddb14SDimitry Andric   return getOperand(VariableOp);
8475ffd83dbSDimitry Andric }
8485ffd83dbSDimitry Andric 
getDebugVariableOp()8495ffd83dbSDimitry Andric MachineOperand &MachineInstr::getDebugVariableOp() {
850*5f7ddb14SDimitry Andric   assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*");
851*5f7ddb14SDimitry Andric   unsigned VariableOp = isDebugValueList() ? 0 : 2;
852*5f7ddb14SDimitry Andric   return getOperand(VariableOp);
8535ffd83dbSDimitry Andric }
8545ffd83dbSDimitry Andric 
getDebugVariable() const8550b57cec5SDimitry Andric const DILocalVariable *MachineInstr::getDebugVariable() const {
856*5f7ddb14SDimitry Andric   return cast<DILocalVariable>(getDebugVariableOp().getMetadata());
857*5f7ddb14SDimitry Andric }
858*5f7ddb14SDimitry Andric 
getDebugExpressionOp() const859*5f7ddb14SDimitry Andric const MachineOperand &MachineInstr::getDebugExpressionOp() const {
860*5f7ddb14SDimitry Andric   assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*");
861*5f7ddb14SDimitry Andric   unsigned ExpressionOp = isDebugValueList() ? 1 : 3;
862*5f7ddb14SDimitry Andric   return getOperand(ExpressionOp);
8630b57cec5SDimitry Andric }
8640b57cec5SDimitry Andric 
getDebugExpressionOp()8655ffd83dbSDimitry Andric MachineOperand &MachineInstr::getDebugExpressionOp() {
866*5f7ddb14SDimitry Andric   assert((isDebugValue() || isDebugRef()) && "not a DBG_VALUE*");
867*5f7ddb14SDimitry Andric   unsigned ExpressionOp = isDebugValueList() ? 1 : 3;
868*5f7ddb14SDimitry Andric   return getOperand(ExpressionOp);
8695ffd83dbSDimitry Andric }
8705ffd83dbSDimitry Andric 
getDebugExpression() const8710b57cec5SDimitry Andric const DIExpression *MachineInstr::getDebugExpression() const {
872*5f7ddb14SDimitry Andric   return cast<DIExpression>(getDebugExpressionOp().getMetadata());
8730b57cec5SDimitry Andric }
8740b57cec5SDimitry Andric 
isDebugEntryValue() const8758bcb0991SDimitry Andric bool MachineInstr::isDebugEntryValue() const {
8768bcb0991SDimitry Andric   return isDebugValue() && getDebugExpression()->isEntryValue();
8778bcb0991SDimitry Andric }
8788bcb0991SDimitry Andric 
8790b57cec5SDimitry Andric const TargetRegisterClass*
getRegClassConstraint(unsigned OpIdx,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const8800b57cec5SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx,
8810b57cec5SDimitry Andric                                     const TargetInstrInfo *TII,
8820b57cec5SDimitry Andric                                     const TargetRegisterInfo *TRI) const {
8830b57cec5SDimitry Andric   assert(getParent() && "Can't have an MBB reference here!");
8840b57cec5SDimitry Andric   assert(getMF() && "Can't have an MF reference here!");
8850b57cec5SDimitry Andric   const MachineFunction &MF = *getMF();
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric   // Most opcodes have fixed constraints in their MCInstrDesc.
8880b57cec5SDimitry Andric   if (!isInlineAsm())
8890b57cec5SDimitry Andric     return TII->getRegClass(getDesc(), OpIdx, TRI, MF);
8900b57cec5SDimitry Andric 
8910b57cec5SDimitry Andric   if (!getOperand(OpIdx).isReg())
8920b57cec5SDimitry Andric     return nullptr;
8930b57cec5SDimitry Andric 
8940b57cec5SDimitry Andric   // For tied uses on inline asm, get the constraint from the def.
8950b57cec5SDimitry Andric   unsigned DefIdx;
8960b57cec5SDimitry Andric   if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx))
8970b57cec5SDimitry Andric     OpIdx = DefIdx;
8980b57cec5SDimitry Andric 
8990b57cec5SDimitry Andric   // Inline asm stores register class constraints in the flag word.
9000b57cec5SDimitry Andric   int FlagIdx = findInlineAsmFlagIdx(OpIdx);
9010b57cec5SDimitry Andric   if (FlagIdx < 0)
9020b57cec5SDimitry Andric     return nullptr;
9030b57cec5SDimitry Andric 
9040b57cec5SDimitry Andric   unsigned Flag = getOperand(FlagIdx).getImm();
9050b57cec5SDimitry Andric   unsigned RCID;
9060b57cec5SDimitry Andric   if ((InlineAsm::getKind(Flag) == InlineAsm::Kind_RegUse ||
9070b57cec5SDimitry Andric        InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDef ||
9080b57cec5SDimitry Andric        InlineAsm::getKind(Flag) == InlineAsm::Kind_RegDefEarlyClobber) &&
9090b57cec5SDimitry Andric       InlineAsm::hasRegClassConstraint(Flag, RCID))
9100b57cec5SDimitry Andric     return TRI->getRegClass(RCID);
9110b57cec5SDimitry Andric 
9120b57cec5SDimitry Andric   // Assume that all registers in a memory operand are pointers.
9130b57cec5SDimitry Andric   if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem)
9140b57cec5SDimitry Andric     return TRI->getPointerRegClass(MF);
9150b57cec5SDimitry Andric 
9160b57cec5SDimitry Andric   return nullptr;
9170b57cec5SDimitry Andric }
9180b57cec5SDimitry Andric 
getRegClassConstraintEffectForVReg(Register Reg,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI,bool ExploreBundle) const9190b57cec5SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg(
9208bcb0991SDimitry Andric     Register Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII,
9210b57cec5SDimitry Andric     const TargetRegisterInfo *TRI, bool ExploreBundle) const {
9220b57cec5SDimitry Andric   // Check every operands inside the bundle if we have
9230b57cec5SDimitry Andric   // been asked to.
9240b57cec5SDimitry Andric   if (ExploreBundle)
9250b57cec5SDimitry Andric     for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC;
9260b57cec5SDimitry Andric          ++OpndIt)
9270b57cec5SDimitry Andric       CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl(
9280b57cec5SDimitry Andric           OpndIt.getOperandNo(), Reg, CurRC, TII, TRI);
9290b57cec5SDimitry Andric   else
9300b57cec5SDimitry Andric     // Otherwise, just check the current operands.
9310b57cec5SDimitry Andric     for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i)
9320b57cec5SDimitry Andric       CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI);
9330b57cec5SDimitry Andric   return CurRC;
9340b57cec5SDimitry Andric }
9350b57cec5SDimitry Andric 
getRegClassConstraintEffectForVRegImpl(unsigned OpIdx,Register Reg,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const9360b57cec5SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl(
9378bcb0991SDimitry Andric     unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
9380b57cec5SDimitry Andric     const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
9390b57cec5SDimitry Andric   assert(CurRC && "Invalid initial register class");
9400b57cec5SDimitry Andric   // Check if Reg is constrained by some of its use/def from MI.
9410b57cec5SDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
9420b57cec5SDimitry Andric   if (!MO.isReg() || MO.getReg() != Reg)
9430b57cec5SDimitry Andric     return CurRC;
9440b57cec5SDimitry Andric   // If yes, accumulate the constraints through the operand.
9450b57cec5SDimitry Andric   return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI);
9460b57cec5SDimitry Andric }
9470b57cec5SDimitry Andric 
getRegClassConstraintEffect(unsigned OpIdx,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const9480b57cec5SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect(
9490b57cec5SDimitry Andric     unsigned OpIdx, const TargetRegisterClass *CurRC,
9500b57cec5SDimitry Andric     const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
9510b57cec5SDimitry Andric   const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI);
9520b57cec5SDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
9530b57cec5SDimitry Andric   assert(MO.isReg() &&
9540b57cec5SDimitry Andric          "Cannot get register constraints for non-register operand");
9550b57cec5SDimitry Andric   assert(CurRC && "Invalid initial register class");
9560b57cec5SDimitry Andric   if (unsigned SubIdx = MO.getSubReg()) {
9570b57cec5SDimitry Andric     if (OpRC)
9580b57cec5SDimitry Andric       CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx);
9590b57cec5SDimitry Andric     else
9600b57cec5SDimitry Andric       CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx);
9610b57cec5SDimitry Andric   } else if (OpRC)
9620b57cec5SDimitry Andric     CurRC = TRI->getCommonSubClass(CurRC, OpRC);
9630b57cec5SDimitry Andric   return CurRC;
9640b57cec5SDimitry Andric }
9650b57cec5SDimitry Andric 
9660b57cec5SDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the
9670b57cec5SDimitry Andric /// header instruction.
getBundleSize() const9680b57cec5SDimitry Andric unsigned MachineInstr::getBundleSize() const {
9690b57cec5SDimitry Andric   MachineBasicBlock::const_instr_iterator I = getIterator();
9700b57cec5SDimitry Andric   unsigned Size = 0;
9710b57cec5SDimitry Andric   while (I->isBundledWithSucc()) {
9720b57cec5SDimitry Andric     ++Size;
9730b57cec5SDimitry Andric     ++I;
9740b57cec5SDimitry Andric   }
9750b57cec5SDimitry Andric   return Size;
9760b57cec5SDimitry Andric }
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric /// Returns true if the MachineInstr has an implicit-use operand of exactly
9790b57cec5SDimitry Andric /// the given register (not considering sub/super-registers).
hasRegisterImplicitUseOperand(Register Reg) const9808bcb0991SDimitry Andric bool MachineInstr::hasRegisterImplicitUseOperand(Register Reg) const {
9810b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
9820b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
9830b57cec5SDimitry Andric     if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == Reg)
9840b57cec5SDimitry Andric       return true;
9850b57cec5SDimitry Andric   }
9860b57cec5SDimitry Andric   return false;
9870b57cec5SDimitry Andric }
9880b57cec5SDimitry Andric 
9890b57cec5SDimitry Andric /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of
9900b57cec5SDimitry Andric /// the specific register or -1 if it is not found. It further tightens
9910b57cec5SDimitry Andric /// the search criteria to a use that kills the register if isKill is true.
findRegisterUseOperandIdx(Register Reg,bool isKill,const TargetRegisterInfo * TRI) const9920b57cec5SDimitry Andric int MachineInstr::findRegisterUseOperandIdx(
9938bcb0991SDimitry Andric     Register Reg, bool isKill, const TargetRegisterInfo *TRI) const {
9940b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
9950b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
9960b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isUse())
9970b57cec5SDimitry Andric       continue;
9988bcb0991SDimitry Andric     Register MOReg = MO.getReg();
9990b57cec5SDimitry Andric     if (!MOReg)
10000b57cec5SDimitry Andric       continue;
10010b57cec5SDimitry Andric     if (MOReg == Reg || (TRI && Reg && MOReg && TRI->regsOverlap(MOReg, Reg)))
10020b57cec5SDimitry Andric       if (!isKill || MO.isKill())
10030b57cec5SDimitry Andric         return i;
10040b57cec5SDimitry Andric   }
10050b57cec5SDimitry Andric   return -1;
10060b57cec5SDimitry Andric }
10070b57cec5SDimitry Andric 
10080b57cec5SDimitry Andric /// readsWritesVirtualRegister - Return a pair of bools (reads, writes)
10090b57cec5SDimitry Andric /// indicating if this instruction reads or writes Reg. This also considers
10100b57cec5SDimitry Andric /// partial defines.
10110b57cec5SDimitry Andric std::pair<bool,bool>
readsWritesVirtualRegister(Register Reg,SmallVectorImpl<unsigned> * Ops) const10128bcb0991SDimitry Andric MachineInstr::readsWritesVirtualRegister(Register Reg,
10130b57cec5SDimitry Andric                                          SmallVectorImpl<unsigned> *Ops) const {
10140b57cec5SDimitry Andric   bool PartDef = false; // Partial redefine.
10150b57cec5SDimitry Andric   bool FullDef = false; // Full define.
10160b57cec5SDimitry Andric   bool Use = false;
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
10190b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
10200b57cec5SDimitry Andric     if (!MO.isReg() || MO.getReg() != Reg)
10210b57cec5SDimitry Andric       continue;
10220b57cec5SDimitry Andric     if (Ops)
10230b57cec5SDimitry Andric       Ops->push_back(i);
10240b57cec5SDimitry Andric     if (MO.isUse())
10250b57cec5SDimitry Andric       Use |= !MO.isUndef();
10260b57cec5SDimitry Andric     else if (MO.getSubReg() && !MO.isUndef())
10270b57cec5SDimitry Andric       // A partial def undef doesn't count as reading the register.
10280b57cec5SDimitry Andric       PartDef = true;
10290b57cec5SDimitry Andric     else
10300b57cec5SDimitry Andric       FullDef = true;
10310b57cec5SDimitry Andric   }
10320b57cec5SDimitry Andric   // A partial redefine uses Reg unless there is also a full define.
10330b57cec5SDimitry Andric   return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef);
10340b57cec5SDimitry Andric }
10350b57cec5SDimitry Andric 
10360b57cec5SDimitry Andric /// findRegisterDefOperandIdx() - Returns the operand index that is a def of
10370b57cec5SDimitry Andric /// the specified register or -1 if it is not found. If isDead is true, defs
10380b57cec5SDimitry Andric /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it
10390b57cec5SDimitry Andric /// also checks if there is a def of a super-register.
10400b57cec5SDimitry Andric int
findRegisterDefOperandIdx(Register Reg,bool isDead,bool Overlap,const TargetRegisterInfo * TRI) const10418bcb0991SDimitry Andric MachineInstr::findRegisterDefOperandIdx(Register Reg, bool isDead, bool Overlap,
10420b57cec5SDimitry Andric                                         const TargetRegisterInfo *TRI) const {
10438bcb0991SDimitry Andric   bool isPhys = Register::isPhysicalRegister(Reg);
10440b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
10450b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
10460b57cec5SDimitry Andric     // Accept regmask operands when Overlap is set.
10470b57cec5SDimitry Andric     // Ignore them when looking for a specific def operand (Overlap == false).
10480b57cec5SDimitry Andric     if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg))
10490b57cec5SDimitry Andric       return i;
10500b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef())
10510b57cec5SDimitry Andric       continue;
10528bcb0991SDimitry Andric     Register MOReg = MO.getReg();
10530b57cec5SDimitry Andric     bool Found = (MOReg == Reg);
10548bcb0991SDimitry Andric     if (!Found && TRI && isPhys && Register::isPhysicalRegister(MOReg)) {
10550b57cec5SDimitry Andric       if (Overlap)
10560b57cec5SDimitry Andric         Found = TRI->regsOverlap(MOReg, Reg);
10570b57cec5SDimitry Andric       else
10580b57cec5SDimitry Andric         Found = TRI->isSubRegister(MOReg, Reg);
10590b57cec5SDimitry Andric     }
10600b57cec5SDimitry Andric     if (Found && (!isDead || MO.isDead()))
10610b57cec5SDimitry Andric       return i;
10620b57cec5SDimitry Andric   }
10630b57cec5SDimitry Andric   return -1;
10640b57cec5SDimitry Andric }
10650b57cec5SDimitry Andric 
10660b57cec5SDimitry Andric /// findFirstPredOperandIdx() - Find the index of the first operand in the
10670b57cec5SDimitry Andric /// operand list that is used to represent the predicate. It returns -1 if
10680b57cec5SDimitry Andric /// none is found.
findFirstPredOperandIdx() const10690b57cec5SDimitry Andric int MachineInstr::findFirstPredOperandIdx() const {
10700b57cec5SDimitry Andric   // Don't call MCID.findFirstPredOperandIdx() because this variant
10710b57cec5SDimitry Andric   // is sometimes called on an instruction that's not yet complete, and
10720b57cec5SDimitry Andric   // so the number of operands is less than the MCID indicates. In
10730b57cec5SDimitry Andric   // particular, the PTX target does this.
10740b57cec5SDimitry Andric   const MCInstrDesc &MCID = getDesc();
10750b57cec5SDimitry Andric   if (MCID.isPredicable()) {
10760b57cec5SDimitry Andric     for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
10770b57cec5SDimitry Andric       if (MCID.OpInfo[i].isPredicate())
10780b57cec5SDimitry Andric         return i;
10790b57cec5SDimitry Andric   }
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric   return -1;
10820b57cec5SDimitry Andric }
10830b57cec5SDimitry Andric 
10840b57cec5SDimitry Andric // MachineOperand::TiedTo is 4 bits wide.
10850b57cec5SDimitry Andric const unsigned TiedMax = 15;
10860b57cec5SDimitry Andric 
10870b57cec5SDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other.
10880b57cec5SDimitry Andric ///
10890b57cec5SDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo
10900b57cec5SDimitry Andric /// field. TiedTo can have these values:
10910b57cec5SDimitry Andric ///
10920b57cec5SDimitry Andric /// 0:              Operand is not tied to anything.
10930b57cec5SDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1).
10940b57cec5SDimitry Andric /// TiedMax:        Tied to an operand >= TiedMax-1.
10950b57cec5SDimitry Andric ///
10960b57cec5SDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal
10970b57cec5SDimitry Andric /// instruction. INLINEASM instructions allow more tied defs.
10980b57cec5SDimitry Andric ///
tieOperands(unsigned DefIdx,unsigned UseIdx)10990b57cec5SDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) {
11000b57cec5SDimitry Andric   MachineOperand &DefMO = getOperand(DefIdx);
11010b57cec5SDimitry Andric   MachineOperand &UseMO = getOperand(UseIdx);
11020b57cec5SDimitry Andric   assert(DefMO.isDef() && "DefIdx must be a def operand");
11030b57cec5SDimitry Andric   assert(UseMO.isUse() && "UseIdx must be a use operand");
11040b57cec5SDimitry Andric   assert(!DefMO.isTied() && "Def is already tied to another use");
11050b57cec5SDimitry Andric   assert(!UseMO.isTied() && "Use is already tied to another def");
11060b57cec5SDimitry Andric 
11070b57cec5SDimitry Andric   if (DefIdx < TiedMax)
11080b57cec5SDimitry Andric     UseMO.TiedTo = DefIdx + 1;
11090b57cec5SDimitry Andric   else {
1110af732203SDimitry Andric     // Inline asm can use the group descriptors to find tied operands,
1111af732203SDimitry Andric     // statepoint tied operands are trivial to match (1-1 reg def with reg use),
1112af732203SDimitry Andric     // but on normal instruction, the tied def must be within the first TiedMax
11130b57cec5SDimitry Andric     // operands.
1114af732203SDimitry Andric     assert((isInlineAsm() || getOpcode() == TargetOpcode::STATEPOINT) &&
1115af732203SDimitry Andric            "DefIdx out of range");
11160b57cec5SDimitry Andric     UseMO.TiedTo = TiedMax;
11170b57cec5SDimitry Andric   }
11180b57cec5SDimitry Andric 
11190b57cec5SDimitry Andric   // UseIdx can be out of range, we'll search for it in findTiedOperandIdx().
11200b57cec5SDimitry Andric   DefMO.TiedTo = std::min(UseIdx + 1, TiedMax);
11210b57cec5SDimitry Andric }
11220b57cec5SDimitry Andric 
11230b57cec5SDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to.
11240b57cec5SDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand
11250b57cec5SDimitry Andric /// which must exist.
findTiedOperandIdx(unsigned OpIdx) const11260b57cec5SDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const {
11270b57cec5SDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
11280b57cec5SDimitry Andric   assert(MO.isTied() && "Operand isn't tied");
11290b57cec5SDimitry Andric 
11300b57cec5SDimitry Andric   // Normally TiedTo is in range.
11310b57cec5SDimitry Andric   if (MO.TiedTo < TiedMax)
11320b57cec5SDimitry Andric     return MO.TiedTo - 1;
11330b57cec5SDimitry Andric 
11340b57cec5SDimitry Andric   // Uses on normal instructions can be out of range.
1135af732203SDimitry Andric   if (!isInlineAsm() && getOpcode() != TargetOpcode::STATEPOINT) {
11360b57cec5SDimitry Andric     // Normal tied defs must be in the 0..TiedMax-1 range.
11370b57cec5SDimitry Andric     if (MO.isUse())
11380b57cec5SDimitry Andric       return TiedMax - 1;
11390b57cec5SDimitry Andric     // MO is a def. Search for the tied use.
11400b57cec5SDimitry Andric     for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) {
11410b57cec5SDimitry Andric       const MachineOperand &UseMO = getOperand(i);
11420b57cec5SDimitry Andric       if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1)
11430b57cec5SDimitry Andric         return i;
11440b57cec5SDimitry Andric     }
11450b57cec5SDimitry Andric     llvm_unreachable("Can't find tied use");
11460b57cec5SDimitry Andric   }
11470b57cec5SDimitry Andric 
1148af732203SDimitry Andric   if (getOpcode() == TargetOpcode::STATEPOINT) {
1149af732203SDimitry Andric     // In STATEPOINT defs correspond 1-1 to GC pointer operands passed
1150af732203SDimitry Andric     // on registers.
1151af732203SDimitry Andric     StatepointOpers SO(this);
1152af732203SDimitry Andric     unsigned CurUseIdx = SO.getFirstGCPtrIdx();
1153af732203SDimitry Andric     assert(CurUseIdx != -1U && "only gc pointer statepoint operands can be tied");
1154af732203SDimitry Andric     unsigned NumDefs = getNumDefs();
1155af732203SDimitry Andric     for (unsigned CurDefIdx = 0; CurDefIdx < NumDefs; ++CurDefIdx) {
1156af732203SDimitry Andric       while (!getOperand(CurUseIdx).isReg())
1157af732203SDimitry Andric         CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx);
1158af732203SDimitry Andric       if (OpIdx == CurDefIdx)
1159af732203SDimitry Andric         return CurUseIdx;
1160af732203SDimitry Andric       if (OpIdx == CurUseIdx)
1161af732203SDimitry Andric         return CurDefIdx;
1162af732203SDimitry Andric       CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx);
1163af732203SDimitry Andric     }
1164af732203SDimitry Andric     llvm_unreachable("Can't find tied use");
1165af732203SDimitry Andric   }
1166af732203SDimitry Andric 
11670b57cec5SDimitry Andric   // Now deal with inline asm by parsing the operand group descriptor flags.
11680b57cec5SDimitry Andric   // Find the beginning of each operand group.
11690b57cec5SDimitry Andric   SmallVector<unsigned, 8> GroupIdx;
11700b57cec5SDimitry Andric   unsigned OpIdxGroup = ~0u;
11710b57cec5SDimitry Andric   unsigned NumOps;
11720b57cec5SDimitry Andric   for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e;
11730b57cec5SDimitry Andric        i += NumOps) {
11740b57cec5SDimitry Andric     const MachineOperand &FlagMO = getOperand(i);
11750b57cec5SDimitry Andric     assert(FlagMO.isImm() && "Invalid tied operand on inline asm");
11760b57cec5SDimitry Andric     unsigned CurGroup = GroupIdx.size();
11770b57cec5SDimitry Andric     GroupIdx.push_back(i);
11780b57cec5SDimitry Andric     NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm());
11790b57cec5SDimitry Andric     // OpIdx belongs to this operand group.
11800b57cec5SDimitry Andric     if (OpIdx > i && OpIdx < i + NumOps)
11810b57cec5SDimitry Andric       OpIdxGroup = CurGroup;
11820b57cec5SDimitry Andric     unsigned TiedGroup;
11830b57cec5SDimitry Andric     if (!InlineAsm::isUseOperandTiedToDef(FlagMO.getImm(), TiedGroup))
11840b57cec5SDimitry Andric       continue;
11850b57cec5SDimitry Andric     // Operands in this group are tied to operands in TiedGroup which must be
11860b57cec5SDimitry Andric     // earlier. Find the number of operands between the two groups.
11870b57cec5SDimitry Andric     unsigned Delta = i - GroupIdx[TiedGroup];
11880b57cec5SDimitry Andric 
11890b57cec5SDimitry Andric     // OpIdx is a use tied to TiedGroup.
11900b57cec5SDimitry Andric     if (OpIdxGroup == CurGroup)
11910b57cec5SDimitry Andric       return OpIdx - Delta;
11920b57cec5SDimitry Andric 
11930b57cec5SDimitry Andric     // OpIdx is a def tied to this use group.
11940b57cec5SDimitry Andric     if (OpIdxGroup == TiedGroup)
11950b57cec5SDimitry Andric       return OpIdx + Delta;
11960b57cec5SDimitry Andric   }
11970b57cec5SDimitry Andric   llvm_unreachable("Invalid tied operand on inline asm");
11980b57cec5SDimitry Andric }
11990b57cec5SDimitry Andric 
12000b57cec5SDimitry Andric /// clearKillInfo - Clears kill flags on all operands.
12010b57cec5SDimitry Andric ///
clearKillInfo()12020b57cec5SDimitry Andric void MachineInstr::clearKillInfo() {
12030b57cec5SDimitry Andric   for (MachineOperand &MO : operands()) {
12040b57cec5SDimitry Andric     if (MO.isReg() && MO.isUse())
12050b57cec5SDimitry Andric       MO.setIsKill(false);
12060b57cec5SDimitry Andric   }
12070b57cec5SDimitry Andric }
12080b57cec5SDimitry Andric 
substituteRegister(Register FromReg,Register ToReg,unsigned SubIdx,const TargetRegisterInfo & RegInfo)12098bcb0991SDimitry Andric void MachineInstr::substituteRegister(Register FromReg, Register ToReg,
12100b57cec5SDimitry Andric                                       unsigned SubIdx,
12110b57cec5SDimitry Andric                                       const TargetRegisterInfo &RegInfo) {
12128bcb0991SDimitry Andric   if (Register::isPhysicalRegister(ToReg)) {
12130b57cec5SDimitry Andric     if (SubIdx)
12140b57cec5SDimitry Andric       ToReg = RegInfo.getSubReg(ToReg, SubIdx);
12150b57cec5SDimitry Andric     for (MachineOperand &MO : operands()) {
12160b57cec5SDimitry Andric       if (!MO.isReg() || MO.getReg() != FromReg)
12170b57cec5SDimitry Andric         continue;
12180b57cec5SDimitry Andric       MO.substPhysReg(ToReg, RegInfo);
12190b57cec5SDimitry Andric     }
12200b57cec5SDimitry Andric   } else {
12210b57cec5SDimitry Andric     for (MachineOperand &MO : operands()) {
12220b57cec5SDimitry Andric       if (!MO.isReg() || MO.getReg() != FromReg)
12230b57cec5SDimitry Andric         continue;
12240b57cec5SDimitry Andric       MO.substVirtReg(ToReg, SubIdx, RegInfo);
12250b57cec5SDimitry Andric     }
12260b57cec5SDimitry Andric   }
12270b57cec5SDimitry Andric }
12280b57cec5SDimitry Andric 
12290b57cec5SDimitry Andric /// isSafeToMove - Return true if it is safe to move this instruction. If
12300b57cec5SDimitry Andric /// SawStore is set to true, it means that there is a store (or call) between
12310b57cec5SDimitry Andric /// the instruction's location and its intended destination.
isSafeToMove(AAResults * AA,bool & SawStore) const12328bcb0991SDimitry Andric bool MachineInstr::isSafeToMove(AAResults *AA, bool &SawStore) const {
12330b57cec5SDimitry Andric   // Ignore stuff that we obviously can't move.
12340b57cec5SDimitry Andric   //
12350b57cec5SDimitry Andric   // Treat volatile loads as stores. This is not strictly necessary for
12360b57cec5SDimitry Andric   // volatiles, but it is required for atomic loads. It is not allowed to move
12370b57cec5SDimitry Andric   // a load across an atomic load with Ordering > Monotonic.
12380b57cec5SDimitry Andric   if (mayStore() || isCall() || isPHI() ||
12390b57cec5SDimitry Andric       (mayLoad() && hasOrderedMemoryRef())) {
12400b57cec5SDimitry Andric     SawStore = true;
12410b57cec5SDimitry Andric     return false;
12420b57cec5SDimitry Andric   }
12430b57cec5SDimitry Andric 
12440b57cec5SDimitry Andric   if (isPosition() || isDebugInstr() || isTerminator() ||
12450b57cec5SDimitry Andric       mayRaiseFPException() || hasUnmodeledSideEffects())
12460b57cec5SDimitry Andric     return false;
12470b57cec5SDimitry Andric 
12480b57cec5SDimitry Andric   // See if this instruction does a load.  If so, we have to guarantee that the
12490b57cec5SDimitry Andric   // loaded value doesn't change between the load and the its intended
1250af732203SDimitry Andric   // destination. The check for isInvariantLoad gives the target the chance to
12510b57cec5SDimitry Andric   // classify the load as always returning a constant, e.g. a constant pool
12520b57cec5SDimitry Andric   // load.
12530b57cec5SDimitry Andric   if (mayLoad() && !isDereferenceableInvariantLoad(AA))
12540b57cec5SDimitry Andric     // Otherwise, this is a real load.  If there is a store between the load and
12550b57cec5SDimitry Andric     // end of block, we can't move it.
12560b57cec5SDimitry Andric     return !SawStore;
12570b57cec5SDimitry Andric 
12580b57cec5SDimitry Andric   return true;
12590b57cec5SDimitry Andric }
12600b57cec5SDimitry Andric 
MemOperandsHaveAlias(const MachineFrameInfo & MFI,AAResults * AA,bool UseTBAA,const MachineMemOperand * MMOa,const MachineMemOperand * MMOb)1261af732203SDimitry Andric static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA,
1262af732203SDimitry Andric                                  bool UseTBAA, const MachineMemOperand *MMOa,
1263af732203SDimitry Andric                                  const MachineMemOperand *MMOb) {
1264af732203SDimitry Andric   // The following interface to AA is fashioned after DAGCombiner::isAlias and
1265af732203SDimitry Andric   // operates with MachineMemOperand offset with some important assumptions:
12660b57cec5SDimitry Andric   //   - LLVM fundamentally assumes flat address spaces.
1267af732203SDimitry Andric   //   - MachineOperand offset can *only* result from legalization and cannot
1268af732203SDimitry Andric   //     affect queries other than the trivial case of overlap checking.
1269af732203SDimitry Andric   //   - These offsets never wrap and never step outside of allocated objects.
12700b57cec5SDimitry Andric   //   - There should never be any negative offsets here.
12710b57cec5SDimitry Andric   //
12720b57cec5SDimitry Andric   // FIXME: Modify API to hide this math from "user"
1273af732203SDimitry Andric   // Even before we go to AA we can reason locally about some memory objects. It
1274af732203SDimitry Andric   // can save compile time, and possibly catch some corner cases not currently
1275af732203SDimitry Andric   // covered.
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric   int64_t OffsetA = MMOa->getOffset();
12780b57cec5SDimitry Andric   int64_t OffsetB = MMOb->getOffset();
12790b57cec5SDimitry Andric   int64_t MinOffset = std::min(OffsetA, OffsetB);
12800b57cec5SDimitry Andric 
12810b57cec5SDimitry Andric   uint64_t WidthA = MMOa->getSize();
12820b57cec5SDimitry Andric   uint64_t WidthB = MMOb->getSize();
12830b57cec5SDimitry Andric   bool KnownWidthA = WidthA != MemoryLocation::UnknownSize;
12840b57cec5SDimitry Andric   bool KnownWidthB = WidthB != MemoryLocation::UnknownSize;
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric   const Value *ValA = MMOa->getValue();
12870b57cec5SDimitry Andric   const Value *ValB = MMOb->getValue();
12880b57cec5SDimitry Andric   bool SameVal = (ValA && ValB && (ValA == ValB));
12890b57cec5SDimitry Andric   if (!SameVal) {
12900b57cec5SDimitry Andric     const PseudoSourceValue *PSVa = MMOa->getPseudoValue();
12910b57cec5SDimitry Andric     const PseudoSourceValue *PSVb = MMOb->getPseudoValue();
12920b57cec5SDimitry Andric     if (PSVa && ValB && !PSVa->mayAlias(&MFI))
12930b57cec5SDimitry Andric       return false;
12940b57cec5SDimitry Andric     if (PSVb && ValA && !PSVb->mayAlias(&MFI))
12950b57cec5SDimitry Andric       return false;
12960b57cec5SDimitry Andric     if (PSVa && PSVb && (PSVa == PSVb))
12970b57cec5SDimitry Andric       SameVal = true;
12980b57cec5SDimitry Andric   }
12990b57cec5SDimitry Andric 
13000b57cec5SDimitry Andric   if (SameVal) {
13010b57cec5SDimitry Andric     if (!KnownWidthA || !KnownWidthB)
13020b57cec5SDimitry Andric       return true;
13030b57cec5SDimitry Andric     int64_t MaxOffset = std::max(OffsetA, OffsetB);
13040b57cec5SDimitry Andric     int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB;
13050b57cec5SDimitry Andric     return (MinOffset + LowWidth > MaxOffset);
13060b57cec5SDimitry Andric   }
13070b57cec5SDimitry Andric 
13080b57cec5SDimitry Andric   if (!AA)
13090b57cec5SDimitry Andric     return true;
13100b57cec5SDimitry Andric 
13110b57cec5SDimitry Andric   if (!ValA || !ValB)
13120b57cec5SDimitry Andric     return true;
13130b57cec5SDimitry Andric 
13140b57cec5SDimitry Andric   assert((OffsetA >= 0) && "Negative MachineMemOperand offset");
13150b57cec5SDimitry Andric   assert((OffsetB >= 0) && "Negative MachineMemOperand offset");
13160b57cec5SDimitry Andric 
1317af732203SDimitry Andric   int64_t OverlapA =
1318af732203SDimitry Andric       KnownWidthA ? WidthA + OffsetA - MinOffset : MemoryLocation::UnknownSize;
1319af732203SDimitry Andric   int64_t OverlapB =
1320af732203SDimitry Andric       KnownWidthB ? WidthB + OffsetB - MinOffset : MemoryLocation::UnknownSize;
13210b57cec5SDimitry Andric 
1322*5f7ddb14SDimitry Andric   return !AA->isNoAlias(
1323af732203SDimitry Andric       MemoryLocation(ValA, OverlapA, UseTBAA ? MMOa->getAAInfo() : AAMDNodes()),
13240b57cec5SDimitry Andric       MemoryLocation(ValB, OverlapB,
13250b57cec5SDimitry Andric                      UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));
13260b57cec5SDimitry Andric }
13270b57cec5SDimitry Andric 
mayAlias(AAResults * AA,const MachineInstr & Other,bool UseTBAA) const1328af732203SDimitry Andric bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
1329af732203SDimitry Andric                             bool UseTBAA) const {
1330af732203SDimitry Andric   const MachineFunction *MF = getMF();
1331af732203SDimitry Andric   const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
1332af732203SDimitry Andric   const MachineFrameInfo &MFI = MF->getFrameInfo();
1333af732203SDimitry Andric 
1334af732203SDimitry Andric   // Exclude call instruction which may alter the memory but can not be handled
1335af732203SDimitry Andric   // by this function.
1336af732203SDimitry Andric   if (isCall() || Other.isCall())
1337af732203SDimitry Andric     return true;
1338af732203SDimitry Andric 
1339af732203SDimitry Andric   // If neither instruction stores to memory, they can't alias in any
1340af732203SDimitry Andric   // meaningful way, even if they read from the same address.
1341af732203SDimitry Andric   if (!mayStore() && !Other.mayStore())
1342af732203SDimitry Andric     return false;
1343af732203SDimitry Andric 
1344af732203SDimitry Andric   // Both instructions must be memory operations to be able to alias.
1345af732203SDimitry Andric   if (!mayLoadOrStore() || !Other.mayLoadOrStore())
1346af732203SDimitry Andric     return false;
1347af732203SDimitry Andric 
1348af732203SDimitry Andric   // Let the target decide if memory accesses cannot possibly overlap.
1349af732203SDimitry Andric   if (TII->areMemAccessesTriviallyDisjoint(*this, Other))
1350af732203SDimitry Andric     return false;
1351af732203SDimitry Andric 
1352af732203SDimitry Andric   // Memory operations without memory operands may access anything. Be
1353af732203SDimitry Andric   // conservative and assume `MayAlias`.
1354af732203SDimitry Andric   if (memoperands_empty() || Other.memoperands_empty())
1355af732203SDimitry Andric     return true;
1356af732203SDimitry Andric 
1357af732203SDimitry Andric   // Skip if there are too many memory operands.
1358af732203SDimitry Andric   auto NumChecks = getNumMemOperands() * Other.getNumMemOperands();
1359af732203SDimitry Andric   if (NumChecks > TII->getMemOperandAACheckLimit())
1360af732203SDimitry Andric     return true;
1361af732203SDimitry Andric 
1362af732203SDimitry Andric   // Check each pair of memory operands from both instructions, which can't
1363af732203SDimitry Andric   // alias only if all pairs won't alias.
1364af732203SDimitry Andric   for (auto *MMOa : memoperands())
1365af732203SDimitry Andric     for (auto *MMOb : Other.memoperands())
1366af732203SDimitry Andric       if (MemOperandsHaveAlias(MFI, AA, UseTBAA, MMOa, MMOb))
1367af732203SDimitry Andric         return true;
1368af732203SDimitry Andric 
1369af732203SDimitry Andric   return false;
1370af732203SDimitry Andric }
1371af732203SDimitry Andric 
13720b57cec5SDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered
13730b57cec5SDimitry Andric /// or volatile memory reference, or if the information describing the memory
13740b57cec5SDimitry Andric /// reference is not available. Return false if it is known to have no ordered
13750b57cec5SDimitry Andric /// memory references.
hasOrderedMemoryRef() const13760b57cec5SDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const {
13770b57cec5SDimitry Andric   // An instruction known never to access memory won't have a volatile access.
13780b57cec5SDimitry Andric   if (!mayStore() &&
13790b57cec5SDimitry Andric       !mayLoad() &&
13800b57cec5SDimitry Andric       !isCall() &&
13810b57cec5SDimitry Andric       !hasUnmodeledSideEffects())
13820b57cec5SDimitry Andric     return false;
13830b57cec5SDimitry Andric 
13840b57cec5SDimitry Andric   // Otherwise, if the instruction has no memory reference information,
13850b57cec5SDimitry Andric   // conservatively assume it wasn't preserved.
13860b57cec5SDimitry Andric   if (memoperands_empty())
13870b57cec5SDimitry Andric     return true;
13880b57cec5SDimitry Andric 
13890b57cec5SDimitry Andric   // Check if any of our memory operands are ordered.
13900b57cec5SDimitry Andric   return llvm::any_of(memoperands(), [](const MachineMemOperand *MMO) {
13910b57cec5SDimitry Andric     return !MMO->isUnordered();
13920b57cec5SDimitry Andric   });
13930b57cec5SDimitry Andric }
13940b57cec5SDimitry Andric 
13950b57cec5SDimitry Andric /// isDereferenceableInvariantLoad - Return true if this instruction will never
13960b57cec5SDimitry Andric /// trap and is loading from a location whose value is invariant across a run of
13970b57cec5SDimitry Andric /// this function.
isDereferenceableInvariantLoad(AAResults * AA) const13988bcb0991SDimitry Andric bool MachineInstr::isDereferenceableInvariantLoad(AAResults *AA) const {
13990b57cec5SDimitry Andric   // If the instruction doesn't load at all, it isn't an invariant load.
14000b57cec5SDimitry Andric   if (!mayLoad())
14010b57cec5SDimitry Andric     return false;
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric   // If the instruction has lost its memoperands, conservatively assume that
14040b57cec5SDimitry Andric   // it may not be an invariant load.
14050b57cec5SDimitry Andric   if (memoperands_empty())
14060b57cec5SDimitry Andric     return false;
14070b57cec5SDimitry Andric 
14080b57cec5SDimitry Andric   const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo();
14090b57cec5SDimitry Andric 
14100b57cec5SDimitry Andric   for (MachineMemOperand *MMO : memoperands()) {
14110b57cec5SDimitry Andric     if (!MMO->isUnordered())
14120b57cec5SDimitry Andric       // If the memory operand has ordering side effects, we can't move the
14130b57cec5SDimitry Andric       // instruction.  Such an instruction is technically an invariant load,
14140b57cec5SDimitry Andric       // but the caller code would need updated to expect that.
14150b57cec5SDimitry Andric       return false;
14160b57cec5SDimitry Andric     if (MMO->isStore()) return false;
14170b57cec5SDimitry Andric     if (MMO->isInvariant() && MMO->isDereferenceable())
14180b57cec5SDimitry Andric       continue;
14190b57cec5SDimitry Andric 
14200b57cec5SDimitry Andric     // A load from a constant PseudoSourceValue is invariant.
14210b57cec5SDimitry Andric     if (const PseudoSourceValue *PSV = MMO->getPseudoValue())
14220b57cec5SDimitry Andric       if (PSV->isConstant(&MFI))
14230b57cec5SDimitry Andric         continue;
14240b57cec5SDimitry Andric 
14250b57cec5SDimitry Andric     if (const Value *V = MMO->getValue()) {
14260b57cec5SDimitry Andric       // If we have an AliasAnalysis, ask it whether the memory is constant.
14270b57cec5SDimitry Andric       if (AA &&
14280b57cec5SDimitry Andric           AA->pointsToConstantMemory(
14290b57cec5SDimitry Andric               MemoryLocation(V, MMO->getSize(), MMO->getAAInfo())))
14300b57cec5SDimitry Andric         continue;
14310b57cec5SDimitry Andric     }
14320b57cec5SDimitry Andric 
14330b57cec5SDimitry Andric     // Otherwise assume conservatively.
14340b57cec5SDimitry Andric     return false;
14350b57cec5SDimitry Andric   }
14360b57cec5SDimitry Andric 
14370b57cec5SDimitry Andric   // Everything checks out.
14380b57cec5SDimitry Andric   return true;
14390b57cec5SDimitry Andric }
14400b57cec5SDimitry Andric 
14410b57cec5SDimitry Andric /// isConstantValuePHI - If the specified instruction is a PHI that always
14420b57cec5SDimitry Andric /// merges together the same virtual register, return the register, otherwise
14430b57cec5SDimitry Andric /// return 0.
isConstantValuePHI() const14440b57cec5SDimitry Andric unsigned MachineInstr::isConstantValuePHI() const {
14450b57cec5SDimitry Andric   if (!isPHI())
14460b57cec5SDimitry Andric     return 0;
14470b57cec5SDimitry Andric   assert(getNumOperands() >= 3 &&
14480b57cec5SDimitry Andric          "It's illegal to have a PHI without source operands");
14490b57cec5SDimitry Andric 
14508bcb0991SDimitry Andric   Register Reg = getOperand(1).getReg();
14510b57cec5SDimitry Andric   for (unsigned i = 3, e = getNumOperands(); i < e; i += 2)
14520b57cec5SDimitry Andric     if (getOperand(i).getReg() != Reg)
14530b57cec5SDimitry Andric       return 0;
14540b57cec5SDimitry Andric   return Reg;
14550b57cec5SDimitry Andric }
14560b57cec5SDimitry Andric 
hasUnmodeledSideEffects() const14570b57cec5SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const {
14580b57cec5SDimitry Andric   if (hasProperty(MCID::UnmodeledSideEffects))
14590b57cec5SDimitry Andric     return true;
14600b57cec5SDimitry Andric   if (isInlineAsm()) {
14610b57cec5SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
14620b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
14630b57cec5SDimitry Andric       return true;
14640b57cec5SDimitry Andric   }
14650b57cec5SDimitry Andric 
14660b57cec5SDimitry Andric   return false;
14670b57cec5SDimitry Andric }
14680b57cec5SDimitry Andric 
isLoadFoldBarrier() const14690b57cec5SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const {
1470af732203SDimitry Andric   return mayStore() || isCall() ||
1471af732203SDimitry Andric          (hasUnmodeledSideEffects() && !isPseudoProbe());
14720b57cec5SDimitry Andric }
14730b57cec5SDimitry Andric 
14740b57cec5SDimitry Andric /// allDefsAreDead - Return true if all the defs of this instruction are dead.
14750b57cec5SDimitry Andric ///
allDefsAreDead() const14760b57cec5SDimitry Andric bool MachineInstr::allDefsAreDead() const {
14770b57cec5SDimitry Andric   for (const MachineOperand &MO : operands()) {
14780b57cec5SDimitry Andric     if (!MO.isReg() || MO.isUse())
14790b57cec5SDimitry Andric       continue;
14800b57cec5SDimitry Andric     if (!MO.isDead())
14810b57cec5SDimitry Andric       return false;
14820b57cec5SDimitry Andric   }
14830b57cec5SDimitry Andric   return true;
14840b57cec5SDimitry Andric }
14850b57cec5SDimitry Andric 
14860b57cec5SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified
14870b57cec5SDimitry Andric /// instruction to this instruction.
copyImplicitOps(MachineFunction & MF,const MachineInstr & MI)14880b57cec5SDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF,
14890b57cec5SDimitry Andric                                    const MachineInstr &MI) {
14900b57cec5SDimitry Andric   for (unsigned i = MI.getDesc().getNumOperands(), e = MI.getNumOperands();
14910b57cec5SDimitry Andric        i != e; ++i) {
14920b57cec5SDimitry Andric     const MachineOperand &MO = MI.getOperand(i);
14930b57cec5SDimitry Andric     if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask())
14940b57cec5SDimitry Andric       addOperand(MF, MO);
14950b57cec5SDimitry Andric   }
14960b57cec5SDimitry Andric }
14970b57cec5SDimitry Andric 
hasComplexRegisterTies() const14980b57cec5SDimitry Andric bool MachineInstr::hasComplexRegisterTies() const {
14990b57cec5SDimitry Andric   const MCInstrDesc &MCID = getDesc();
1500af732203SDimitry Andric   if (MCID.Opcode == TargetOpcode::STATEPOINT)
1501af732203SDimitry Andric     return true;
15020b57cec5SDimitry Andric   for (unsigned I = 0, E = getNumOperands(); I < E; ++I) {
15030b57cec5SDimitry Andric     const auto &Operand = getOperand(I);
15040b57cec5SDimitry Andric     if (!Operand.isReg() || Operand.isDef())
15050b57cec5SDimitry Andric       // Ignore the defined registers as MCID marks only the uses as tied.
15060b57cec5SDimitry Andric       continue;
15070b57cec5SDimitry Andric     int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO);
15080b57cec5SDimitry Andric     int TiedIdx = Operand.isTied() ? int(findTiedOperandIdx(I)) : -1;
15090b57cec5SDimitry Andric     if (ExpectedTiedIdx != TiedIdx)
15100b57cec5SDimitry Andric       return true;
15110b57cec5SDimitry Andric   }
15120b57cec5SDimitry Andric   return false;
15130b57cec5SDimitry Andric }
15140b57cec5SDimitry Andric 
getTypeToPrint(unsigned OpIdx,SmallBitVector & PrintedTypes,const MachineRegisterInfo & MRI) const15150b57cec5SDimitry Andric LLT MachineInstr::getTypeToPrint(unsigned OpIdx, SmallBitVector &PrintedTypes,
15160b57cec5SDimitry Andric                                  const MachineRegisterInfo &MRI) const {
15170b57cec5SDimitry Andric   const MachineOperand &Op = getOperand(OpIdx);
15180b57cec5SDimitry Andric   if (!Op.isReg())
15190b57cec5SDimitry Andric     return LLT{};
15200b57cec5SDimitry Andric 
15210b57cec5SDimitry Andric   if (isVariadic() || OpIdx >= getNumExplicitOperands())
15220b57cec5SDimitry Andric     return MRI.getType(Op.getReg());
15230b57cec5SDimitry Andric 
15240b57cec5SDimitry Andric   auto &OpInfo = getDesc().OpInfo[OpIdx];
15250b57cec5SDimitry Andric   if (!OpInfo.isGenericType())
15260b57cec5SDimitry Andric     return MRI.getType(Op.getReg());
15270b57cec5SDimitry Andric 
15280b57cec5SDimitry Andric   if (PrintedTypes[OpInfo.getGenericTypeIndex()])
15290b57cec5SDimitry Andric     return LLT{};
15300b57cec5SDimitry Andric 
15310b57cec5SDimitry Andric   LLT TypeToPrint = MRI.getType(Op.getReg());
15320b57cec5SDimitry Andric   // Don't mark the type index printed if it wasn't actually printed: maybe
15330b57cec5SDimitry Andric   // another operand with the same type index has an actual type attached:
15340b57cec5SDimitry Andric   if (TypeToPrint.isValid())
15350b57cec5SDimitry Andric     PrintedTypes.set(OpInfo.getGenericTypeIndex());
15360b57cec5SDimitry Andric   return TypeToPrint;
15370b57cec5SDimitry Andric }
15380b57cec5SDimitry Andric 
15390b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const15400b57cec5SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dump() const {
15410b57cec5SDimitry Andric   dbgs() << "  ";
15420b57cec5SDimitry Andric   print(dbgs());
15430b57cec5SDimitry Andric }
15445ffd83dbSDimitry Andric 
dumprImpl(const MachineRegisterInfo & MRI,unsigned Depth,unsigned MaxDepth,SmallPtrSetImpl<const MachineInstr * > & AlreadySeenInstrs) const15455ffd83dbSDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dumprImpl(
15465ffd83dbSDimitry Andric     const MachineRegisterInfo &MRI, unsigned Depth, unsigned MaxDepth,
15475ffd83dbSDimitry Andric     SmallPtrSetImpl<const MachineInstr *> &AlreadySeenInstrs) const {
15485ffd83dbSDimitry Andric   if (Depth >= MaxDepth)
15495ffd83dbSDimitry Andric     return;
15505ffd83dbSDimitry Andric   if (!AlreadySeenInstrs.insert(this).second)
15515ffd83dbSDimitry Andric     return;
15525ffd83dbSDimitry Andric   // PadToColumn always inserts at least one space.
15535ffd83dbSDimitry Andric   // Don't mess up the alignment if we don't want any space.
15545ffd83dbSDimitry Andric   if (Depth)
15555ffd83dbSDimitry Andric     fdbgs().PadToColumn(Depth * 2);
15565ffd83dbSDimitry Andric   print(fdbgs());
15575ffd83dbSDimitry Andric   for (const MachineOperand &MO : operands()) {
15585ffd83dbSDimitry Andric     if (!MO.isReg() || MO.isDef())
15595ffd83dbSDimitry Andric       continue;
15605ffd83dbSDimitry Andric     Register Reg = MO.getReg();
15615ffd83dbSDimitry Andric     if (Reg.isPhysical())
15625ffd83dbSDimitry Andric       continue;
15635ffd83dbSDimitry Andric     const MachineInstr *NewMI = MRI.getUniqueVRegDef(Reg);
15645ffd83dbSDimitry Andric     if (NewMI == nullptr)
15655ffd83dbSDimitry Andric       continue;
15665ffd83dbSDimitry Andric     NewMI->dumprImpl(MRI, Depth + 1, MaxDepth, AlreadySeenInstrs);
15675ffd83dbSDimitry Andric   }
15685ffd83dbSDimitry Andric }
15695ffd83dbSDimitry Andric 
dumpr(const MachineRegisterInfo & MRI,unsigned MaxDepth) const15705ffd83dbSDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dumpr(const MachineRegisterInfo &MRI,
15715ffd83dbSDimitry Andric                                           unsigned MaxDepth) const {
15725ffd83dbSDimitry Andric   SmallPtrSet<const MachineInstr *, 16> AlreadySeenInstrs;
15735ffd83dbSDimitry Andric   dumprImpl(MRI, 0, MaxDepth, AlreadySeenInstrs);
15745ffd83dbSDimitry Andric }
15750b57cec5SDimitry Andric #endif
15760b57cec5SDimitry Andric 
print(raw_ostream & OS,bool IsStandalone,bool SkipOpers,bool SkipDebugLoc,bool AddNewLine,const TargetInstrInfo * TII) const15770b57cec5SDimitry Andric void MachineInstr::print(raw_ostream &OS, bool IsStandalone, bool SkipOpers,
15780b57cec5SDimitry Andric                          bool SkipDebugLoc, bool AddNewLine,
15790b57cec5SDimitry Andric                          const TargetInstrInfo *TII) const {
15800b57cec5SDimitry Andric   const Module *M = nullptr;
15810b57cec5SDimitry Andric   const Function *F = nullptr;
15820b57cec5SDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(*this)) {
15830b57cec5SDimitry Andric     F = &MF->getFunction();
15840b57cec5SDimitry Andric     M = F->getParent();
15850b57cec5SDimitry Andric     if (!TII)
15860b57cec5SDimitry Andric       TII = MF->getSubtarget().getInstrInfo();
15870b57cec5SDimitry Andric   }
15880b57cec5SDimitry Andric 
15890b57cec5SDimitry Andric   ModuleSlotTracker MST(M);
15900b57cec5SDimitry Andric   if (F)
15910b57cec5SDimitry Andric     MST.incorporateFunction(*F);
15920b57cec5SDimitry Andric   print(OS, MST, IsStandalone, SkipOpers, SkipDebugLoc, AddNewLine, TII);
15930b57cec5SDimitry Andric }
15940b57cec5SDimitry Andric 
print(raw_ostream & OS,ModuleSlotTracker & MST,bool IsStandalone,bool SkipOpers,bool SkipDebugLoc,bool AddNewLine,const TargetInstrInfo * TII) const15950b57cec5SDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
15960b57cec5SDimitry Andric                          bool IsStandalone, bool SkipOpers, bool SkipDebugLoc,
15970b57cec5SDimitry Andric                          bool AddNewLine, const TargetInstrInfo *TII) const {
15980b57cec5SDimitry Andric   // We can be a bit tidier if we know the MachineFunction.
15990b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = nullptr;
16000b57cec5SDimitry Andric   const MachineRegisterInfo *MRI = nullptr;
16010b57cec5SDimitry Andric   const TargetIntrinsicInfo *IntrinsicInfo = nullptr;
16020b57cec5SDimitry Andric   tryToGetTargetInfo(*this, TRI, MRI, IntrinsicInfo, TII);
16030b57cec5SDimitry Andric 
16040b57cec5SDimitry Andric   if (isCFIInstruction())
16050b57cec5SDimitry Andric     assert(getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
16060b57cec5SDimitry Andric 
16070b57cec5SDimitry Andric   SmallBitVector PrintedTypes(8);
16080b57cec5SDimitry Andric   bool ShouldPrintRegisterTies = IsStandalone || hasComplexRegisterTies();
16090b57cec5SDimitry Andric   auto getTiedOperandIdx = [&](unsigned OpIdx) {
16100b57cec5SDimitry Andric     if (!ShouldPrintRegisterTies)
16110b57cec5SDimitry Andric       return 0U;
16120b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(OpIdx);
16130b57cec5SDimitry Andric     if (MO.isReg() && MO.isTied() && !MO.isDef())
16140b57cec5SDimitry Andric       return findTiedOperandIdx(OpIdx);
16150b57cec5SDimitry Andric     return 0U;
16160b57cec5SDimitry Andric   };
16170b57cec5SDimitry Andric   unsigned StartOp = 0;
16180b57cec5SDimitry Andric   unsigned e = getNumOperands();
16190b57cec5SDimitry Andric 
16200b57cec5SDimitry Andric   // Print explicitly defined operands on the left of an assignment syntax.
16210b57cec5SDimitry Andric   while (StartOp < e) {
16220b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(StartOp);
16230b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
16240b57cec5SDimitry Andric       break;
16250b57cec5SDimitry Andric 
16260b57cec5SDimitry Andric     if (StartOp != 0)
16270b57cec5SDimitry Andric       OS << ", ";
16280b57cec5SDimitry Andric 
16290b57cec5SDimitry Andric     LLT TypeToPrint = MRI ? getTypeToPrint(StartOp, PrintedTypes, *MRI) : LLT{};
16300b57cec5SDimitry Andric     unsigned TiedOperandIdx = getTiedOperandIdx(StartOp);
1631480093f4SDimitry Andric     MO.print(OS, MST, TypeToPrint, StartOp, /*PrintDef=*/false, IsStandalone,
16320b57cec5SDimitry Andric              ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
16330b57cec5SDimitry Andric     ++StartOp;
16340b57cec5SDimitry Andric   }
16350b57cec5SDimitry Andric 
16360b57cec5SDimitry Andric   if (StartOp != 0)
16370b57cec5SDimitry Andric     OS << " = ";
16380b57cec5SDimitry Andric 
16390b57cec5SDimitry Andric   if (getFlag(MachineInstr::FrameSetup))
16400b57cec5SDimitry Andric     OS << "frame-setup ";
16410b57cec5SDimitry Andric   if (getFlag(MachineInstr::FrameDestroy))
16420b57cec5SDimitry Andric     OS << "frame-destroy ";
16430b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmNoNans))
16440b57cec5SDimitry Andric     OS << "nnan ";
16450b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmNoInfs))
16460b57cec5SDimitry Andric     OS << "ninf ";
16470b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmNsz))
16480b57cec5SDimitry Andric     OS << "nsz ";
16490b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmArcp))
16500b57cec5SDimitry Andric     OS << "arcp ";
16510b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmContract))
16520b57cec5SDimitry Andric     OS << "contract ";
16530b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmAfn))
16540b57cec5SDimitry Andric     OS << "afn ";
16550b57cec5SDimitry Andric   if (getFlag(MachineInstr::FmReassoc))
16560b57cec5SDimitry Andric     OS << "reassoc ";
16570b57cec5SDimitry Andric   if (getFlag(MachineInstr::NoUWrap))
16580b57cec5SDimitry Andric     OS << "nuw ";
16590b57cec5SDimitry Andric   if (getFlag(MachineInstr::NoSWrap))
16600b57cec5SDimitry Andric     OS << "nsw ";
16610b57cec5SDimitry Andric   if (getFlag(MachineInstr::IsExact))
16620b57cec5SDimitry Andric     OS << "exact ";
1663480093f4SDimitry Andric   if (getFlag(MachineInstr::NoFPExcept))
1664480093f4SDimitry Andric     OS << "nofpexcept ";
16655ffd83dbSDimitry Andric   if (getFlag(MachineInstr::NoMerge))
16665ffd83dbSDimitry Andric     OS << "nomerge ";
16670b57cec5SDimitry Andric 
16680b57cec5SDimitry Andric   // Print the opcode name.
16690b57cec5SDimitry Andric   if (TII)
16700b57cec5SDimitry Andric     OS << TII->getName(getOpcode());
16710b57cec5SDimitry Andric   else
16720b57cec5SDimitry Andric     OS << "UNKNOWN";
16730b57cec5SDimitry Andric 
16740b57cec5SDimitry Andric   if (SkipOpers)
16750b57cec5SDimitry Andric     return;
16760b57cec5SDimitry Andric 
16770b57cec5SDimitry Andric   // Print the rest of the operands.
16780b57cec5SDimitry Andric   bool FirstOp = true;
16790b57cec5SDimitry Andric   unsigned AsmDescOp = ~0u;
16800b57cec5SDimitry Andric   unsigned AsmOpCount = 0;
16810b57cec5SDimitry Andric 
16820b57cec5SDimitry Andric   if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) {
16830b57cec5SDimitry Andric     // Print asm string.
16840b57cec5SDimitry Andric     OS << " ";
16850b57cec5SDimitry Andric     const unsigned OpIdx = InlineAsm::MIOp_AsmString;
16860b57cec5SDimitry Andric     LLT TypeToPrint = MRI ? getTypeToPrint(OpIdx, PrintedTypes, *MRI) : LLT{};
16870b57cec5SDimitry Andric     unsigned TiedOperandIdx = getTiedOperandIdx(OpIdx);
1688480093f4SDimitry Andric     getOperand(OpIdx).print(OS, MST, TypeToPrint, OpIdx, /*PrintDef=*/true, IsStandalone,
16890b57cec5SDimitry Andric                             ShouldPrintRegisterTies, TiedOperandIdx, TRI,
16900b57cec5SDimitry Andric                             IntrinsicInfo);
16910b57cec5SDimitry Andric 
16920b57cec5SDimitry Andric     // Print HasSideEffects, MayLoad, MayStore, IsAlignStack
16930b57cec5SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
16940b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
16950b57cec5SDimitry Andric       OS << " [sideeffect]";
16960b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_MayLoad)
16970b57cec5SDimitry Andric       OS << " [mayload]";
16980b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_MayStore)
16990b57cec5SDimitry Andric       OS << " [maystore]";
17000b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsConvergent)
17010b57cec5SDimitry Andric       OS << " [isconvergent]";
17020b57cec5SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
17030b57cec5SDimitry Andric       OS << " [alignstack]";
17040b57cec5SDimitry Andric     if (getInlineAsmDialect() == InlineAsm::AD_ATT)
17050b57cec5SDimitry Andric       OS << " [attdialect]";
17060b57cec5SDimitry Andric     if (getInlineAsmDialect() == InlineAsm::AD_Intel)
17070b57cec5SDimitry Andric       OS << " [inteldialect]";
17080b57cec5SDimitry Andric 
17090b57cec5SDimitry Andric     StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand;
17100b57cec5SDimitry Andric     FirstOp = false;
17110b57cec5SDimitry Andric   }
17120b57cec5SDimitry Andric 
17130b57cec5SDimitry Andric   for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
17140b57cec5SDimitry Andric     const MachineOperand &MO = getOperand(i);
17150b57cec5SDimitry Andric 
17160b57cec5SDimitry Andric     if (FirstOp) FirstOp = false; else OS << ",";
17170b57cec5SDimitry Andric     OS << " ";
17180b57cec5SDimitry Andric 
17190b57cec5SDimitry Andric     if (isDebugValue() && MO.isMetadata()) {
1720*5f7ddb14SDimitry Andric       // Pretty print DBG_VALUE* instructions.
17210b57cec5SDimitry Andric       auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata());
17220b57cec5SDimitry Andric       if (DIV && !DIV->getName().empty())
17230b57cec5SDimitry Andric         OS << "!\"" << DIV->getName() << '\"';
17240b57cec5SDimitry Andric       else {
17250b57cec5SDimitry Andric         LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
17260b57cec5SDimitry Andric         unsigned TiedOperandIdx = getTiedOperandIdx(i);
1727480093f4SDimitry Andric         MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone,
17280b57cec5SDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
17290b57cec5SDimitry Andric       }
17300b57cec5SDimitry Andric     } else if (isDebugLabel() && MO.isMetadata()) {
17310b57cec5SDimitry Andric       // Pretty print DBG_LABEL instructions.
17320b57cec5SDimitry Andric       auto *DIL = dyn_cast<DILabel>(MO.getMetadata());
17330b57cec5SDimitry Andric       if (DIL && !DIL->getName().empty())
17340b57cec5SDimitry Andric         OS << "\"" << DIL->getName() << '\"';
17350b57cec5SDimitry Andric       else {
17360b57cec5SDimitry Andric         LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
17370b57cec5SDimitry Andric         unsigned TiedOperandIdx = getTiedOperandIdx(i);
1738480093f4SDimitry Andric         MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone,
17390b57cec5SDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
17400b57cec5SDimitry Andric       }
17410b57cec5SDimitry Andric     } else if (i == AsmDescOp && MO.isImm()) {
17420b57cec5SDimitry Andric       // Pretty print the inline asm operand descriptor.
17430b57cec5SDimitry Andric       OS << '$' << AsmOpCount++;
17440b57cec5SDimitry Andric       unsigned Flag = MO.getImm();
17455ffd83dbSDimitry Andric       OS << ":[";
17465ffd83dbSDimitry Andric       OS << InlineAsm::getKindName(InlineAsm::getKind(Flag));
17470b57cec5SDimitry Andric 
17480b57cec5SDimitry Andric       unsigned RCID = 0;
17490b57cec5SDimitry Andric       if (!InlineAsm::isImmKind(Flag) && !InlineAsm::isMemKind(Flag) &&
17500b57cec5SDimitry Andric           InlineAsm::hasRegClassConstraint(Flag, RCID)) {
17510b57cec5SDimitry Andric         if (TRI) {
17520b57cec5SDimitry Andric           OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID));
17530b57cec5SDimitry Andric         } else
17540b57cec5SDimitry Andric           OS << ":RC" << RCID;
17550b57cec5SDimitry Andric       }
17560b57cec5SDimitry Andric 
17570b57cec5SDimitry Andric       if (InlineAsm::isMemKind(Flag)) {
17580b57cec5SDimitry Andric         unsigned MCID = InlineAsm::getMemoryConstraintID(Flag);
17595ffd83dbSDimitry Andric         OS << ":" << InlineAsm::getMemConstraintName(MCID);
17600b57cec5SDimitry Andric       }
17610b57cec5SDimitry Andric 
17620b57cec5SDimitry Andric       unsigned TiedTo = 0;
17630b57cec5SDimitry Andric       if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo))
17640b57cec5SDimitry Andric         OS << " tiedto:$" << TiedTo;
17650b57cec5SDimitry Andric 
17660b57cec5SDimitry Andric       OS << ']';
17670b57cec5SDimitry Andric 
17680b57cec5SDimitry Andric       // Compute the index of the next operand descriptor.
17690b57cec5SDimitry Andric       AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag);
17700b57cec5SDimitry Andric     } else {
17710b57cec5SDimitry Andric       LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
17720b57cec5SDimitry Andric       unsigned TiedOperandIdx = getTiedOperandIdx(i);
17730b57cec5SDimitry Andric       if (MO.isImm() && isOperandSubregIdx(i))
17740b57cec5SDimitry Andric         MachineOperand::printSubRegIdx(OS, MO.getImm(), TRI);
17750b57cec5SDimitry Andric       else
1776480093f4SDimitry Andric         MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone,
17770b57cec5SDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
17780b57cec5SDimitry Andric     }
17790b57cec5SDimitry Andric   }
17800b57cec5SDimitry Andric 
17810b57cec5SDimitry Andric   // Print any optional symbols attached to this instruction as-if they were
17820b57cec5SDimitry Andric   // operands.
17830b57cec5SDimitry Andric   if (MCSymbol *PreInstrSymbol = getPreInstrSymbol()) {
17840b57cec5SDimitry Andric     if (!FirstOp) {
17850b57cec5SDimitry Andric       FirstOp = false;
17860b57cec5SDimitry Andric       OS << ',';
17870b57cec5SDimitry Andric     }
17880b57cec5SDimitry Andric     OS << " pre-instr-symbol ";
17890b57cec5SDimitry Andric     MachineOperand::printSymbol(OS, *PreInstrSymbol);
17900b57cec5SDimitry Andric   }
17910b57cec5SDimitry Andric   if (MCSymbol *PostInstrSymbol = getPostInstrSymbol()) {
17920b57cec5SDimitry Andric     if (!FirstOp) {
17930b57cec5SDimitry Andric       FirstOp = false;
17940b57cec5SDimitry Andric       OS << ',';
17950b57cec5SDimitry Andric     }
17960b57cec5SDimitry Andric     OS << " post-instr-symbol ";
17970b57cec5SDimitry Andric     MachineOperand::printSymbol(OS, *PostInstrSymbol);
17980b57cec5SDimitry Andric   }
1799c14a5a88SDimitry Andric   if (MDNode *HeapAllocMarker = getHeapAllocMarker()) {
1800c14a5a88SDimitry Andric     if (!FirstOp) {
1801c14a5a88SDimitry Andric       FirstOp = false;
1802c14a5a88SDimitry Andric       OS << ',';
1803c14a5a88SDimitry Andric     }
1804c14a5a88SDimitry Andric     OS << " heap-alloc-marker ";
1805480093f4SDimitry Andric     HeapAllocMarker->printAsOperand(OS, MST);
1806c14a5a88SDimitry Andric   }
18070b57cec5SDimitry Andric 
1808af732203SDimitry Andric   if (DebugInstrNum) {
1809af732203SDimitry Andric     if (!FirstOp)
1810af732203SDimitry Andric       OS << ",";
1811af732203SDimitry Andric     OS << " debug-instr-number " << DebugInstrNum;
1812af732203SDimitry Andric   }
1813af732203SDimitry Andric 
18140b57cec5SDimitry Andric   if (!SkipDebugLoc) {
18150b57cec5SDimitry Andric     if (const DebugLoc &DL = getDebugLoc()) {
18160b57cec5SDimitry Andric       if (!FirstOp)
18170b57cec5SDimitry Andric         OS << ',';
18180b57cec5SDimitry Andric       OS << " debug-location ";
18190b57cec5SDimitry Andric       DL->printAsOperand(OS, MST);
18200b57cec5SDimitry Andric     }
18210b57cec5SDimitry Andric   }
18220b57cec5SDimitry Andric 
18230b57cec5SDimitry Andric   if (!memoperands_empty()) {
18240b57cec5SDimitry Andric     SmallVector<StringRef, 0> SSNs;
18250b57cec5SDimitry Andric     const LLVMContext *Context = nullptr;
18260b57cec5SDimitry Andric     std::unique_ptr<LLVMContext> CtxPtr;
18270b57cec5SDimitry Andric     const MachineFrameInfo *MFI = nullptr;
18280b57cec5SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
18290b57cec5SDimitry Andric       MFI = &MF->getFrameInfo();
18300b57cec5SDimitry Andric       Context = &MF->getFunction().getContext();
18310b57cec5SDimitry Andric     } else {
18328bcb0991SDimitry Andric       CtxPtr = std::make_unique<LLVMContext>();
18330b57cec5SDimitry Andric       Context = CtxPtr.get();
18340b57cec5SDimitry Andric     }
18350b57cec5SDimitry Andric 
18360b57cec5SDimitry Andric     OS << " :: ";
18370b57cec5SDimitry Andric     bool NeedComma = false;
18380b57cec5SDimitry Andric     for (const MachineMemOperand *Op : memoperands()) {
18390b57cec5SDimitry Andric       if (NeedComma)
18400b57cec5SDimitry Andric         OS << ", ";
18410b57cec5SDimitry Andric       Op->print(OS, MST, SSNs, *Context, MFI, TII);
18420b57cec5SDimitry Andric       NeedComma = true;
18430b57cec5SDimitry Andric     }
18440b57cec5SDimitry Andric   }
18450b57cec5SDimitry Andric 
18460b57cec5SDimitry Andric   if (SkipDebugLoc)
18470b57cec5SDimitry Andric     return;
18480b57cec5SDimitry Andric 
18490b57cec5SDimitry Andric   bool HaveSemi = false;
18500b57cec5SDimitry Andric 
18510b57cec5SDimitry Andric   // Print debug location information.
18520b57cec5SDimitry Andric   if (const DebugLoc &DL = getDebugLoc()) {
18530b57cec5SDimitry Andric     if (!HaveSemi) {
18540b57cec5SDimitry Andric       OS << ';';
18550b57cec5SDimitry Andric       HaveSemi = true;
18560b57cec5SDimitry Andric     }
18570b57cec5SDimitry Andric     OS << ' ';
18580b57cec5SDimitry Andric     DL.print(OS);
18590b57cec5SDimitry Andric   }
18600b57cec5SDimitry Andric 
18610b57cec5SDimitry Andric   // Print extra comments for DEBUG_VALUE.
18625ffd83dbSDimitry Andric   if (isDebugValue() && getDebugVariableOp().isMetadata()) {
18630b57cec5SDimitry Andric     if (!HaveSemi) {
18640b57cec5SDimitry Andric       OS << ";";
18650b57cec5SDimitry Andric       HaveSemi = true;
18660b57cec5SDimitry Andric     }
18675ffd83dbSDimitry Andric     auto *DV = getDebugVariable();
18680b57cec5SDimitry Andric     OS << " line no:" <<  DV->getLine();
18690b57cec5SDimitry Andric     if (isIndirectDebugValue())
18700b57cec5SDimitry Andric       OS << " indirect";
18710b57cec5SDimitry Andric   }
18720b57cec5SDimitry Andric   // TODO: DBG_LABEL
18730b57cec5SDimitry Andric 
18740b57cec5SDimitry Andric   if (AddNewLine)
18750b57cec5SDimitry Andric     OS << '\n';
18760b57cec5SDimitry Andric }
18770b57cec5SDimitry Andric 
addRegisterKilled(Register IncomingReg,const TargetRegisterInfo * RegInfo,bool AddIfNotFound)18788bcb0991SDimitry Andric bool MachineInstr::addRegisterKilled(Register IncomingReg,
18790b57cec5SDimitry Andric                                      const TargetRegisterInfo *RegInfo,
18800b57cec5SDimitry Andric                                      bool AddIfNotFound) {
18818bcb0991SDimitry Andric   bool isPhysReg = Register::isPhysicalRegister(IncomingReg);
18820b57cec5SDimitry Andric   bool hasAliases = isPhysReg &&
18830b57cec5SDimitry Andric     MCRegAliasIterator(IncomingReg, RegInfo, false).isValid();
18840b57cec5SDimitry Andric   bool Found = false;
18850b57cec5SDimitry Andric   SmallVector<unsigned,4> DeadOps;
18860b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
18870b57cec5SDimitry Andric     MachineOperand &MO = getOperand(i);
18880b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isUse() || MO.isUndef())
18890b57cec5SDimitry Andric       continue;
18900b57cec5SDimitry Andric 
18910b57cec5SDimitry Andric     // DEBUG_VALUE nodes do not contribute to code generation and should
18920b57cec5SDimitry Andric     // always be ignored. Failure to do so may result in trying to modify
18930b57cec5SDimitry Andric     // KILL flags on DEBUG_VALUE nodes.
18940b57cec5SDimitry Andric     if (MO.isDebug())
18950b57cec5SDimitry Andric       continue;
18960b57cec5SDimitry Andric 
18978bcb0991SDimitry Andric     Register Reg = MO.getReg();
18980b57cec5SDimitry Andric     if (!Reg)
18990b57cec5SDimitry Andric       continue;
19000b57cec5SDimitry Andric 
19010b57cec5SDimitry Andric     if (Reg == IncomingReg) {
19020b57cec5SDimitry Andric       if (!Found) {
19030b57cec5SDimitry Andric         if (MO.isKill())
19040b57cec5SDimitry Andric           // The register is already marked kill.
19050b57cec5SDimitry Andric           return true;
19060b57cec5SDimitry Andric         if (isPhysReg && isRegTiedToDefOperand(i))
19070b57cec5SDimitry Andric           // Two-address uses of physregs must not be marked kill.
19080b57cec5SDimitry Andric           return true;
19090b57cec5SDimitry Andric         MO.setIsKill();
19100b57cec5SDimitry Andric         Found = true;
19110b57cec5SDimitry Andric       }
19128bcb0991SDimitry Andric     } else if (hasAliases && MO.isKill() && Register::isPhysicalRegister(Reg)) {
19130b57cec5SDimitry Andric       // A super-register kill already exists.
19140b57cec5SDimitry Andric       if (RegInfo->isSuperRegister(IncomingReg, Reg))
19150b57cec5SDimitry Andric         return true;
19160b57cec5SDimitry Andric       if (RegInfo->isSubRegister(IncomingReg, Reg))
19170b57cec5SDimitry Andric         DeadOps.push_back(i);
19180b57cec5SDimitry Andric     }
19190b57cec5SDimitry Andric   }
19200b57cec5SDimitry Andric 
19210b57cec5SDimitry Andric   // Trim unneeded kill operands.
19220b57cec5SDimitry Andric   while (!DeadOps.empty()) {
19230b57cec5SDimitry Andric     unsigned OpIdx = DeadOps.back();
19240b57cec5SDimitry Andric     if (getOperand(OpIdx).isImplicit() &&
19250b57cec5SDimitry Andric         (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0))
19260b57cec5SDimitry Andric       RemoveOperand(OpIdx);
19270b57cec5SDimitry Andric     else
19280b57cec5SDimitry Andric       getOperand(OpIdx).setIsKill(false);
19290b57cec5SDimitry Andric     DeadOps.pop_back();
19300b57cec5SDimitry Andric   }
19310b57cec5SDimitry Andric 
19320b57cec5SDimitry Andric   // If not found, this means an alias of one of the operands is killed. Add a
19330b57cec5SDimitry Andric   // new implicit operand if required.
19340b57cec5SDimitry Andric   if (!Found && AddIfNotFound) {
19350b57cec5SDimitry Andric     addOperand(MachineOperand::CreateReg(IncomingReg,
19360b57cec5SDimitry Andric                                          false /*IsDef*/,
19370b57cec5SDimitry Andric                                          true  /*IsImp*/,
19380b57cec5SDimitry Andric                                          true  /*IsKill*/));
19390b57cec5SDimitry Andric     return true;
19400b57cec5SDimitry Andric   }
19410b57cec5SDimitry Andric   return Found;
19420b57cec5SDimitry Andric }
19430b57cec5SDimitry Andric 
clearRegisterKills(Register Reg,const TargetRegisterInfo * RegInfo)19448bcb0991SDimitry Andric void MachineInstr::clearRegisterKills(Register Reg,
19450b57cec5SDimitry Andric                                       const TargetRegisterInfo *RegInfo) {
19468bcb0991SDimitry Andric   if (!Register::isPhysicalRegister(Reg))
19470b57cec5SDimitry Andric     RegInfo = nullptr;
19480b57cec5SDimitry Andric   for (MachineOperand &MO : operands()) {
19490b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isUse() || !MO.isKill())
19500b57cec5SDimitry Andric       continue;
19518bcb0991SDimitry Andric     Register OpReg = MO.getReg();
19520b57cec5SDimitry Andric     if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg)
19530b57cec5SDimitry Andric       MO.setIsKill(false);
19540b57cec5SDimitry Andric   }
19550b57cec5SDimitry Andric }
19560b57cec5SDimitry Andric 
addRegisterDead(Register Reg,const TargetRegisterInfo * RegInfo,bool AddIfNotFound)19578bcb0991SDimitry Andric bool MachineInstr::addRegisterDead(Register Reg,
19580b57cec5SDimitry Andric                                    const TargetRegisterInfo *RegInfo,
19590b57cec5SDimitry Andric                                    bool AddIfNotFound) {
19608bcb0991SDimitry Andric   bool isPhysReg = Register::isPhysicalRegister(Reg);
19610b57cec5SDimitry Andric   bool hasAliases = isPhysReg &&
19620b57cec5SDimitry Andric     MCRegAliasIterator(Reg, RegInfo, false).isValid();
19630b57cec5SDimitry Andric   bool Found = false;
19640b57cec5SDimitry Andric   SmallVector<unsigned,4> DeadOps;
19650b57cec5SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
19660b57cec5SDimitry Andric     MachineOperand &MO = getOperand(i);
19670b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef())
19680b57cec5SDimitry Andric       continue;
19698bcb0991SDimitry Andric     Register MOReg = MO.getReg();
19700b57cec5SDimitry Andric     if (!MOReg)
19710b57cec5SDimitry Andric       continue;
19720b57cec5SDimitry Andric 
19730b57cec5SDimitry Andric     if (MOReg == Reg) {
19740b57cec5SDimitry Andric       MO.setIsDead();
19750b57cec5SDimitry Andric       Found = true;
19760b57cec5SDimitry Andric     } else if (hasAliases && MO.isDead() &&
19778bcb0991SDimitry Andric                Register::isPhysicalRegister(MOReg)) {
19780b57cec5SDimitry Andric       // There exists a super-register that's marked dead.
19790b57cec5SDimitry Andric       if (RegInfo->isSuperRegister(Reg, MOReg))
19800b57cec5SDimitry Andric         return true;
19810b57cec5SDimitry Andric       if (RegInfo->isSubRegister(Reg, MOReg))
19820b57cec5SDimitry Andric         DeadOps.push_back(i);
19830b57cec5SDimitry Andric     }
19840b57cec5SDimitry Andric   }
19850b57cec5SDimitry Andric 
19860b57cec5SDimitry Andric   // Trim unneeded dead operands.
19870b57cec5SDimitry Andric   while (!DeadOps.empty()) {
19880b57cec5SDimitry Andric     unsigned OpIdx = DeadOps.back();
19890b57cec5SDimitry Andric     if (getOperand(OpIdx).isImplicit() &&
19900b57cec5SDimitry Andric         (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0))
19910b57cec5SDimitry Andric       RemoveOperand(OpIdx);
19920b57cec5SDimitry Andric     else
19930b57cec5SDimitry Andric       getOperand(OpIdx).setIsDead(false);
19940b57cec5SDimitry Andric     DeadOps.pop_back();
19950b57cec5SDimitry Andric   }
19960b57cec5SDimitry Andric 
19970b57cec5SDimitry Andric   // If not found, this means an alias of one of the operands is dead. Add a
19980b57cec5SDimitry Andric   // new implicit operand if required.
19990b57cec5SDimitry Andric   if (Found || !AddIfNotFound)
20000b57cec5SDimitry Andric     return Found;
20010b57cec5SDimitry Andric 
20020b57cec5SDimitry Andric   addOperand(MachineOperand::CreateReg(Reg,
20030b57cec5SDimitry Andric                                        true  /*IsDef*/,
20040b57cec5SDimitry Andric                                        true  /*IsImp*/,
20050b57cec5SDimitry Andric                                        false /*IsKill*/,
20060b57cec5SDimitry Andric                                        true  /*IsDead*/));
20070b57cec5SDimitry Andric   return true;
20080b57cec5SDimitry Andric }
20090b57cec5SDimitry Andric 
clearRegisterDeads(Register Reg)20108bcb0991SDimitry Andric void MachineInstr::clearRegisterDeads(Register Reg) {
20110b57cec5SDimitry Andric   for (MachineOperand &MO : operands()) {
20120b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg)
20130b57cec5SDimitry Andric       continue;
20140b57cec5SDimitry Andric     MO.setIsDead(false);
20150b57cec5SDimitry Andric   }
20160b57cec5SDimitry Andric }
20170b57cec5SDimitry Andric 
setRegisterDefReadUndef(Register Reg,bool IsUndef)20188bcb0991SDimitry Andric void MachineInstr::setRegisterDefReadUndef(Register Reg, bool IsUndef) {
20190b57cec5SDimitry Andric   for (MachineOperand &MO : operands()) {
20200b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0)
20210b57cec5SDimitry Andric       continue;
20220b57cec5SDimitry Andric     MO.setIsUndef(IsUndef);
20230b57cec5SDimitry Andric   }
20240b57cec5SDimitry Andric }
20250b57cec5SDimitry Andric 
addRegisterDefined(Register Reg,const TargetRegisterInfo * RegInfo)20268bcb0991SDimitry Andric void MachineInstr::addRegisterDefined(Register Reg,
20270b57cec5SDimitry Andric                                       const TargetRegisterInfo *RegInfo) {
20288bcb0991SDimitry Andric   if (Register::isPhysicalRegister(Reg)) {
20290b57cec5SDimitry Andric     MachineOperand *MO = findRegisterDefOperand(Reg, false, false, RegInfo);
20300b57cec5SDimitry Andric     if (MO)
20310b57cec5SDimitry Andric       return;
20320b57cec5SDimitry Andric   } else {
20330b57cec5SDimitry Andric     for (const MachineOperand &MO : operands()) {
20340b57cec5SDimitry Andric       if (MO.isReg() && MO.getReg() == Reg && MO.isDef() &&
20350b57cec5SDimitry Andric           MO.getSubReg() == 0)
20360b57cec5SDimitry Andric         return;
20370b57cec5SDimitry Andric     }
20380b57cec5SDimitry Andric   }
20390b57cec5SDimitry Andric   addOperand(MachineOperand::CreateReg(Reg,
20400b57cec5SDimitry Andric                                        true  /*IsDef*/,
20410b57cec5SDimitry Andric                                        true  /*IsImp*/));
20420b57cec5SDimitry Andric }
20430b57cec5SDimitry Andric 
setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs,const TargetRegisterInfo & TRI)20448bcb0991SDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs,
20450b57cec5SDimitry Andric                                          const TargetRegisterInfo &TRI) {
20460b57cec5SDimitry Andric   bool HasRegMask = false;
20470b57cec5SDimitry Andric   for (MachineOperand &MO : operands()) {
20480b57cec5SDimitry Andric     if (MO.isRegMask()) {
20490b57cec5SDimitry Andric       HasRegMask = true;
20500b57cec5SDimitry Andric       continue;
20510b57cec5SDimitry Andric     }
20520b57cec5SDimitry Andric     if (!MO.isReg() || !MO.isDef()) continue;
20538bcb0991SDimitry Andric     Register Reg = MO.getReg();
20548bcb0991SDimitry Andric     if (!Reg.isPhysical())
20558bcb0991SDimitry Andric       continue;
20560b57cec5SDimitry Andric     // If there are no uses, including partial uses, the def is dead.
20570b57cec5SDimitry Andric     if (llvm::none_of(UsedRegs,
20588bcb0991SDimitry Andric                       [&](MCRegister Use) { return TRI.regsOverlap(Use, Reg); }))
20590b57cec5SDimitry Andric       MO.setIsDead();
20600b57cec5SDimitry Andric   }
20610b57cec5SDimitry Andric 
20620b57cec5SDimitry Andric   // This is a call with a register mask operand.
20630b57cec5SDimitry Andric   // Mask clobbers are always dead, so add defs for the non-dead defines.
20640b57cec5SDimitry Andric   if (HasRegMask)
2065*5f7ddb14SDimitry Andric     for (const Register &UsedReg : UsedRegs)
2066*5f7ddb14SDimitry Andric       addRegisterDefined(UsedReg, &TRI);
20670b57cec5SDimitry Andric }
20680b57cec5SDimitry Andric 
20690b57cec5SDimitry Andric unsigned
getHashValue(const MachineInstr * const & MI)20700b57cec5SDimitry Andric MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) {
20710b57cec5SDimitry Andric   // Build up a buffer of hash code components.
2072480093f4SDimitry Andric   SmallVector<size_t, 16> HashComponents;
20730b57cec5SDimitry Andric   HashComponents.reserve(MI->getNumOperands() + 1);
20740b57cec5SDimitry Andric   HashComponents.push_back(MI->getOpcode());
20750b57cec5SDimitry Andric   for (const MachineOperand &MO : MI->operands()) {
20768bcb0991SDimitry Andric     if (MO.isReg() && MO.isDef() && Register::isVirtualRegister(MO.getReg()))
20770b57cec5SDimitry Andric       continue;  // Skip virtual register defs.
20780b57cec5SDimitry Andric 
20790b57cec5SDimitry Andric     HashComponents.push_back(hash_value(MO));
20800b57cec5SDimitry Andric   }
20810b57cec5SDimitry Andric   return hash_combine_range(HashComponents.begin(), HashComponents.end());
20820b57cec5SDimitry Andric }
20830b57cec5SDimitry Andric 
emitError(StringRef Msg) const20840b57cec5SDimitry Andric void MachineInstr::emitError(StringRef Msg) const {
20850b57cec5SDimitry Andric   // Find the source location cookie.
2086*5f7ddb14SDimitry Andric   uint64_t LocCookie = 0;
20870b57cec5SDimitry Andric   const MDNode *LocMD = nullptr;
20880b57cec5SDimitry Andric   for (unsigned i = getNumOperands(); i != 0; --i) {
20890b57cec5SDimitry Andric     if (getOperand(i-1).isMetadata() &&
20900b57cec5SDimitry Andric         (LocMD = getOperand(i-1).getMetadata()) &&
20910b57cec5SDimitry Andric         LocMD->getNumOperands() != 0) {
20920b57cec5SDimitry Andric       if (const ConstantInt *CI =
20930b57cec5SDimitry Andric               mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) {
20940b57cec5SDimitry Andric         LocCookie = CI->getZExtValue();
20950b57cec5SDimitry Andric         break;
20960b57cec5SDimitry Andric       }
20970b57cec5SDimitry Andric     }
20980b57cec5SDimitry Andric   }
20990b57cec5SDimitry Andric 
21000b57cec5SDimitry Andric   if (const MachineBasicBlock *MBB = getParent())
21010b57cec5SDimitry Andric     if (const MachineFunction *MF = MBB->getParent())
21020b57cec5SDimitry Andric       return MF->getMMI().getModule()->getContext().emitError(LocCookie, Msg);
21030b57cec5SDimitry Andric   report_fatal_error(Msg);
21040b57cec5SDimitry Andric }
21050b57cec5SDimitry Andric 
BuildMI(MachineFunction & MF,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,Register Reg,const MDNode * Variable,const MDNode * Expr)21060b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
21070b57cec5SDimitry Andric                                   const MCInstrDesc &MCID, bool IsIndirect,
21088bcb0991SDimitry Andric                                   Register Reg, const MDNode *Variable,
21090b57cec5SDimitry Andric                                   const MDNode *Expr) {
21100b57cec5SDimitry Andric   assert(isa<DILocalVariable>(Variable) && "not a variable");
21110b57cec5SDimitry Andric   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
21120b57cec5SDimitry Andric   assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
21130b57cec5SDimitry Andric          "Expected inlined-at fields to agree");
21140b57cec5SDimitry Andric   auto MIB = BuildMI(MF, DL, MCID).addReg(Reg, RegState::Debug);
21150b57cec5SDimitry Andric   if (IsIndirect)
21160b57cec5SDimitry Andric     MIB.addImm(0U);
21170b57cec5SDimitry Andric   else
21180b57cec5SDimitry Andric     MIB.addReg(0U, RegState::Debug);
21190b57cec5SDimitry Andric   return MIB.addMetadata(Variable).addMetadata(Expr);
21200b57cec5SDimitry Andric }
21210b57cec5SDimitry Andric 
BuildMI(MachineFunction & MF,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,const MachineOperand & MO,const MDNode * Variable,const MDNode * Expr)21220b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
21230b57cec5SDimitry Andric                                   const MCInstrDesc &MCID, bool IsIndirect,
2124*5f7ddb14SDimitry Andric                                   const MachineOperand &MO,
2125*5f7ddb14SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
21260b57cec5SDimitry Andric   assert(isa<DILocalVariable>(Variable) && "not a variable");
21270b57cec5SDimitry Andric   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
21280b57cec5SDimitry Andric   assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
21290b57cec5SDimitry Andric          "Expected inlined-at fields to agree");
21300b57cec5SDimitry Andric   if (MO.isReg())
21310b57cec5SDimitry Andric     return BuildMI(MF, DL, MCID, IsIndirect, MO.getReg(), Variable, Expr);
21320b57cec5SDimitry Andric 
21330b57cec5SDimitry Andric   auto MIB = BuildMI(MF, DL, MCID).add(MO);
21340b57cec5SDimitry Andric   if (IsIndirect)
21350b57cec5SDimitry Andric     MIB.addImm(0U);
21360b57cec5SDimitry Andric   else
21370b57cec5SDimitry Andric     MIB.addReg(0U, RegState::Debug);
21380b57cec5SDimitry Andric   return MIB.addMetadata(Variable).addMetadata(Expr);
21390b57cec5SDimitry Andric }
21400b57cec5SDimitry Andric 
BuildMI(MachineFunction & MF,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,ArrayRef<MachineOperand> MOs,const MDNode * Variable,const MDNode * Expr)2141*5f7ddb14SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
2142*5f7ddb14SDimitry Andric                                   const MCInstrDesc &MCID, bool IsIndirect,
2143*5f7ddb14SDimitry Andric                                   ArrayRef<MachineOperand> MOs,
2144*5f7ddb14SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
2145*5f7ddb14SDimitry Andric   assert(isa<DILocalVariable>(Variable) && "not a variable");
2146*5f7ddb14SDimitry Andric   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
2147*5f7ddb14SDimitry Andric   assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
2148*5f7ddb14SDimitry Andric          "Expected inlined-at fields to agree");
2149*5f7ddb14SDimitry Andric   if (MCID.Opcode == TargetOpcode::DBG_VALUE)
2150*5f7ddb14SDimitry Andric     return BuildMI(MF, DL, MCID, IsIndirect, MOs[0], Variable, Expr);
2151*5f7ddb14SDimitry Andric 
2152*5f7ddb14SDimitry Andric   auto MIB = BuildMI(MF, DL, MCID);
2153*5f7ddb14SDimitry Andric   MIB.addMetadata(Variable).addMetadata(Expr);
2154*5f7ddb14SDimitry Andric   for (const MachineOperand &MO : MOs)
2155*5f7ddb14SDimitry Andric     if (MO.isReg())
2156*5f7ddb14SDimitry Andric       MIB.addReg(MO.getReg(), RegState::Debug);
2157*5f7ddb14SDimitry Andric     else
2158*5f7ddb14SDimitry Andric       MIB.add(MO);
2159*5f7ddb14SDimitry Andric   return MIB;
2160*5f7ddb14SDimitry Andric }
2161*5f7ddb14SDimitry Andric 
BuildMI(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,Register Reg,const MDNode * Variable,const MDNode * Expr)21620b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
21630b57cec5SDimitry Andric                                   MachineBasicBlock::iterator I,
21640b57cec5SDimitry Andric                                   const DebugLoc &DL, const MCInstrDesc &MCID,
21658bcb0991SDimitry Andric                                   bool IsIndirect, Register Reg,
21660b57cec5SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
21670b57cec5SDimitry Andric   MachineFunction &MF = *BB.getParent();
21680b57cec5SDimitry Andric   MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Variable, Expr);
21690b57cec5SDimitry Andric   BB.insert(I, MI);
21700b57cec5SDimitry Andric   return MachineInstrBuilder(MF, MI);
21710b57cec5SDimitry Andric }
21720b57cec5SDimitry Andric 
BuildMI(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,MachineOperand & MO,const MDNode * Variable,const MDNode * Expr)21730b57cec5SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
21740b57cec5SDimitry Andric                                   MachineBasicBlock::iterator I,
21750b57cec5SDimitry Andric                                   const DebugLoc &DL, const MCInstrDesc &MCID,
21760b57cec5SDimitry Andric                                   bool IsIndirect, MachineOperand &MO,
21770b57cec5SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
21780b57cec5SDimitry Andric   MachineFunction &MF = *BB.getParent();
21790b57cec5SDimitry Andric   MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, MO, Variable, Expr);
21800b57cec5SDimitry Andric   BB.insert(I, MI);
21810b57cec5SDimitry Andric   return MachineInstrBuilder(MF, *MI);
21820b57cec5SDimitry Andric }
21830b57cec5SDimitry Andric 
BuildMI(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,ArrayRef<MachineOperand> MOs,const MDNode * Variable,const MDNode * Expr)2184*5f7ddb14SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
2185*5f7ddb14SDimitry Andric                                   MachineBasicBlock::iterator I,
2186*5f7ddb14SDimitry Andric                                   const DebugLoc &DL, const MCInstrDesc &MCID,
2187*5f7ddb14SDimitry Andric                                   bool IsIndirect, ArrayRef<MachineOperand> MOs,
2188*5f7ddb14SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
2189*5f7ddb14SDimitry Andric   MachineFunction &MF = *BB.getParent();
2190*5f7ddb14SDimitry Andric   MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, MOs, Variable, Expr);
2191*5f7ddb14SDimitry Andric   BB.insert(I, MI);
2192*5f7ddb14SDimitry Andric   return MachineInstrBuilder(MF, *MI);
2193*5f7ddb14SDimitry Andric }
2194*5f7ddb14SDimitry Andric 
21950b57cec5SDimitry Andric /// Compute the new DIExpression to use with a DBG_VALUE for a spill slot.
21960b57cec5SDimitry Andric /// This prepends DW_OP_deref when spilling an indirect DBG_VALUE.
2197*5f7ddb14SDimitry Andric static const DIExpression *
computeExprForSpill(const MachineInstr & MI,SmallVectorImpl<const MachineOperand * > & SpilledOperands)2198*5f7ddb14SDimitry Andric computeExprForSpill(const MachineInstr &MI,
2199*5f7ddb14SDimitry Andric                     SmallVectorImpl<const MachineOperand *> &SpilledOperands) {
22000b57cec5SDimitry Andric   assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
22010b57cec5SDimitry Andric          "Expected inlined-at fields to agree");
22020b57cec5SDimitry Andric 
22030b57cec5SDimitry Andric   const DIExpression *Expr = MI.getDebugExpression();
22040b57cec5SDimitry Andric   if (MI.isIndirectDebugValue()) {
22055ffd83dbSDimitry Andric     assert(MI.getDebugOffset().getImm() == 0 &&
22065ffd83dbSDimitry Andric            "DBG_VALUE with nonzero offset");
22070b57cec5SDimitry Andric     Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore);
2208*5f7ddb14SDimitry Andric   } else if (MI.isDebugValueList()) {
2209*5f7ddb14SDimitry Andric     // We will replace the spilled register with a frame index, so
2210*5f7ddb14SDimitry Andric     // immediately deref all references to the spilled register.
2211*5f7ddb14SDimitry Andric     std::array<uint64_t, 1> Ops{{dwarf::DW_OP_deref}};
2212*5f7ddb14SDimitry Andric     for (const MachineOperand *Op : SpilledOperands) {
2213*5f7ddb14SDimitry Andric       unsigned OpIdx = MI.getDebugOperandIndex(Op);
2214*5f7ddb14SDimitry Andric       Expr = DIExpression::appendOpsToArg(Expr, Ops, OpIdx);
2215*5f7ddb14SDimitry Andric     }
22160b57cec5SDimitry Andric   }
22170b57cec5SDimitry Andric   return Expr;
22180b57cec5SDimitry Andric }
computeExprForSpill(const MachineInstr & MI,Register SpillReg)2219*5f7ddb14SDimitry Andric static const DIExpression *computeExprForSpill(const MachineInstr &MI,
2220*5f7ddb14SDimitry Andric                                                Register SpillReg) {
2221*5f7ddb14SDimitry Andric   assert(MI.hasDebugOperandForReg(SpillReg) && "Spill Reg is not used in MI.");
2222*5f7ddb14SDimitry Andric   SmallVector<const MachineOperand *> SpillOperands;
2223*5f7ddb14SDimitry Andric   for (const MachineOperand &Op : MI.getDebugOperandsForReg(SpillReg))
2224*5f7ddb14SDimitry Andric     SpillOperands.push_back(&Op);
2225*5f7ddb14SDimitry Andric   return computeExprForSpill(MI, SpillOperands);
2226*5f7ddb14SDimitry Andric }
22270b57cec5SDimitry Andric 
buildDbgValueForSpill(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const MachineInstr & Orig,int FrameIndex,Register SpillReg)22280b57cec5SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB,
22290b57cec5SDimitry Andric                                           MachineBasicBlock::iterator I,
22300b57cec5SDimitry Andric                                           const MachineInstr &Orig,
2231*5f7ddb14SDimitry Andric                                           int FrameIndex, Register SpillReg) {
2232*5f7ddb14SDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig, SpillReg);
2233*5f7ddb14SDimitry Andric   MachineInstrBuilder NewMI =
2234*5f7ddb14SDimitry Andric       BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc());
2235*5f7ddb14SDimitry Andric   // Non-Variadic Operands: Location, Offset, Variable, Expression
2236*5f7ddb14SDimitry Andric   // Variadic Operands:     Variable, Expression, Locations...
2237*5f7ddb14SDimitry Andric   if (Orig.isNonListDebugValue())
2238*5f7ddb14SDimitry Andric     NewMI.addFrameIndex(FrameIndex).addImm(0U);
2239*5f7ddb14SDimitry Andric   NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr);
2240*5f7ddb14SDimitry Andric   if (Orig.isDebugValueList()) {
2241*5f7ddb14SDimitry Andric     for (const MachineOperand &Op : Orig.debug_operands())
2242*5f7ddb14SDimitry Andric       if (Op.isReg() && Op.getReg() == SpillReg)
2243*5f7ddb14SDimitry Andric         NewMI.addFrameIndex(FrameIndex);
2244*5f7ddb14SDimitry Andric       else
2245*5f7ddb14SDimitry Andric         NewMI.add(MachineOperand(Op));
2246*5f7ddb14SDimitry Andric   }
2247*5f7ddb14SDimitry Andric   return NewMI;
2248*5f7ddb14SDimitry Andric }
buildDbgValueForSpill(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const MachineInstr & Orig,int FrameIndex,SmallVectorImpl<const MachineOperand * > & SpilledOperands)2249*5f7ddb14SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(
2250*5f7ddb14SDimitry Andric     MachineBasicBlock &BB, MachineBasicBlock::iterator I,
2251*5f7ddb14SDimitry Andric     const MachineInstr &Orig, int FrameIndex,
2252*5f7ddb14SDimitry Andric     SmallVectorImpl<const MachineOperand *> &SpilledOperands) {
2253*5f7ddb14SDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig, SpilledOperands);
2254*5f7ddb14SDimitry Andric   MachineInstrBuilder NewMI =
2255*5f7ddb14SDimitry Andric       BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc());
2256*5f7ddb14SDimitry Andric   // Non-Variadic Operands: Location, Offset, Variable, Expression
2257*5f7ddb14SDimitry Andric   // Variadic Operands:     Variable, Expression, Locations...
2258*5f7ddb14SDimitry Andric   if (Orig.isNonListDebugValue())
2259*5f7ddb14SDimitry Andric     NewMI.addFrameIndex(FrameIndex).addImm(0U);
2260*5f7ddb14SDimitry Andric   NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr);
2261*5f7ddb14SDimitry Andric   if (Orig.isDebugValueList()) {
2262*5f7ddb14SDimitry Andric     for (const MachineOperand &Op : Orig.debug_operands())
2263*5f7ddb14SDimitry Andric       if (is_contained(SpilledOperands, &Op))
2264*5f7ddb14SDimitry Andric         NewMI.addFrameIndex(FrameIndex);
2265*5f7ddb14SDimitry Andric       else
2266*5f7ddb14SDimitry Andric         NewMI.add(MachineOperand(Op));
2267*5f7ddb14SDimitry Andric   }
2268*5f7ddb14SDimitry Andric   return NewMI;
22690b57cec5SDimitry Andric }
22700b57cec5SDimitry Andric 
updateDbgValueForSpill(MachineInstr & Orig,int FrameIndex,Register Reg)2271*5f7ddb14SDimitry Andric void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex,
2272*5f7ddb14SDimitry Andric                                   Register Reg) {
2273*5f7ddb14SDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig, Reg);
2274*5f7ddb14SDimitry Andric   if (Orig.isNonListDebugValue())
22755ffd83dbSDimitry Andric     Orig.getDebugOffset().ChangeToImmediate(0U);
2276*5f7ddb14SDimitry Andric   for (MachineOperand &Op : Orig.getDebugOperandsForReg(Reg))
2277*5f7ddb14SDimitry Andric     Op.ChangeToFrameIndex(FrameIndex);
22785ffd83dbSDimitry Andric   Orig.getDebugExpressionOp().setMetadata(Expr);
22790b57cec5SDimitry Andric }
22800b57cec5SDimitry Andric 
collectDebugValues(SmallVectorImpl<MachineInstr * > & DbgValues)22810b57cec5SDimitry Andric void MachineInstr::collectDebugValues(
22820b57cec5SDimitry Andric                                 SmallVectorImpl<MachineInstr *> &DbgValues) {
22830b57cec5SDimitry Andric   MachineInstr &MI = *this;
22840b57cec5SDimitry Andric   if (!MI.getOperand(0).isReg())
22850b57cec5SDimitry Andric     return;
22860b57cec5SDimitry Andric 
22870b57cec5SDimitry Andric   MachineBasicBlock::iterator DI = MI; ++DI;
22880b57cec5SDimitry Andric   for (MachineBasicBlock::iterator DE = MI.getParent()->end();
22890b57cec5SDimitry Andric        DI != DE; ++DI) {
22900b57cec5SDimitry Andric     if (!DI->isDebugValue())
22910b57cec5SDimitry Andric       return;
2292*5f7ddb14SDimitry Andric     if (DI->hasDebugOperandForReg(MI.getOperand(0).getReg()))
22930b57cec5SDimitry Andric       DbgValues.push_back(&*DI);
22940b57cec5SDimitry Andric   }
22950b57cec5SDimitry Andric }
22960b57cec5SDimitry Andric 
changeDebugValuesDefReg(Register Reg)22978bcb0991SDimitry Andric void MachineInstr::changeDebugValuesDefReg(Register Reg) {
22980b57cec5SDimitry Andric   // Collect matching debug values.
22990b57cec5SDimitry Andric   SmallVector<MachineInstr *, 2> DbgValues;
23008bcb0991SDimitry Andric 
23018bcb0991SDimitry Andric   if (!getOperand(0).isReg())
23028bcb0991SDimitry Andric     return;
23038bcb0991SDimitry Andric 
23045ffd83dbSDimitry Andric   Register DefReg = getOperand(0).getReg();
23058bcb0991SDimitry Andric   auto *MRI = getRegInfo();
23068bcb0991SDimitry Andric   for (auto &MO : MRI->use_operands(DefReg)) {
23078bcb0991SDimitry Andric     auto *DI = MO.getParent();
23088bcb0991SDimitry Andric     if (!DI->isDebugValue())
23098bcb0991SDimitry Andric       continue;
2310*5f7ddb14SDimitry Andric     if (DI->hasDebugOperandForReg(DefReg)) {
23118bcb0991SDimitry Andric       DbgValues.push_back(DI);
23128bcb0991SDimitry Andric     }
23138bcb0991SDimitry Andric   }
23140b57cec5SDimitry Andric 
23150b57cec5SDimitry Andric   // Propagate Reg to debug value instructions.
23160b57cec5SDimitry Andric   for (auto *DBI : DbgValues)
2317*5f7ddb14SDimitry Andric     for (MachineOperand &Op : DBI->getDebugOperandsForReg(DefReg))
2318*5f7ddb14SDimitry Andric       Op.setReg(Reg);
23190b57cec5SDimitry Andric }
23200b57cec5SDimitry Andric 
23210b57cec5SDimitry Andric using MMOList = SmallVector<const MachineMemOperand *, 2>;
23220b57cec5SDimitry Andric 
getSpillSlotSize(const MMOList & Accesses,const MachineFrameInfo & MFI)23235ffd83dbSDimitry Andric static unsigned getSpillSlotSize(const MMOList &Accesses,
23240b57cec5SDimitry Andric                                  const MachineFrameInfo &MFI) {
23250b57cec5SDimitry Andric   unsigned Size = 0;
23260b57cec5SDimitry Andric   for (auto A : Accesses)
23270b57cec5SDimitry Andric     if (MFI.isSpillSlotObjectIndex(
23280b57cec5SDimitry Andric             cast<FixedStackPseudoSourceValue>(A->getPseudoValue())
23290b57cec5SDimitry Andric                 ->getFrameIndex()))
23300b57cec5SDimitry Andric       Size += A->getSize();
23310b57cec5SDimitry Andric   return Size;
23320b57cec5SDimitry Andric }
23330b57cec5SDimitry Andric 
23340b57cec5SDimitry Andric Optional<unsigned>
getSpillSize(const TargetInstrInfo * TII) const23350b57cec5SDimitry Andric MachineInstr::getSpillSize(const TargetInstrInfo *TII) const {
23360b57cec5SDimitry Andric   int FI;
23370b57cec5SDimitry Andric   if (TII->isStoreToStackSlotPostFE(*this, FI)) {
23380b57cec5SDimitry Andric     const MachineFrameInfo &MFI = getMF()->getFrameInfo();
23390b57cec5SDimitry Andric     if (MFI.isSpillSlotObjectIndex(FI))
23400b57cec5SDimitry Andric       return (*memoperands_begin())->getSize();
23410b57cec5SDimitry Andric   }
23420b57cec5SDimitry Andric   return None;
23430b57cec5SDimitry Andric }
23440b57cec5SDimitry Andric 
23450b57cec5SDimitry Andric Optional<unsigned>
getFoldedSpillSize(const TargetInstrInfo * TII) const23460b57cec5SDimitry Andric MachineInstr::getFoldedSpillSize(const TargetInstrInfo *TII) const {
23470b57cec5SDimitry Andric   MMOList Accesses;
23480b57cec5SDimitry Andric   if (TII->hasStoreToStackSlot(*this, Accesses))
23490b57cec5SDimitry Andric     return getSpillSlotSize(Accesses, getMF()->getFrameInfo());
23500b57cec5SDimitry Andric   return None;
23510b57cec5SDimitry Andric }
23520b57cec5SDimitry Andric 
23530b57cec5SDimitry Andric Optional<unsigned>
getRestoreSize(const TargetInstrInfo * TII) const23540b57cec5SDimitry Andric MachineInstr::getRestoreSize(const TargetInstrInfo *TII) const {
23550b57cec5SDimitry Andric   int FI;
23560b57cec5SDimitry Andric   if (TII->isLoadFromStackSlotPostFE(*this, FI)) {
23570b57cec5SDimitry Andric     const MachineFrameInfo &MFI = getMF()->getFrameInfo();
23580b57cec5SDimitry Andric     if (MFI.isSpillSlotObjectIndex(FI))
23590b57cec5SDimitry Andric       return (*memoperands_begin())->getSize();
23600b57cec5SDimitry Andric   }
23610b57cec5SDimitry Andric   return None;
23620b57cec5SDimitry Andric }
23630b57cec5SDimitry Andric 
23640b57cec5SDimitry Andric Optional<unsigned>
getFoldedRestoreSize(const TargetInstrInfo * TII) const23650b57cec5SDimitry Andric MachineInstr::getFoldedRestoreSize(const TargetInstrInfo *TII) const {
23660b57cec5SDimitry Andric   MMOList Accesses;
23670b57cec5SDimitry Andric   if (TII->hasLoadFromStackSlot(*this, Accesses))
23680b57cec5SDimitry Andric     return getSpillSlotSize(Accesses, getMF()->getFrameInfo());
23690b57cec5SDimitry Andric   return None;
23700b57cec5SDimitry Andric }
2371af732203SDimitry Andric 
getDebugInstrNum()2372af732203SDimitry Andric unsigned MachineInstr::getDebugInstrNum() {
2373af732203SDimitry Andric   if (DebugInstrNum == 0)
2374af732203SDimitry Andric     DebugInstrNum = getParent()->getParent()->getNewDebugInstrNum();
2375af732203SDimitry Andric   return DebugInstrNum;
2376af732203SDimitry Andric }
2377*5f7ddb14SDimitry Andric 
getDebugInstrNum(MachineFunction & MF)2378*5f7ddb14SDimitry Andric unsigned MachineInstr::getDebugInstrNum(MachineFunction &MF) {
2379*5f7ddb14SDimitry Andric   if (DebugInstrNum == 0)
2380*5f7ddb14SDimitry Andric     DebugInstrNum = MF.getNewDebugInstrNum();
2381*5f7ddb14SDimitry Andric   return DebugInstrNum;
2382*5f7ddb14SDimitry Andric }
2383