xref: /src/contrib/llvm-project/llvm/lib/CodeGen/MachineInstr.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1f382538dSDimitry Andric //===- lib/CodeGen/MachineInstr.cpp ---------------------------------------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // Methods common to all machine instructions.
10009b1c42SEd Schouten //
11009b1c42SEd Schouten //===----------------------------------------------------------------------===//
12009b1c42SEd Schouten 
137ab83427SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
14f382538dSDimitry Andric #include "llvm/ADT/ArrayRef.h"
154a16efa3SDimitry Andric #include "llvm/ADT/Hashing.h"
167ab83427SDimitry Andric #include "llvm/ADT/STLExtras.h"
17044eb2f6SDimitry Andric #include "llvm/ADT/SmallBitVector.h"
18f382538dSDimitry Andric #include "llvm/ADT/SmallVector.h"
194a16efa3SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h"
20f382538dSDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
21f382538dSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
22e6d15924SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
23009b1c42SEd Schouten #include "llvm/CodeGen/MachineFunction.h"
2401095a5dSDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
25f382538dSDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h"
2659850d08SRoman Divacky #include "llvm/CodeGen/MachineMemOperand.h"
27411bd29eSDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
28f382538dSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
29009b1c42SEd Schouten #include "llvm/CodeGen/MachineRegisterInfo.h"
30009b1c42SEd Schouten #include "llvm/CodeGen/PseudoSourceValue.h"
317fa27ce4SDimitry Andric #include "llvm/CodeGen/Register.h"
32b60736ecSDimitry Andric #include "llvm/CodeGen/StackMaps.h"
33044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
34044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
35044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
36ac9a064cSDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h"
374a16efa3SDimitry Andric #include "llvm/IR/Constants.h"
38f382538dSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
39f382538dSDimitry Andric #include "llvm/IR/DebugLoc.h"
404a16efa3SDimitry Andric #include "llvm/IR/Function.h"
414a16efa3SDimitry Andric #include "llvm/IR/InlineAsm.h"
42ac9a064cSDimitry Andric #include "llvm/IR/Instructions.h"
434a16efa3SDimitry Andric #include "llvm/IR/LLVMContext.h"
444a16efa3SDimitry Andric #include "llvm/IR/Metadata.h"
454a16efa3SDimitry Andric #include "llvm/IR/Module.h"
461a82d4c0SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
47e6d15924SDimitry Andric #include "llvm/IR/Operator.h"
48411bd29eSDimitry Andric #include "llvm/MC/MCInstrDesc.h"
49f382538dSDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
50f382538dSDimitry Andric #include "llvm/Support/Casting.h"
51f382538dSDimitry Andric #include "llvm/Support/Compiler.h"
52829000e0SRoman Divacky #include "llvm/Support/Debug.h"
5359850d08SRoman Divacky #include "llvm/Support/ErrorHandling.h"
54cfca06d7SDimitry Andric #include "llvm/Support/FormattedStream.h"
55009b1c42SEd Schouten #include "llvm/Support/raw_ostream.h"
564a16efa3SDimitry Andric #include "llvm/Target/TargetMachine.h"
57f382538dSDimitry Andric #include <algorithm>
58f382538dSDimitry Andric #include <cassert>
59f382538dSDimitry Andric #include <cstdint>
60f382538dSDimitry Andric #include <cstring>
61f382538dSDimitry Andric #include <utility>
62f382538dSDimitry Andric 
63009b1c42SEd Schouten using namespace llvm;
64009b1c42SEd Schouten 
getMFIfAvailable(const MachineInstr & MI)65eb11fae6SDimitry Andric static const MachineFunction *getMFIfAvailable(const MachineInstr &MI) {
66eb11fae6SDimitry Andric   if (const MachineBasicBlock *MBB = MI.getParent())
67eb11fae6SDimitry Andric     if (const MachineFunction *MF = MBB->getParent())
68eb11fae6SDimitry Andric       return MF;
69eb11fae6SDimitry Andric   return nullptr;
70eb11fae6SDimitry Andric }
71eb11fae6SDimitry Andric 
72eb11fae6SDimitry Andric // Try to crawl up to the machine function and get TRI and IntrinsicInfo from
73eb11fae6SDimitry Andric // it.
tryToGetTargetInfo(const MachineInstr & MI,const TargetRegisterInfo * & TRI,const MachineRegisterInfo * & MRI,const TargetIntrinsicInfo * & IntrinsicInfo,const TargetInstrInfo * & TII)74eb11fae6SDimitry Andric static void tryToGetTargetInfo(const MachineInstr &MI,
75eb11fae6SDimitry Andric                                const TargetRegisterInfo *&TRI,
76eb11fae6SDimitry Andric                                const MachineRegisterInfo *&MRI,
77eb11fae6SDimitry Andric                                const TargetIntrinsicInfo *&IntrinsicInfo,
78eb11fae6SDimitry Andric                                const TargetInstrInfo *&TII) {
79eb11fae6SDimitry Andric 
80eb11fae6SDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(MI)) {
81eb11fae6SDimitry Andric     TRI = MF->getSubtarget().getRegisterInfo();
82eb11fae6SDimitry Andric     MRI = &MF->getRegInfo();
83eb11fae6SDimitry Andric     IntrinsicInfo = MF->getTarget().getIntrinsicInfo();
84eb11fae6SDimitry Andric     TII = MF->getSubtarget().getInstrInfo();
85eb11fae6SDimitry Andric   }
86eb11fae6SDimitry Andric }
87eb11fae6SDimitry Andric 
addImplicitDefUseOperands(MachineFunction & MF)884a16efa3SDimitry Andric void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) {
89e3b55780SDimitry Andric   for (MCPhysReg ImpDef : MCID->implicit_defs())
90e3b55780SDimitry Andric     addOperand(MF, MachineOperand::CreateReg(ImpDef, true, true));
91e3b55780SDimitry Andric   for (MCPhysReg ImpUse : MCID->implicit_uses())
92e3b55780SDimitry Andric     addOperand(MF, MachineOperand::CreateReg(ImpUse, false, true));
93009b1c42SEd Schouten }
94009b1c42SEd Schouten 
95d7f7719eSRoman Divacky /// MachineInstr ctor - This constructor creates a MachineInstr and adds the
96d7f7719eSRoman Divacky /// implicit operands. It reserves space for the number of operands specified by
97411bd29eSDimitry Andric /// the MCInstrDesc.
MachineInstr(MachineFunction & MF,const MCInstrDesc & TID,DebugLoc DL,bool NoImp)9877fc4c14SDimitry Andric MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &TID,
9977fc4c14SDimitry Andric                            DebugLoc DL, bool NoImp)
1007fa27ce4SDimitry Andric     : MCID(&TID), NumOperands(0), Flags(0), AsmPrinterFlags(0),
101ac9a064cSDimitry Andric       DbgLoc(std::move(DL)), DebugInstrNum(0), Opcode(TID.Opcode) {
10277fc4c14SDimitry Andric   assert(DbgLoc.hasTrivialDestructor() && "Expected trivial destructor");
10367c32a98SDimitry Andric 
1044a16efa3SDimitry Andric   // Reserve space for the expected number of operands.
105e3b55780SDimitry Andric   if (unsigned NumOps = MCID->getNumOperands() + MCID->implicit_defs().size() +
106e3b55780SDimitry Andric                         MCID->implicit_uses().size()) {
1074a16efa3SDimitry Andric     CapOperands = OperandCapacity::get(NumOps);
1084a16efa3SDimitry Andric     Operands = MF.allocateOperandArray(CapOperands);
109009b1c42SEd Schouten   }
110009b1c42SEd Schouten 
1114a16efa3SDimitry Andric   if (!NoImp)
1124a16efa3SDimitry Andric     addImplicitDefUseOperands(MF);
113009b1c42SEd Schouten }
114009b1c42SEd Schouten 
115b60736ecSDimitry Andric /// MachineInstr ctor - Copies MachineInstr arg exactly.
116b60736ecSDimitry Andric /// Does not copy the number from debug instruction numbering, to preserve
117b60736ecSDimitry Andric /// uniqueness.
MachineInstr(MachineFunction & MF,const MachineInstr & MI)118009b1c42SEd Schouten MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
1197fa27ce4SDimitry Andric     : MCID(&MI.getDesc()), NumOperands(0), Flags(0), AsmPrinterFlags(0),
120ac9a064cSDimitry Andric       Info(MI.Info), DbgLoc(MI.getDebugLoc()), DebugInstrNum(0),
121ac9a064cSDimitry Andric       Opcode(MI.getOpcode()) {
12277fc4c14SDimitry Andric   assert(DbgLoc.hasTrivialDestructor() && "Expected trivial destructor");
12367c32a98SDimitry Andric 
1244a16efa3SDimitry Andric   CapOperands = OperandCapacity::get(MI.getNumOperands());
1254a16efa3SDimitry Andric   Operands = MF.allocateOperandArray(CapOperands);
126009b1c42SEd Schouten 
1274a16efa3SDimitry Andric   // Copy operands.
1285a5ac124SDimitry Andric   for (const MachineOperand &MO : MI.operands())
1295a5ac124SDimitry Andric     addOperand(MF, MO);
130009b1c42SEd Schouten 
131e3b55780SDimitry Andric   // Replicate ties between the operands, which addOperand was not
132e3b55780SDimitry Andric   // able to do reliably.
133e3b55780SDimitry Andric   for (unsigned i = 0, e = getNumOperands(); i < e; ++i) {
134e3b55780SDimitry Andric     MachineOperand &NewMO = getOperand(i);
135e3b55780SDimitry Andric     const MachineOperand &OrigMO = MI.getOperand(i);
136e3b55780SDimitry Andric     NewMO.TiedTo = OrigMO.TiedTo;
137e3b55780SDimitry Andric   }
138e3b55780SDimitry Andric 
1394a16efa3SDimitry Andric   // Copy all the sensible flags.
1404a16efa3SDimitry Andric   setFlags(MI.Flags);
141009b1c42SEd Schouten }
142009b1c42SEd Schouten 
setDesc(const MCInstrDesc & TID)143b1c73532SDimitry Andric void MachineInstr::setDesc(const MCInstrDesc &TID) {
144b1c73532SDimitry Andric   if (getParent())
145b1c73532SDimitry Andric     getMF()->handleChangeDesc(*this, TID);
146b1c73532SDimitry Andric   MCID = &TID;
147ac9a064cSDimitry Andric   Opcode = TID.Opcode;
148b1c73532SDimitry Andric }
149b1c73532SDimitry Andric 
moveBefore(MachineInstr * MovePos)150b60736ecSDimitry Andric void MachineInstr::moveBefore(MachineInstr *MovePos) {
151b60736ecSDimitry Andric   MovePos->getParent()->splice(MovePos, getParent(), getIterator());
152b60736ecSDimitry Andric }
153b60736ecSDimitry Andric 
154009b1c42SEd Schouten /// getRegInfo - If this instruction is embedded into a MachineFunction,
155009b1c42SEd Schouten /// return the MachineRegisterInfo object for the current function, otherwise
156009b1c42SEd Schouten /// return null.
getRegInfo()157009b1c42SEd Schouten MachineRegisterInfo *MachineInstr::getRegInfo() {
158009b1c42SEd Schouten   if (MachineBasicBlock *MBB = getParent())
159009b1c42SEd Schouten     return &MBB->getParent()->getRegInfo();
1605ca98fd9SDimitry Andric   return nullptr;
161009b1c42SEd Schouten }
162009b1c42SEd Schouten 
getRegInfo() const1637fa27ce4SDimitry Andric const MachineRegisterInfo *MachineInstr::getRegInfo() const {
1647fa27ce4SDimitry Andric   if (const MachineBasicBlock *MBB = getParent())
1657fa27ce4SDimitry Andric     return &MBB->getParent()->getRegInfo();
1667fa27ce4SDimitry Andric   return nullptr;
1677fa27ce4SDimitry Andric }
1687fa27ce4SDimitry Andric 
removeRegOperandsFromUseLists(MachineRegisterInfo & MRI)169145449b1SDimitry Andric void MachineInstr::removeRegOperandsFromUseLists(MachineRegisterInfo &MRI) {
1705a5ac124SDimitry Andric   for (MachineOperand &MO : operands())
1715a5ac124SDimitry Andric     if (MO.isReg())
1725a5ac124SDimitry Andric       MRI.removeRegOperandFromUseList(&MO);
173009b1c42SEd Schouten }
174009b1c42SEd Schouten 
addRegOperandsToUseLists(MachineRegisterInfo & MRI)175145449b1SDimitry Andric void MachineInstr::addRegOperandsToUseLists(MachineRegisterInfo &MRI) {
1765a5ac124SDimitry Andric   for (MachineOperand &MO : operands())
1775a5ac124SDimitry Andric     if (MO.isReg())
1785a5ac124SDimitry Andric       MRI.addRegOperandToUseList(&MO);
179009b1c42SEd Schouten }
180009b1c42SEd Schouten 
addOperand(const MachineOperand & Op)1814a16efa3SDimitry Andric void MachineInstr::addOperand(const MachineOperand &Op) {
1824a16efa3SDimitry Andric   MachineBasicBlock *MBB = getParent();
1834a16efa3SDimitry Andric   assert(MBB && "Use MachineInstrBuilder to add operands to dangling instrs");
1844a16efa3SDimitry Andric   MachineFunction *MF = MBB->getParent();
1854a16efa3SDimitry Andric   assert(MF && "Use MachineInstrBuilder to add operands to dangling instrs");
1864a16efa3SDimitry Andric   addOperand(*MF, Op);
1874a16efa3SDimitry Andric }
1884a16efa3SDimitry Andric 
1894a16efa3SDimitry Andric /// Move NumOps MachineOperands from Src to Dst, with support for overlapping
1904a16efa3SDimitry Andric /// ranges. If MRI is non-null also update use-def chains.
moveOperands(MachineOperand * Dst,MachineOperand * Src,unsigned NumOps,MachineRegisterInfo * MRI)1914a16efa3SDimitry Andric static void moveOperands(MachineOperand *Dst, MachineOperand *Src,
1924a16efa3SDimitry Andric                          unsigned NumOps, MachineRegisterInfo *MRI) {
1934a16efa3SDimitry Andric   if (MRI)
1944a16efa3SDimitry Andric     return MRI->moveOperands(Dst, Src, NumOps);
1955a5ac124SDimitry Andric   // MachineOperand is a trivially copyable type so we can just use memmove.
196706b4fc4SDimitry Andric   assert(Dst && Src && "Unknown operands");
1975a5ac124SDimitry Andric   std::memmove(Dst, Src, NumOps * sizeof(MachineOperand));
1984a16efa3SDimitry Andric }
1994a16efa3SDimitry Andric 
200009b1c42SEd Schouten /// addOperand - Add the specified operand to the instruction.  If it is an
201009b1c42SEd Schouten /// implicit operand, it is added to the end of the operand list.  If it is
202009b1c42SEd Schouten /// an explicit operand it is added at the end of the explicit operand list
203009b1c42SEd Schouten /// (before the first implicit operand).
addOperand(MachineFunction & MF,const MachineOperand & Op)2044a16efa3SDimitry Andric void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) {
2057fa27ce4SDimitry Andric   assert(isUInt<LLVM_MI_NUMOPERANDS_BITS>(NumOperands + 1) &&
2067fa27ce4SDimitry Andric          "Cannot add more operands.");
20730815c53SDimitry Andric   assert(MCID && "Cannot add operands before providing an instr descriptor");
208009b1c42SEd Schouten 
2094a16efa3SDimitry Andric   // Check if we're adding one of our existing operands.
2104a16efa3SDimitry Andric   if (&Op >= Operands && &Op < Operands + NumOperands) {
2114a16efa3SDimitry Andric     // This is unusual: MI->addOperand(MI->getOperand(i)).
2124a16efa3SDimitry Andric     // If adding Op requires reallocating or moving existing operands around,
2134a16efa3SDimitry Andric     // the Op reference could go stale. Support it by copying Op.
2144a16efa3SDimitry Andric     MachineOperand CopyOp(Op);
2154a16efa3SDimitry Andric     return addOperand(MF, CopyOp);
2164a16efa3SDimitry Andric   }
217009b1c42SEd Schouten 
21830815c53SDimitry Andric   // Find the insert location for the new operand.  Implicit registers go at
2194a16efa3SDimitry Andric   // the end, everything else goes before the implicit regs.
2204a16efa3SDimitry Andric   //
22130815c53SDimitry Andric   // FIXME: Allow mixed explicit and implicit operands on inline asm.
22230815c53SDimitry Andric   // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as
22330815c53SDimitry Andric   // implicit-defs, but they must not be moved around.  See the FIXME in
22430815c53SDimitry Andric   // InstrEmitter.cpp.
2254a16efa3SDimitry Andric   unsigned OpNo = getNumOperands();
2264a16efa3SDimitry Andric   bool isImpReg = Op.isReg() && Op.isImplicit();
22730815c53SDimitry Andric   if (!isImpReg && !isInlineAsm()) {
22830815c53SDimitry Andric     while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) {
22930815c53SDimitry Andric       --OpNo;
230522600a2SDimitry Andric       assert(!Operands[OpNo].isTied() && "Cannot move tied operands");
231009b1c42SEd Schouten     }
232009b1c42SEd Schouten   }
233009b1c42SEd Schouten 
23430815c53SDimitry Andric   // OpNo now points as the desired insertion point.  Unless this is a variadic
23530815c53SDimitry Andric   // instruction, only implicit regs are allowed beyond MCID->getNumOperands().
23658b69754SDimitry Andric   // RegMask operands go between the explicit and implicit operands.
2374a16efa3SDimitry Andric   MachineRegisterInfo *MRI = getRegInfo();
238009b1c42SEd Schouten 
2394a16efa3SDimitry Andric   // Determine if the Operands array needs to be reallocated.
2404a16efa3SDimitry Andric   // Save the old capacity and operand array.
2414a16efa3SDimitry Andric   OperandCapacity OldCap = CapOperands;
2424a16efa3SDimitry Andric   MachineOperand *OldOperands = Operands;
2434a16efa3SDimitry Andric   if (!OldOperands || OldCap.getSize() == getNumOperands()) {
2444a16efa3SDimitry Andric     CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1);
2454a16efa3SDimitry Andric     Operands = MF.allocateOperandArray(CapOperands);
2464a16efa3SDimitry Andric     // Move the operands before the insertion point.
2474a16efa3SDimitry Andric     if (OpNo)
2484a16efa3SDimitry Andric       moveOperands(Operands, OldOperands, OpNo, MRI);
2494a16efa3SDimitry Andric   }
250009b1c42SEd Schouten 
2514a16efa3SDimitry Andric   // Move the operands following the insertion point.
2524a16efa3SDimitry Andric   if (OpNo != NumOperands)
2534a16efa3SDimitry Andric     moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo,
2544a16efa3SDimitry Andric                  MRI);
2554a16efa3SDimitry Andric   ++NumOperands;
25630815c53SDimitry Andric 
2574a16efa3SDimitry Andric   // Deallocate the old operand array.
2584a16efa3SDimitry Andric   if (OldOperands != Operands && OldOperands)
2594a16efa3SDimitry Andric     MF.deallocateOperandArray(OldCap, OldOperands);
2604a16efa3SDimitry Andric 
2614a16efa3SDimitry Andric   // Copy Op into place. It still needs to be inserted into the MRI use lists.
2624a16efa3SDimitry Andric   MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op);
2634a16efa3SDimitry Andric   NewMO->ParentMI = this;
2644a16efa3SDimitry Andric 
2654a16efa3SDimitry Andric   // When adding a register operand, tell MRI about it.
2664a16efa3SDimitry Andric   if (NewMO->isReg()) {
26758b69754SDimitry Andric     // Ensure isOnRegUseList() returns false, regardless of Op's status.
2685ca98fd9SDimitry Andric     NewMO->Contents.Reg.Prev = nullptr;
269522600a2SDimitry Andric     // Ignore existing ties. This is not a property that can be copied.
2704a16efa3SDimitry Andric     NewMO->TiedTo = 0;
2714a16efa3SDimitry Andric     // Add the new operand to MRI, but only for instructions in an MBB.
2724a16efa3SDimitry Andric     if (MRI)
2734a16efa3SDimitry Andric       MRI->addRegOperandToUseList(NewMO);
274522600a2SDimitry Andric     // The MCID operand information isn't accurate until we start adding
275522600a2SDimitry Andric     // explicit operands. The implicit operands are added first, then the
276522600a2SDimitry Andric     // explicits are inserted before them.
277522600a2SDimitry Andric     if (!isImpReg) {
278522600a2SDimitry Andric       // Tie uses to defs as indicated in MCInstrDesc.
2794a16efa3SDimitry Andric       if (NewMO->isUse()) {
280522600a2SDimitry Andric         int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO);
281522600a2SDimitry Andric         if (DefIdx != -1)
282522600a2SDimitry Andric           tieOperands(DefIdx, OpNo);
283522600a2SDimitry Andric       }
28430815c53SDimitry Andric       // If the register operand is flagged as early, mark the operand as such.
285411bd29eSDimitry Andric       if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1)
2864a16efa3SDimitry Andric         NewMO->setIsEarlyClobber(true);
287009b1c42SEd Schouten     }
288c0981da4SDimitry Andric     // Ensure debug instructions set debug flag on register uses.
289c0981da4SDimitry Andric     if (NewMO->isUse() && isDebugInstr())
290c0981da4SDimitry Andric       NewMO->setIsDebug();
291009b1c42SEd Schouten   }
292009b1c42SEd Schouten }
293009b1c42SEd Schouten 
removeOperand(unsigned OpNo)294145449b1SDimitry Andric void MachineInstr::removeOperand(unsigned OpNo) {
2954a16efa3SDimitry Andric   assert(OpNo < getNumOperands() && "Invalid operand number");
296522600a2SDimitry Andric   untieRegOperand(OpNo);
297009b1c42SEd Schouten 
298522600a2SDimitry Andric #ifndef NDEBUG
299522600a2SDimitry Andric   // Moving tied operands would break the ties.
3004a16efa3SDimitry Andric   for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i)
301522600a2SDimitry Andric     if (Operands[i].isReg())
302522600a2SDimitry Andric       assert(!Operands[i].isTied() && "Cannot move tied operands");
303522600a2SDimitry Andric #endif
304522600a2SDimitry Andric 
3054a16efa3SDimitry Andric   MachineRegisterInfo *MRI = getRegInfo();
3064a16efa3SDimitry Andric   if (MRI && Operands[OpNo].isReg())
3074a16efa3SDimitry Andric     MRI->removeRegOperandFromUseList(Operands + OpNo);
308009b1c42SEd Schouten 
3094a16efa3SDimitry Andric   // Don't call the MachineOperand destructor. A lot of this code depends on
3104a16efa3SDimitry Andric   // MachineOperand having a trivial destructor anyway, and adding a call here
3114a16efa3SDimitry Andric   // wouldn't make it 'destructor-correct'.
3124a16efa3SDimitry Andric 
3134a16efa3SDimitry Andric   if (unsigned N = NumOperands - 1 - OpNo)
3144a16efa3SDimitry Andric     moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI);
3154a16efa3SDimitry Andric   --NumOperands;
316009b1c42SEd Schouten }
317009b1c42SEd Schouten 
setExtraInfo(MachineFunction & MF,ArrayRef<MachineMemOperand * > MMOs,MCSymbol * PreInstrSymbol,MCSymbol * PostInstrSymbol,MDNode * HeapAllocMarker,MDNode * PCSections,uint32_t CFIType,MDNode * MMRAs)318706b4fc4SDimitry Andric void MachineInstr::setExtraInfo(MachineFunction &MF,
319706b4fc4SDimitry Andric                                 ArrayRef<MachineMemOperand *> MMOs,
320706b4fc4SDimitry Andric                                 MCSymbol *PreInstrSymbol,
321706b4fc4SDimitry Andric                                 MCSymbol *PostInstrSymbol,
322e3b55780SDimitry Andric                                 MDNode *HeapAllocMarker, MDNode *PCSections,
323ac9a064cSDimitry Andric                                 uint32_t CFIType, MDNode *MMRAs) {
324706b4fc4SDimitry Andric   bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
325706b4fc4SDimitry Andric   bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
326706b4fc4SDimitry Andric   bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
327e3b55780SDimitry Andric   bool HasPCSections = PCSections != nullptr;
328e3b55780SDimitry Andric   bool HasCFIType = CFIType != 0;
329ac9a064cSDimitry Andric   bool HasMMRAs = MMRAs != nullptr;
330e3b55780SDimitry Andric   int NumPointers = MMOs.size() + HasPreInstrSymbol + HasPostInstrSymbol +
331ac9a064cSDimitry Andric                     HasHeapAllocMarker + HasPCSections + HasCFIType + HasMMRAs;
332706b4fc4SDimitry Andric 
333706b4fc4SDimitry Andric   // Drop all extra info if there is none.
334706b4fc4SDimitry Andric   if (NumPointers <= 0) {
335706b4fc4SDimitry Andric     Info.clear();
336706b4fc4SDimitry Andric     return;
337706b4fc4SDimitry Andric   }
338706b4fc4SDimitry Andric 
339706b4fc4SDimitry Andric   // If more than one pointer, then store out of line. Store heap alloc markers
340706b4fc4SDimitry Andric   // out of line because PointerSumType cannot hold more than 4 tag types with
341706b4fc4SDimitry Andric   // 32-bit pointers.
342706b4fc4SDimitry Andric   // FIXME: Maybe we should make the symbols in the extra info mutable?
343ac9a064cSDimitry Andric   else if (NumPointers > 1 || HasMMRAs || HasHeapAllocMarker || HasPCSections ||
344e3b55780SDimitry Andric            HasCFIType) {
345e3b55780SDimitry Andric     Info.set<EIIK_OutOfLine>(
346e3b55780SDimitry Andric         MF.createMIExtraInfo(MMOs, PreInstrSymbol, PostInstrSymbol,
347ac9a064cSDimitry Andric                              HeapAllocMarker, PCSections, CFIType, MMRAs));
348706b4fc4SDimitry Andric     return;
349706b4fc4SDimitry Andric   }
350706b4fc4SDimitry Andric 
351706b4fc4SDimitry Andric   // Otherwise store the single pointer inline.
352706b4fc4SDimitry Andric   if (HasPreInstrSymbol)
353706b4fc4SDimitry Andric     Info.set<EIIK_PreInstrSymbol>(PreInstrSymbol);
354706b4fc4SDimitry Andric   else if (HasPostInstrSymbol)
355706b4fc4SDimitry Andric     Info.set<EIIK_PostInstrSymbol>(PostInstrSymbol);
356706b4fc4SDimitry Andric   else
357706b4fc4SDimitry Andric     Info.set<EIIK_MMO>(MMOs[0]);
358706b4fc4SDimitry Andric }
359706b4fc4SDimitry Andric 
dropMemRefs(MachineFunction & MF)360d8e91e46SDimitry Andric void MachineInstr::dropMemRefs(MachineFunction &MF) {
361d8e91e46SDimitry Andric   if (memoperands_empty())
362d8e91e46SDimitry Andric     return;
363d8e91e46SDimitry Andric 
364706b4fc4SDimitry Andric   setExtraInfo(MF, {}, getPreInstrSymbol(), getPostInstrSymbol(),
365ac9a064cSDimitry Andric                getHeapAllocMarker(), getPCSections(), getCFIType(),
366ac9a064cSDimitry Andric                getMMRAMetadata());
367d8e91e46SDimitry Andric }
368d8e91e46SDimitry Andric 
setMemRefs(MachineFunction & MF,ArrayRef<MachineMemOperand * > MMOs)369d8e91e46SDimitry Andric void MachineInstr::setMemRefs(MachineFunction &MF,
370d8e91e46SDimitry Andric                               ArrayRef<MachineMemOperand *> MMOs) {
371d8e91e46SDimitry Andric   if (MMOs.empty()) {
372d8e91e46SDimitry Andric     dropMemRefs(MF);
373d8e91e46SDimitry Andric     return;
374d8e91e46SDimitry Andric   }
375d8e91e46SDimitry Andric 
376706b4fc4SDimitry Andric   setExtraInfo(MF, MMOs, getPreInstrSymbol(), getPostInstrSymbol(),
377ac9a064cSDimitry Andric                getHeapAllocMarker(), getPCSections(), getCFIType(),
378ac9a064cSDimitry Andric                getMMRAMetadata());
379d8e91e46SDimitry Andric }
380d8e91e46SDimitry Andric 
addMemOperand(MachineFunction & MF,MachineMemOperand * MO)381009b1c42SEd Schouten void MachineInstr::addMemOperand(MachineFunction &MF,
38259850d08SRoman Divacky                                  MachineMemOperand *MO) {
383d8e91e46SDimitry Andric   SmallVector<MachineMemOperand *, 2> MMOs;
384d8e91e46SDimitry Andric   MMOs.append(memoperands_begin(), memoperands_end());
385d8e91e46SDimitry Andric   MMOs.push_back(MO);
386d8e91e46SDimitry Andric   setMemRefs(MF, MMOs);
387d8e91e46SDimitry Andric }
388009b1c42SEd Schouten 
cloneMemRefs(MachineFunction & MF,const MachineInstr & MI)389d8e91e46SDimitry Andric void MachineInstr::cloneMemRefs(MachineFunction &MF, const MachineInstr &MI) {
390d8e91e46SDimitry Andric   if (this == &MI)
391d8e91e46SDimitry Andric     // Nothing to do for a self-clone!
392d8e91e46SDimitry Andric     return;
393009b1c42SEd Schouten 
394d8e91e46SDimitry Andric   assert(&MF == MI.getMF() &&
395d8e91e46SDimitry Andric          "Invalid machine functions when cloning memory refrences!");
396d8e91e46SDimitry Andric   // See if we can just steal the extra info already allocated for the
397d8e91e46SDimitry Andric   // instruction. We can do this whenever the pre- and post-instruction symbols
398d8e91e46SDimitry Andric   // are the same (including null).
399d8e91e46SDimitry Andric   if (getPreInstrSymbol() == MI.getPreInstrSymbol() &&
400706b4fc4SDimitry Andric       getPostInstrSymbol() == MI.getPostInstrSymbol() &&
401e3b55780SDimitry Andric       getHeapAllocMarker() == MI.getHeapAllocMarker() &&
402ac9a064cSDimitry Andric       getPCSections() == MI.getPCSections() && getMMRAMetadata() &&
403ac9a064cSDimitry Andric       MI.getMMRAMetadata()) {
404d8e91e46SDimitry Andric     Info = MI.Info;
405d8e91e46SDimitry Andric     return;
406d8e91e46SDimitry Andric   }
407d8e91e46SDimitry Andric 
408d8e91e46SDimitry Andric   // Otherwise, fall back on a copy-based clone.
409d8e91e46SDimitry Andric   setMemRefs(MF, MI.memoperands());
41063faed5bSDimitry Andric }
41163faed5bSDimitry Andric 
412050e163aSDimitry Andric /// Check to see if the MMOs pointed to by the two MemRefs arrays are
413050e163aSDimitry Andric /// identical.
hasIdenticalMMOs(ArrayRef<MachineMemOperand * > LHS,ArrayRef<MachineMemOperand * > RHS)414d8e91e46SDimitry Andric static bool hasIdenticalMMOs(ArrayRef<MachineMemOperand *> LHS,
415d8e91e46SDimitry Andric                              ArrayRef<MachineMemOperand *> RHS) {
416d8e91e46SDimitry Andric   if (LHS.size() != RHS.size())
417050e163aSDimitry Andric     return false;
418d8e91e46SDimitry Andric 
419d8e91e46SDimitry Andric   auto LHSPointees = make_pointee_range(LHS);
420d8e91e46SDimitry Andric   auto RHSPointees = make_pointee_range(RHS);
421d8e91e46SDimitry Andric   return std::equal(LHSPointees.begin(), LHSPointees.end(),
422d8e91e46SDimitry Andric                     RHSPointees.begin());
423050e163aSDimitry Andric }
424050e163aSDimitry Andric 
cloneMergedMemRefs(MachineFunction & MF,ArrayRef<const MachineInstr * > MIs)425d8e91e46SDimitry Andric void MachineInstr::cloneMergedMemRefs(MachineFunction &MF,
426d8e91e46SDimitry Andric                                       ArrayRef<const MachineInstr *> MIs) {
427d8e91e46SDimitry Andric   // Try handling easy numbers of MIs with simpler mechanisms.
428d8e91e46SDimitry Andric   if (MIs.empty()) {
429d8e91e46SDimitry Andric     dropMemRefs(MF);
430d8e91e46SDimitry Andric     return;
431d8e91e46SDimitry Andric   }
432d8e91e46SDimitry Andric   if (MIs.size() == 1) {
433d8e91e46SDimitry Andric     cloneMemRefs(MF, *MIs[0]);
434d8e91e46SDimitry Andric     return;
435d8e91e46SDimitry Andric   }
436d8e91e46SDimitry Andric   // Because an empty memoperands list provides *no* information and must be
437d8e91e46SDimitry Andric   // handled conservatively (assuming the instruction can do anything), the only
438d8e91e46SDimitry Andric   // way to merge with it is to drop all other memoperands.
439d8e91e46SDimitry Andric   if (MIs[0]->memoperands_empty()) {
440d8e91e46SDimitry Andric     dropMemRefs(MF);
441d8e91e46SDimitry Andric     return;
442d8e91e46SDimitry Andric   }
443050e163aSDimitry Andric 
444d8e91e46SDimitry Andric   // Handle the general case.
445d8e91e46SDimitry Andric   SmallVector<MachineMemOperand *, 2> MergedMMOs;
446d8e91e46SDimitry Andric   // Start with the first instruction.
447d8e91e46SDimitry Andric   assert(&MF == MIs[0]->getMF() &&
448d8e91e46SDimitry Andric          "Invalid machine functions when cloning memory references!");
449d8e91e46SDimitry Andric   MergedMMOs.append(MIs[0]->memoperands_begin(), MIs[0]->memoperands_end());
450d8e91e46SDimitry Andric   // Now walk all the other instructions and accumulate any different MMOs.
451d8e91e46SDimitry Andric   for (const MachineInstr &MI : make_pointee_range(MIs.slice(1))) {
452d8e91e46SDimitry Andric     assert(&MF == MI.getMF() &&
453d8e91e46SDimitry Andric            "Invalid machine functions when cloning memory references!");
454050e163aSDimitry Andric 
455d8e91e46SDimitry Andric     // Skip MIs with identical operands to the first. This is a somewhat
456d8e91e46SDimitry Andric     // arbitrary hack but will catch common cases without being quadratic.
457d8e91e46SDimitry Andric     // TODO: We could fully implement merge semantics here if needed.
458d8e91e46SDimitry Andric     if (hasIdenticalMMOs(MIs[0]->memoperands(), MI.memoperands()))
459d8e91e46SDimitry Andric       continue;
460050e163aSDimitry Andric 
461d8e91e46SDimitry Andric     // Because an empty memoperands list provides *no* information and must be
462d8e91e46SDimitry Andric     // handled conservatively (assuming the instruction can do anything), the
463d8e91e46SDimitry Andric     // only way to merge with it is to drop all other memoperands.
464d8e91e46SDimitry Andric     if (MI.memoperands_empty()) {
465d8e91e46SDimitry Andric       dropMemRefs(MF);
466d8e91e46SDimitry Andric       return;
467d8e91e46SDimitry Andric     }
468050e163aSDimitry Andric 
469d8e91e46SDimitry Andric     // Otherwise accumulate these into our temporary buffer of the merged state.
470d8e91e46SDimitry Andric     MergedMMOs.append(MI.memoperands_begin(), MI.memoperands_end());
471d8e91e46SDimitry Andric   }
4728a6c1c25SDimitry Andric 
473d8e91e46SDimitry Andric   setMemRefs(MF, MergedMMOs);
474d8e91e46SDimitry Andric }
4758a6c1c25SDimitry Andric 
setPreInstrSymbol(MachineFunction & MF,MCSymbol * Symbol)476d8e91e46SDimitry Andric void MachineInstr::setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
477706b4fc4SDimitry Andric   // Do nothing if old and new symbols are the same.
478706b4fc4SDimitry Andric   if (Symbol == getPreInstrSymbol())
479d8e91e46SDimitry Andric     return;
480706b4fc4SDimitry Andric 
481706b4fc4SDimitry Andric   // If there was only one symbol and we're removing it, just clear info.
482706b4fc4SDimitry Andric   if (!Symbol && Info.is<EIIK_PreInstrSymbol>()) {
483d8e91e46SDimitry Andric     Info.clear();
484d8e91e46SDimitry Andric     return;
485d8e91e46SDimitry Andric   }
486d8e91e46SDimitry Andric 
487706b4fc4SDimitry Andric   setExtraInfo(MF, memoperands(), Symbol, getPostInstrSymbol(),
488ac9a064cSDimitry Andric                getHeapAllocMarker(), getPCSections(), getCFIType(),
489ac9a064cSDimitry Andric                getMMRAMetadata());
490d8e91e46SDimitry Andric }
491d8e91e46SDimitry Andric 
setPostInstrSymbol(MachineFunction & MF,MCSymbol * Symbol)492d8e91e46SDimitry Andric void MachineInstr::setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol) {
493706b4fc4SDimitry Andric   // Do nothing if old and new symbols are the same.
494706b4fc4SDimitry Andric   if (Symbol == getPostInstrSymbol())
495d8e91e46SDimitry Andric     return;
496706b4fc4SDimitry Andric 
497706b4fc4SDimitry Andric   // If there was only one symbol and we're removing it, just clear info.
498706b4fc4SDimitry Andric   if (!Symbol && Info.is<EIIK_PostInstrSymbol>()) {
499d8e91e46SDimitry Andric     Info.clear();
500d8e91e46SDimitry Andric     return;
501d8e91e46SDimitry Andric   }
502d8e91e46SDimitry Andric 
503706b4fc4SDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), Symbol,
504ac9a064cSDimitry Andric                getHeapAllocMarker(), getPCSections(), getCFIType(),
505ac9a064cSDimitry Andric                getMMRAMetadata());
506d8e91e46SDimitry Andric }
507d8e91e46SDimitry Andric 
setHeapAllocMarker(MachineFunction & MF,MDNode * Marker)508706b4fc4SDimitry Andric void MachineInstr::setHeapAllocMarker(MachineFunction &MF, MDNode *Marker) {
509706b4fc4SDimitry Andric   // Do nothing if old and new symbols are the same.
510706b4fc4SDimitry Andric   if (Marker == getHeapAllocMarker())
511d8e91e46SDimitry Andric     return;
512d8e91e46SDimitry Andric 
513706b4fc4SDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(),
514ac9a064cSDimitry Andric                Marker, getPCSections(), getCFIType(), getMMRAMetadata());
515e3b55780SDimitry Andric }
516e3b55780SDimitry Andric 
setPCSections(MachineFunction & MF,MDNode * PCSections)517e3b55780SDimitry Andric void MachineInstr::setPCSections(MachineFunction &MF, MDNode *PCSections) {
518e3b55780SDimitry Andric   // Do nothing if old and new symbols are the same.
519e3b55780SDimitry Andric   if (PCSections == getPCSections())
520e3b55780SDimitry Andric     return;
521e3b55780SDimitry Andric 
522e3b55780SDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(),
523ac9a064cSDimitry Andric                getHeapAllocMarker(), PCSections, getCFIType(),
524ac9a064cSDimitry Andric                getMMRAMetadata());
525e3b55780SDimitry Andric }
526e3b55780SDimitry Andric 
setCFIType(MachineFunction & MF,uint32_t Type)527e3b55780SDimitry Andric void MachineInstr::setCFIType(MachineFunction &MF, uint32_t Type) {
528e3b55780SDimitry Andric   // Do nothing if old and new types are the same.
529e3b55780SDimitry Andric   if (Type == getCFIType())
530e3b55780SDimitry Andric     return;
531e3b55780SDimitry Andric 
532e3b55780SDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(),
533ac9a064cSDimitry Andric                getHeapAllocMarker(), getPCSections(), Type, getMMRAMetadata());
534ac9a064cSDimitry Andric }
535ac9a064cSDimitry Andric 
setMMRAMetadata(MachineFunction & MF,MDNode * MMRAs)536ac9a064cSDimitry Andric void MachineInstr::setMMRAMetadata(MachineFunction &MF, MDNode *MMRAs) {
537ac9a064cSDimitry Andric   // Do nothing if old and new symbols are the same.
538ac9a064cSDimitry Andric   if (MMRAs == getMMRAMetadata())
539ac9a064cSDimitry Andric     return;
540ac9a064cSDimitry Andric 
541ac9a064cSDimitry Andric   setExtraInfo(MF, memoperands(), getPreInstrSymbol(), getPostInstrSymbol(),
542ac9a064cSDimitry Andric                getHeapAllocMarker(), getPCSections(), getCFIType(), MMRAs);
5438a6c1c25SDimitry Andric }
5448a6c1c25SDimitry Andric 
cloneInstrSymbols(MachineFunction & MF,const MachineInstr & MI)545e6d15924SDimitry Andric void MachineInstr::cloneInstrSymbols(MachineFunction &MF,
546e6d15924SDimitry Andric                                      const MachineInstr &MI) {
547e6d15924SDimitry Andric   if (this == &MI)
548e6d15924SDimitry Andric     // Nothing to do for a self-clone!
549e6d15924SDimitry Andric     return;
550e6d15924SDimitry Andric 
551e6d15924SDimitry Andric   assert(&MF == MI.getMF() &&
552e6d15924SDimitry Andric          "Invalid machine functions when cloning instruction symbols!");
553e6d15924SDimitry Andric 
554e6d15924SDimitry Andric   setPreInstrSymbol(MF, MI.getPreInstrSymbol());
555e6d15924SDimitry Andric   setPostInstrSymbol(MF, MI.getPostInstrSymbol());
556706b4fc4SDimitry Andric   setHeapAllocMarker(MF, MI.getHeapAllocMarker());
557e3b55780SDimitry Andric   setPCSections(MF, MI.getPCSections());
558ac9a064cSDimitry Andric   setMMRAMetadata(MF, MI.getMMRAMetadata());
559e6d15924SDimitry Andric }
560e6d15924SDimitry Andric 
mergeFlagsWith(const MachineInstr & Other) const5617fa27ce4SDimitry Andric uint32_t MachineInstr::mergeFlagsWith(const MachineInstr &Other) const {
562eb11fae6SDimitry Andric   // For now, the just return the union of the flags. If the flags get more
563eb11fae6SDimitry Andric   // complicated over time, we might need more logic here.
564eb11fae6SDimitry Andric   return getFlags() | Other.getFlags();
565eb11fae6SDimitry Andric }
566eb11fae6SDimitry Andric 
copyFlagsFromInstruction(const Instruction & I)5677fa27ce4SDimitry Andric uint32_t MachineInstr::copyFlagsFromInstruction(const Instruction &I) {
5687fa27ce4SDimitry Andric   uint32_t MIFlags = 0;
569d8e91e46SDimitry Andric   // Copy the wrapping flags.
570d8e91e46SDimitry Andric   if (const OverflowingBinaryOperator *OB =
571d8e91e46SDimitry Andric           dyn_cast<OverflowingBinaryOperator>(&I)) {
572d8e91e46SDimitry Andric     if (OB->hasNoSignedWrap())
573e6d15924SDimitry Andric       MIFlags |= MachineInstr::MIFlag::NoSWrap;
574d8e91e46SDimitry Andric     if (OB->hasNoUnsignedWrap())
575e6d15924SDimitry Andric       MIFlags |= MachineInstr::MIFlag::NoUWrap;
576ac9a064cSDimitry Andric   } else if (const TruncInst *TI = dyn_cast<TruncInst>(&I)) {
577ac9a064cSDimitry Andric     if (TI->hasNoSignedWrap())
578ac9a064cSDimitry Andric       MIFlags |= MachineInstr::MIFlag::NoSWrap;
579ac9a064cSDimitry Andric     if (TI->hasNoUnsignedWrap())
580ac9a064cSDimitry Andric       MIFlags |= MachineInstr::MIFlag::NoUWrap;
581ac9a064cSDimitry Andric   } else if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(&I)) {
582ac9a064cSDimitry Andric     if (GEP->hasNoUnsignedSignedWrap())
583ac9a064cSDimitry Andric       MIFlags |= MachineInstr::MIFlag::NoUSWrap;
584ac9a064cSDimitry Andric     if (GEP->hasNoUnsignedWrap())
585ac9a064cSDimitry Andric       MIFlags |= MachineInstr::MIFlag::NoUWrap;
586ac9a064cSDimitry Andric   }
587ac9a064cSDimitry Andric 
588ac9a064cSDimitry Andric   // Copy the nonneg flag.
589ac9a064cSDimitry Andric   if (const PossiblyNonNegInst *PNI = dyn_cast<PossiblyNonNegInst>(&I)) {
590ac9a064cSDimitry Andric     if (PNI->hasNonNeg())
591ac9a064cSDimitry Andric       MIFlags |= MachineInstr::MIFlag::NonNeg;
592ac9a064cSDimitry Andric     // Copy the disjoint flag.
593ac9a064cSDimitry Andric   } else if (const PossiblyDisjointInst *PD =
594ac9a064cSDimitry Andric                  dyn_cast<PossiblyDisjointInst>(&I)) {
595ac9a064cSDimitry Andric     if (PD->isDisjoint())
596ac9a064cSDimitry Andric       MIFlags |= MachineInstr::MIFlag::Disjoint;
597d8e91e46SDimitry Andric   }
598d8e91e46SDimitry Andric 
599d8e91e46SDimitry Andric   // Copy the exact flag.
600d8e91e46SDimitry Andric   if (const PossiblyExactOperator *PE = dyn_cast<PossiblyExactOperator>(&I))
601d8e91e46SDimitry Andric     if (PE->isExact())
602e6d15924SDimitry Andric       MIFlags |= MachineInstr::MIFlag::IsExact;
603d8e91e46SDimitry Andric 
604d8e91e46SDimitry Andric   // Copy the fast-math flags.
605d8e91e46SDimitry Andric   if (const FPMathOperator *FP = dyn_cast<FPMathOperator>(&I)) {
606d8e91e46SDimitry Andric     const FastMathFlags Flags = FP->getFastMathFlags();
607d8e91e46SDimitry Andric     if (Flags.noNaNs())
608e6d15924SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmNoNans;
609d8e91e46SDimitry Andric     if (Flags.noInfs())
610e6d15924SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmNoInfs;
611d8e91e46SDimitry Andric     if (Flags.noSignedZeros())
612e6d15924SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmNsz;
613d8e91e46SDimitry Andric     if (Flags.allowReciprocal())
614e6d15924SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmArcp;
615d8e91e46SDimitry Andric     if (Flags.allowContract())
616e6d15924SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmContract;
617d8e91e46SDimitry Andric     if (Flags.approxFunc())
618e6d15924SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmAfn;
619d8e91e46SDimitry Andric     if (Flags.allowReassoc())
620e6d15924SDimitry Andric       MIFlags |= MachineInstr::MIFlag::FmReassoc;
621d8e91e46SDimitry Andric   }
622e6d15924SDimitry Andric 
6237fa27ce4SDimitry Andric   if (I.getMetadata(LLVMContext::MD_unpredictable))
6247fa27ce4SDimitry Andric     MIFlags |= MachineInstr::MIFlag::Unpredictable;
6257fa27ce4SDimitry Andric 
626e6d15924SDimitry Andric   return MIFlags;
627e6d15924SDimitry Andric }
628e6d15924SDimitry Andric 
copyIRFlags(const Instruction & I)629e6d15924SDimitry Andric void MachineInstr::copyIRFlags(const Instruction &I) {
630e6d15924SDimitry Andric   Flags = copyFlagsFromInstruction(I);
631d8e91e46SDimitry Andric }
632d8e91e46SDimitry Andric 
hasPropertyInBundle(uint64_t Mask,QueryType Type) const633d8e91e46SDimitry Andric bool MachineInstr::hasPropertyInBundle(uint64_t Mask, QueryType Type) const {
6344a16efa3SDimitry Andric   assert(!isBundledWithPred() && "Must be called on bundle header");
635dd58ef01SDimitry Andric   for (MachineBasicBlock::const_instr_iterator MII = getIterator();; ++MII) {
63663faed5bSDimitry Andric     if (MII->getDesc().getFlags() & Mask) {
63763faed5bSDimitry Andric       if (Type == AnyInBundle)
63863faed5bSDimitry Andric         return true;
63963faed5bSDimitry Andric     } else {
6404a16efa3SDimitry Andric       if (Type == AllInBundle && !MII->isBundle())
64163faed5bSDimitry Andric         return false;
64263faed5bSDimitry Andric     }
6434a16efa3SDimitry Andric     // This was the last instruction in the bundle.
6444a16efa3SDimitry Andric     if (!MII->isBundledWithSucc())
64563faed5bSDimitry Andric       return Type == AllInBundle;
64659850d08SRoman Divacky   }
6474a16efa3SDimitry Andric }
648009b1c42SEd Schouten 
isIdenticalTo(const MachineInstr & Other,MICheckType Check) const64901095a5dSDimitry Andric bool MachineInstr::isIdenticalTo(const MachineInstr &Other,
65067a71b31SRoman Divacky                                  MICheckType Check) const {
651f5a3459aSRoman Divacky   // If opcodes or number of operands are not the same then the two
652f5a3459aSRoman Divacky   // instructions are obviously not identical.
65301095a5dSDimitry Andric   if (Other.getOpcode() != getOpcode() ||
65401095a5dSDimitry Andric       Other.getNumOperands() != getNumOperands())
65567a71b31SRoman Divacky     return false;
656f5a3459aSRoman Divacky 
65763faed5bSDimitry Andric   if (isBundle()) {
658b915e9e0SDimitry Andric     // We have passed the test above that both instructions have the same
659b915e9e0SDimitry Andric     // opcode, so we know that both instructions are bundles here. Let's compare
660b915e9e0SDimitry Andric     // MIs inside the bundle.
661b915e9e0SDimitry Andric     assert(Other.isBundle() && "Expected that both instructions are bundles.");
662dd58ef01SDimitry Andric     MachineBasicBlock::const_instr_iterator I1 = getIterator();
66301095a5dSDimitry Andric     MachineBasicBlock::const_instr_iterator I2 = Other.getIterator();
664b915e9e0SDimitry Andric     // Loop until we analysed the last intruction inside at least one of the
665b915e9e0SDimitry Andric     // bundles.
666b915e9e0SDimitry Andric     while (I1->isBundledWithSucc() && I2->isBundledWithSucc()) {
667b915e9e0SDimitry Andric       ++I1;
66863faed5bSDimitry Andric       ++I2;
669b915e9e0SDimitry Andric       if (!I1->isIdenticalTo(*I2, Check))
67063faed5bSDimitry Andric         return false;
67163faed5bSDimitry Andric     }
672b915e9e0SDimitry Andric     // If we've reached the end of just one of the two bundles, but not both,
673b915e9e0SDimitry Andric     // the instructions are not identical.
674b915e9e0SDimitry Andric     if (I1->isBundledWithSucc() || I2->isBundledWithSucc())
675b915e9e0SDimitry Andric       return false;
67663faed5bSDimitry Andric   }
67763faed5bSDimitry Andric 
678f5a3459aSRoman Divacky   // Check operands to make sure they match.
67967a71b31SRoman Divacky   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
68067a71b31SRoman Divacky     const MachineOperand &MO = getOperand(i);
68101095a5dSDimitry Andric     const MachineOperand &OMO = Other.getOperand(i);
68256fe8f14SDimitry Andric     if (!MO.isReg()) {
68356fe8f14SDimitry Andric       if (!MO.isIdenticalTo(OMO))
68456fe8f14SDimitry Andric         return false;
68556fe8f14SDimitry Andric       continue;
68656fe8f14SDimitry Andric     }
68756fe8f14SDimitry Andric 
688f5a3459aSRoman Divacky     // Clients may or may not want to ignore defs when testing for equality.
689f5a3459aSRoman Divacky     // For example, machine CSE pass only cares about finding common
690f5a3459aSRoman Divacky     // subexpressions, so it's safe to ignore virtual register defs.
69156fe8f14SDimitry Andric     if (MO.isDef()) {
69267a71b31SRoman Divacky       if (Check == IgnoreDefs)
69367a71b31SRoman Divacky         continue;
69456fe8f14SDimitry Andric       else if (Check == IgnoreVRegDefs) {
695e3b55780SDimitry Andric         if (!MO.getReg().isVirtual() || !OMO.getReg().isVirtual())
696044eb2f6SDimitry Andric           if (!MO.isIdenticalTo(OMO))
69767a71b31SRoman Divacky             return false;
69856fe8f14SDimitry Andric       } else {
69956fe8f14SDimitry Andric         if (!MO.isIdenticalTo(OMO))
70067a71b31SRoman Divacky           return false;
70156fe8f14SDimitry Andric         if (Check == CheckKillDead && MO.isDead() != OMO.isDead())
70256fe8f14SDimitry Andric           return false;
70356fe8f14SDimitry Andric       }
70456fe8f14SDimitry Andric     } else {
70556fe8f14SDimitry Andric       if (!MO.isIdenticalTo(OMO))
70656fe8f14SDimitry Andric         return false;
70756fe8f14SDimitry Andric       if (Check == CheckKillDead && MO.isKill() != OMO.isKill())
70856fe8f14SDimitry Andric         return false;
70956fe8f14SDimitry Andric     }
71067a71b31SRoman Divacky   }
711eb11fae6SDimitry Andric   // If DebugLoc does not match then two debug instructions are not identical.
712eb11fae6SDimitry Andric   if (isDebugInstr())
71301095a5dSDimitry Andric     if (getDebugLoc() && Other.getDebugLoc() &&
71401095a5dSDimitry Andric         getDebugLoc() != Other.getDebugLoc())
715411bd29eSDimitry Andric       return false;
716e3b55780SDimitry Andric   // If pre- or post-instruction symbols do not match then the two instructions
717e3b55780SDimitry Andric   // are not identical.
718e3b55780SDimitry Andric   if (getPreInstrSymbol() != Other.getPreInstrSymbol() ||
719e3b55780SDimitry Andric       getPostInstrSymbol() != Other.getPostInstrSymbol())
720e3b55780SDimitry Andric     return false;
721e3b55780SDimitry Andric   // Call instructions with different CFI types are not identical.
722e3b55780SDimitry Andric   if (isCall() && getCFIType() != Other.getCFIType())
723e3b55780SDimitry Andric     return false;
724e3b55780SDimitry Andric 
725e3b55780SDimitry Andric   return true;
726e3b55780SDimitry Andric }
727e3b55780SDimitry Andric 
isEquivalentDbgInstr(const MachineInstr & Other) const728e3b55780SDimitry Andric bool MachineInstr::isEquivalentDbgInstr(const MachineInstr &Other) const {
729e3b55780SDimitry Andric   if (!isDebugValueLike() || !Other.isDebugValueLike())
730e3b55780SDimitry Andric     return false;
731e3b55780SDimitry Andric   if (getDebugLoc() != Other.getDebugLoc())
732e3b55780SDimitry Andric     return false;
733e3b55780SDimitry Andric   if (getDebugVariable() != Other.getDebugVariable())
734e3b55780SDimitry Andric     return false;
735e3b55780SDimitry Andric   if (getNumDebugOperands() != Other.getNumDebugOperands())
736e3b55780SDimitry Andric     return false;
737e3b55780SDimitry Andric   for (unsigned OpIdx = 0; OpIdx < getNumDebugOperands(); ++OpIdx)
738e3b55780SDimitry Andric     if (!getDebugOperand(OpIdx).isIdenticalTo(Other.getDebugOperand(OpIdx)))
739e3b55780SDimitry Andric       return false;
740e3b55780SDimitry Andric   if (!DIExpression::isEqualExpression(
741e3b55780SDimitry Andric           getDebugExpression(), isIndirectDebugValue(),
742e3b55780SDimitry Andric           Other.getDebugExpression(), Other.isIndirectDebugValue()))
743e3b55780SDimitry Andric     return false;
74467a71b31SRoman Divacky   return true;
74567a71b31SRoman Divacky }
74667a71b31SRoman Divacky 
getMF() const747044eb2f6SDimitry Andric const MachineFunction *MachineInstr::getMF() const {
748044eb2f6SDimitry Andric   return getParent()->getParent();
749044eb2f6SDimitry Andric }
750044eb2f6SDimitry Andric 
removeFromParent()751009b1c42SEd Schouten MachineInstr *MachineInstr::removeFromParent() {
752009b1c42SEd Schouten   assert(getParent() && "Not embedded in a basic block!");
7534a16efa3SDimitry Andric   return getParent()->remove(this);
754009b1c42SEd Schouten }
755009b1c42SEd Schouten 
removeFromBundle()7564a16efa3SDimitry Andric MachineInstr *MachineInstr::removeFromBundle() {
7574a16efa3SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
7584a16efa3SDimitry Andric   return getParent()->remove_instr(this);
7594a16efa3SDimitry Andric }
760009b1c42SEd Schouten 
eraseFromParent()761009b1c42SEd Schouten void MachineInstr::eraseFromParent() {
762009b1c42SEd Schouten   assert(getParent() && "Not embedded in a basic block!");
7634a16efa3SDimitry Andric   getParent()->erase(this);
764009b1c42SEd Schouten }
765009b1c42SEd Schouten 
eraseFromBundle()7664a16efa3SDimitry Andric void MachineInstr::eraseFromBundle() {
7674a16efa3SDimitry Andric   assert(getParent() && "Not embedded in a basic block!");
7684a16efa3SDimitry Andric   getParent()->erase_instr(this);
7694a16efa3SDimitry Andric }
770009b1c42SEd Schouten 
isCandidateForCallSiteEntry(QueryType Type) const771cfca06d7SDimitry Andric bool MachineInstr::isCandidateForCallSiteEntry(QueryType Type) const {
772cfca06d7SDimitry Andric   if (!isCall(Type))
773cfca06d7SDimitry Andric     return false;
774cfca06d7SDimitry Andric   switch (getOpcode()) {
775cfca06d7SDimitry Andric   case TargetOpcode::PATCHPOINT:
776cfca06d7SDimitry Andric   case TargetOpcode::STACKMAP:
777cfca06d7SDimitry Andric   case TargetOpcode::STATEPOINT:
778b60736ecSDimitry Andric   case TargetOpcode::FENTRY_CALL:
779cfca06d7SDimitry Andric     return false;
780cfca06d7SDimitry Andric   }
781cfca06d7SDimitry Andric   return true;
782cfca06d7SDimitry Andric }
783cfca06d7SDimitry Andric 
shouldUpdateCallSiteInfo() const784cfca06d7SDimitry Andric bool MachineInstr::shouldUpdateCallSiteInfo() const {
785cfca06d7SDimitry Andric   if (isBundle())
786cfca06d7SDimitry Andric     return isCandidateForCallSiteEntry(MachineInstr::AnyInBundle);
787cfca06d7SDimitry Andric   return isCandidateForCallSiteEntry();
788cfca06d7SDimitry Andric }
789cfca06d7SDimitry Andric 
getNumExplicitOperands() const790009b1c42SEd Schouten unsigned MachineInstr::getNumExplicitOperands() const {
791411bd29eSDimitry Andric   unsigned NumOperands = MCID->getNumOperands();
792411bd29eSDimitry Andric   if (!MCID->isVariadic())
793009b1c42SEd Schouten     return NumOperands;
794009b1c42SEd Schouten 
795eb11fae6SDimitry Andric   for (unsigned I = NumOperands, E = getNumOperands(); I != E; ++I) {
796eb11fae6SDimitry Andric     const MachineOperand &MO = getOperand(I);
797eb11fae6SDimitry Andric     // The operands must always be in the following order:
798eb11fae6SDimitry Andric     // - explicit reg defs,
799eb11fae6SDimitry Andric     // - other explicit operands (reg uses, immediates, etc.),
800eb11fae6SDimitry Andric     // - implicit reg defs
801eb11fae6SDimitry Andric     // - implicit reg uses
802eb11fae6SDimitry Andric     if (MO.isReg() && MO.isImplicit())
803eb11fae6SDimitry Andric       break;
804eb11fae6SDimitry Andric     ++NumOperands;
805009b1c42SEd Schouten   }
806009b1c42SEd Schouten   return NumOperands;
807009b1c42SEd Schouten }
808009b1c42SEd Schouten 
getNumExplicitDefs() const809eb11fae6SDimitry Andric unsigned MachineInstr::getNumExplicitDefs() const {
810eb11fae6SDimitry Andric   unsigned NumDefs = MCID->getNumDefs();
811eb11fae6SDimitry Andric   if (!MCID->isVariadic())
812eb11fae6SDimitry Andric     return NumDefs;
813eb11fae6SDimitry Andric 
814eb11fae6SDimitry Andric   for (unsigned I = NumDefs, E = getNumOperands(); I != E; ++I) {
815eb11fae6SDimitry Andric     const MachineOperand &MO = getOperand(I);
816eb11fae6SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
817eb11fae6SDimitry Andric       break;
818eb11fae6SDimitry Andric     ++NumDefs;
819eb11fae6SDimitry Andric   }
820eb11fae6SDimitry Andric   return NumDefs;
821eb11fae6SDimitry Andric }
822eb11fae6SDimitry Andric 
bundleWithPred()8234a16efa3SDimitry Andric void MachineInstr::bundleWithPred() {
8244a16efa3SDimitry Andric   assert(!isBundledWithPred() && "MI is already bundled with its predecessor");
8254a16efa3SDimitry Andric   setFlag(BundledPred);
826dd58ef01SDimitry Andric   MachineBasicBlock::instr_iterator Pred = getIterator();
8274a16efa3SDimitry Andric   --Pred;
8284a16efa3SDimitry Andric   assert(!Pred->isBundledWithSucc() && "Inconsistent bundle flags");
8294a16efa3SDimitry Andric   Pred->setFlag(BundledSucc);
8304a16efa3SDimitry Andric }
8314a16efa3SDimitry Andric 
bundleWithSucc()8324a16efa3SDimitry Andric void MachineInstr::bundleWithSucc() {
8334a16efa3SDimitry Andric   assert(!isBundledWithSucc() && "MI is already bundled with its successor");
8344a16efa3SDimitry Andric   setFlag(BundledSucc);
835dd58ef01SDimitry Andric   MachineBasicBlock::instr_iterator Succ = getIterator();
8364a16efa3SDimitry Andric   ++Succ;
8374a16efa3SDimitry Andric   assert(!Succ->isBundledWithPred() && "Inconsistent bundle flags");
8384a16efa3SDimitry Andric   Succ->setFlag(BundledPred);
8394a16efa3SDimitry Andric }
8404a16efa3SDimitry Andric 
unbundleFromPred()8414a16efa3SDimitry Andric void MachineInstr::unbundleFromPred() {
8424a16efa3SDimitry Andric   assert(isBundledWithPred() && "MI isn't bundled with its predecessor");
8434a16efa3SDimitry Andric   clearFlag(BundledPred);
844dd58ef01SDimitry Andric   MachineBasicBlock::instr_iterator Pred = getIterator();
8454a16efa3SDimitry Andric   --Pred;
8464a16efa3SDimitry Andric   assert(Pred->isBundledWithSucc() && "Inconsistent bundle flags");
8474a16efa3SDimitry Andric   Pred->clearFlag(BundledSucc);
8484a16efa3SDimitry Andric }
8494a16efa3SDimitry Andric 
unbundleFromSucc()8504a16efa3SDimitry Andric void MachineInstr::unbundleFromSucc() {
8514a16efa3SDimitry Andric   assert(isBundledWithSucc() && "MI isn't bundled with its successor");
8524a16efa3SDimitry Andric   clearFlag(BundledSucc);
853dd58ef01SDimitry Andric   MachineBasicBlock::instr_iterator Succ = getIterator();
8544a16efa3SDimitry Andric   ++Succ;
8554a16efa3SDimitry Andric   assert(Succ->isBundledWithPred() && "Inconsistent bundle flags");
8564a16efa3SDimitry Andric   Succ->clearFlag(BundledPred);
85763faed5bSDimitry Andric }
85863faed5bSDimitry Andric 
isStackAligningInlineAsm() const859cf099d11SDimitry Andric bool MachineInstr::isStackAligningInlineAsm() const {
860cf099d11SDimitry Andric   if (isInlineAsm()) {
861cf099d11SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
862cf099d11SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
863cf099d11SDimitry Andric       return true;
864cf099d11SDimitry Andric   }
865cf099d11SDimitry Andric   return false;
866cf099d11SDimitry Andric }
867009b1c42SEd Schouten 
getInlineAsmDialect() const868522600a2SDimitry Andric InlineAsm::AsmDialect MachineInstr::getInlineAsmDialect() const {
869522600a2SDimitry Andric   assert(isInlineAsm() && "getInlineAsmDialect() only works for inline asms!");
870522600a2SDimitry Andric   unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
871522600a2SDimitry Andric   return InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect) != 0);
872522600a2SDimitry Andric }
873522600a2SDimitry Andric 
findInlineAsmFlagIdx(unsigned OpIdx,unsigned * GroupNo) const87430815c53SDimitry Andric int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx,
87530815c53SDimitry Andric                                        unsigned *GroupNo) const {
87630815c53SDimitry Andric   assert(isInlineAsm() && "Expected an inline asm instruction");
87730815c53SDimitry Andric   assert(OpIdx < getNumOperands() && "OpIdx out of range");
87830815c53SDimitry Andric 
87930815c53SDimitry Andric   // Ignore queries about the initial operands.
88030815c53SDimitry Andric   if (OpIdx < InlineAsm::MIOp_FirstOperand)
88130815c53SDimitry Andric     return -1;
88230815c53SDimitry Andric 
88330815c53SDimitry Andric   unsigned Group = 0;
88430815c53SDimitry Andric   unsigned NumOps;
88530815c53SDimitry Andric   for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e;
88630815c53SDimitry Andric        i += NumOps) {
88730815c53SDimitry Andric     const MachineOperand &FlagMO = getOperand(i);
88830815c53SDimitry Andric     // If we reach the implicit register operands, stop looking.
88930815c53SDimitry Andric     if (!FlagMO.isImm())
89030815c53SDimitry Andric       return -1;
891b1c73532SDimitry Andric     const InlineAsm::Flag F(FlagMO.getImm());
892b1c73532SDimitry Andric     NumOps = 1 + F.getNumOperandRegisters();
89330815c53SDimitry Andric     if (i + NumOps > OpIdx) {
89430815c53SDimitry Andric       if (GroupNo)
89530815c53SDimitry Andric         *GroupNo = Group;
89630815c53SDimitry Andric       return i;
89730815c53SDimitry Andric     }
89830815c53SDimitry Andric     ++Group;
89930815c53SDimitry Andric   }
90030815c53SDimitry Andric   return -1;
90130815c53SDimitry Andric }
90230815c53SDimitry Andric 
getDebugLabel() const903eb11fae6SDimitry Andric const DILabel *MachineInstr::getDebugLabel() const {
904eb11fae6SDimitry Andric   assert(isDebugLabel() && "not a DBG_LABEL");
905eb11fae6SDimitry Andric   return cast<DILabel>(getOperand(0).getMetadata());
906eb11fae6SDimitry Andric }
907eb11fae6SDimitry Andric 
getDebugVariableOp() const908cfca06d7SDimitry Andric const MachineOperand &MachineInstr::getDebugVariableOp() const {
909e3b55780SDimitry Andric   assert((isDebugValueLike()) && "not a DBG_VALUE*");
910e3b55780SDimitry Andric   unsigned VariableOp = isNonListDebugValue() ? 2 : 0;
911344a3780SDimitry Andric   return getOperand(VariableOp);
912cfca06d7SDimitry Andric }
913cfca06d7SDimitry Andric 
getDebugVariableOp()914cfca06d7SDimitry Andric MachineOperand &MachineInstr::getDebugVariableOp() {
915e3b55780SDimitry Andric   assert((isDebugValueLike()) && "not a DBG_VALUE*");
916e3b55780SDimitry Andric   unsigned VariableOp = isNonListDebugValue() ? 2 : 0;
917344a3780SDimitry Andric   return getOperand(VariableOp);
918cfca06d7SDimitry Andric }
919cfca06d7SDimitry Andric 
getDebugVariable() const92001095a5dSDimitry Andric const DILocalVariable *MachineInstr::getDebugVariable() const {
921344a3780SDimitry Andric   return cast<DILocalVariable>(getDebugVariableOp().getMetadata());
922344a3780SDimitry Andric }
923344a3780SDimitry Andric 
getDebugExpressionOp() const924344a3780SDimitry Andric const MachineOperand &MachineInstr::getDebugExpressionOp() const {
925e3b55780SDimitry Andric   assert((isDebugValueLike()) && "not a DBG_VALUE*");
926e3b55780SDimitry Andric   unsigned ExpressionOp = isNonListDebugValue() ? 3 : 1;
927344a3780SDimitry Andric   return getOperand(ExpressionOp);
92801095a5dSDimitry Andric }
92901095a5dSDimitry Andric 
getDebugExpressionOp()930cfca06d7SDimitry Andric MachineOperand &MachineInstr::getDebugExpressionOp() {
931e3b55780SDimitry Andric   assert((isDebugValueLike()) && "not a DBG_VALUE*");
932e3b55780SDimitry Andric   unsigned ExpressionOp = isNonListDebugValue() ? 3 : 1;
933344a3780SDimitry Andric   return getOperand(ExpressionOp);
934cfca06d7SDimitry Andric }
935cfca06d7SDimitry Andric 
getDebugExpression() const93601095a5dSDimitry Andric const DIExpression *MachineInstr::getDebugExpression() const {
937344a3780SDimitry Andric   return cast<DIExpression>(getDebugExpressionOp().getMetadata());
93801095a5dSDimitry Andric }
93901095a5dSDimitry Andric 
isDebugEntryValue() const9401d5ae102SDimitry Andric bool MachineInstr::isDebugEntryValue() const {
9411d5ae102SDimitry Andric   return isDebugValue() && getDebugExpression()->isEntryValue();
9421d5ae102SDimitry Andric }
9431d5ae102SDimitry Andric 
94430815c53SDimitry Andric const TargetRegisterClass*
getRegClassConstraint(unsigned OpIdx,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const94530815c53SDimitry Andric MachineInstr::getRegClassConstraint(unsigned OpIdx,
94630815c53SDimitry Andric                                     const TargetInstrInfo *TII,
94730815c53SDimitry Andric                                     const TargetRegisterInfo *TRI) const {
94858b69754SDimitry Andric   assert(getParent() && "Can't have an MBB reference here!");
949044eb2f6SDimitry Andric   assert(getMF() && "Can't have an MF reference here!");
950044eb2f6SDimitry Andric   const MachineFunction &MF = *getMF();
95158b69754SDimitry Andric 
95230815c53SDimitry Andric   // Most opcodes have fixed constraints in their MCInstrDesc.
95330815c53SDimitry Andric   if (!isInlineAsm())
95458b69754SDimitry Andric     return TII->getRegClass(getDesc(), OpIdx, TRI, MF);
95530815c53SDimitry Andric 
95630815c53SDimitry Andric   if (!getOperand(OpIdx).isReg())
9575ca98fd9SDimitry Andric     return nullptr;
95830815c53SDimitry Andric 
95930815c53SDimitry Andric   // For tied uses on inline asm, get the constraint from the def.
96030815c53SDimitry Andric   unsigned DefIdx;
96130815c53SDimitry Andric   if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx))
96230815c53SDimitry Andric     OpIdx = DefIdx;
96330815c53SDimitry Andric 
96430815c53SDimitry Andric   // Inline asm stores register class constraints in the flag word.
96530815c53SDimitry Andric   int FlagIdx = findInlineAsmFlagIdx(OpIdx);
96630815c53SDimitry Andric   if (FlagIdx < 0)
9675ca98fd9SDimitry Andric     return nullptr;
96830815c53SDimitry Andric 
969b1c73532SDimitry Andric   const InlineAsm::Flag F(getOperand(FlagIdx).getImm());
97030815c53SDimitry Andric   unsigned RCID;
971b1c73532SDimitry Andric   if ((F.isRegUseKind() || F.isRegDefKind() || F.isRegDefEarlyClobberKind()) &&
972b1c73532SDimitry Andric       F.hasRegClassConstraint(RCID))
97330815c53SDimitry Andric     return TRI->getRegClass(RCID);
97430815c53SDimitry Andric 
97530815c53SDimitry Andric   // Assume that all registers in a memory operand are pointers.
976b1c73532SDimitry Andric   if (F.isMemKind())
97758b69754SDimitry Andric     return TRI->getPointerRegClass(MF);
97830815c53SDimitry Andric 
9795ca98fd9SDimitry Andric   return nullptr;
9805ca98fd9SDimitry Andric }
9815ca98fd9SDimitry Andric 
getRegClassConstraintEffectForVReg(Register Reg,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI,bool ExploreBundle) const9825ca98fd9SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVReg(
9831d5ae102SDimitry Andric     Register Reg, const TargetRegisterClass *CurRC, const TargetInstrInfo *TII,
9845ca98fd9SDimitry Andric     const TargetRegisterInfo *TRI, bool ExploreBundle) const {
9855ca98fd9SDimitry Andric   // Check every operands inside the bundle if we have
9865ca98fd9SDimitry Andric   // been asked to.
9875ca98fd9SDimitry Andric   if (ExploreBundle)
98801095a5dSDimitry Andric     for (ConstMIBundleOperands OpndIt(*this); OpndIt.isValid() && CurRC;
9895ca98fd9SDimitry Andric          ++OpndIt)
9905ca98fd9SDimitry Andric       CurRC = OpndIt->getParent()->getRegClassConstraintEffectForVRegImpl(
9915ca98fd9SDimitry Andric           OpndIt.getOperandNo(), Reg, CurRC, TII, TRI);
9925ca98fd9SDimitry Andric   else
9935ca98fd9SDimitry Andric     // Otherwise, just check the current operands.
99485d8b2bbSDimitry Andric     for (unsigned i = 0, e = NumOperands; i < e && CurRC; ++i)
99585d8b2bbSDimitry Andric       CurRC = getRegClassConstraintEffectForVRegImpl(i, Reg, CurRC, TII, TRI);
9965ca98fd9SDimitry Andric   return CurRC;
9975ca98fd9SDimitry Andric }
9985ca98fd9SDimitry Andric 
getRegClassConstraintEffectForVRegImpl(unsigned OpIdx,Register Reg,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const9995ca98fd9SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffectForVRegImpl(
10001d5ae102SDimitry Andric     unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
10015ca98fd9SDimitry Andric     const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
10025ca98fd9SDimitry Andric   assert(CurRC && "Invalid initial register class");
10035ca98fd9SDimitry Andric   // Check if Reg is constrained by some of its use/def from MI.
10045ca98fd9SDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
10055ca98fd9SDimitry Andric   if (!MO.isReg() || MO.getReg() != Reg)
10065ca98fd9SDimitry Andric     return CurRC;
10075ca98fd9SDimitry Andric   // If yes, accumulate the constraints through the operand.
10085ca98fd9SDimitry Andric   return getRegClassConstraintEffect(OpIdx, CurRC, TII, TRI);
10095ca98fd9SDimitry Andric }
10105ca98fd9SDimitry Andric 
getRegClassConstraintEffect(unsigned OpIdx,const TargetRegisterClass * CurRC,const TargetInstrInfo * TII,const TargetRegisterInfo * TRI) const10115ca98fd9SDimitry Andric const TargetRegisterClass *MachineInstr::getRegClassConstraintEffect(
10125ca98fd9SDimitry Andric     unsigned OpIdx, const TargetRegisterClass *CurRC,
10135ca98fd9SDimitry Andric     const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const {
10145ca98fd9SDimitry Andric   const TargetRegisterClass *OpRC = getRegClassConstraint(OpIdx, TII, TRI);
10155ca98fd9SDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
10165ca98fd9SDimitry Andric   assert(MO.isReg() &&
10175ca98fd9SDimitry Andric          "Cannot get register constraints for non-register operand");
10185ca98fd9SDimitry Andric   assert(CurRC && "Invalid initial register class");
10195ca98fd9SDimitry Andric   if (unsigned SubIdx = MO.getSubReg()) {
10205ca98fd9SDimitry Andric     if (OpRC)
10215ca98fd9SDimitry Andric       CurRC = TRI->getMatchingSuperRegClass(CurRC, OpRC, SubIdx);
10225ca98fd9SDimitry Andric     else
10235ca98fd9SDimitry Andric       CurRC = TRI->getSubClassWithSubReg(CurRC, SubIdx);
10245ca98fd9SDimitry Andric   } else if (OpRC)
10255ca98fd9SDimitry Andric     CurRC = TRI->getCommonSubClass(CurRC, OpRC);
10265ca98fd9SDimitry Andric   return CurRC;
102730815c53SDimitry Andric }
102830815c53SDimitry Andric 
10294a16efa3SDimitry Andric /// Return the number of instructions inside the MI bundle, not counting the
10304a16efa3SDimitry Andric /// header instruction.
getBundleSize() const103163faed5bSDimitry Andric unsigned MachineInstr::getBundleSize() const {
1032dd58ef01SDimitry Andric   MachineBasicBlock::const_instr_iterator I = getIterator();
103363faed5bSDimitry Andric   unsigned Size = 0;
103401095a5dSDimitry Andric   while (I->isBundledWithSucc()) {
103501095a5dSDimitry Andric     ++Size;
103601095a5dSDimitry Andric     ++I;
103701095a5dSDimitry Andric   }
103863faed5bSDimitry Andric   return Size;
103963faed5bSDimitry Andric }
104063faed5bSDimitry Andric 
104101095a5dSDimitry Andric /// Returns true if the MachineInstr has an implicit-use operand of exactly
104201095a5dSDimitry Andric /// the given register (not considering sub/super-registers).
hasRegisterImplicitUseOperand(Register Reg) const10431d5ae102SDimitry Andric bool MachineInstr::hasRegisterImplicitUseOperand(Register Reg) const {
1044ac9a064cSDimitry Andric   for (const MachineOperand &MO : operands()) {
104501095a5dSDimitry Andric     if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == Reg)
104601095a5dSDimitry Andric       return true;
104701095a5dSDimitry Andric   }
104801095a5dSDimitry Andric   return false;
104901095a5dSDimitry Andric }
105001095a5dSDimitry Andric 
1051009b1c42SEd Schouten /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of
105259850d08SRoman Divacky /// the specific register or -1 if it is not found. It further tightens
1053009b1c42SEd Schouten /// the search criteria to a use that kills the register if isKill is true.
findRegisterUseOperandIdx(Register Reg,const TargetRegisterInfo * TRI,bool isKill) const1054ac9a064cSDimitry Andric int MachineInstr::findRegisterUseOperandIdx(Register Reg,
1055ac9a064cSDimitry Andric                                             const TargetRegisterInfo *TRI,
1056ac9a064cSDimitry Andric                                             bool isKill) const {
1057009b1c42SEd Schouten   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
1058009b1c42SEd Schouten     const MachineOperand &MO = getOperand(i);
1059009b1c42SEd Schouten     if (!MO.isReg() || !MO.isUse())
1060009b1c42SEd Schouten       continue;
10611d5ae102SDimitry Andric     Register MOReg = MO.getReg();
1062009b1c42SEd Schouten     if (!MOReg)
1063009b1c42SEd Schouten       continue;
1064d8e91e46SDimitry Andric     if (MOReg == Reg || (TRI && Reg && MOReg && TRI->regsOverlap(MOReg, Reg)))
1065009b1c42SEd Schouten       if (!isKill || MO.isKill())
1066009b1c42SEd Schouten         return i;
1067009b1c42SEd Schouten   }
1068009b1c42SEd Schouten   return -1;
1069009b1c42SEd Schouten }
1070009b1c42SEd Schouten 
1071abdf259dSRoman Divacky /// readsWritesVirtualRegister - Return a pair of bools (reads, writes)
1072abdf259dSRoman Divacky /// indicating if this instruction reads or writes Reg. This also considers
1073abdf259dSRoman Divacky /// partial defines.
1074abdf259dSRoman Divacky std::pair<bool,bool>
readsWritesVirtualRegister(Register Reg,SmallVectorImpl<unsigned> * Ops) const10751d5ae102SDimitry Andric MachineInstr::readsWritesVirtualRegister(Register Reg,
1076abdf259dSRoman Divacky                                          SmallVectorImpl<unsigned> *Ops) const {
1077abdf259dSRoman Divacky   bool PartDef = false; // Partial redefine.
1078abdf259dSRoman Divacky   bool FullDef = false; // Full define.
1079abdf259dSRoman Divacky   bool Use = false;
1080abdf259dSRoman Divacky 
1081abdf259dSRoman Divacky   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
1082abdf259dSRoman Divacky     const MachineOperand &MO = getOperand(i);
1083abdf259dSRoman Divacky     if (!MO.isReg() || MO.getReg() != Reg)
1084abdf259dSRoman Divacky       continue;
1085abdf259dSRoman Divacky     if (Ops)
1086abdf259dSRoman Divacky       Ops->push_back(i);
1087abdf259dSRoman Divacky     if (MO.isUse())
1088abdf259dSRoman Divacky       Use |= !MO.isUndef();
108930815c53SDimitry Andric     else if (MO.getSubReg() && !MO.isUndef())
1090044eb2f6SDimitry Andric       // A partial def undef doesn't count as reading the register.
1091abdf259dSRoman Divacky       PartDef = true;
1092abdf259dSRoman Divacky     else
1093abdf259dSRoman Divacky       FullDef = true;
1094abdf259dSRoman Divacky   }
1095abdf259dSRoman Divacky   // A partial redefine uses Reg unless there is also a full define.
1096abdf259dSRoman Divacky   return std::make_pair(Use || (PartDef && !FullDef), PartDef || FullDef);
1097abdf259dSRoman Divacky }
1098abdf259dSRoman Divacky 
1099009b1c42SEd Schouten /// findRegisterDefOperandIdx() - Returns the operand index that is a def of
1100009b1c42SEd Schouten /// the specified register or -1 if it is not found. If isDead is true, defs
1101009b1c42SEd Schouten /// that are not dead are skipped. If TargetRegisterInfo is non-null, then it
1102009b1c42SEd Schouten /// also checks if there is a def of a super-register.
findRegisterDefOperandIdx(Register Reg,const TargetRegisterInfo * TRI,bool isDead,bool Overlap) const1103ac9a064cSDimitry Andric int MachineInstr::findRegisterDefOperandIdx(Register Reg,
1104ac9a064cSDimitry Andric                                             const TargetRegisterInfo *TRI,
1105ac9a064cSDimitry Andric                                             bool isDead, bool Overlap) const {
1106e3b55780SDimitry Andric   bool isPhys = Reg.isPhysical();
1107009b1c42SEd Schouten   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
1108009b1c42SEd Schouten     const MachineOperand &MO = getOperand(i);
110963faed5bSDimitry Andric     // Accept regmask operands when Overlap is set.
111063faed5bSDimitry Andric     // Ignore them when looking for a specific def operand (Overlap == false).
111163faed5bSDimitry Andric     if (isPhys && Overlap && MO.isRegMask() && MO.clobbersPhysReg(Reg))
111263faed5bSDimitry Andric       return i;
1113009b1c42SEd Schouten     if (!MO.isReg() || !MO.isDef())
1114009b1c42SEd Schouten       continue;
11151d5ae102SDimitry Andric     Register MOReg = MO.getReg();
1116abdf259dSRoman Divacky     bool Found = (MOReg == Reg);
1117e3b55780SDimitry Andric     if (!Found && TRI && isPhys && MOReg.isPhysical()) {
1118abdf259dSRoman Divacky       if (Overlap)
1119abdf259dSRoman Divacky         Found = TRI->regsOverlap(MOReg, Reg);
1120abdf259dSRoman Divacky       else
1121abdf259dSRoman Divacky         Found = TRI->isSubRegister(MOReg, Reg);
1122abdf259dSRoman Divacky     }
1123abdf259dSRoman Divacky     if (Found && (!isDead || MO.isDead()))
1124009b1c42SEd Schouten       return i;
1125009b1c42SEd Schouten   }
1126009b1c42SEd Schouten   return -1;
1127009b1c42SEd Schouten }
1128009b1c42SEd Schouten 
1129009b1c42SEd Schouten /// findFirstPredOperandIdx() - Find the index of the first operand in the
1130009b1c42SEd Schouten /// operand list that is used to represent the predicate. It returns -1 if
1131009b1c42SEd Schouten /// none is found.
findFirstPredOperandIdx() const1132009b1c42SEd Schouten int MachineInstr::findFirstPredOperandIdx() const {
113330815c53SDimitry Andric   // Don't call MCID.findFirstPredOperandIdx() because this variant
113430815c53SDimitry Andric   // is sometimes called on an instruction that's not yet complete, and
113530815c53SDimitry Andric   // so the number of operands is less than the MCID indicates. In
113630815c53SDimitry Andric   // particular, the PTX target does this.
1137411bd29eSDimitry Andric   const MCInstrDesc &MCID = getDesc();
1138411bd29eSDimitry Andric   if (MCID.isPredicable()) {
1139009b1c42SEd Schouten     for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
1140e3b55780SDimitry Andric       if (MCID.operands()[i].isPredicate())
1141009b1c42SEd Schouten         return i;
1142009b1c42SEd Schouten   }
1143009b1c42SEd Schouten 
1144009b1c42SEd Schouten   return -1;
1145009b1c42SEd Schouten }
1146009b1c42SEd Schouten 
1147522600a2SDimitry Andric // MachineOperand::TiedTo is 4 bits wide.
1148522600a2SDimitry Andric const unsigned TiedMax = 15;
114930815c53SDimitry Andric 
1150522600a2SDimitry Andric /// tieOperands - Mark operands at DefIdx and UseIdx as tied to each other.
1151522600a2SDimitry Andric ///
1152522600a2SDimitry Andric /// Use and def operands can be tied together, indicated by a non-zero TiedTo
1153522600a2SDimitry Andric /// field. TiedTo can have these values:
1154522600a2SDimitry Andric ///
1155522600a2SDimitry Andric /// 0:              Operand is not tied to anything.
1156522600a2SDimitry Andric /// 1 to TiedMax-1: Tied to getOperand(TiedTo-1).
1157522600a2SDimitry Andric /// TiedMax:        Tied to an operand >= TiedMax-1.
1158522600a2SDimitry Andric ///
1159522600a2SDimitry Andric /// The tied def must be one of the first TiedMax operands on a normal
1160522600a2SDimitry Andric /// instruction. INLINEASM instructions allow more tied defs.
1161522600a2SDimitry Andric ///
tieOperands(unsigned DefIdx,unsigned UseIdx)1162522600a2SDimitry Andric void MachineInstr::tieOperands(unsigned DefIdx, unsigned UseIdx) {
1163522600a2SDimitry Andric   MachineOperand &DefMO = getOperand(DefIdx);
1164522600a2SDimitry Andric   MachineOperand &UseMO = getOperand(UseIdx);
1165522600a2SDimitry Andric   assert(DefMO.isDef() && "DefIdx must be a def operand");
1166522600a2SDimitry Andric   assert(UseMO.isUse() && "UseIdx must be a use operand");
1167522600a2SDimitry Andric   assert(!DefMO.isTied() && "Def is already tied to another use");
1168522600a2SDimitry Andric   assert(!UseMO.isTied() && "Use is already tied to another def");
116930815c53SDimitry Andric 
1170522600a2SDimitry Andric   if (DefIdx < TiedMax)
1171522600a2SDimitry Andric     UseMO.TiedTo = DefIdx + 1;
1172522600a2SDimitry Andric   else {
1173b60736ecSDimitry Andric     // Inline asm can use the group descriptors to find tied operands,
1174b60736ecSDimitry Andric     // statepoint tied operands are trivial to match (1-1 reg def with reg use),
1175b60736ecSDimitry Andric     // but on normal instruction, the tied def must be within the first TiedMax
1176522600a2SDimitry Andric     // operands.
1177b60736ecSDimitry Andric     assert((isInlineAsm() || getOpcode() == TargetOpcode::STATEPOINT) &&
1178b60736ecSDimitry Andric            "DefIdx out of range");
1179522600a2SDimitry Andric     UseMO.TiedTo = TiedMax;
1180522600a2SDimitry Andric   }
1181522600a2SDimitry Andric 
1182522600a2SDimitry Andric   // UseIdx can be out of range, we'll search for it in findTiedOperandIdx().
1183522600a2SDimitry Andric   DefMO.TiedTo = std::min(UseIdx + 1, TiedMax);
1184522600a2SDimitry Andric }
1185522600a2SDimitry Andric 
1186522600a2SDimitry Andric /// Given the index of a tied register operand, find the operand it is tied to.
1187522600a2SDimitry Andric /// Defs are tied to uses and vice versa. Returns the index of the tied operand
1188522600a2SDimitry Andric /// which must exist.
findTiedOperandIdx(unsigned OpIdx) const1189522600a2SDimitry Andric unsigned MachineInstr::findTiedOperandIdx(unsigned OpIdx) const {
1190522600a2SDimitry Andric   const MachineOperand &MO = getOperand(OpIdx);
1191522600a2SDimitry Andric   assert(MO.isTied() && "Operand isn't tied");
1192522600a2SDimitry Andric 
1193522600a2SDimitry Andric   // Normally TiedTo is in range.
1194522600a2SDimitry Andric   if (MO.TiedTo < TiedMax)
1195522600a2SDimitry Andric     return MO.TiedTo - 1;
1196522600a2SDimitry Andric 
1197522600a2SDimitry Andric   // Uses on normal instructions can be out of range.
1198b60736ecSDimitry Andric   if (!isInlineAsm() && getOpcode() != TargetOpcode::STATEPOINT) {
1199522600a2SDimitry Andric     // Normal tied defs must be in the 0..TiedMax-1 range.
1200522600a2SDimitry Andric     if (MO.isUse())
1201522600a2SDimitry Andric       return TiedMax - 1;
1202522600a2SDimitry Andric     // MO is a def. Search for the tied use.
1203522600a2SDimitry Andric     for (unsigned i = TiedMax - 1, e = getNumOperands(); i != e; ++i) {
1204522600a2SDimitry Andric       const MachineOperand &UseMO = getOperand(i);
1205522600a2SDimitry Andric       if (UseMO.isReg() && UseMO.isUse() && UseMO.TiedTo == OpIdx + 1)
1206522600a2SDimitry Andric         return i;
1207522600a2SDimitry Andric     }
1208522600a2SDimitry Andric     llvm_unreachable("Can't find tied use");
1209522600a2SDimitry Andric   }
1210522600a2SDimitry Andric 
1211b60736ecSDimitry Andric   if (getOpcode() == TargetOpcode::STATEPOINT) {
1212b60736ecSDimitry Andric     // In STATEPOINT defs correspond 1-1 to GC pointer operands passed
1213b60736ecSDimitry Andric     // on registers.
1214b60736ecSDimitry Andric     StatepointOpers SO(this);
1215b60736ecSDimitry Andric     unsigned CurUseIdx = SO.getFirstGCPtrIdx();
1216b60736ecSDimitry Andric     assert(CurUseIdx != -1U && "only gc pointer statepoint operands can be tied");
1217b60736ecSDimitry Andric     unsigned NumDefs = getNumDefs();
1218b60736ecSDimitry Andric     for (unsigned CurDefIdx = 0; CurDefIdx < NumDefs; ++CurDefIdx) {
1219b60736ecSDimitry Andric       while (!getOperand(CurUseIdx).isReg())
1220b60736ecSDimitry Andric         CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx);
1221b60736ecSDimitry Andric       if (OpIdx == CurDefIdx)
1222b60736ecSDimitry Andric         return CurUseIdx;
1223b60736ecSDimitry Andric       if (OpIdx == CurUseIdx)
1224b60736ecSDimitry Andric         return CurDefIdx;
1225b60736ecSDimitry Andric       CurUseIdx = StackMaps::getNextMetaArgIdx(this, CurUseIdx);
1226b60736ecSDimitry Andric     }
1227b60736ecSDimitry Andric     llvm_unreachable("Can't find tied use");
1228b60736ecSDimitry Andric   }
1229b60736ecSDimitry Andric 
1230522600a2SDimitry Andric   // Now deal with inline asm by parsing the operand group descriptor flags.
1231522600a2SDimitry Andric   // Find the beginning of each operand group.
1232522600a2SDimitry Andric   SmallVector<unsigned, 8> GroupIdx;
1233522600a2SDimitry Andric   unsigned OpIdxGroup = ~0u;
1234522600a2SDimitry Andric   unsigned NumOps;
1235522600a2SDimitry Andric   for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e;
1236522600a2SDimitry Andric        i += NumOps) {
1237522600a2SDimitry Andric     const MachineOperand &FlagMO = getOperand(i);
1238522600a2SDimitry Andric     assert(FlagMO.isImm() && "Invalid tied operand on inline asm");
1239522600a2SDimitry Andric     unsigned CurGroup = GroupIdx.size();
1240522600a2SDimitry Andric     GroupIdx.push_back(i);
1241b1c73532SDimitry Andric     const InlineAsm::Flag F(FlagMO.getImm());
1242b1c73532SDimitry Andric     NumOps = 1 + F.getNumOperandRegisters();
1243522600a2SDimitry Andric     // OpIdx belongs to this operand group.
1244522600a2SDimitry Andric     if (OpIdx > i && OpIdx < i + NumOps)
1245522600a2SDimitry Andric       OpIdxGroup = CurGroup;
1246522600a2SDimitry Andric     unsigned TiedGroup;
1247b1c73532SDimitry Andric     if (!F.isUseOperandTiedToDef(TiedGroup))
1248009b1c42SEd Schouten       continue;
1249522600a2SDimitry Andric     // Operands in this group are tied to operands in TiedGroup which must be
1250522600a2SDimitry Andric     // earlier. Find the number of operands between the two groups.
1251522600a2SDimitry Andric     unsigned Delta = i - GroupIdx[TiedGroup];
1252009b1c42SEd Schouten 
1253522600a2SDimitry Andric     // OpIdx is a use tied to TiedGroup.
1254522600a2SDimitry Andric     if (OpIdxGroup == CurGroup)
1255522600a2SDimitry Andric       return OpIdx - Delta;
1256009b1c42SEd Schouten 
1257522600a2SDimitry Andric     // OpIdx is a def tied to this use group.
1258522600a2SDimitry Andric     if (OpIdxGroup == TiedGroup)
1259522600a2SDimitry Andric       return OpIdx + Delta;
1260009b1c42SEd Schouten   }
1261522600a2SDimitry Andric   llvm_unreachable("Invalid tied operand on inline asm");
1262009b1c42SEd Schouten }
1263009b1c42SEd Schouten 
1264abdf259dSRoman Divacky /// clearKillInfo - Clears kill flags on all operands.
1265abdf259dSRoman Divacky ///
clearKillInfo()1266abdf259dSRoman Divacky void MachineInstr::clearKillInfo() {
12675a5ac124SDimitry Andric   for (MachineOperand &MO : operands()) {
1268abdf259dSRoman Divacky     if (MO.isReg() && MO.isUse())
1269abdf259dSRoman Divacky       MO.setIsKill(false);
1270abdf259dSRoman Divacky   }
1271abdf259dSRoman Divacky }
1272abdf259dSRoman Divacky 
substituteRegister(Register FromReg,Register ToReg,unsigned SubIdx,const TargetRegisterInfo & RegInfo)12731d5ae102SDimitry Andric void MachineInstr::substituteRegister(Register FromReg, Register ToReg,
127466e41e3cSRoman Divacky                                       unsigned SubIdx,
127566e41e3cSRoman Divacky                                       const TargetRegisterInfo &RegInfo) {
1276e3b55780SDimitry Andric   if (ToReg.isPhysical()) {
127766e41e3cSRoman Divacky     if (SubIdx)
127866e41e3cSRoman Divacky       ToReg = RegInfo.getSubReg(ToReg, SubIdx);
12795a5ac124SDimitry Andric     for (MachineOperand &MO : operands()) {
128066e41e3cSRoman Divacky       if (!MO.isReg() || MO.getReg() != FromReg)
128166e41e3cSRoman Divacky         continue;
128266e41e3cSRoman Divacky       MO.substPhysReg(ToReg, RegInfo);
128366e41e3cSRoman Divacky     }
128466e41e3cSRoman Divacky   } else {
12855a5ac124SDimitry Andric     for (MachineOperand &MO : operands()) {
128666e41e3cSRoman Divacky       if (!MO.isReg() || MO.getReg() != FromReg)
128766e41e3cSRoman Divacky         continue;
128866e41e3cSRoman Divacky       MO.substVirtReg(ToReg, SubIdx, RegInfo);
128966e41e3cSRoman Divacky     }
129066e41e3cSRoman Divacky   }
129166e41e3cSRoman Divacky }
129266e41e3cSRoman Divacky 
1293009b1c42SEd Schouten /// isSafeToMove - Return true if it is safe to move this instruction. If
1294009b1c42SEd Schouten /// SawStore is set to true, it means that there is a store (or call) between
1295009b1c42SEd Schouten /// the instruction's location and its intended destination.
isSafeToMove(AAResults * AA,bool & SawStore) const12961d5ae102SDimitry Andric bool MachineInstr::isSafeToMove(AAResults *AA, bool &SawStore) const {
1297009b1c42SEd Schouten   // Ignore stuff that we obviously can't move.
1298522600a2SDimitry Andric   //
1299522600a2SDimitry Andric   // Treat volatile loads as stores. This is not strictly necessary for
1300522600a2SDimitry Andric   // volatiles, but it is required for atomic loads. It is not allowed to move
1301522600a2SDimitry Andric   // a load across an atomic load with Ordering > Monotonic.
1302044eb2f6SDimitry Andric   if (mayStore() || isCall() || isPHI() ||
1303522600a2SDimitry Andric       (mayLoad() && hasOrderedMemoryRef())) {
1304009b1c42SEd Schouten     SawStore = true;
1305009b1c42SEd Schouten     return false;
1306009b1c42SEd Schouten   }
1307cf099d11SDimitry Andric 
1308eb11fae6SDimitry Andric   if (isPosition() || isDebugInstr() || isTerminator() ||
1309b1c73532SDimitry Andric       mayRaiseFPException() || hasUnmodeledSideEffects() ||
1310b1c73532SDimitry Andric       isJumpTableDebugInfo())
1311009b1c42SEd Schouten     return false;
1312009b1c42SEd Schouten 
1313009b1c42SEd Schouten   // See if this instruction does a load.  If so, we have to guarantee that the
1314009b1c42SEd Schouten   // loaded value doesn't change between the load and the its intended
1315b60736ecSDimitry Andric   // destination. The check for isInvariantLoad gives the target the chance to
1316009b1c42SEd Schouten   // classify the load as always returning a constant, e.g. a constant pool
1317009b1c42SEd Schouten   // load.
13184b4fe385SDimitry Andric   if (mayLoad() && !isDereferenceableInvariantLoad())
1319009b1c42SEd Schouten     // Otherwise, this is a real load.  If there is a store between the load and
1320522600a2SDimitry Andric     // end of block, we can't move it.
1321522600a2SDimitry Andric     return !SawStore;
1322009b1c42SEd Schouten 
1323009b1c42SEd Schouten   return true;
1324009b1c42SEd Schouten }
1325009b1c42SEd Schouten 
MemOperandsHaveAlias(const MachineFrameInfo & MFI,AAResults * AA,bool UseTBAA,const MachineMemOperand * MMOa,const MachineMemOperand * MMOb)1326b60736ecSDimitry Andric static bool MemOperandsHaveAlias(const MachineFrameInfo &MFI, AAResults *AA,
1327b60736ecSDimitry Andric                                  bool UseTBAA, const MachineMemOperand *MMOa,
1328b60736ecSDimitry Andric                                  const MachineMemOperand *MMOb) {
1329b60736ecSDimitry Andric   // The following interface to AA is fashioned after DAGCombiner::isAlias and
1330b60736ecSDimitry Andric   // operates with MachineMemOperand offset with some important assumptions:
133171d5a254SDimitry Andric   //   - LLVM fundamentally assumes flat address spaces.
1332b60736ecSDimitry Andric   //   - MachineOperand offset can *only* result from legalization and cannot
1333b60736ecSDimitry Andric   //     affect queries other than the trivial case of overlap checking.
1334b60736ecSDimitry Andric   //   - These offsets never wrap and never step outside of allocated objects.
133571d5a254SDimitry Andric   //   - There should never be any negative offsets here.
133671d5a254SDimitry Andric   //
133771d5a254SDimitry Andric   // FIXME: Modify API to hide this math from "user"
1338b60736ecSDimitry Andric   // Even before we go to AA we can reason locally about some memory objects. It
1339b60736ecSDimitry Andric   // can save compile time, and possibly catch some corner cases not currently
1340b60736ecSDimitry Andric   // covered.
134171d5a254SDimitry Andric 
1342044eb2f6SDimitry Andric   int64_t OffsetA = MMOa->getOffset();
1343044eb2f6SDimitry Andric   int64_t OffsetB = MMOb->getOffset();
1344044eb2f6SDimitry Andric   int64_t MinOffset = std::min(OffsetA, OffsetB);
1345d8e91e46SDimitry Andric 
1346ac9a064cSDimitry Andric   LocationSize WidthA = MMOa->getSize();
1347ac9a064cSDimitry Andric   LocationSize WidthB = MMOb->getSize();
1348ac9a064cSDimitry Andric   bool KnownWidthA = WidthA.hasValue();
1349ac9a064cSDimitry Andric   bool KnownWidthB = WidthB.hasValue();
1350ac9a064cSDimitry Andric   bool BothMMONonScalable = !WidthA.isScalable() && !WidthB.isScalable();
1351d8e91e46SDimitry Andric 
1352044eb2f6SDimitry Andric   const Value *ValA = MMOa->getValue();
1353044eb2f6SDimitry Andric   const Value *ValB = MMOb->getValue();
1354044eb2f6SDimitry Andric   bool SameVal = (ValA && ValB && (ValA == ValB));
1355044eb2f6SDimitry Andric   if (!SameVal) {
1356044eb2f6SDimitry Andric     const PseudoSourceValue *PSVa = MMOa->getPseudoValue();
1357044eb2f6SDimitry Andric     const PseudoSourceValue *PSVb = MMOb->getPseudoValue();
1358044eb2f6SDimitry Andric     if (PSVa && ValB && !PSVa->mayAlias(&MFI))
1359044eb2f6SDimitry Andric       return false;
1360044eb2f6SDimitry Andric     if (PSVb && ValA && !PSVb->mayAlias(&MFI))
1361044eb2f6SDimitry Andric       return false;
1362044eb2f6SDimitry Andric     if (PSVa && PSVb && (PSVa == PSVb))
1363044eb2f6SDimitry Andric       SameVal = true;
1364044eb2f6SDimitry Andric   }
136571d5a254SDimitry Andric 
1366ac9a064cSDimitry Andric   if (SameVal && BothMMONonScalable) {
1367d8e91e46SDimitry Andric     if (!KnownWidthA || !KnownWidthB)
1368d8e91e46SDimitry Andric       return true;
1369044eb2f6SDimitry Andric     int64_t MaxOffset = std::max(OffsetA, OffsetB);
1370ac9a064cSDimitry Andric     int64_t LowWidth = (MinOffset == OffsetA)
1371ac9a064cSDimitry Andric                            ? WidthA.getValue().getKnownMinValue()
1372ac9a064cSDimitry Andric                            : WidthB.getValue().getKnownMinValue();
1373044eb2f6SDimitry Andric     return (MinOffset + LowWidth > MaxOffset);
1374044eb2f6SDimitry Andric   }
1375044eb2f6SDimitry Andric 
1376044eb2f6SDimitry Andric   if (!AA)
1377044eb2f6SDimitry Andric     return true;
1378044eb2f6SDimitry Andric 
1379044eb2f6SDimitry Andric   if (!ValA || !ValB)
1380044eb2f6SDimitry Andric     return true;
1381044eb2f6SDimitry Andric 
1382044eb2f6SDimitry Andric   assert((OffsetA >= 0) && "Negative MachineMemOperand offset");
1383044eb2f6SDimitry Andric   assert((OffsetB >= 0) && "Negative MachineMemOperand offset");
1384044eb2f6SDimitry Andric 
1385ac9a064cSDimitry Andric   // If Scalable Location Size has non-zero offset, Width + Offset does not work
1386ac9a064cSDimitry Andric   // at the moment
1387ac9a064cSDimitry Andric   if ((WidthA.isScalable() && OffsetA > 0) ||
1388ac9a064cSDimitry Andric       (WidthB.isScalable() && OffsetB > 0))
1389ac9a064cSDimitry Andric     return true;
1390ac9a064cSDimitry Andric 
1391b60736ecSDimitry Andric   int64_t OverlapA =
1392ac9a064cSDimitry Andric       KnownWidthA ? WidthA.getValue().getKnownMinValue() + OffsetA - MinOffset
1393ac9a064cSDimitry Andric                   : MemoryLocation::UnknownSize;
1394b60736ecSDimitry Andric   int64_t OverlapB =
1395ac9a064cSDimitry Andric       KnownWidthB ? WidthB.getValue().getKnownMinValue() + OffsetB - MinOffset
1396ac9a064cSDimitry Andric                   : MemoryLocation::UnknownSize;
1397ac9a064cSDimitry Andric 
1398ac9a064cSDimitry Andric   LocationSize LocA = (WidthA.isScalable() || !KnownWidthA)
1399ac9a064cSDimitry Andric                           ? WidthA
1400ac9a064cSDimitry Andric                           : LocationSize::precise(OverlapA);
1401ac9a064cSDimitry Andric   LocationSize LocB = (WidthB.isScalable() || !KnownWidthB)
1402ac9a064cSDimitry Andric                           ? WidthB
1403ac9a064cSDimitry Andric                           : LocationSize::precise(OverlapB);
1404044eb2f6SDimitry Andric 
1405344a3780SDimitry Andric   return !AA->isNoAlias(
1406ac9a064cSDimitry Andric       MemoryLocation(ValA, LocA, UseTBAA ? MMOa->getAAInfo() : AAMDNodes()),
1407ac9a064cSDimitry Andric       MemoryLocation(ValB, LocB, UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));
140871d5a254SDimitry Andric }
140971d5a254SDimitry Andric 
mayAlias(AAResults * AA,const MachineInstr & Other,bool UseTBAA) const1410b60736ecSDimitry Andric bool MachineInstr::mayAlias(AAResults *AA, const MachineInstr &Other,
1411b60736ecSDimitry Andric                             bool UseTBAA) const {
1412b60736ecSDimitry Andric   const MachineFunction *MF = getMF();
1413b60736ecSDimitry Andric   const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
1414b60736ecSDimitry Andric   const MachineFrameInfo &MFI = MF->getFrameInfo();
1415b60736ecSDimitry Andric 
1416b60736ecSDimitry Andric   // Exclude call instruction which may alter the memory but can not be handled
1417b60736ecSDimitry Andric   // by this function.
1418b60736ecSDimitry Andric   if (isCall() || Other.isCall())
1419b60736ecSDimitry Andric     return true;
1420b60736ecSDimitry Andric 
1421b60736ecSDimitry Andric   // If neither instruction stores to memory, they can't alias in any
1422b60736ecSDimitry Andric   // meaningful way, even if they read from the same address.
1423b60736ecSDimitry Andric   if (!mayStore() && !Other.mayStore())
1424b60736ecSDimitry Andric     return false;
1425b60736ecSDimitry Andric 
1426b60736ecSDimitry Andric   // Both instructions must be memory operations to be able to alias.
1427b60736ecSDimitry Andric   if (!mayLoadOrStore() || !Other.mayLoadOrStore())
1428b60736ecSDimitry Andric     return false;
1429b60736ecSDimitry Andric 
1430b60736ecSDimitry Andric   // Let the target decide if memory accesses cannot possibly overlap.
1431b60736ecSDimitry Andric   if (TII->areMemAccessesTriviallyDisjoint(*this, Other))
1432b60736ecSDimitry Andric     return false;
1433b60736ecSDimitry Andric 
1434b60736ecSDimitry Andric   // Memory operations without memory operands may access anything. Be
1435b60736ecSDimitry Andric   // conservative and assume `MayAlias`.
1436b60736ecSDimitry Andric   if (memoperands_empty() || Other.memoperands_empty())
1437b60736ecSDimitry Andric     return true;
1438b60736ecSDimitry Andric 
1439b60736ecSDimitry Andric   // Skip if there are too many memory operands.
1440b60736ecSDimitry Andric   auto NumChecks = getNumMemOperands() * Other.getNumMemOperands();
1441b60736ecSDimitry Andric   if (NumChecks > TII->getMemOperandAACheckLimit())
1442b60736ecSDimitry Andric     return true;
1443b60736ecSDimitry Andric 
1444b60736ecSDimitry Andric   // Check each pair of memory operands from both instructions, which can't
1445b60736ecSDimitry Andric   // alias only if all pairs won't alias.
1446b60736ecSDimitry Andric   for (auto *MMOa : memoperands())
1447b60736ecSDimitry Andric     for (auto *MMOb : Other.memoperands())
1448b60736ecSDimitry Andric       if (MemOperandsHaveAlias(MFI, AA, UseTBAA, MMOa, MMOb))
1449b60736ecSDimitry Andric         return true;
1450b60736ecSDimitry Andric 
1451b60736ecSDimitry Andric   return false;
1452b60736ecSDimitry Andric }
1453b60736ecSDimitry Andric 
1454522600a2SDimitry Andric /// hasOrderedMemoryRef - Return true if this instruction may have an ordered
1455522600a2SDimitry Andric /// or volatile memory reference, or if the information describing the memory
1456522600a2SDimitry Andric /// reference is not available. Return false if it is known to have no ordered
1457522600a2SDimitry Andric /// memory references.
hasOrderedMemoryRef() const1458522600a2SDimitry Andric bool MachineInstr::hasOrderedMemoryRef() const {
1459009b1c42SEd Schouten   // An instruction known never to access memory won't have a volatile access.
146063faed5bSDimitry Andric   if (!mayStore() &&
146163faed5bSDimitry Andric       !mayLoad() &&
146263faed5bSDimitry Andric       !isCall() &&
1463cf099d11SDimitry Andric       !hasUnmodeledSideEffects())
1464009b1c42SEd Schouten     return false;
1465009b1c42SEd Schouten 
1466009b1c42SEd Schouten   // Otherwise, if the instruction has no memory reference information,
1467009b1c42SEd Schouten   // conservatively assume it wasn't preserved.
1468009b1c42SEd Schouten   if (memoperands_empty())
1469009b1c42SEd Schouten     return true;
1470009b1c42SEd Schouten 
147101095a5dSDimitry Andric   // Check if any of our memory operands are ordered.
1472f382538dSDimitry Andric   return llvm::any_of(memoperands(), [](const MachineMemOperand *MMO) {
147301095a5dSDimitry Andric     return !MMO->isUnordered();
147401095a5dSDimitry Andric   });
1475009b1c42SEd Schouten }
1476009b1c42SEd Schouten 
1477b915e9e0SDimitry Andric /// isDereferenceableInvariantLoad - Return true if this instruction will never
1478b915e9e0SDimitry Andric /// trap and is loading from a location whose value is invariant across a run of
1479b915e9e0SDimitry Andric /// this function.
isDereferenceableInvariantLoad() const14804b4fe385SDimitry Andric bool MachineInstr::isDereferenceableInvariantLoad() const {
148159850d08SRoman Divacky   // If the instruction doesn't load at all, it isn't an invariant load.
148263faed5bSDimitry Andric   if (!mayLoad())
148359850d08SRoman Divacky     return false;
148459850d08SRoman Divacky 
148559850d08SRoman Divacky   // If the instruction has lost its memoperands, conservatively assume that
148659850d08SRoman Divacky   // it may not be an invariant load.
148759850d08SRoman Divacky   if (memoperands_empty())
148859850d08SRoman Divacky     return false;
148959850d08SRoman Divacky 
1490b915e9e0SDimitry Andric   const MachineFrameInfo &MFI = getParent()->getParent()->getFrameInfo();
149159850d08SRoman Divacky 
149201095a5dSDimitry Andric   for (MachineMemOperand *MMO : memoperands()) {
1493e6d15924SDimitry Andric     if (!MMO->isUnordered())
1494e6d15924SDimitry Andric       // If the memory operand has ordering side effects, we can't move the
1495e6d15924SDimitry Andric       // instruction.  Such an instruction is technically an invariant load,
1496e6d15924SDimitry Andric       // but the caller code would need updated to expect that.
1497e6d15924SDimitry Andric       return false;
149801095a5dSDimitry Andric     if (MMO->isStore()) return false;
1499b915e9e0SDimitry Andric     if (MMO->isInvariant() && MMO->isDereferenceable())
1500b915e9e0SDimitry Andric       continue;
15015ca98fd9SDimitry Andric 
150259850d08SRoman Divacky     // A load from a constant PseudoSourceValue is invariant.
1503145449b1SDimitry Andric     if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) {
1504b915e9e0SDimitry Andric       if (PSV->isConstant(&MFI))
150559850d08SRoman Divacky         continue;
1506009b1c42SEd Schouten     }
1507009b1c42SEd Schouten 
150859850d08SRoman Divacky     // Otherwise assume conservatively.
150959850d08SRoman Divacky     return false;
151059850d08SRoman Divacky   }
151159850d08SRoman Divacky 
151259850d08SRoman Divacky   // Everything checks out.
151359850d08SRoman Divacky   return true;
151459850d08SRoman Divacky }
151559850d08SRoman Divacky 
1516571945e6SRoman Divacky /// isConstantValuePHI - If the specified instruction is a PHI that always
1517571945e6SRoman Divacky /// merges together the same virtual register, return the register, otherwise
1518571945e6SRoman Divacky /// return 0.
isConstantValuePHI() const1519571945e6SRoman Divacky unsigned MachineInstr::isConstantValuePHI() const {
15206fe5c7aaSRoman Divacky   if (!isPHI())
1521571945e6SRoman Divacky     return 0;
1522571945e6SRoman Divacky   assert(getNumOperands() >= 3 &&
1523571945e6SRoman Divacky          "It's illegal to have a PHI without source operands");
1524571945e6SRoman Divacky 
15251d5ae102SDimitry Andric   Register Reg = getOperand(1).getReg();
1526571945e6SRoman Divacky   for (unsigned i = 3, e = getNumOperands(); i < e; i += 2)
1527571945e6SRoman Divacky     if (getOperand(i).getReg() != Reg)
1528571945e6SRoman Divacky       return 0;
1529571945e6SRoman Divacky   return Reg;
1530571945e6SRoman Divacky }
1531571945e6SRoman Divacky 
hasUnmodeledSideEffects() const1532cf099d11SDimitry Andric bool MachineInstr::hasUnmodeledSideEffects() const {
153363faed5bSDimitry Andric   if (hasProperty(MCID::UnmodeledSideEffects))
1534cf099d11SDimitry Andric     return true;
1535cf099d11SDimitry Andric   if (isInlineAsm()) {
1536cf099d11SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
1537cf099d11SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
1538cf099d11SDimitry Andric       return true;
1539cf099d11SDimitry Andric   }
1540cf099d11SDimitry Andric 
1541cf099d11SDimitry Andric   return false;
1542cf099d11SDimitry Andric }
1543cf099d11SDimitry Andric 
isLoadFoldBarrier() const1544dd58ef01SDimitry Andric bool MachineInstr::isLoadFoldBarrier() const {
1545344a3780SDimitry Andric   return mayStore() || isCall() ||
1546344a3780SDimitry Andric          (hasUnmodeledSideEffects() && !isPseudoProbe());
1547dd58ef01SDimitry Andric }
1548dd58ef01SDimitry Andric 
1549d7f7719eSRoman Divacky /// allDefsAreDead - Return true if all the defs of this instruction are dead.
1550d7f7719eSRoman Divacky ///
allDefsAreDead() const1551d7f7719eSRoman Divacky bool MachineInstr::allDefsAreDead() const {
15525a5ac124SDimitry Andric   for (const MachineOperand &MO : operands()) {
1553d7f7719eSRoman Divacky     if (!MO.isReg() || MO.isUse())
1554d7f7719eSRoman Divacky       continue;
1555d7f7719eSRoman Divacky     if (!MO.isDead())
1556d7f7719eSRoman Divacky       return false;
1557d7f7719eSRoman Divacky   }
1558d7f7719eSRoman Divacky   return true;
1559d7f7719eSRoman Divacky }
1560d7f7719eSRoman Divacky 
allImplicitDefsAreDead() const1561b1c73532SDimitry Andric bool MachineInstr::allImplicitDefsAreDead() const {
1562b1c73532SDimitry Andric   for (const MachineOperand &MO : implicit_operands()) {
1563b1c73532SDimitry Andric     if (!MO.isReg() || MO.isUse())
1564b1c73532SDimitry Andric       continue;
1565b1c73532SDimitry Andric     if (!MO.isDead())
1566b1c73532SDimitry Andric       return false;
1567b1c73532SDimitry Andric   }
1568b1c73532SDimitry Andric   return true;
1569b1c73532SDimitry Andric }
1570b1c73532SDimitry Andric 
1571cf099d11SDimitry Andric /// copyImplicitOps - Copy implicit register operands from specified
1572cf099d11SDimitry Andric /// instruction to this instruction.
copyImplicitOps(MachineFunction & MF,const MachineInstr & MI)15734a16efa3SDimitry Andric void MachineInstr::copyImplicitOps(MachineFunction &MF,
157401095a5dSDimitry Andric                                    const MachineInstr &MI) {
1575f65dcba8SDimitry Andric   for (const MachineOperand &MO :
1576f65dcba8SDimitry Andric        llvm::drop_begin(MI.operands(), MI.getDesc().getNumOperands()))
15775ca98fd9SDimitry Andric     if ((MO.isReg() && MO.isImplicit()) || MO.isRegMask())
15784a16efa3SDimitry Andric       addOperand(MF, MO);
1579cf099d11SDimitry Andric }
1580cf099d11SDimitry Andric 
hasComplexRegisterTies() const1581044eb2f6SDimitry Andric bool MachineInstr::hasComplexRegisterTies() const {
1582044eb2f6SDimitry Andric   const MCInstrDesc &MCID = getDesc();
1583b60736ecSDimitry Andric   if (MCID.Opcode == TargetOpcode::STATEPOINT)
1584b60736ecSDimitry Andric     return true;
1585044eb2f6SDimitry Andric   for (unsigned I = 0, E = getNumOperands(); I < E; ++I) {
1586044eb2f6SDimitry Andric     const auto &Operand = getOperand(I);
1587044eb2f6SDimitry Andric     if (!Operand.isReg() || Operand.isDef())
1588044eb2f6SDimitry Andric       // Ignore the defined registers as MCID marks only the uses as tied.
1589044eb2f6SDimitry Andric       continue;
1590044eb2f6SDimitry Andric     int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO);
1591044eb2f6SDimitry Andric     int TiedIdx = Operand.isTied() ? int(findTiedOperandIdx(I)) : -1;
1592044eb2f6SDimitry Andric     if (ExpectedTiedIdx != TiedIdx)
1593044eb2f6SDimitry Andric       return true;
1594044eb2f6SDimitry Andric   }
1595044eb2f6SDimitry Andric   return false;
1596044eb2f6SDimitry Andric }
1597044eb2f6SDimitry Andric 
getTypeToPrint(unsigned OpIdx,SmallBitVector & PrintedTypes,const MachineRegisterInfo & MRI) const1598044eb2f6SDimitry Andric LLT MachineInstr::getTypeToPrint(unsigned OpIdx, SmallBitVector &PrintedTypes,
1599044eb2f6SDimitry Andric                                  const MachineRegisterInfo &MRI) const {
1600044eb2f6SDimitry Andric   const MachineOperand &Op = getOperand(OpIdx);
1601044eb2f6SDimitry Andric   if (!Op.isReg())
1602044eb2f6SDimitry Andric     return LLT{};
1603044eb2f6SDimitry Andric 
1604044eb2f6SDimitry Andric   if (isVariadic() || OpIdx >= getNumExplicitOperands())
1605044eb2f6SDimitry Andric     return MRI.getType(Op.getReg());
1606044eb2f6SDimitry Andric 
1607e3b55780SDimitry Andric   auto &OpInfo = getDesc().operands()[OpIdx];
1608044eb2f6SDimitry Andric   if (!OpInfo.isGenericType())
1609044eb2f6SDimitry Andric     return MRI.getType(Op.getReg());
1610044eb2f6SDimitry Andric 
1611044eb2f6SDimitry Andric   if (PrintedTypes[OpInfo.getGenericTypeIndex()])
1612044eb2f6SDimitry Andric     return LLT{};
1613044eb2f6SDimitry Andric 
1614eb11fae6SDimitry Andric   LLT TypeToPrint = MRI.getType(Op.getReg());
1615eb11fae6SDimitry Andric   // Don't mark the type index printed if it wasn't actually printed: maybe
1616eb11fae6SDimitry Andric   // another operand with the same type index has an actual type attached:
1617eb11fae6SDimitry Andric   if (TypeToPrint.isValid())
1618044eb2f6SDimitry Andric     PrintedTypes.set(OpInfo.getGenericTypeIndex());
1619eb11fae6SDimitry Andric   return TypeToPrint;
1620044eb2f6SDimitry Andric }
1621044eb2f6SDimitry Andric 
1622522600a2SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const162371d5a254SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dump() const {
1624b915e9e0SDimitry Andric   dbgs() << "  ";
162571d5a254SDimitry Andric   print(dbgs());
1626009b1c42SEd Schouten }
1627cfca06d7SDimitry Andric 
dumprImpl(const MachineRegisterInfo & MRI,unsigned Depth,unsigned MaxDepth,SmallPtrSetImpl<const MachineInstr * > & AlreadySeenInstrs) const1628cfca06d7SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dumprImpl(
1629cfca06d7SDimitry Andric     const MachineRegisterInfo &MRI, unsigned Depth, unsigned MaxDepth,
1630cfca06d7SDimitry Andric     SmallPtrSetImpl<const MachineInstr *> &AlreadySeenInstrs) const {
1631cfca06d7SDimitry Andric   if (Depth >= MaxDepth)
1632cfca06d7SDimitry Andric     return;
1633cfca06d7SDimitry Andric   if (!AlreadySeenInstrs.insert(this).second)
1634cfca06d7SDimitry Andric     return;
1635cfca06d7SDimitry Andric   // PadToColumn always inserts at least one space.
1636cfca06d7SDimitry Andric   // Don't mess up the alignment if we don't want any space.
1637cfca06d7SDimitry Andric   if (Depth)
1638cfca06d7SDimitry Andric     fdbgs().PadToColumn(Depth * 2);
1639cfca06d7SDimitry Andric   print(fdbgs());
1640cfca06d7SDimitry Andric   for (const MachineOperand &MO : operands()) {
1641cfca06d7SDimitry Andric     if (!MO.isReg() || MO.isDef())
1642cfca06d7SDimitry Andric       continue;
1643cfca06d7SDimitry Andric     Register Reg = MO.getReg();
1644cfca06d7SDimitry Andric     if (Reg.isPhysical())
1645cfca06d7SDimitry Andric       continue;
1646cfca06d7SDimitry Andric     const MachineInstr *NewMI = MRI.getUniqueVRegDef(Reg);
1647cfca06d7SDimitry Andric     if (NewMI == nullptr)
1648cfca06d7SDimitry Andric       continue;
1649cfca06d7SDimitry Andric     NewMI->dumprImpl(MRI, Depth + 1, MaxDepth, AlreadySeenInstrs);
1650cfca06d7SDimitry Andric   }
1651cfca06d7SDimitry Andric }
1652cfca06d7SDimitry Andric 
dumpr(const MachineRegisterInfo & MRI,unsigned MaxDepth) const1653cfca06d7SDimitry Andric LLVM_DUMP_METHOD void MachineInstr::dumpr(const MachineRegisterInfo &MRI,
1654cfca06d7SDimitry Andric                                           unsigned MaxDepth) const {
1655cfca06d7SDimitry Andric   SmallPtrSet<const MachineInstr *, 16> AlreadySeenInstrs;
1656cfca06d7SDimitry Andric   dumprImpl(MRI, 0, MaxDepth, AlreadySeenInstrs);
1657cfca06d7SDimitry Andric }
165871d5a254SDimitry Andric #endif
1659009b1c42SEd Schouten 
print(raw_ostream & OS,bool IsStandalone,bool SkipOpers,bool SkipDebugLoc,bool AddNewLine,const TargetInstrInfo * TII) const1660eb11fae6SDimitry Andric void MachineInstr::print(raw_ostream &OS, bool IsStandalone, bool SkipOpers,
1661eb11fae6SDimitry Andric                          bool SkipDebugLoc, bool AddNewLine,
1662b915e9e0SDimitry Andric                          const TargetInstrInfo *TII) const {
16631a82d4c0SDimitry Andric   const Module *M = nullptr;
1664eb11fae6SDimitry Andric   const Function *F = nullptr;
1665eb11fae6SDimitry Andric   if (const MachineFunction *MF = getMFIfAvailable(*this)) {
1666eb11fae6SDimitry Andric     F = &MF->getFunction();
1667eb11fae6SDimitry Andric     M = F->getParent();
1668eb11fae6SDimitry Andric     if (!TII)
1669eb11fae6SDimitry Andric       TII = MF->getSubtarget().getInstrInfo();
1670eb11fae6SDimitry Andric   }
16711a82d4c0SDimitry Andric 
16721a82d4c0SDimitry Andric   ModuleSlotTracker MST(M);
1673eb11fae6SDimitry Andric   if (F)
1674eb11fae6SDimitry Andric     MST.incorporateFunction(*F);
1675e6d15924SDimitry Andric   print(OS, MST, IsStandalone, SkipOpers, SkipDebugLoc, AddNewLine, TII);
16761a82d4c0SDimitry Andric }
16771a82d4c0SDimitry Andric 
print(raw_ostream & OS,ModuleSlotTracker & MST,bool IsStandalone,bool SkipOpers,bool SkipDebugLoc,bool AddNewLine,const TargetInstrInfo * TII) const16781a82d4c0SDimitry Andric void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,
1679eb11fae6SDimitry Andric                          bool IsStandalone, bool SkipOpers, bool SkipDebugLoc,
1680eb11fae6SDimitry Andric                          bool AddNewLine, const TargetInstrInfo *TII) const {
16815a5ac124SDimitry Andric   // We can be a bit tidier if we know the MachineFunction.
16825a5ac124SDimitry Andric   const TargetRegisterInfo *TRI = nullptr;
16835ca98fd9SDimitry Andric   const MachineRegisterInfo *MRI = nullptr;
1684b915e9e0SDimitry Andric   const TargetIntrinsicInfo *IntrinsicInfo = nullptr;
1685eb11fae6SDimitry Andric   tryToGetTargetInfo(*this, TRI, MRI, IntrinsicInfo, TII);
1686b915e9e0SDimitry Andric 
1687eb11fae6SDimitry Andric   if (isCFIInstruction())
1688eb11fae6SDimitry Andric     assert(getNumOperands() == 1 && "Expected 1 operand in CFI instruction");
1689d39c594dSDimitry Andric 
1690044eb2f6SDimitry Andric   SmallBitVector PrintedTypes(8);
1691d8e91e46SDimitry Andric   bool ShouldPrintRegisterTies = IsStandalone || hasComplexRegisterTies();
1692044eb2f6SDimitry Andric   auto getTiedOperandIdx = [&](unsigned OpIdx) {
1693044eb2f6SDimitry Andric     if (!ShouldPrintRegisterTies)
1694044eb2f6SDimitry Andric       return 0U;
1695044eb2f6SDimitry Andric     const MachineOperand &MO = getOperand(OpIdx);
1696044eb2f6SDimitry Andric     if (MO.isReg() && MO.isTied() && !MO.isDef())
1697044eb2f6SDimitry Andric       return findTiedOperandIdx(OpIdx);
1698044eb2f6SDimitry Andric     return 0U;
1699044eb2f6SDimitry Andric   };
1700eb11fae6SDimitry Andric   unsigned StartOp = 0;
1701eb11fae6SDimitry Andric   unsigned e = getNumOperands();
1702eb11fae6SDimitry Andric 
170336bf506aSRoman Divacky   // Print explicitly defined operands on the left of an assignment syntax.
1704eb11fae6SDimitry Andric   while (StartOp < e) {
1705eb11fae6SDimitry Andric     const MachineOperand &MO = getOperand(StartOp);
1706eb11fae6SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.isImplicit())
1707eb11fae6SDimitry Andric       break;
1708eb11fae6SDimitry Andric 
1709044eb2f6SDimitry Andric     if (StartOp != 0)
1710044eb2f6SDimitry Andric       OS << ", ";
1711eb11fae6SDimitry Andric 
1712044eb2f6SDimitry Andric     LLT TypeToPrint = MRI ? getTypeToPrint(StartOp, PrintedTypes, *MRI) : LLT{};
1713044eb2f6SDimitry Andric     unsigned TiedOperandIdx = getTiedOperandIdx(StartOp);
1714706b4fc4SDimitry Andric     MO.print(OS, MST, TypeToPrint, StartOp, /*PrintDef=*/false, IsStandalone,
1715eb11fae6SDimitry Andric              ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
1716eb11fae6SDimitry Andric     ++StartOp;
1717009b1c42SEd Schouten   }
1718009b1c42SEd Schouten 
171936bf506aSRoman Divacky   if (StartOp != 0)
172036bf506aSRoman Divacky     OS << " = ";
172136bf506aSRoman Divacky 
1722eb11fae6SDimitry Andric   if (getFlag(MachineInstr::FrameSetup))
1723eb11fae6SDimitry Andric     OS << "frame-setup ";
1724eb11fae6SDimitry Andric   if (getFlag(MachineInstr::FrameDestroy))
1725eb11fae6SDimitry Andric     OS << "frame-destroy ";
1726eb11fae6SDimitry Andric   if (getFlag(MachineInstr::FmNoNans))
1727eb11fae6SDimitry Andric     OS << "nnan ";
1728eb11fae6SDimitry Andric   if (getFlag(MachineInstr::FmNoInfs))
1729eb11fae6SDimitry Andric     OS << "ninf ";
1730eb11fae6SDimitry Andric   if (getFlag(MachineInstr::FmNsz))
1731eb11fae6SDimitry Andric     OS << "nsz ";
1732eb11fae6SDimitry Andric   if (getFlag(MachineInstr::FmArcp))
1733eb11fae6SDimitry Andric     OS << "arcp ";
1734eb11fae6SDimitry Andric   if (getFlag(MachineInstr::FmContract))
1735eb11fae6SDimitry Andric     OS << "contract ";
1736eb11fae6SDimitry Andric   if (getFlag(MachineInstr::FmAfn))
1737eb11fae6SDimitry Andric     OS << "afn ";
1738eb11fae6SDimitry Andric   if (getFlag(MachineInstr::FmReassoc))
1739eb11fae6SDimitry Andric     OS << "reassoc ";
1740d8e91e46SDimitry Andric   if (getFlag(MachineInstr::NoUWrap))
1741d8e91e46SDimitry Andric     OS << "nuw ";
1742d8e91e46SDimitry Andric   if (getFlag(MachineInstr::NoSWrap))
1743d8e91e46SDimitry Andric     OS << "nsw ";
1744d8e91e46SDimitry Andric   if (getFlag(MachineInstr::IsExact))
1745d8e91e46SDimitry Andric     OS << "exact ";
1746706b4fc4SDimitry Andric   if (getFlag(MachineInstr::NoFPExcept))
1747706b4fc4SDimitry Andric     OS << "nofpexcept ";
1748cfca06d7SDimitry Andric   if (getFlag(MachineInstr::NoMerge))
1749cfca06d7SDimitry Andric     OS << "nomerge ";
1750ac9a064cSDimitry Andric   if (getFlag(MachineInstr::NonNeg))
1751ac9a064cSDimitry Andric     OS << "nneg ";
1752ac9a064cSDimitry Andric   if (getFlag(MachineInstr::Disjoint))
1753ac9a064cSDimitry Andric     OS << "disjoint ";
1754eb11fae6SDimitry Andric 
175536bf506aSRoman Divacky   // Print the opcode name.
17565a5ac124SDimitry Andric   if (TII)
17575a5ac124SDimitry Andric     OS << TII->getName(getOpcode());
175863faed5bSDimitry Andric   else
175963faed5bSDimitry Andric     OS << "UNKNOWN";
1760009b1c42SEd Schouten 
17614a16efa3SDimitry Andric   if (SkipOpers)
17624a16efa3SDimitry Andric     return;
17634a16efa3SDimitry Andric 
176436bf506aSRoman Divacky   // Print the rest of the operands.
1765907da171SRoman Divacky   bool FirstOp = true;
1766411bd29eSDimitry Andric   unsigned AsmDescOp = ~0u;
1767411bd29eSDimitry Andric   unsigned AsmOpCount = 0;
1768cf099d11SDimitry Andric 
176930815c53SDimitry Andric   if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) {
1770cf099d11SDimitry Andric     // Print asm string.
1771cf099d11SDimitry Andric     OS << " ";
1772044eb2f6SDimitry Andric     const unsigned OpIdx = InlineAsm::MIOp_AsmString;
1773044eb2f6SDimitry Andric     LLT TypeToPrint = MRI ? getTypeToPrint(OpIdx, PrintedTypes, *MRI) : LLT{};
1774044eb2f6SDimitry Andric     unsigned TiedOperandIdx = getTiedOperandIdx(OpIdx);
1775706b4fc4SDimitry Andric     getOperand(OpIdx).print(OS, MST, TypeToPrint, OpIdx, /*PrintDef=*/true, IsStandalone,
1776044eb2f6SDimitry Andric                             ShouldPrintRegisterTies, TiedOperandIdx, TRI,
1777044eb2f6SDimitry Andric                             IntrinsicInfo);
1778cf099d11SDimitry Andric 
17794a16efa3SDimitry Andric     // Print HasSideEffects, MayLoad, MayStore, IsAlignStack
1780cf099d11SDimitry Andric     unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
1781cf099d11SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
1782cf099d11SDimitry Andric       OS << " [sideeffect]";
17834a16efa3SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_MayLoad)
17844a16efa3SDimitry Andric       OS << " [mayload]";
17854a16efa3SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_MayStore)
17864a16efa3SDimitry Andric       OS << " [maystore]";
178701095a5dSDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsConvergent)
178801095a5dSDimitry Andric       OS << " [isconvergent]";
1789cf099d11SDimitry Andric     if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
1790cf099d11SDimitry Andric       OS << " [alignstack]";
1791522600a2SDimitry Andric     if (getInlineAsmDialect() == InlineAsm::AD_ATT)
1792522600a2SDimitry Andric       OS << " [attdialect]";
1793522600a2SDimitry Andric     if (getInlineAsmDialect() == InlineAsm::AD_Intel)
1794522600a2SDimitry Andric       OS << " [inteldialect]";
1795cf099d11SDimitry Andric 
1796411bd29eSDimitry Andric     StartOp = AsmDescOp = InlineAsm::MIOp_FirstOperand;
1797cf099d11SDimitry Andric     FirstOp = false;
1798cf099d11SDimitry Andric   }
1799cf099d11SDimitry Andric 
1800009b1c42SEd Schouten   for (unsigned i = StartOp, e = getNumOperands(); i != e; ++i) {
1801907da171SRoman Divacky     const MachineOperand &MO = getOperand(i);
1802907da171SRoman Divacky 
1803907da171SRoman Divacky     if (FirstOp) FirstOp = false; else OS << ",";
1804009b1c42SEd Schouten     OS << " ";
1805eb11fae6SDimitry Andric 
18067fa27ce4SDimitry Andric     if (isDebugValueLike() && MO.isMetadata()) {
1807344a3780SDimitry Andric       // Pretty print DBG_VALUE* instructions.
18085a5ac124SDimitry Andric       auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata());
18095a5ac124SDimitry Andric       if (DIV && !DIV->getName().empty())
18105a5ac124SDimitry Andric         OS << "!\"" << DIV->getName() << '\"';
1811044eb2f6SDimitry Andric       else {
1812044eb2f6SDimitry Andric         LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
1813044eb2f6SDimitry Andric         unsigned TiedOperandIdx = getTiedOperandIdx(i);
1814706b4fc4SDimitry Andric         MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone,
1815044eb2f6SDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
1816044eb2f6SDimitry Andric       }
1817eb11fae6SDimitry Andric     } else if (isDebugLabel() && MO.isMetadata()) {
1818eb11fae6SDimitry Andric       // Pretty print DBG_LABEL instructions.
1819eb11fae6SDimitry Andric       auto *DIL = dyn_cast<DILabel>(MO.getMetadata());
1820eb11fae6SDimitry Andric       if (DIL && !DIL->getName().empty())
1821eb11fae6SDimitry Andric         OS << "\"" << DIL->getName() << '\"';
1822eb11fae6SDimitry Andric       else {
1823eb11fae6SDimitry Andric         LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
1824eb11fae6SDimitry Andric         unsigned TiedOperandIdx = getTiedOperandIdx(i);
1825706b4fc4SDimitry Andric         MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone,
1826eb11fae6SDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
1827eb11fae6SDimitry Andric       }
1828411bd29eSDimitry Andric     } else if (i == AsmDescOp && MO.isImm()) {
1829411bd29eSDimitry Andric       // Pretty print the inline asm operand descriptor.
1830411bd29eSDimitry Andric       OS << '$' << AsmOpCount++;
1831411bd29eSDimitry Andric       unsigned Flag = MO.getImm();
1832b1c73532SDimitry Andric       const InlineAsm::Flag F(Flag);
1833cfca06d7SDimitry Andric       OS << ":[";
1834b1c73532SDimitry Andric       OS << F.getKindName();
183530815c53SDimitry Andric 
1836b1c73532SDimitry Andric       unsigned RCID;
1837b1c73532SDimitry Andric       if (!F.isImmKind() && !F.isMemKind() && F.hasRegClassConstraint(RCID)) {
18385a5ac124SDimitry Andric         if (TRI) {
18395a5ac124SDimitry Andric           OS << ':' << TRI->getRegClassName(TRI->getRegClass(RCID));
184067c32a98SDimitry Andric         } else
184130815c53SDimitry Andric           OS << ":RC" << RCID;
1842411bd29eSDimitry Andric       }
1843411bd29eSDimitry Andric 
1844b1c73532SDimitry Andric       if (F.isMemKind()) {
1845b1c73532SDimitry Andric         const InlineAsm::ConstraintCode MCID = F.getMemoryConstraintID();
1846cfca06d7SDimitry Andric         OS << ":" << InlineAsm::getMemConstraintName(MCID);
184701095a5dSDimitry Andric       }
184801095a5dSDimitry Andric 
1849b1c73532SDimitry Andric       unsigned TiedTo;
1850b1c73532SDimitry Andric       if (F.isUseOperandTiedToDef(TiedTo))
185130815c53SDimitry Andric         OS << " tiedto:$" << TiedTo;
185230815c53SDimitry Andric 
1853b1c73532SDimitry Andric       if ((F.isRegDefKind() || F.isRegDefEarlyClobberKind() ||
1854b1c73532SDimitry Andric            F.isRegUseKind()) &&
1855b1c73532SDimitry Andric           F.getRegMayBeFolded()) {
1856b1c73532SDimitry Andric         OS << " foldable";
1857b1c73532SDimitry Andric       }
1858b1c73532SDimitry Andric 
185930815c53SDimitry Andric       OS << ']';
1860411bd29eSDimitry Andric 
1861411bd29eSDimitry Andric       // Compute the index of the next operand descriptor.
1862b1c73532SDimitry Andric       AsmDescOp += 1 + F.getNumOperandRegisters();
1863044eb2f6SDimitry Andric     } else {
1864044eb2f6SDimitry Andric       LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{};
1865044eb2f6SDimitry Andric       unsigned TiedOperandIdx = getTiedOperandIdx(i);
1866044eb2f6SDimitry Andric       if (MO.isImm() && isOperandSubregIdx(i))
1867eb11fae6SDimitry Andric         MachineOperand::printSubRegIdx(OS, MO.getImm(), TRI);
1868044eb2f6SDimitry Andric       else
1869706b4fc4SDimitry Andric         MO.print(OS, MST, TypeToPrint, i, /*PrintDef=*/true, IsStandalone,
1870044eb2f6SDimitry Andric                  ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo);
1871044eb2f6SDimitry Andric     }
1872907da171SRoman Divacky   }
1873907da171SRoman Divacky 
1874d8e91e46SDimitry Andric   // Print any optional symbols attached to this instruction as-if they were
1875d8e91e46SDimitry Andric   // operands.
1876d8e91e46SDimitry Andric   if (MCSymbol *PreInstrSymbol = getPreInstrSymbol()) {
1877d8e91e46SDimitry Andric     if (!FirstOp) {
1878d8e91e46SDimitry Andric       FirstOp = false;
1879d8e91e46SDimitry Andric       OS << ',';
1880d8e91e46SDimitry Andric     }
1881d8e91e46SDimitry Andric     OS << " pre-instr-symbol ";
1882d8e91e46SDimitry Andric     MachineOperand::printSymbol(OS, *PreInstrSymbol);
1883d8e91e46SDimitry Andric   }
1884d8e91e46SDimitry Andric   if (MCSymbol *PostInstrSymbol = getPostInstrSymbol()) {
1885d8e91e46SDimitry Andric     if (!FirstOp) {
1886d8e91e46SDimitry Andric       FirstOp = false;
1887d8e91e46SDimitry Andric       OS << ',';
1888d8e91e46SDimitry Andric     }
1889d8e91e46SDimitry Andric     OS << " post-instr-symbol ";
1890d8e91e46SDimitry Andric     MachineOperand::printSymbol(OS, *PostInstrSymbol);
1891d8e91e46SDimitry Andric   }
1892706b4fc4SDimitry Andric   if (MDNode *HeapAllocMarker = getHeapAllocMarker()) {
1893706b4fc4SDimitry Andric     if (!FirstOp) {
1894706b4fc4SDimitry Andric       FirstOp = false;
1895706b4fc4SDimitry Andric       OS << ',';
1896706b4fc4SDimitry Andric     }
1897706b4fc4SDimitry Andric     OS << " heap-alloc-marker ";
1898706b4fc4SDimitry Andric     HeapAllocMarker->printAsOperand(OS, MST);
1899706b4fc4SDimitry Andric   }
1900e3b55780SDimitry Andric   if (MDNode *PCSections = getPCSections()) {
1901e3b55780SDimitry Andric     if (!FirstOp) {
1902e3b55780SDimitry Andric       FirstOp = false;
1903e3b55780SDimitry Andric       OS << ',';
1904e3b55780SDimitry Andric     }
1905e3b55780SDimitry Andric     OS << " pcsections ";
1906e3b55780SDimitry Andric     PCSections->printAsOperand(OS, MST);
1907e3b55780SDimitry Andric   }
1908ac9a064cSDimitry Andric   if (MDNode *MMRA = getMMRAMetadata()) {
1909ac9a064cSDimitry Andric     if (!FirstOp) {
1910ac9a064cSDimitry Andric       FirstOp = false;
1911ac9a064cSDimitry Andric       OS << ',';
1912ac9a064cSDimitry Andric     }
1913ac9a064cSDimitry Andric     OS << " mmra ";
1914ac9a064cSDimitry Andric     MMRA->printAsOperand(OS, MST);
1915ac9a064cSDimitry Andric   }
1916e3b55780SDimitry Andric   if (uint32_t CFIType = getCFIType()) {
1917e3b55780SDimitry Andric     if (!FirstOp)
1918e3b55780SDimitry Andric       OS << ',';
1919e3b55780SDimitry Andric     OS << " cfi-type " << CFIType;
1920e3b55780SDimitry Andric   }
1921d8e91e46SDimitry Andric 
1922b60736ecSDimitry Andric   if (DebugInstrNum) {
1923b60736ecSDimitry Andric     if (!FirstOp)
1924b60736ecSDimitry Andric       OS << ",";
1925b60736ecSDimitry Andric     OS << " debug-instr-number " << DebugInstrNum;
1926b60736ecSDimitry Andric   }
1927b60736ecSDimitry Andric 
1928eb11fae6SDimitry Andric   if (!SkipDebugLoc) {
1929eb11fae6SDimitry Andric     if (const DebugLoc &DL = getDebugLoc()) {
1930eb11fae6SDimitry Andric       if (!FirstOp)
1931eb11fae6SDimitry Andric         OS << ',';
1932eb11fae6SDimitry Andric       OS << " debug-location ";
1933eb11fae6SDimitry Andric       DL->printAsOperand(OS, MST);
19348a6c1c25SDimitry Andric     }
19356b943ff3SDimitry Andric   }
19366b943ff3SDimitry Andric 
1937009b1c42SEd Schouten   if (!memoperands_empty()) {
1938eb11fae6SDimitry Andric     SmallVector<StringRef, 0> SSNs;
1939eb11fae6SDimitry Andric     const LLVMContext *Context = nullptr;
1940eb11fae6SDimitry Andric     std::unique_ptr<LLVMContext> CtxPtr;
1941eb11fae6SDimitry Andric     const MachineFrameInfo *MFI = nullptr;
1942eb11fae6SDimitry Andric     if (const MachineFunction *MF = getMFIfAvailable(*this)) {
1943eb11fae6SDimitry Andric       MFI = &MF->getFrameInfo();
1944eb11fae6SDimitry Andric       Context = &MF->getFunction().getContext();
1945eb11fae6SDimitry Andric     } else {
19461d5ae102SDimitry Andric       CtxPtr = std::make_unique<LLVMContext>();
1947eb11fae6SDimitry Andric       Context = CtxPtr.get();
19488a6c1c25SDimitry Andric     }
194936bf506aSRoman Divacky 
1950eb11fae6SDimitry Andric     OS << " :: ";
1951eb11fae6SDimitry Andric     bool NeedComma = false;
1952eb11fae6SDimitry Andric     for (const MachineMemOperand *Op : memoperands()) {
1953eb11fae6SDimitry Andric       if (NeedComma)
1954eb11fae6SDimitry Andric         OS << ", ";
1955eb11fae6SDimitry Andric       Op->print(OS, MST, SSNs, *Context, MFI, TII);
1956eb11fae6SDimitry Andric       NeedComma = true;
1957009b1c42SEd Schouten     }
1958009b1c42SEd Schouten   }
1959009b1c42SEd Schouten 
1960eb11fae6SDimitry Andric   if (SkipDebugLoc)
1961eb11fae6SDimitry Andric     return;
1962eb11fae6SDimitry Andric 
1963eb11fae6SDimitry Andric   bool HaveSemi = false;
1964d39c594dSDimitry Andric 
19656b943ff3SDimitry Andric   // Print debug location information.
1966eb11fae6SDimitry Andric   if (const DebugLoc &DL = getDebugLoc()) {
1967eb11fae6SDimitry Andric     if (!HaveSemi) {
1968eb11fae6SDimitry Andric       OS << ';';
1969eb11fae6SDimitry Andric       HaveSemi = true;
1970eb11fae6SDimitry Andric     }
1971eb11fae6SDimitry Andric     OS << ' ';
1972eb11fae6SDimitry Andric     DL.print(OS);
1973eb11fae6SDimitry Andric   }
1974eb11fae6SDimitry Andric 
1975b1c73532SDimitry Andric   // Print extra comments for DEBUG_VALUE and friends if they are well-formed.
1976b1c73532SDimitry Andric   if ((isNonListDebugValue() && getNumOperands() >= 4) ||
1977b1c73532SDimitry Andric       (isDebugValueList() && getNumOperands() >= 2) ||
1978b1c73532SDimitry Andric       (isDebugRef() && getNumOperands() >= 3)) {
1979b1c73532SDimitry Andric     if (getDebugVariableOp().isMetadata()) {
1980eb11fae6SDimitry Andric       if (!HaveSemi) {
19818a6c1c25SDimitry Andric         OS << ";";
1982eb11fae6SDimitry Andric         HaveSemi = true;
1983eb11fae6SDimitry Andric       }
1984cfca06d7SDimitry Andric       auto *DV = getDebugVariable();
19855a5ac124SDimitry Andric       OS << " line no:" << DV->getLine();
198667c32a98SDimitry Andric       if (isIndirectDebugValue())
198767c32a98SDimitry Andric         OS << " indirect";
1988009b1c42SEd Schouten     }
1989b1c73532SDimitry Andric   }
1990eb11fae6SDimitry Andric   // TODO: DBG_LABEL
1991009b1c42SEd Schouten 
1992eb11fae6SDimitry Andric   if (AddNewLine)
19936b943ff3SDimitry Andric     OS << '\n';
1994009b1c42SEd Schouten }
1995009b1c42SEd Schouten 
addRegisterKilled(Register IncomingReg,const TargetRegisterInfo * RegInfo,bool AddIfNotFound)19961d5ae102SDimitry Andric bool MachineInstr::addRegisterKilled(Register IncomingReg,
1997009b1c42SEd Schouten                                      const TargetRegisterInfo *RegInfo,
1998009b1c42SEd Schouten                                      bool AddIfNotFound) {
1999e3b55780SDimitry Andric   bool isPhysReg = IncomingReg.isPhysical();
200058b69754SDimitry Andric   bool hasAliases = isPhysReg &&
200158b69754SDimitry Andric     MCRegAliasIterator(IncomingReg, RegInfo, false).isValid();
2002009b1c42SEd Schouten   bool Found = false;
2003009b1c42SEd Schouten   SmallVector<unsigned,4> DeadOps;
2004009b1c42SEd Schouten   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
2005009b1c42SEd Schouten     MachineOperand &MO = getOperand(i);
200659850d08SRoman Divacky     if (!MO.isReg() || !MO.isUse() || MO.isUndef())
2007009b1c42SEd Schouten       continue;
200801095a5dSDimitry Andric 
200901095a5dSDimitry Andric     // DEBUG_VALUE nodes do not contribute to code generation and should
201001095a5dSDimitry Andric     // always be ignored. Failure to do so may result in trying to modify
201101095a5dSDimitry Andric     // KILL flags on DEBUG_VALUE nodes.
201201095a5dSDimitry Andric     if (MO.isDebug())
201301095a5dSDimitry Andric       continue;
201401095a5dSDimitry Andric 
20151d5ae102SDimitry Andric     Register Reg = MO.getReg();
2016009b1c42SEd Schouten     if (!Reg)
2017009b1c42SEd Schouten       continue;
2018009b1c42SEd Schouten 
2019009b1c42SEd Schouten     if (Reg == IncomingReg) {
2020009b1c42SEd Schouten       if (!Found) {
2021009b1c42SEd Schouten         if (MO.isKill())
2022009b1c42SEd Schouten           // The register is already marked kill.
2023009b1c42SEd Schouten           return true;
202459850d08SRoman Divacky         if (isPhysReg && isRegTiedToDefOperand(i))
202559850d08SRoman Divacky           // Two-address uses of physregs must not be marked kill.
202659850d08SRoman Divacky           return true;
2027009b1c42SEd Schouten         MO.setIsKill();
2028009b1c42SEd Schouten         Found = true;
2029009b1c42SEd Schouten       }
2030e3b55780SDimitry Andric     } else if (hasAliases && MO.isKill() && Reg.isPhysical()) {
2031009b1c42SEd Schouten       // A super-register kill already exists.
2032009b1c42SEd Schouten       if (RegInfo->isSuperRegister(IncomingReg, Reg))
2033009b1c42SEd Schouten         return true;
2034009b1c42SEd Schouten       if (RegInfo->isSubRegister(IncomingReg, Reg))
2035009b1c42SEd Schouten         DeadOps.push_back(i);
2036009b1c42SEd Schouten     }
2037009b1c42SEd Schouten   }
2038009b1c42SEd Schouten 
2039009b1c42SEd Schouten   // Trim unneeded kill operands.
2040009b1c42SEd Schouten   while (!DeadOps.empty()) {
2041009b1c42SEd Schouten     unsigned OpIdx = DeadOps.back();
2042d8e91e46SDimitry Andric     if (getOperand(OpIdx).isImplicit() &&
2043d8e91e46SDimitry Andric         (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0))
2044145449b1SDimitry Andric       removeOperand(OpIdx);
2045009b1c42SEd Schouten     else
2046009b1c42SEd Schouten       getOperand(OpIdx).setIsKill(false);
2047009b1c42SEd Schouten     DeadOps.pop_back();
2048009b1c42SEd Schouten   }
2049009b1c42SEd Schouten 
2050009b1c42SEd Schouten   // If not found, this means an alias of one of the operands is killed. Add a
2051009b1c42SEd Schouten   // new implicit operand if required.
2052009b1c42SEd Schouten   if (!Found && AddIfNotFound) {
2053009b1c42SEd Schouten     addOperand(MachineOperand::CreateReg(IncomingReg,
2054009b1c42SEd Schouten                                          false /*IsDef*/,
2055009b1c42SEd Schouten                                          true  /*IsImp*/,
2056009b1c42SEd Schouten                                          true  /*IsKill*/));
2057009b1c42SEd Schouten     return true;
2058009b1c42SEd Schouten   }
2059009b1c42SEd Schouten   return Found;
2060009b1c42SEd Schouten }
2061009b1c42SEd Schouten 
clearRegisterKills(Register Reg,const TargetRegisterInfo * RegInfo)20621d5ae102SDimitry Andric void MachineInstr::clearRegisterKills(Register Reg,
206363faed5bSDimitry Andric                                       const TargetRegisterInfo *RegInfo) {
2064e3b55780SDimitry Andric   if (!Reg.isPhysical())
20655ca98fd9SDimitry Andric     RegInfo = nullptr;
20665a5ac124SDimitry Andric   for (MachineOperand &MO : operands()) {
206763faed5bSDimitry Andric     if (!MO.isReg() || !MO.isUse() || !MO.isKill())
206863faed5bSDimitry Andric       continue;
20691d5ae102SDimitry Andric     Register OpReg = MO.getReg();
207001095a5dSDimitry Andric     if ((RegInfo && RegInfo->regsOverlap(Reg, OpReg)) || Reg == OpReg)
207163faed5bSDimitry Andric       MO.setIsKill(false);
207263faed5bSDimitry Andric   }
207363faed5bSDimitry Andric }
207463faed5bSDimitry Andric 
addRegisterDead(Register Reg,const TargetRegisterInfo * RegInfo,bool AddIfNotFound)20751d5ae102SDimitry Andric bool MachineInstr::addRegisterDead(Register Reg,
2076009b1c42SEd Schouten                                    const TargetRegisterInfo *RegInfo,
2077009b1c42SEd Schouten                                    bool AddIfNotFound) {
2078e3b55780SDimitry Andric   bool isPhysReg = Reg.isPhysical();
207958b69754SDimitry Andric   bool hasAliases = isPhysReg &&
2080f8af5cf6SDimitry Andric     MCRegAliasIterator(Reg, RegInfo, false).isValid();
2081009b1c42SEd Schouten   bool Found = false;
2082009b1c42SEd Schouten   SmallVector<unsigned,4> DeadOps;
2083009b1c42SEd Schouten   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
2084009b1c42SEd Schouten     MachineOperand &MO = getOperand(i);
2085009b1c42SEd Schouten     if (!MO.isReg() || !MO.isDef())
2086009b1c42SEd Schouten       continue;
20871d5ae102SDimitry Andric     Register MOReg = MO.getReg();
2088f8af5cf6SDimitry Andric     if (!MOReg)
2089009b1c42SEd Schouten       continue;
2090009b1c42SEd Schouten 
2091f8af5cf6SDimitry Andric     if (MOReg == Reg) {
2092009b1c42SEd Schouten       MO.setIsDead();
2093009b1c42SEd Schouten       Found = true;
2094e3b55780SDimitry Andric     } else if (hasAliases && MO.isDead() && MOReg.isPhysical()) {
2095009b1c42SEd Schouten       // There exists a super-register that's marked dead.
2096f8af5cf6SDimitry Andric       if (RegInfo->isSuperRegister(Reg, MOReg))
2097009b1c42SEd Schouten         return true;
2098f8af5cf6SDimitry Andric       if (RegInfo->isSubRegister(Reg, MOReg))
2099009b1c42SEd Schouten         DeadOps.push_back(i);
2100009b1c42SEd Schouten     }
2101009b1c42SEd Schouten   }
2102009b1c42SEd Schouten 
2103009b1c42SEd Schouten   // Trim unneeded dead operands.
2104009b1c42SEd Schouten   while (!DeadOps.empty()) {
2105009b1c42SEd Schouten     unsigned OpIdx = DeadOps.back();
2106d8e91e46SDimitry Andric     if (getOperand(OpIdx).isImplicit() &&
2107d8e91e46SDimitry Andric         (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0))
2108145449b1SDimitry Andric       removeOperand(OpIdx);
2109009b1c42SEd Schouten     else
2110009b1c42SEd Schouten       getOperand(OpIdx).setIsDead(false);
2111009b1c42SEd Schouten     DeadOps.pop_back();
2112009b1c42SEd Schouten   }
2113009b1c42SEd Schouten 
2114009b1c42SEd Schouten   // If not found, this means an alias of one of the operands is dead. Add a
2115009b1c42SEd Schouten   // new implicit operand if required.
2116f859468fSEd Schouten   if (Found || !AddIfNotFound)
2117f859468fSEd Schouten     return Found;
2118f859468fSEd Schouten 
2119f8af5cf6SDimitry Andric   addOperand(MachineOperand::CreateReg(Reg,
2120009b1c42SEd Schouten                                        true  /*IsDef*/,
2121009b1c42SEd Schouten                                        true  /*IsImp*/,
2122009b1c42SEd Schouten                                        false /*IsKill*/,
2123009b1c42SEd Schouten                                        true  /*IsDead*/));
2124009b1c42SEd Schouten   return true;
2125009b1c42SEd Schouten }
2126829000e0SRoman Divacky 
clearRegisterDeads(Register Reg)21271d5ae102SDimitry Andric void MachineInstr::clearRegisterDeads(Register Reg) {
21285a5ac124SDimitry Andric   for (MachineOperand &MO : operands()) {
21295a5ac124SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg)
21305a5ac124SDimitry Andric       continue;
21315a5ac124SDimitry Andric     MO.setIsDead(false);
21325a5ac124SDimitry Andric   }
21335a5ac124SDimitry Andric }
21345a5ac124SDimitry Andric 
setRegisterDefReadUndef(Register Reg,bool IsUndef)21351d5ae102SDimitry Andric void MachineInstr::setRegisterDefReadUndef(Register Reg, bool IsUndef) {
21365a5ac124SDimitry Andric   for (MachineOperand &MO : operands()) {
21375a5ac124SDimitry Andric     if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0)
21385a5ac124SDimitry Andric       continue;
2139dd58ef01SDimitry Andric     MO.setIsUndef(IsUndef);
21405a5ac124SDimitry Andric   }
21415a5ac124SDimitry Andric }
21425a5ac124SDimitry Andric 
addRegisterDefined(Register Reg,const TargetRegisterInfo * RegInfo)21431d5ae102SDimitry Andric void MachineInstr::addRegisterDefined(Register Reg,
2144829000e0SRoman Divacky                                       const TargetRegisterInfo *RegInfo) {
2145e3b55780SDimitry Andric   if (Reg.isPhysical()) {
2146ac9a064cSDimitry Andric     MachineOperand *MO = findRegisterDefOperand(Reg, RegInfo, false, false);
2147abdf259dSRoman Divacky     if (MO)
2148abdf259dSRoman Divacky       return;
2149abdf259dSRoman Divacky   } else {
21505a5ac124SDimitry Andric     for (const MachineOperand &MO : operands()) {
2151f8af5cf6SDimitry Andric       if (MO.isReg() && MO.getReg() == Reg && MO.isDef() &&
2152abdf259dSRoman Divacky           MO.getSubReg() == 0)
2153abdf259dSRoman Divacky         return;
2154abdf259dSRoman Divacky     }
2155abdf259dSRoman Divacky   }
2156f8af5cf6SDimitry Andric   addOperand(MachineOperand::CreateReg(Reg,
2157829000e0SRoman Divacky                                        true  /*IsDef*/,
2158829000e0SRoman Divacky                                        true  /*IsImp*/));
2159829000e0SRoman Divacky }
2160f5a3459aSRoman Divacky 
setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs,const TargetRegisterInfo & TRI)21611d5ae102SDimitry Andric void MachineInstr::setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs,
216266e41e3cSRoman Divacky                                          const TargetRegisterInfo &TRI) {
216363faed5bSDimitry Andric   bool HasRegMask = false;
21645a5ac124SDimitry Andric   for (MachineOperand &MO : operands()) {
216563faed5bSDimitry Andric     if (MO.isRegMask()) {
216663faed5bSDimitry Andric       HasRegMask = true;
216763faed5bSDimitry Andric       continue;
216863faed5bSDimitry Andric     }
216966e41e3cSRoman Divacky     if (!MO.isReg() || !MO.isDef()) continue;
21701d5ae102SDimitry Andric     Register Reg = MO.getReg();
21711d5ae102SDimitry Andric     if (!Reg.isPhysical())
21721d5ae102SDimitry Andric       continue;
217366e41e3cSRoman Divacky     // If there are no uses, including partial uses, the def is dead.
2174f382538dSDimitry Andric     if (llvm::none_of(UsedRegs,
21751d5ae102SDimitry Andric                       [&](MCRegister Use) { return TRI.regsOverlap(Use, Reg); }))
21765a5ac124SDimitry Andric       MO.setIsDead();
217766e41e3cSRoman Divacky   }
217863faed5bSDimitry Andric 
217963faed5bSDimitry Andric   // This is a call with a register mask operand.
218063faed5bSDimitry Andric   // Mask clobbers are always dead, so add defs for the non-dead defines.
218163faed5bSDimitry Andric   if (HasRegMask)
2182344a3780SDimitry Andric     for (const Register &UsedReg : UsedRegs)
2183344a3780SDimitry Andric       addRegisterDefined(UsedReg, &TRI);
218466e41e3cSRoman Divacky }
218566e41e3cSRoman Divacky 
2186f5a3459aSRoman Divacky unsigned
getHashValue(const MachineInstr * const & MI)2187f5a3459aSRoman Divacky MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) {
218863faed5bSDimitry Andric   // Build up a buffer of hash code components.
2189706b4fc4SDimitry Andric   SmallVector<size_t, 16> HashComponents;
219063faed5bSDimitry Andric   HashComponents.reserve(MI->getNumOperands() + 1);
219163faed5bSDimitry Andric   HashComponents.push_back(MI->getOpcode());
21925a5ac124SDimitry Andric   for (const MachineOperand &MO : MI->operands()) {
2193e3b55780SDimitry Andric     if (MO.isReg() && MO.isDef() && MO.getReg().isVirtual())
2194f5a3459aSRoman Divacky       continue;  // Skip virtual register defs.
219558b69754SDimitry Andric 
219658b69754SDimitry Andric     HashComponents.push_back(hash_value(MO));
2197f5a3459aSRoman Divacky   }
219863faed5bSDimitry Andric   return hash_combine_range(HashComponents.begin(), HashComponents.end());
2199f5a3459aSRoman Divacky }
2200411bd29eSDimitry Andric 
emitError(StringRef Msg) const2201411bd29eSDimitry Andric void MachineInstr::emitError(StringRef Msg) const {
2202411bd29eSDimitry Andric   // Find the source location cookie.
2203344a3780SDimitry Andric   uint64_t LocCookie = 0;
22045ca98fd9SDimitry Andric   const MDNode *LocMD = nullptr;
2205411bd29eSDimitry Andric   for (unsigned i = getNumOperands(); i != 0; --i) {
2206411bd29eSDimitry Andric     if (getOperand(i-1).isMetadata() &&
2207411bd29eSDimitry Andric         (LocMD = getOperand(i-1).getMetadata()) &&
2208411bd29eSDimitry Andric         LocMD->getNumOperands() != 0) {
220967c32a98SDimitry Andric       if (const ConstantInt *CI =
221067c32a98SDimitry Andric               mdconst::dyn_extract<ConstantInt>(LocMD->getOperand(0))) {
2211411bd29eSDimitry Andric         LocCookie = CI->getZExtValue();
2212411bd29eSDimitry Andric         break;
2213411bd29eSDimitry Andric       }
2214411bd29eSDimitry Andric     }
2215411bd29eSDimitry Andric   }
2216411bd29eSDimitry Andric 
2217411bd29eSDimitry Andric   if (const MachineBasicBlock *MBB = getParent())
2218411bd29eSDimitry Andric     if (const MachineFunction *MF = MBB->getParent())
2219ac9a064cSDimitry Andric       return MF->getFunction().getContext().emitError(LocCookie, Msg);
2220411bd29eSDimitry Andric   report_fatal_error(Msg);
2221411bd29eSDimitry Andric }
222201095a5dSDimitry Andric 
BuildMI(MachineFunction & MF,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,Register Reg,const MDNode * Variable,const MDNode * Expr)222301095a5dSDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
222401095a5dSDimitry Andric                                   const MCInstrDesc &MCID, bool IsIndirect,
22251d5ae102SDimitry Andric                                   Register Reg, const MDNode *Variable,
2226044eb2f6SDimitry Andric                                   const MDNode *Expr) {
222701095a5dSDimitry Andric   assert(isa<DILocalVariable>(Variable) && "not a variable");
222801095a5dSDimitry Andric   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
222901095a5dSDimitry Andric   assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
223001095a5dSDimitry Andric          "Expected inlined-at fields to agree");
2231c0981da4SDimitry Andric   auto MIB = BuildMI(MF, DL, MCID).addReg(Reg);
223201095a5dSDimitry Andric   if (IsIndirect)
2233eb11fae6SDimitry Andric     MIB.addImm(0U);
2234044eb2f6SDimitry Andric   else
2235c0981da4SDimitry Andric     MIB.addReg(0U);
2236eb11fae6SDimitry Andric   return MIB.addMetadata(Variable).addMetadata(Expr);
2237eb11fae6SDimitry Andric }
2238eb11fae6SDimitry Andric 
BuildMI(MachineFunction & MF,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,ArrayRef<MachineOperand> DebugOps,const MDNode * Variable,const MDNode * Expr)2239eb11fae6SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,
2240eb11fae6SDimitry Andric                                   const MCInstrDesc &MCID, bool IsIndirect,
2241e3b55780SDimitry Andric                                   ArrayRef<MachineOperand> DebugOps,
2242344a3780SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
2243eb11fae6SDimitry Andric   assert(isa<DILocalVariable>(Variable) && "not a variable");
2244eb11fae6SDimitry Andric   assert(cast<DIExpression>(Expr)->isValid() && "not an expression");
2245eb11fae6SDimitry Andric   assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) &&
2246eb11fae6SDimitry Andric          "Expected inlined-at fields to agree");
2247e3b55780SDimitry Andric   if (MCID.Opcode == TargetOpcode::DBG_VALUE) {
2248e3b55780SDimitry Andric     assert(DebugOps.size() == 1 &&
2249e3b55780SDimitry Andric            "DBG_VALUE must contain exactly one debug operand");
2250e3b55780SDimitry Andric     MachineOperand DebugOp = DebugOps[0];
2251e3b55780SDimitry Andric     if (DebugOp.isReg())
2252e3b55780SDimitry Andric       return BuildMI(MF, DL, MCID, IsIndirect, DebugOp.getReg(), Variable,
2253e3b55780SDimitry Andric                      Expr);
2254eb11fae6SDimitry Andric 
2255e3b55780SDimitry Andric     auto MIB = BuildMI(MF, DL, MCID).add(DebugOp);
2256eb11fae6SDimitry Andric     if (IsIndirect)
2257eb11fae6SDimitry Andric       MIB.addImm(0U);
2258eb11fae6SDimitry Andric     else
2259c0981da4SDimitry Andric       MIB.addReg(0U);
2260eb11fae6SDimitry Andric     return MIB.addMetadata(Variable).addMetadata(Expr);
226101095a5dSDimitry Andric   }
226201095a5dSDimitry Andric 
2263344a3780SDimitry Andric   auto MIB = BuildMI(MF, DL, MCID);
2264344a3780SDimitry Andric   MIB.addMetadata(Variable).addMetadata(Expr);
2265e3b55780SDimitry Andric   for (const MachineOperand &DebugOp : DebugOps)
2266e3b55780SDimitry Andric     if (DebugOp.isReg())
2267e3b55780SDimitry Andric       MIB.addReg(DebugOp.getReg());
2268344a3780SDimitry Andric     else
2269e3b55780SDimitry Andric       MIB.add(DebugOp);
2270344a3780SDimitry Andric   return MIB;
2271344a3780SDimitry Andric }
2272344a3780SDimitry Andric 
BuildMI(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,Register Reg,const MDNode * Variable,const MDNode * Expr)227301095a5dSDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
227401095a5dSDimitry Andric                                   MachineBasicBlock::iterator I,
227501095a5dSDimitry Andric                                   const DebugLoc &DL, const MCInstrDesc &MCID,
22761d5ae102SDimitry Andric                                   bool IsIndirect, Register Reg,
2277044eb2f6SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
227801095a5dSDimitry Andric   MachineFunction &MF = *BB.getParent();
2279044eb2f6SDimitry Andric   MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Variable, Expr);
228001095a5dSDimitry Andric   BB.insert(I, MI);
228101095a5dSDimitry Andric   return MachineInstrBuilder(MF, MI);
228201095a5dSDimitry Andric }
2283d99dafe2SDimitry Andric 
BuildMI(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const DebugLoc & DL,const MCInstrDesc & MCID,bool IsIndirect,ArrayRef<MachineOperand> DebugOps,const MDNode * Variable,const MDNode * Expr)2284eb11fae6SDimitry Andric MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,
2285eb11fae6SDimitry Andric                                   MachineBasicBlock::iterator I,
2286eb11fae6SDimitry Andric                                   const DebugLoc &DL, const MCInstrDesc &MCID,
2287e3b55780SDimitry Andric                                   bool IsIndirect,
2288e3b55780SDimitry Andric                                   ArrayRef<MachineOperand> DebugOps,
2289eb11fae6SDimitry Andric                                   const MDNode *Variable, const MDNode *Expr) {
2290eb11fae6SDimitry Andric   MachineFunction &MF = *BB.getParent();
2291e3b55780SDimitry Andric   MachineInstr *MI =
2292e3b55780SDimitry Andric       BuildMI(MF, DL, MCID, IsIndirect, DebugOps, Variable, Expr);
2293344a3780SDimitry Andric   BB.insert(I, MI);
2294344a3780SDimitry Andric   return MachineInstrBuilder(MF, *MI);
2295344a3780SDimitry Andric }
2296344a3780SDimitry Andric 
2297044eb2f6SDimitry Andric /// Compute the new DIExpression to use with a DBG_VALUE for a spill slot.
2298044eb2f6SDimitry Andric /// This prepends DW_OP_deref when spilling an indirect DBG_VALUE.
2299344a3780SDimitry Andric static const DIExpression *
computeExprForSpill(const MachineInstr & MI,SmallVectorImpl<const MachineOperand * > & SpilledOperands)2300344a3780SDimitry Andric computeExprForSpill(const MachineInstr &MI,
2301344a3780SDimitry Andric                     SmallVectorImpl<const MachineOperand *> &SpilledOperands) {
2302044eb2f6SDimitry Andric   assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
2303044eb2f6SDimitry Andric          "Expected inlined-at fields to agree");
2304044eb2f6SDimitry Andric 
2305044eb2f6SDimitry Andric   const DIExpression *Expr = MI.getDebugExpression();
2306044eb2f6SDimitry Andric   if (MI.isIndirectDebugValue()) {
2307cfca06d7SDimitry Andric     assert(MI.getDebugOffset().getImm() == 0 &&
2308cfca06d7SDimitry Andric            "DBG_VALUE with nonzero offset");
2309e6d15924SDimitry Andric     Expr = DIExpression::prepend(Expr, DIExpression::DerefBefore);
2310344a3780SDimitry Andric   } else if (MI.isDebugValueList()) {
2311344a3780SDimitry Andric     // We will replace the spilled register with a frame index, so
2312344a3780SDimitry Andric     // immediately deref all references to the spilled register.
2313344a3780SDimitry Andric     std::array<uint64_t, 1> Ops{{dwarf::DW_OP_deref}};
2314344a3780SDimitry Andric     for (const MachineOperand *Op : SpilledOperands) {
2315344a3780SDimitry Andric       unsigned OpIdx = MI.getDebugOperandIndex(Op);
2316344a3780SDimitry Andric       Expr = DIExpression::appendOpsToArg(Expr, Ops, OpIdx);
2317344a3780SDimitry Andric     }
2318044eb2f6SDimitry Andric   }
2319044eb2f6SDimitry Andric   return Expr;
2320044eb2f6SDimitry Andric }
computeExprForSpill(const MachineInstr & MI,Register SpillReg)2321344a3780SDimitry Andric static const DIExpression *computeExprForSpill(const MachineInstr &MI,
2322344a3780SDimitry Andric                                                Register SpillReg) {
2323344a3780SDimitry Andric   assert(MI.hasDebugOperandForReg(SpillReg) && "Spill Reg is not used in MI.");
2324344a3780SDimitry Andric   SmallVector<const MachineOperand *> SpillOperands;
2325344a3780SDimitry Andric   for (const MachineOperand &Op : MI.getDebugOperandsForReg(SpillReg))
2326344a3780SDimitry Andric     SpillOperands.push_back(&Op);
2327344a3780SDimitry Andric   return computeExprForSpill(MI, SpillOperands);
2328344a3780SDimitry Andric }
2329044eb2f6SDimitry Andric 
buildDbgValueForSpill(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const MachineInstr & Orig,int FrameIndex,Register SpillReg)2330d99dafe2SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB,
2331d99dafe2SDimitry Andric                                           MachineBasicBlock::iterator I,
2332d99dafe2SDimitry Andric                                           const MachineInstr &Orig,
2333344a3780SDimitry Andric                                           int FrameIndex, Register SpillReg) {
2334e3b55780SDimitry Andric   assert(!Orig.isDebugRef() &&
2335e3b55780SDimitry Andric          "DBG_INSTR_REF should not reference a virtual register.");
2336344a3780SDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig, SpillReg);
2337344a3780SDimitry Andric   MachineInstrBuilder NewMI =
2338344a3780SDimitry Andric       BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc());
2339344a3780SDimitry Andric   // Non-Variadic Operands: Location, Offset, Variable, Expression
2340344a3780SDimitry Andric   // Variadic Operands:     Variable, Expression, Locations...
2341344a3780SDimitry Andric   if (Orig.isNonListDebugValue())
2342344a3780SDimitry Andric     NewMI.addFrameIndex(FrameIndex).addImm(0U);
2343344a3780SDimitry Andric   NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr);
2344344a3780SDimitry Andric   if (Orig.isDebugValueList()) {
2345344a3780SDimitry Andric     for (const MachineOperand &Op : Orig.debug_operands())
2346344a3780SDimitry Andric       if (Op.isReg() && Op.getReg() == SpillReg)
2347344a3780SDimitry Andric         NewMI.addFrameIndex(FrameIndex);
2348344a3780SDimitry Andric       else
2349344a3780SDimitry Andric         NewMI.add(MachineOperand(Op));
2350344a3780SDimitry Andric   }
2351344a3780SDimitry Andric   return NewMI;
2352344a3780SDimitry Andric }
buildDbgValueForSpill(MachineBasicBlock & BB,MachineBasicBlock::iterator I,const MachineInstr & Orig,int FrameIndex,SmallVectorImpl<const MachineOperand * > & SpilledOperands)2353344a3780SDimitry Andric MachineInstr *llvm::buildDbgValueForSpill(
2354344a3780SDimitry Andric     MachineBasicBlock &BB, MachineBasicBlock::iterator I,
2355344a3780SDimitry Andric     const MachineInstr &Orig, int FrameIndex,
2356344a3780SDimitry Andric     SmallVectorImpl<const MachineOperand *> &SpilledOperands) {
2357344a3780SDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig, SpilledOperands);
2358344a3780SDimitry Andric   MachineInstrBuilder NewMI =
2359344a3780SDimitry Andric       BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc());
2360344a3780SDimitry Andric   // Non-Variadic Operands: Location, Offset, Variable, Expression
2361344a3780SDimitry Andric   // Variadic Operands:     Variable, Expression, Locations...
2362344a3780SDimitry Andric   if (Orig.isNonListDebugValue())
2363344a3780SDimitry Andric     NewMI.addFrameIndex(FrameIndex).addImm(0U);
2364344a3780SDimitry Andric   NewMI.addMetadata(Orig.getDebugVariable()).addMetadata(Expr);
2365344a3780SDimitry Andric   if (Orig.isDebugValueList()) {
2366344a3780SDimitry Andric     for (const MachineOperand &Op : Orig.debug_operands())
2367344a3780SDimitry Andric       if (is_contained(SpilledOperands, &Op))
2368344a3780SDimitry Andric         NewMI.addFrameIndex(FrameIndex);
2369344a3780SDimitry Andric       else
2370344a3780SDimitry Andric         NewMI.add(MachineOperand(Op));
2371344a3780SDimitry Andric   }
2372344a3780SDimitry Andric   return NewMI;
2373d99dafe2SDimitry Andric }
2374044eb2f6SDimitry Andric 
updateDbgValueForSpill(MachineInstr & Orig,int FrameIndex,Register Reg)2375344a3780SDimitry Andric void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex,
2376344a3780SDimitry Andric                                   Register Reg) {
2377344a3780SDimitry Andric   const DIExpression *Expr = computeExprForSpill(Orig, Reg);
2378344a3780SDimitry Andric   if (Orig.isNonListDebugValue())
2379cfca06d7SDimitry Andric     Orig.getDebugOffset().ChangeToImmediate(0U);
2380344a3780SDimitry Andric   for (MachineOperand &Op : Orig.getDebugOperandsForReg(Reg))
2381344a3780SDimitry Andric     Op.ChangeToFrameIndex(FrameIndex);
2382cfca06d7SDimitry Andric   Orig.getDebugExpressionOp().setMetadata(Expr);
2383044eb2f6SDimitry Andric }
2384d8e91e46SDimitry Andric 
collectDebugValues(SmallVectorImpl<MachineInstr * > & DbgValues)2385d8e91e46SDimitry Andric void MachineInstr::collectDebugValues(
2386d8e91e46SDimitry Andric                                 SmallVectorImpl<MachineInstr *> &DbgValues) {
2387d8e91e46SDimitry Andric   MachineInstr &MI = *this;
2388d8e91e46SDimitry Andric   if (!MI.getOperand(0).isReg())
2389d8e91e46SDimitry Andric     return;
2390d8e91e46SDimitry Andric 
2391d8e91e46SDimitry Andric   MachineBasicBlock::iterator DI = MI; ++DI;
2392d8e91e46SDimitry Andric   for (MachineBasicBlock::iterator DE = MI.getParent()->end();
2393d8e91e46SDimitry Andric        DI != DE; ++DI) {
2394d8e91e46SDimitry Andric     if (!DI->isDebugValue())
2395d8e91e46SDimitry Andric       return;
2396344a3780SDimitry Andric     if (DI->hasDebugOperandForReg(MI.getOperand(0).getReg()))
2397d8e91e46SDimitry Andric       DbgValues.push_back(&*DI);
2398d8e91e46SDimitry Andric   }
2399d8e91e46SDimitry Andric }
2400d8e91e46SDimitry Andric 
changeDebugValuesDefReg(Register Reg)24011d5ae102SDimitry Andric void MachineInstr::changeDebugValuesDefReg(Register Reg) {
2402d8e91e46SDimitry Andric   // Collect matching debug values.
2403d8e91e46SDimitry Andric   SmallVector<MachineInstr *, 2> DbgValues;
24041d5ae102SDimitry Andric 
24051d5ae102SDimitry Andric   if (!getOperand(0).isReg())
24061d5ae102SDimitry Andric     return;
24071d5ae102SDimitry Andric 
2408cfca06d7SDimitry Andric   Register DefReg = getOperand(0).getReg();
24091d5ae102SDimitry Andric   auto *MRI = getRegInfo();
24101d5ae102SDimitry Andric   for (auto &MO : MRI->use_operands(DefReg)) {
24111d5ae102SDimitry Andric     auto *DI = MO.getParent();
24121d5ae102SDimitry Andric     if (!DI->isDebugValue())
24131d5ae102SDimitry Andric       continue;
2414344a3780SDimitry Andric     if (DI->hasDebugOperandForReg(DefReg)) {
24151d5ae102SDimitry Andric       DbgValues.push_back(DI);
24161d5ae102SDimitry Andric     }
24171d5ae102SDimitry Andric   }
2418d8e91e46SDimitry Andric 
2419d8e91e46SDimitry Andric   // Propagate Reg to debug value instructions.
2420d8e91e46SDimitry Andric   for (auto *DBI : DbgValues)
2421344a3780SDimitry Andric     for (MachineOperand &Op : DBI->getDebugOperandsForReg(DefReg))
2422344a3780SDimitry Andric       Op.setReg(Reg);
2423d8e91e46SDimitry Andric }
2424e6d15924SDimitry Andric 
2425e6d15924SDimitry Andric using MMOList = SmallVector<const MachineMemOperand *, 2>;
2426e6d15924SDimitry Andric 
getSpillSlotSize(const MMOList & Accesses,const MachineFrameInfo & MFI)2427ac9a064cSDimitry Andric static LocationSize getSpillSlotSize(const MMOList &Accesses,
2428e6d15924SDimitry Andric                                      const MachineFrameInfo &MFI) {
2429ac9a064cSDimitry Andric   uint64_t Size = 0;
2430ac9a064cSDimitry Andric   for (const auto *A : Accesses) {
2431e6d15924SDimitry Andric     if (MFI.isSpillSlotObjectIndex(
2432e6d15924SDimitry Andric             cast<FixedStackPseudoSourceValue>(A->getPseudoValue())
2433ac9a064cSDimitry Andric                 ->getFrameIndex())) {
2434ac9a064cSDimitry Andric       LocationSize S = A->getSize();
2435ac9a064cSDimitry Andric       if (!S.hasValue())
2436ac9a064cSDimitry Andric         return LocationSize::beforeOrAfterPointer();
2437ac9a064cSDimitry Andric       Size += S.getValue();
2438ac9a064cSDimitry Andric     }
2439ac9a064cSDimitry Andric   }
2440e6d15924SDimitry Andric   return Size;
2441e6d15924SDimitry Andric }
2442e6d15924SDimitry Andric 
2443ac9a064cSDimitry Andric std::optional<LocationSize>
getSpillSize(const TargetInstrInfo * TII) const2444e6d15924SDimitry Andric MachineInstr::getSpillSize(const TargetInstrInfo *TII) const {
2445e6d15924SDimitry Andric   int FI;
2446e6d15924SDimitry Andric   if (TII->isStoreToStackSlotPostFE(*this, FI)) {
2447e6d15924SDimitry Andric     const MachineFrameInfo &MFI = getMF()->getFrameInfo();
2448e6d15924SDimitry Andric     if (MFI.isSpillSlotObjectIndex(FI))
2449e6d15924SDimitry Andric       return (*memoperands_begin())->getSize();
2450e6d15924SDimitry Andric   }
2451e3b55780SDimitry Andric   return std::nullopt;
2452e6d15924SDimitry Andric }
2453e6d15924SDimitry Andric 
2454ac9a064cSDimitry Andric std::optional<LocationSize>
getFoldedSpillSize(const TargetInstrInfo * TII) const2455e6d15924SDimitry Andric MachineInstr::getFoldedSpillSize(const TargetInstrInfo *TII) const {
2456e6d15924SDimitry Andric   MMOList Accesses;
2457e6d15924SDimitry Andric   if (TII->hasStoreToStackSlot(*this, Accesses))
2458e6d15924SDimitry Andric     return getSpillSlotSize(Accesses, getMF()->getFrameInfo());
2459e3b55780SDimitry Andric   return std::nullopt;
2460e6d15924SDimitry Andric }
2461e6d15924SDimitry Andric 
2462ac9a064cSDimitry Andric std::optional<LocationSize>
getRestoreSize(const TargetInstrInfo * TII) const2463e6d15924SDimitry Andric MachineInstr::getRestoreSize(const TargetInstrInfo *TII) const {
2464e6d15924SDimitry Andric   int FI;
2465e6d15924SDimitry Andric   if (TII->isLoadFromStackSlotPostFE(*this, FI)) {
2466e6d15924SDimitry Andric     const MachineFrameInfo &MFI = getMF()->getFrameInfo();
2467e6d15924SDimitry Andric     if (MFI.isSpillSlotObjectIndex(FI))
2468e6d15924SDimitry Andric       return (*memoperands_begin())->getSize();
2469e6d15924SDimitry Andric   }
2470e3b55780SDimitry Andric   return std::nullopt;
2471e6d15924SDimitry Andric }
2472e6d15924SDimitry Andric 
2473ac9a064cSDimitry Andric std::optional<LocationSize>
getFoldedRestoreSize(const TargetInstrInfo * TII) const2474e6d15924SDimitry Andric MachineInstr::getFoldedRestoreSize(const TargetInstrInfo *TII) const {
2475e6d15924SDimitry Andric   MMOList Accesses;
2476e6d15924SDimitry Andric   if (TII->hasLoadFromStackSlot(*this, Accesses))
2477e6d15924SDimitry Andric     return getSpillSlotSize(Accesses, getMF()->getFrameInfo());
2478e3b55780SDimitry Andric   return std::nullopt;
2479e6d15924SDimitry Andric }
2480b60736ecSDimitry Andric 
getDebugInstrNum()2481b60736ecSDimitry Andric unsigned MachineInstr::getDebugInstrNum() {
2482b60736ecSDimitry Andric   if (DebugInstrNum == 0)
2483b60736ecSDimitry Andric     DebugInstrNum = getParent()->getParent()->getNewDebugInstrNum();
2484b60736ecSDimitry Andric   return DebugInstrNum;
2485b60736ecSDimitry Andric }
2486344a3780SDimitry Andric 
getDebugInstrNum(MachineFunction & MF)2487344a3780SDimitry Andric unsigned MachineInstr::getDebugInstrNum(MachineFunction &MF) {
2488344a3780SDimitry Andric   if (DebugInstrNum == 0)
2489344a3780SDimitry Andric     DebugInstrNum = MF.getNewDebugInstrNum();
2490344a3780SDimitry Andric   return DebugInstrNum;
2491344a3780SDimitry Andric }
24927fa27ce4SDimitry Andric 
getFirst2LLTs() const24937fa27ce4SDimitry Andric std::tuple<LLT, LLT> MachineInstr::getFirst2LLTs() const {
24947fa27ce4SDimitry Andric   return std::tuple(getRegInfo()->getType(getOperand(0).getReg()),
24957fa27ce4SDimitry Andric                     getRegInfo()->getType(getOperand(1).getReg()));
24967fa27ce4SDimitry Andric }
24977fa27ce4SDimitry Andric 
getFirst3LLTs() const24987fa27ce4SDimitry Andric std::tuple<LLT, LLT, LLT> MachineInstr::getFirst3LLTs() const {
24997fa27ce4SDimitry Andric   return std::tuple(getRegInfo()->getType(getOperand(0).getReg()),
25007fa27ce4SDimitry Andric                     getRegInfo()->getType(getOperand(1).getReg()),
25017fa27ce4SDimitry Andric                     getRegInfo()->getType(getOperand(2).getReg()));
25027fa27ce4SDimitry Andric }
25037fa27ce4SDimitry Andric 
getFirst4LLTs() const25047fa27ce4SDimitry Andric std::tuple<LLT, LLT, LLT, LLT> MachineInstr::getFirst4LLTs() const {
25057fa27ce4SDimitry Andric   return std::tuple(getRegInfo()->getType(getOperand(0).getReg()),
25067fa27ce4SDimitry Andric                     getRegInfo()->getType(getOperand(1).getReg()),
25077fa27ce4SDimitry Andric                     getRegInfo()->getType(getOperand(2).getReg()),
25087fa27ce4SDimitry Andric                     getRegInfo()->getType(getOperand(3).getReg()));
25097fa27ce4SDimitry Andric }
25107fa27ce4SDimitry Andric 
getFirst5LLTs() const25117fa27ce4SDimitry Andric std::tuple<LLT, LLT, LLT, LLT, LLT> MachineInstr::getFirst5LLTs() const {
25127fa27ce4SDimitry Andric   return std::tuple(getRegInfo()->getType(getOperand(0).getReg()),
25137fa27ce4SDimitry Andric                     getRegInfo()->getType(getOperand(1).getReg()),
25147fa27ce4SDimitry Andric                     getRegInfo()->getType(getOperand(2).getReg()),
25157fa27ce4SDimitry Andric                     getRegInfo()->getType(getOperand(3).getReg()),
25167fa27ce4SDimitry Andric                     getRegInfo()->getType(getOperand(4).getReg()));
25177fa27ce4SDimitry Andric }
25187fa27ce4SDimitry Andric 
25197fa27ce4SDimitry Andric std::tuple<Register, LLT, Register, LLT>
getFirst2RegLLTs() const25207fa27ce4SDimitry Andric MachineInstr::getFirst2RegLLTs() const {
25217fa27ce4SDimitry Andric   Register Reg0 = getOperand(0).getReg();
25227fa27ce4SDimitry Andric   Register Reg1 = getOperand(1).getReg();
25237fa27ce4SDimitry Andric   return std::tuple(Reg0, getRegInfo()->getType(Reg0), Reg1,
25247fa27ce4SDimitry Andric                     getRegInfo()->getType(Reg1));
25257fa27ce4SDimitry Andric }
25267fa27ce4SDimitry Andric 
25277fa27ce4SDimitry Andric std::tuple<Register, LLT, Register, LLT, Register, LLT>
getFirst3RegLLTs() const25287fa27ce4SDimitry Andric MachineInstr::getFirst3RegLLTs() const {
25297fa27ce4SDimitry Andric   Register Reg0 = getOperand(0).getReg();
25307fa27ce4SDimitry Andric   Register Reg1 = getOperand(1).getReg();
25317fa27ce4SDimitry Andric   Register Reg2 = getOperand(2).getReg();
25327fa27ce4SDimitry Andric   return std::tuple(Reg0, getRegInfo()->getType(Reg0), Reg1,
25337fa27ce4SDimitry Andric                     getRegInfo()->getType(Reg1), Reg2,
25347fa27ce4SDimitry Andric                     getRegInfo()->getType(Reg2));
25357fa27ce4SDimitry Andric }
25367fa27ce4SDimitry Andric 
25377fa27ce4SDimitry Andric std::tuple<Register, LLT, Register, LLT, Register, LLT, Register, LLT>
getFirst4RegLLTs() const25387fa27ce4SDimitry Andric MachineInstr::getFirst4RegLLTs() const {
25397fa27ce4SDimitry Andric   Register Reg0 = getOperand(0).getReg();
25407fa27ce4SDimitry Andric   Register Reg1 = getOperand(1).getReg();
25417fa27ce4SDimitry Andric   Register Reg2 = getOperand(2).getReg();
25427fa27ce4SDimitry Andric   Register Reg3 = getOperand(3).getReg();
25437fa27ce4SDimitry Andric   return std::tuple(
25447fa27ce4SDimitry Andric       Reg0, getRegInfo()->getType(Reg0), Reg1, getRegInfo()->getType(Reg1),
25457fa27ce4SDimitry Andric       Reg2, getRegInfo()->getType(Reg2), Reg3, getRegInfo()->getType(Reg3));
25467fa27ce4SDimitry Andric }
25477fa27ce4SDimitry Andric 
25487fa27ce4SDimitry Andric std::tuple<Register, LLT, Register, LLT, Register, LLT, Register, LLT, Register,
25497fa27ce4SDimitry Andric            LLT>
getFirst5RegLLTs() const25507fa27ce4SDimitry Andric MachineInstr::getFirst5RegLLTs() const {
25517fa27ce4SDimitry Andric   Register Reg0 = getOperand(0).getReg();
25527fa27ce4SDimitry Andric   Register Reg1 = getOperand(1).getReg();
25537fa27ce4SDimitry Andric   Register Reg2 = getOperand(2).getReg();
25547fa27ce4SDimitry Andric   Register Reg3 = getOperand(3).getReg();
25557fa27ce4SDimitry Andric   Register Reg4 = getOperand(4).getReg();
25567fa27ce4SDimitry Andric   return std::tuple(
25577fa27ce4SDimitry Andric       Reg0, getRegInfo()->getType(Reg0), Reg1, getRegInfo()->getType(Reg1),
25587fa27ce4SDimitry Andric       Reg2, getRegInfo()->getType(Reg2), Reg3, getRegInfo()->getType(Reg3),
25597fa27ce4SDimitry Andric       Reg4, getRegInfo()->getType(Reg4));
25607fa27ce4SDimitry Andric }
2561b1c73532SDimitry Andric 
insert(mop_iterator InsertBefore,ArrayRef<MachineOperand> Ops)2562b1c73532SDimitry Andric void MachineInstr::insert(mop_iterator InsertBefore,
2563b1c73532SDimitry Andric                           ArrayRef<MachineOperand> Ops) {
2564b1c73532SDimitry Andric   assert(InsertBefore != nullptr && "invalid iterator");
2565b1c73532SDimitry Andric   assert(InsertBefore->getParent() == this &&
2566b1c73532SDimitry Andric          "iterator points to operand of other inst");
2567b1c73532SDimitry Andric   if (Ops.empty())
2568b1c73532SDimitry Andric     return;
2569b1c73532SDimitry Andric 
2570b1c73532SDimitry Andric   // Do one pass to untie operands.
2571b1c73532SDimitry Andric   SmallDenseMap<unsigned, unsigned> TiedOpIndices;
2572b1c73532SDimitry Andric   for (const MachineOperand &MO : operands()) {
2573b1c73532SDimitry Andric     if (MO.isReg() && MO.isTied()) {
2574b1c73532SDimitry Andric       unsigned OpNo = getOperandNo(&MO);
2575b1c73532SDimitry Andric       unsigned TiedTo = findTiedOperandIdx(OpNo);
2576b1c73532SDimitry Andric       TiedOpIndices[OpNo] = TiedTo;
2577b1c73532SDimitry Andric       untieRegOperand(OpNo);
2578b1c73532SDimitry Andric     }
2579b1c73532SDimitry Andric   }
2580b1c73532SDimitry Andric 
2581b1c73532SDimitry Andric   unsigned OpIdx = getOperandNo(InsertBefore);
2582b1c73532SDimitry Andric   unsigned NumOperands = getNumOperands();
2583b1c73532SDimitry Andric   unsigned OpsToMove = NumOperands - OpIdx;
2584b1c73532SDimitry Andric 
2585b1c73532SDimitry Andric   SmallVector<MachineOperand> MovingOps;
2586b1c73532SDimitry Andric   MovingOps.reserve(OpsToMove);
2587b1c73532SDimitry Andric 
2588b1c73532SDimitry Andric   for (unsigned I = 0; I < OpsToMove; ++I) {
2589b1c73532SDimitry Andric     MovingOps.emplace_back(getOperand(OpIdx));
2590b1c73532SDimitry Andric     removeOperand(OpIdx);
2591b1c73532SDimitry Andric   }
2592b1c73532SDimitry Andric   for (const MachineOperand &MO : Ops)
2593b1c73532SDimitry Andric     addOperand(MO);
2594b1c73532SDimitry Andric   for (const MachineOperand &OpMoved : MovingOps)
2595b1c73532SDimitry Andric     addOperand(OpMoved);
2596b1c73532SDimitry Andric 
2597b1c73532SDimitry Andric   // Re-tie operands.
2598b1c73532SDimitry Andric   for (auto [Tie1, Tie2] : TiedOpIndices) {
2599b1c73532SDimitry Andric     if (Tie1 >= OpIdx)
2600b1c73532SDimitry Andric       Tie1 += Ops.size();
2601b1c73532SDimitry Andric     if (Tie2 >= OpIdx)
2602b1c73532SDimitry Andric       Tie2 += Ops.size();
2603b1c73532SDimitry Andric     tieOperands(Tie1, Tie2);
2604b1c73532SDimitry Andric   }
2605b1c73532SDimitry Andric }
2606b1c73532SDimitry Andric 
mayFoldInlineAsmRegOp(unsigned OpId) const2607b1c73532SDimitry Andric bool MachineInstr::mayFoldInlineAsmRegOp(unsigned OpId) const {
2608b1c73532SDimitry Andric   assert(OpId && "expected non-zero operand id");
2609b1c73532SDimitry Andric   assert(isInlineAsm() && "should only be used on inline asm");
2610b1c73532SDimitry Andric 
2611b1c73532SDimitry Andric   if (!getOperand(OpId).isReg())
2612b1c73532SDimitry Andric     return false;
2613b1c73532SDimitry Andric 
2614b1c73532SDimitry Andric   const MachineOperand &MD = getOperand(OpId - 1);
2615b1c73532SDimitry Andric   if (!MD.isImm())
2616b1c73532SDimitry Andric     return false;
2617b1c73532SDimitry Andric 
2618b1c73532SDimitry Andric   InlineAsm::Flag F(MD.getImm());
2619b1c73532SDimitry Andric   if (F.isRegUseKind() || F.isRegDefKind() || F.isRegDefEarlyClobberKind())
2620b1c73532SDimitry Andric     return F.getRegMayBeFolded();
2621b1c73532SDimitry Andric   return false;
2622b1c73532SDimitry Andric }
2623