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