File indexing completed on 2026-05-10 08:43:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_CODEGEN_MACHINEINSTR_H
0016 #define LLVM_CODEGEN_MACHINEINSTR_H
0017
0018 #include "llvm/ADT/DenseMapInfo.h"
0019 #include "llvm/ADT/PointerSumType.h"
0020 #include "llvm/ADT/ilist.h"
0021 #include "llvm/ADT/ilist_node.h"
0022 #include "llvm/ADT/iterator_range.h"
0023 #include "llvm/Analysis/MemoryLocation.h"
0024 #include "llvm/CodeGen/MachineMemOperand.h"
0025 #include "llvm/CodeGen/MachineOperand.h"
0026 #include "llvm/CodeGen/TargetOpcodes.h"
0027 #include "llvm/IR/DebugLoc.h"
0028 #include "llvm/IR/InlineAsm.h"
0029 #include "llvm/MC/MCInstrDesc.h"
0030 #include "llvm/MC/MCSymbol.h"
0031 #include "llvm/Support/ArrayRecycler.h"
0032 #include "llvm/Support/MathExtras.h"
0033 #include "llvm/Support/TrailingObjects.h"
0034 #include <algorithm>
0035 #include <cassert>
0036 #include <cstdint>
0037 #include <utility>
0038
0039 namespace llvm {
0040
0041 class DILabel;
0042 class Instruction;
0043 class MDNode;
0044 class AAResults;
0045 class BatchAAResults;
0046 template <typename T> class ArrayRef;
0047 class DIExpression;
0048 class DILocalVariable;
0049 class LiveRegUnits;
0050 class MachineBasicBlock;
0051 class MachineFunction;
0052 class MachineRegisterInfo;
0053 class ModuleSlotTracker;
0054 class raw_ostream;
0055 template <typename T> class SmallVectorImpl;
0056 class SmallBitVector;
0057 class StringRef;
0058 class TargetInstrInfo;
0059 class TargetRegisterClass;
0060 class TargetRegisterInfo;
0061
0062
0063
0064
0065
0066
0067
0068
0069 class MachineInstr
0070 : public ilist_node_with_parent<MachineInstr, MachineBasicBlock,
0071 ilist_sentinel_tracking<true>> {
0072 public:
0073 using mmo_iterator = ArrayRef<MachineMemOperand *>::iterator;
0074
0075
0076
0077
0078
0079 enum CommentFlag {
0080 ReloadReuse = 0x1,
0081 NoSchedComment = 0x2,
0082 TAsmComments = 0x4
0083 };
0084
0085 enum MIFlag {
0086 NoFlags = 0,
0087 FrameSetup = 1 << 0,
0088
0089 FrameDestroy = 1 << 1,
0090
0091 BundledPred = 1 << 2,
0092 BundledSucc = 1 << 3,
0093 FmNoNans = 1 << 4,
0094
0095 FmNoInfs = 1 << 5,
0096
0097 FmNsz = 1 << 6,
0098
0099 FmArcp = 1 << 7,
0100
0101 FmContract = 1 << 8,
0102
0103 FmAfn = 1 << 9,
0104
0105 FmReassoc = 1 << 10,
0106
0107 NoUWrap = 1 << 11,
0108
0109 NoSWrap = 1 << 12,
0110
0111 IsExact = 1 << 13,
0112
0113 NoFPExcept = 1 << 14,
0114
0115 NoMerge = 1 << 15,
0116
0117
0118 Unpredictable = 1 << 16,
0119 NoConvergent = 1 << 17,
0120 NonNeg = 1 << 18,
0121 Disjoint = 1 << 19,
0122 NoUSWrap = 1 << 20,
0123
0124 SameSign = 1 << 21
0125 };
0126
0127 private:
0128 const MCInstrDesc *MCID;
0129 MachineBasicBlock *Parent = nullptr;
0130
0131
0132 MachineOperand *Operands = nullptr;
0133
0134 #define LLVM_MI_NUMOPERANDS_BITS 24
0135 #define LLVM_MI_FLAGS_BITS 24
0136 #define LLVM_MI_ASMPRINTERFLAGS_BITS 8
0137
0138
0139 uint32_t NumOperands : LLVM_MI_NUMOPERANDS_BITS;
0140
0141
0142
0143 using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
0144 OperandCapacity CapOperands;
0145
0146
0147 uint32_t Flags : LLVM_MI_FLAGS_BITS;
0148
0149
0150
0151
0152 uint8_t AsmPrinterFlags : LLVM_MI_ASMPRINTERFLAGS_BITS;
0153
0154
0155
0156
0157
0158
0159
0160 class ExtraInfo final : TrailingObjects<ExtraInfo, MachineMemOperand *,
0161 MCSymbol *, MDNode *, uint32_t> {
0162 public:
0163 static ExtraInfo *create(BumpPtrAllocator &Allocator,
0164 ArrayRef<MachineMemOperand *> MMOs,
0165 MCSymbol *PreInstrSymbol = nullptr,
0166 MCSymbol *PostInstrSymbol = nullptr,
0167 MDNode *HeapAllocMarker = nullptr,
0168 MDNode *PCSections = nullptr, uint32_t CFIType = 0,
0169 MDNode *MMRAs = nullptr) {
0170 bool HasPreInstrSymbol = PreInstrSymbol != nullptr;
0171 bool HasPostInstrSymbol = PostInstrSymbol != nullptr;
0172 bool HasHeapAllocMarker = HeapAllocMarker != nullptr;
0173 bool HasMMRAs = MMRAs != nullptr;
0174 bool HasCFIType = CFIType != 0;
0175 bool HasPCSections = PCSections != nullptr;
0176 auto *Result = new (Allocator.Allocate(
0177 totalSizeToAlloc<MachineMemOperand *, MCSymbol *, MDNode *, uint32_t>(
0178 MMOs.size(), HasPreInstrSymbol + HasPostInstrSymbol,
0179 HasHeapAllocMarker + HasPCSections + HasMMRAs, HasCFIType),
0180 alignof(ExtraInfo)))
0181 ExtraInfo(MMOs.size(), HasPreInstrSymbol, HasPostInstrSymbol,
0182 HasHeapAllocMarker, HasPCSections, HasCFIType, HasMMRAs);
0183
0184
0185 std::copy(MMOs.begin(), MMOs.end(),
0186 Result->getTrailingObjects<MachineMemOperand *>());
0187
0188 unsigned MDNodeIdx = 0;
0189
0190 if (HasPreInstrSymbol)
0191 Result->getTrailingObjects<MCSymbol *>()[0] = PreInstrSymbol;
0192 if (HasPostInstrSymbol)
0193 Result->getTrailingObjects<MCSymbol *>()[HasPreInstrSymbol] =
0194 PostInstrSymbol;
0195 if (HasHeapAllocMarker)
0196 Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = HeapAllocMarker;
0197 if (HasPCSections)
0198 Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = PCSections;
0199 if (HasCFIType)
0200 Result->getTrailingObjects<uint32_t>()[0] = CFIType;
0201 if (HasMMRAs)
0202 Result->getTrailingObjects<MDNode *>()[MDNodeIdx++] = MMRAs;
0203
0204 return Result;
0205 }
0206
0207 ArrayRef<MachineMemOperand *> getMMOs() const {
0208 return ArrayRef(getTrailingObjects<MachineMemOperand *>(), NumMMOs);
0209 }
0210
0211 MCSymbol *getPreInstrSymbol() const {
0212 return HasPreInstrSymbol ? getTrailingObjects<MCSymbol *>()[0] : nullptr;
0213 }
0214
0215 MCSymbol *getPostInstrSymbol() const {
0216 return HasPostInstrSymbol
0217 ? getTrailingObjects<MCSymbol *>()[HasPreInstrSymbol]
0218 : nullptr;
0219 }
0220
0221 MDNode *getHeapAllocMarker() const {
0222 return HasHeapAllocMarker ? getTrailingObjects<MDNode *>()[0] : nullptr;
0223 }
0224
0225 MDNode *getPCSections() const {
0226 return HasPCSections
0227 ? getTrailingObjects<MDNode *>()[HasHeapAllocMarker]
0228 : nullptr;
0229 }
0230
0231 uint32_t getCFIType() const {
0232 return HasCFIType ? getTrailingObjects<uint32_t>()[0] : 0;
0233 }
0234
0235 MDNode *getMMRAMetadata() const {
0236 return HasMMRAs ? getTrailingObjects<MDNode *>()[HasHeapAllocMarker +
0237 HasPCSections]
0238 : nullptr;
0239 }
0240
0241 private:
0242 friend TrailingObjects;
0243
0244
0245
0246
0247
0248
0249 const int NumMMOs;
0250 const bool HasPreInstrSymbol;
0251 const bool HasPostInstrSymbol;
0252 const bool HasHeapAllocMarker;
0253 const bool HasPCSections;
0254 const bool HasCFIType;
0255 const bool HasMMRAs;
0256
0257
0258 size_t numTrailingObjects(OverloadToken<MachineMemOperand *>) const {
0259 return NumMMOs;
0260 }
0261 size_t numTrailingObjects(OverloadToken<MCSymbol *>) const {
0262 return HasPreInstrSymbol + HasPostInstrSymbol;
0263 }
0264 size_t numTrailingObjects(OverloadToken<MDNode *>) const {
0265 return HasHeapAllocMarker + HasPCSections;
0266 }
0267 size_t numTrailingObjects(OverloadToken<uint32_t>) const {
0268 return HasCFIType;
0269 }
0270
0271
0272
0273 ExtraInfo(int NumMMOs, bool HasPreInstrSymbol, bool HasPostInstrSymbol,
0274 bool HasHeapAllocMarker, bool HasPCSections, bool HasCFIType,
0275 bool HasMMRAs)
0276 : NumMMOs(NumMMOs), HasPreInstrSymbol(HasPreInstrSymbol),
0277 HasPostInstrSymbol(HasPostInstrSymbol),
0278 HasHeapAllocMarker(HasHeapAllocMarker), HasPCSections(HasPCSections),
0279 HasCFIType(HasCFIType), HasMMRAs(HasMMRAs) {}
0280 };
0281
0282
0283
0284
0285 enum ExtraInfoInlineKinds {
0286 EIIK_MMO = 0,
0287 EIIK_PreInstrSymbol,
0288 EIIK_PostInstrSymbol,
0289 EIIK_OutOfLine
0290 };
0291
0292
0293
0294
0295
0296
0297 PointerSumType<ExtraInfoInlineKinds,
0298 PointerSumTypeMember<EIIK_MMO, MachineMemOperand *>,
0299 PointerSumTypeMember<EIIK_PreInstrSymbol, MCSymbol *>,
0300 PointerSumTypeMember<EIIK_PostInstrSymbol, MCSymbol *>,
0301 PointerSumTypeMember<EIIK_OutOfLine, ExtraInfo *>>
0302 Info;
0303
0304 DebugLoc DbgLoc;
0305
0306
0307
0308 unsigned DebugInstrNum;
0309
0310
0311 uint16_t Opcode;
0312
0313
0314 friend struct ilist_traits<MachineInstr>;
0315 friend struct ilist_callback_traits<MachineBasicBlock>;
0316 void setParent(MachineBasicBlock *P) { Parent = P; }
0317
0318
0319
0320 MachineInstr(MachineFunction &, const MachineInstr &);
0321
0322
0323
0324
0325 MachineInstr(MachineFunction &, const MCInstrDesc &TID, DebugLoc DL,
0326 bool NoImp = false);
0327
0328
0329 friend class MachineFunction;
0330
0331 void
0332 dumprImpl(const MachineRegisterInfo &MRI, unsigned Depth, unsigned MaxDepth,
0333 SmallPtrSetImpl<const MachineInstr *> &AlreadySeenInstrs) const;
0334
0335 static bool opIsRegDef(const MachineOperand &Op) {
0336 return Op.isReg() && Op.isDef();
0337 }
0338
0339 static bool opIsRegUse(const MachineOperand &Op) {
0340 return Op.isReg() && Op.isUse();
0341 }
0342
0343 public:
0344 MachineInstr(const MachineInstr &) = delete;
0345 MachineInstr &operator=(const MachineInstr &) = delete;
0346
0347 ~MachineInstr() = delete;
0348
0349 const MachineBasicBlock* getParent() const { return Parent; }
0350 MachineBasicBlock* getParent() { return Parent; }
0351
0352
0353 void moveBefore(MachineInstr *MovePos);
0354
0355
0356
0357
0358
0359
0360 const MachineFunction *getMF() const;
0361 MachineFunction *getMF() {
0362 return const_cast<MachineFunction *>(
0363 static_cast<const MachineInstr *>(this)->getMF());
0364 }
0365
0366
0367 uint8_t getAsmPrinterFlags() const { return AsmPrinterFlags; }
0368
0369
0370 void clearAsmPrinterFlags() { AsmPrinterFlags = 0; }
0371
0372
0373 bool getAsmPrinterFlag(CommentFlag Flag) const {
0374 assert(isUInt<LLVM_MI_ASMPRINTERFLAGS_BITS>(unsigned(Flag)) &&
0375 "Flag is out of range for the AsmPrinterFlags field");
0376 return AsmPrinterFlags & Flag;
0377 }
0378
0379
0380 void setAsmPrinterFlag(uint8_t Flag) {
0381 assert(isUInt<LLVM_MI_ASMPRINTERFLAGS_BITS>(unsigned(Flag)) &&
0382 "Flag is out of range for the AsmPrinterFlags field");
0383 AsmPrinterFlags |= Flag;
0384 }
0385
0386
0387 void clearAsmPrinterFlag(CommentFlag Flag) {
0388 assert(isUInt<LLVM_MI_ASMPRINTERFLAGS_BITS>(unsigned(Flag)) &&
0389 "Flag is out of range for the AsmPrinterFlags field");
0390 AsmPrinterFlags &= ~Flag;
0391 }
0392
0393
0394 uint32_t getFlags() const {
0395 return Flags;
0396 }
0397
0398
0399 bool getFlag(MIFlag Flag) const {
0400 assert(isUInt<LLVM_MI_FLAGS_BITS>(unsigned(Flag)) &&
0401 "Flag is out of range for the Flags field");
0402 return Flags & Flag;
0403 }
0404
0405
0406 void setFlag(MIFlag Flag) {
0407 assert(isUInt<LLVM_MI_FLAGS_BITS>(unsigned(Flag)) &&
0408 "Flag is out of range for the Flags field");
0409 Flags |= (uint32_t)Flag;
0410 }
0411
0412 void setFlags(unsigned flags) {
0413 assert(isUInt<LLVM_MI_FLAGS_BITS>(flags) &&
0414 "flags to be set are out of range for the Flags field");
0415
0416 unsigned Mask = BundledPred | BundledSucc;
0417 Flags = (Flags & Mask) | (flags & ~Mask);
0418 }
0419
0420
0421 void clearFlag(MIFlag Flag) {
0422 assert(isUInt<LLVM_MI_FLAGS_BITS>(unsigned(Flag)) &&
0423 "Flag to clear is out of range for the Flags field");
0424 Flags &= ~((uint32_t)Flag);
0425 }
0426
0427 void clearFlags(unsigned flags) {
0428 assert(isUInt<LLVM_MI_FLAGS_BITS>(flags) &&
0429 "flags to be cleared are out of range for the Flags field");
0430 Flags &= ~flags;
0431 }
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468 bool isInsideBundle() const {
0469 return getFlag(BundledPred);
0470 }
0471
0472
0473
0474 bool isBundled() const {
0475 return isBundledWithPred() || isBundledWithSucc();
0476 }
0477
0478
0479
0480 bool isBundledWithPred() const { return getFlag(BundledPred); }
0481
0482
0483
0484 bool isBundledWithSucc() const { return getFlag(BundledSucc); }
0485
0486
0487
0488 void bundleWithPred();
0489
0490
0491
0492 void bundleWithSucc();
0493
0494
0495 void unbundleFromPred();
0496
0497
0498 void unbundleFromSucc();
0499
0500
0501 const DebugLoc &getDebugLoc() const { return DbgLoc; }
0502
0503
0504
0505
0506 const MachineOperand &getDebugOffset() const {
0507 assert(isNonListDebugValue() && "not a DBG_VALUE");
0508 return getOperand(1);
0509 }
0510 MachineOperand &getDebugOffset() {
0511 assert(isNonListDebugValue() && "not a DBG_VALUE");
0512 return getOperand(1);
0513 }
0514
0515
0516
0517 const MachineOperand &getDebugVariableOp() const;
0518 MachineOperand &getDebugVariableOp();
0519
0520
0521
0522 const DILocalVariable *getDebugVariable() const;
0523
0524
0525
0526 const MachineOperand &getDebugExpressionOp() const;
0527 MachineOperand &getDebugExpressionOp();
0528
0529
0530
0531 const DIExpression *getDebugExpression() const;
0532
0533
0534
0535 const DILabel *getDebugLabel() const;
0536
0537
0538
0539 unsigned getDebugInstrNum();
0540
0541
0542
0543
0544 unsigned getDebugInstrNum(MachineFunction &MF);
0545
0546
0547
0548 unsigned peekDebugInstrNum() const { return DebugInstrNum; }
0549
0550
0551
0552 void setDebugInstrNum(unsigned Num) { DebugInstrNum = Num; }
0553
0554
0555
0556
0557
0558 void dropDebugNumber() { DebugInstrNum = 0; }
0559
0560
0561
0562 const MDNode *getLocCookieMD() const;
0563
0564
0565
0566
0567 void emitInlineAsmError(const Twine &ErrMsg) const;
0568
0569
0570
0571 void emitGenericError(const Twine &ErrMsg) const;
0572
0573
0574 const MCInstrDesc &getDesc() const { return *MCID; }
0575
0576
0577 unsigned getOpcode() const { return Opcode; }
0578
0579
0580 unsigned getNumOperands() const { return NumOperands; }
0581
0582
0583 unsigned getNumDebugOperands() const {
0584 return std::distance(debug_operands().begin(), debug_operands().end());
0585 }
0586
0587 const MachineOperand& getOperand(unsigned i) const {
0588 assert(i < getNumOperands() && "getOperand() out of range!");
0589 return Operands[i];
0590 }
0591 MachineOperand& getOperand(unsigned i) {
0592 assert(i < getNumOperands() && "getOperand() out of range!");
0593 return Operands[i];
0594 }
0595
0596 MachineOperand &getDebugOperand(unsigned Index) {
0597 assert(Index < getNumDebugOperands() && "getDebugOperand() out of range!");
0598 return *(debug_operands().begin() + Index);
0599 }
0600 const MachineOperand &getDebugOperand(unsigned Index) const {
0601 assert(Index < getNumDebugOperands() && "getDebugOperand() out of range!");
0602 return *(debug_operands().begin() + Index);
0603 }
0604
0605
0606
0607 bool hasDebugOperandForReg(Register Reg) const {
0608 return any_of(debug_operands(), [Reg](const MachineOperand &Op) {
0609 return Op.isReg() && Op.getReg() == Reg;
0610 });
0611 }
0612
0613
0614
0615 template <typename Operand, typename Instruction>
0616 static iterator_range<
0617 filter_iterator<Operand *, std::function<bool(Operand &Op)>>>
0618 getDebugOperandsForReg(Instruction *MI, Register Reg) {
0619 std::function<bool(Operand & Op)> OpUsesReg(
0620 [Reg](Operand &Op) { return Op.isReg() && Op.getReg() == Reg; });
0621 return make_filter_range(MI->debug_operands(), OpUsesReg);
0622 }
0623 iterator_range<filter_iterator<const MachineOperand *,
0624 std::function<bool(const MachineOperand &Op)>>>
0625 getDebugOperandsForReg(Register Reg) const {
0626 return MachineInstr::getDebugOperandsForReg<const MachineOperand,
0627 const MachineInstr>(this, Reg);
0628 }
0629 iterator_range<filter_iterator<MachineOperand *,
0630 std::function<bool(MachineOperand &Op)>>>
0631 getDebugOperandsForReg(Register Reg) {
0632 return MachineInstr::getDebugOperandsForReg<MachineOperand, MachineInstr>(
0633 this, Reg);
0634 }
0635
0636 bool isDebugOperand(const MachineOperand *Op) const {
0637 return Op >= adl_begin(debug_operands()) && Op <= adl_end(debug_operands());
0638 }
0639
0640 unsigned getDebugOperandIndex(const MachineOperand *Op) const {
0641 assert(isDebugOperand(Op) && "Expected a debug operand.");
0642 return std::distance(adl_begin(debug_operands()), Op);
0643 }
0644
0645
0646 unsigned getNumDefs() const {
0647 return getNumExplicitDefs() + MCID->implicit_defs().size();
0648 }
0649
0650
0651 bool hasImplicitDef() const {
0652 for (const MachineOperand &MO : implicit_operands())
0653 if (MO.isDef())
0654 return true;
0655 return false;
0656 }
0657
0658
0659 unsigned getNumImplicitOperands() const {
0660 return getNumOperands() - getNumExplicitOperands();
0661 }
0662
0663
0664 bool isOperandSubregIdx(unsigned OpIdx) const {
0665 assert(getOperand(OpIdx).isImm() && "Expected MO_Immediate operand type.");
0666 if (isExtractSubreg() && OpIdx == 2)
0667 return true;
0668 if (isInsertSubreg() && OpIdx == 3)
0669 return true;
0670 if (isRegSequence() && OpIdx > 1 && (OpIdx % 2) == 0)
0671 return true;
0672 if (isSubregToReg() && OpIdx == 3)
0673 return true;
0674 return false;
0675 }
0676
0677
0678 unsigned getNumExplicitOperands() const;
0679
0680
0681 unsigned getNumExplicitDefs() const;
0682
0683
0684 using mop_iterator = MachineOperand *;
0685 using const_mop_iterator = const MachineOperand *;
0686
0687 mop_iterator operands_begin() { return Operands; }
0688 mop_iterator operands_end() { return Operands + NumOperands; }
0689
0690 const_mop_iterator operands_begin() const { return Operands; }
0691 const_mop_iterator operands_end() const { return Operands + NumOperands; }
0692
0693 iterator_range<mop_iterator> operands() {
0694 return make_range(operands_begin(), operands_end());
0695 }
0696 iterator_range<const_mop_iterator> operands() const {
0697 return make_range(operands_begin(), operands_end());
0698 }
0699 iterator_range<mop_iterator> explicit_operands() {
0700 return make_range(operands_begin(),
0701 operands_begin() + getNumExplicitOperands());
0702 }
0703 iterator_range<const_mop_iterator> explicit_operands() const {
0704 return make_range(operands_begin(),
0705 operands_begin() + getNumExplicitOperands());
0706 }
0707 iterator_range<mop_iterator> implicit_operands() {
0708 return make_range(explicit_operands().end(), operands_end());
0709 }
0710 iterator_range<const_mop_iterator> implicit_operands() const {
0711 return make_range(explicit_operands().end(), operands_end());
0712 }
0713
0714
0715 iterator_range<mop_iterator> debug_operands() {
0716 assert((isDebugValueLike()) && "Must be a debug value instruction.");
0717 return isNonListDebugValue()
0718 ? make_range(operands_begin(), operands_begin() + 1)
0719 : make_range(operands_begin() + 2, operands_end());
0720 }
0721
0722 iterator_range<const_mop_iterator> debug_operands() const {
0723 assert((isDebugValueLike()) && "Must be a debug value instruction.");
0724 return isNonListDebugValue()
0725 ? make_range(operands_begin(), operands_begin() + 1)
0726 : make_range(operands_begin() + 2, operands_end());
0727 }
0728
0729
0730 iterator_range<mop_iterator> defs() {
0731 return make_range(operands_begin(),
0732 operands_begin() + getNumExplicitDefs());
0733 }
0734
0735 iterator_range<const_mop_iterator> defs() const {
0736 return make_range(operands_begin(),
0737 operands_begin() + getNumExplicitDefs());
0738 }
0739
0740
0741 iterator_range<mop_iterator> uses() {
0742 return make_range(operands_begin() + getNumExplicitDefs(), operands_end());
0743 }
0744
0745 iterator_range<const_mop_iterator> uses() const {
0746 return make_range(operands_begin() + getNumExplicitDefs(), operands_end());
0747 }
0748 iterator_range<mop_iterator> explicit_uses() {
0749 return make_range(operands_begin() + getNumExplicitDefs(),
0750 operands_begin() + getNumExplicitOperands());
0751 }
0752 iterator_range<const_mop_iterator> explicit_uses() const {
0753 return make_range(operands_begin() + getNumExplicitDefs(),
0754 operands_begin() + getNumExplicitOperands());
0755 }
0756
0757 using filtered_mop_iterator =
0758 filter_iterator<mop_iterator, bool (*)(const MachineOperand &)>;
0759 using filtered_const_mop_iterator =
0760 filter_iterator<const_mop_iterator, bool (*)(const MachineOperand &)>;
0761
0762
0763
0764 iterator_range<filtered_mop_iterator> all_defs() {
0765 return make_filter_range(operands(), opIsRegDef);
0766 }
0767
0768 iterator_range<filtered_const_mop_iterator> all_defs() const {
0769 return make_filter_range(operands(), opIsRegDef);
0770 }
0771
0772
0773
0774 iterator_range<filtered_mop_iterator> all_uses() {
0775 return make_filter_range(uses(), opIsRegUse);
0776 }
0777
0778 iterator_range<filtered_const_mop_iterator> all_uses() const {
0779 return make_filter_range(uses(), opIsRegUse);
0780 }
0781
0782
0783 unsigned getOperandNo(const_mop_iterator I) const {
0784 return I - operands_begin();
0785 }
0786
0787
0788
0789
0790 ArrayRef<MachineMemOperand *> memoperands() const {
0791 if (!Info)
0792 return {};
0793
0794 if (Info.is<EIIK_MMO>())
0795 return ArrayRef(Info.getAddrOfZeroTagPointer(), 1);
0796
0797 if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
0798 return EI->getMMOs();
0799
0800 return {};
0801 }
0802
0803
0804
0805
0806
0807
0808 mmo_iterator memoperands_begin() const { return memoperands().begin(); }
0809
0810
0811
0812
0813
0814
0815 mmo_iterator memoperands_end() const { return memoperands().end(); }
0816
0817
0818
0819
0820 bool memoperands_empty() const { return memoperands().empty(); }
0821
0822
0823 bool hasOneMemOperand() const { return memoperands().size() == 1; }
0824
0825
0826 unsigned getNumMemOperands() const { return memoperands().size(); }
0827
0828
0829 MCSymbol *getPreInstrSymbol() const {
0830 if (!Info)
0831 return nullptr;
0832 if (MCSymbol *S = Info.get<EIIK_PreInstrSymbol>())
0833 return S;
0834 if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
0835 return EI->getPreInstrSymbol();
0836
0837 return nullptr;
0838 }
0839
0840
0841 MCSymbol *getPostInstrSymbol() const {
0842 if (!Info)
0843 return nullptr;
0844 if (MCSymbol *S = Info.get<EIIK_PostInstrSymbol>())
0845 return S;
0846 if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
0847 return EI->getPostInstrSymbol();
0848
0849 return nullptr;
0850 }
0851
0852
0853 MDNode *getHeapAllocMarker() const {
0854 if (!Info)
0855 return nullptr;
0856 if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
0857 return EI->getHeapAllocMarker();
0858
0859 return nullptr;
0860 }
0861
0862
0863 MDNode *getPCSections() const {
0864 if (!Info)
0865 return nullptr;
0866 if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
0867 return EI->getPCSections();
0868
0869 return nullptr;
0870 }
0871
0872
0873 MDNode *getMMRAMetadata() const {
0874 if (!Info)
0875 return nullptr;
0876 if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
0877 return EI->getMMRAMetadata();
0878 return nullptr;
0879 }
0880
0881
0882 uint32_t getCFIType() const {
0883 if (!Info)
0884 return 0;
0885 if (ExtraInfo *EI = Info.get<EIIK_OutOfLine>())
0886 return EI->getCFIType();
0887
0888 return 0;
0889 }
0890
0891
0892
0893
0894 enum QueryType {
0895 IgnoreBundle,
0896 AnyInBundle,
0897 AllInBundle
0898 };
0899
0900
0901
0902
0903
0904
0905 bool hasProperty(unsigned MCFlag, QueryType Type = AnyInBundle) const {
0906 assert(MCFlag < 64 &&
0907 "MCFlag out of range for bit mask in getFlags/hasPropertyInBundle.");
0908
0909 if (Type == IgnoreBundle || !isBundled() || isBundledWithPred())
0910 return getDesc().getFlags() & (1ULL << MCFlag);
0911
0912
0913 return hasPropertyInBundle(1ULL << MCFlag, Type);
0914 }
0915
0916
0917
0918 bool isPreISelOpcode(QueryType Type = IgnoreBundle) const {
0919 return hasProperty(MCID::PreISelOpcode, Type);
0920 }
0921
0922
0923
0924
0925
0926 bool isVariadic(QueryType Type = IgnoreBundle) const {
0927 return hasProperty(MCID::Variadic, Type);
0928 }
0929
0930
0931
0932 bool hasOptionalDef(QueryType Type = IgnoreBundle) const {
0933 return hasProperty(MCID::HasOptionalDef, Type);
0934 }
0935
0936
0937
0938 bool isPseudo(QueryType Type = IgnoreBundle) const {
0939 return hasProperty(MCID::Pseudo, Type);
0940 }
0941
0942
0943
0944 bool isMetaInstruction(QueryType Type = IgnoreBundle) const {
0945 return hasProperty(MCID::Meta, Type);
0946 }
0947
0948 bool isReturn(QueryType Type = AnyInBundle) const {
0949 return hasProperty(MCID::Return, Type);
0950 }
0951
0952
0953
0954 bool isEHScopeReturn(QueryType Type = AnyInBundle) const {
0955 return hasProperty(MCID::EHScopeReturn, Type);
0956 }
0957
0958 bool isCall(QueryType Type = AnyInBundle) const {
0959 return hasProperty(MCID::Call, Type);
0960 }
0961
0962
0963
0964 bool isCandidateForAdditionalCallInfo(QueryType Type = IgnoreBundle) const;
0965
0966
0967
0968
0969 bool shouldUpdateAdditionalCallInfo() const;
0970
0971
0972
0973
0974 bool isBarrier(QueryType Type = AnyInBundle) const {
0975 return hasProperty(MCID::Barrier, Type);
0976 }
0977
0978
0979
0980
0981
0982
0983 bool isTerminator(QueryType Type = AnyInBundle) const {
0984 return hasProperty(MCID::Terminator, Type);
0985 }
0986
0987
0988
0989
0990
0991 bool isBranch(QueryType Type = AnyInBundle) const {
0992 return hasProperty(MCID::Branch, Type);
0993 }
0994
0995
0996
0997 bool isIndirectBranch(QueryType Type = AnyInBundle,
0998 bool IncludeJumpTable = true) const {
0999 return hasProperty(MCID::IndirectBranch, Type) &&
1000 (IncludeJumpTable || !llvm::any_of(operands(), [](const auto &Op) {
1001 return Op.isJTI();
1002 }));
1003 }
1004
1005 bool isComputedGoto(QueryType Type = AnyInBundle) const {
1006
1007 return isIndirectBranch(Type, false);
1008 }
1009
1010
1011
1012
1013
1014 bool isConditionalBranch(QueryType Type = AnyInBundle) const {
1015 return isBranch(Type) && !isBarrier(Type) && !isIndirectBranch(Type);
1016 }
1017
1018
1019
1020
1021
1022 bool isUnconditionalBranch(QueryType Type = AnyInBundle) const {
1023 return isBranch(Type) && isBarrier(Type) && !isIndirectBranch(Type);
1024 }
1025
1026
1027
1028
1029
1030 bool isPredicable(QueryType Type = AllInBundle) const {
1031
1032
1033 return hasProperty(MCID::Predicable, Type);
1034 }
1035
1036
1037 bool isCompare(QueryType Type = IgnoreBundle) const {
1038 return hasProperty(MCID::Compare, Type);
1039 }
1040
1041
1042
1043 bool isMoveImmediate(QueryType Type = IgnoreBundle) const {
1044 return hasProperty(MCID::MoveImm, Type);
1045 }
1046
1047
1048
1049 bool isMoveReg(QueryType Type = IgnoreBundle) const {
1050 return hasProperty(MCID::MoveReg, Type);
1051 }
1052
1053
1054 bool isBitcast(QueryType Type = IgnoreBundle) const {
1055 return hasProperty(MCID::Bitcast, Type);
1056 }
1057
1058
1059 bool isSelect(QueryType Type = IgnoreBundle) const {
1060 return hasProperty(MCID::Select, Type);
1061 }
1062
1063
1064
1065
1066 bool isNotDuplicable(QueryType Type = AnyInBundle) const {
1067 if (getPreInstrSymbol() || getPostInstrSymbol())
1068 return true;
1069 return hasProperty(MCID::NotDuplicable, Type);
1070 }
1071
1072
1073
1074
1075 bool isConvergent(QueryType Type = AnyInBundle) const {
1076 if (isInlineAsm()) {
1077 unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
1078 if (ExtraInfo & InlineAsm::Extra_IsConvergent)
1079 return true;
1080 }
1081 if (getFlag(NoConvergent))
1082 return false;
1083 return hasProperty(MCID::Convergent, Type);
1084 }
1085
1086
1087
1088 bool hasDelaySlot(QueryType Type = AnyInBundle) const {
1089 return hasProperty(MCID::DelaySlot, Type);
1090 }
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100 bool canFoldAsLoad(QueryType Type = IgnoreBundle) const {
1101 return hasProperty(MCID::FoldableAsLoad, Type);
1102 }
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114 bool isRegSequenceLike(QueryType Type = IgnoreBundle) const {
1115 return hasProperty(MCID::RegSequence, Type);
1116 }
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129 bool isExtractSubregLike(QueryType Type = IgnoreBundle) const {
1130 return hasProperty(MCID::ExtractSubreg, Type);
1131 }
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143 bool isInsertSubregLike(QueryType Type = IgnoreBundle) const {
1144 return hasProperty(MCID::InsertSubreg, Type);
1145 }
1146
1147
1148
1149
1150
1151
1152
1153
1154 bool mayLoad(QueryType Type = AnyInBundle) const {
1155 if (isInlineAsm()) {
1156 unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
1157 if (ExtraInfo & InlineAsm::Extra_MayLoad)
1158 return true;
1159 }
1160 return hasProperty(MCID::MayLoad, Type);
1161 }
1162
1163
1164
1165
1166
1167 bool mayStore(QueryType Type = AnyInBundle) const {
1168 if (isInlineAsm()) {
1169 unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
1170 if (ExtraInfo & InlineAsm::Extra_MayStore)
1171 return true;
1172 }
1173 return hasProperty(MCID::MayStore, Type);
1174 }
1175
1176
1177 bool mayLoadOrStore(QueryType Type = AnyInBundle) const {
1178 return mayLoad(Type) || mayStore(Type);
1179 }
1180
1181
1182
1183
1184
1185
1186
1187 bool mayRaiseFPException() const {
1188 return hasProperty(MCID::MayRaiseFPException) &&
1189 !getFlag(MachineInstr::MIFlag::NoFPExcept);
1190 }
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206 bool isCommutable(QueryType Type = IgnoreBundle) const {
1207 return hasProperty(MCID::Commutable, Type);
1208 }
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224 bool isConvertibleTo3Addr(QueryType Type = IgnoreBundle) const {
1225 return hasProperty(MCID::ConvertibleTo3Addr, Type);
1226 }
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236 bool usesCustomInsertionHook(QueryType Type = IgnoreBundle) const {
1237 return hasProperty(MCID::UsesCustomInserter, Type);
1238 }
1239
1240
1241
1242
1243
1244 bool hasPostISelHook(QueryType Type = IgnoreBundle) const {
1245 return hasProperty(MCID::HasPostISelHook, Type);
1246 }
1247
1248
1249
1250
1251
1252 bool isRematerializable(QueryType Type = AllInBundle) const {
1253
1254
1255 return hasProperty(MCID::Rematerializable, Type);
1256 }
1257
1258
1259
1260
1261
1262
1263
1264 bool isAsCheapAsAMove(QueryType Type = AllInBundle) const {
1265
1266 return hasProperty(MCID::CheapAsAMove, Type);
1267 }
1268
1269
1270
1271
1272
1273
1274
1275 bool hasExtraSrcRegAllocReq(QueryType Type = AnyInBundle) const {
1276 return hasProperty(MCID::ExtraSrcRegAllocReq, Type);
1277 }
1278
1279
1280
1281
1282
1283
1284
1285 bool hasExtraDefRegAllocReq(QueryType Type = AnyInBundle) const {
1286 return hasProperty(MCID::ExtraDefRegAllocReq, Type);
1287 }
1288
1289 enum MICheckType {
1290 CheckDefs,
1291 CheckKillDead,
1292 IgnoreDefs,
1293 IgnoreVRegDefs
1294 };
1295
1296
1297
1298
1299
1300
1301 bool isIdenticalTo(const MachineInstr &Other,
1302 MICheckType Check = CheckDefs) const;
1303
1304
1305
1306
1307
1308
1309 bool isEquivalentDbgInstr(const MachineInstr &Other) const;
1310
1311
1312
1313
1314
1315
1316 MachineInstr *removeFromParent();
1317
1318
1319
1320
1321
1322
1323 MachineInstr *removeFromBundle();
1324
1325
1326
1327
1328
1329
1330 void eraseFromParent();
1331
1332
1333
1334
1335
1336 void eraseFromBundle();
1337
1338 bool isEHLabel() const { return getOpcode() == TargetOpcode::EH_LABEL; }
1339 bool isGCLabel() const { return getOpcode() == TargetOpcode::GC_LABEL; }
1340 bool isAnnotationLabel() const {
1341 return getOpcode() == TargetOpcode::ANNOTATION_LABEL;
1342 }
1343
1344 bool isLifetimeMarker() const {
1345 return getOpcode() == TargetOpcode::LIFETIME_START ||
1346 getOpcode() == TargetOpcode::LIFETIME_END;
1347 }
1348
1349
1350 bool isLabel() const {
1351 return isEHLabel() || isGCLabel() || isAnnotationLabel();
1352 }
1353
1354 bool isCFIInstruction() const {
1355 return getOpcode() == TargetOpcode::CFI_INSTRUCTION;
1356 }
1357
1358 bool isPseudoProbe() const {
1359 return getOpcode() == TargetOpcode::PSEUDO_PROBE;
1360 }
1361
1362
1363 bool isPosition() const { return isLabel() || isCFIInstruction(); }
1364
1365 bool isNonListDebugValue() const {
1366 return getOpcode() == TargetOpcode::DBG_VALUE;
1367 }
1368 bool isDebugValueList() const {
1369 return getOpcode() == TargetOpcode::DBG_VALUE_LIST;
1370 }
1371 bool isDebugValue() const {
1372 return isNonListDebugValue() || isDebugValueList();
1373 }
1374 bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; }
1375 bool isDebugRef() const { return getOpcode() == TargetOpcode::DBG_INSTR_REF; }
1376 bool isDebugValueLike() const { return isDebugValue() || isDebugRef(); }
1377 bool isDebugPHI() const { return getOpcode() == TargetOpcode::DBG_PHI; }
1378 bool isDebugInstr() const {
1379 return isDebugValue() || isDebugLabel() || isDebugRef() || isDebugPHI();
1380 }
1381 bool isDebugOrPseudoInstr() const {
1382 return isDebugInstr() || isPseudoProbe();
1383 }
1384
1385 bool isDebugOffsetImm() const {
1386 return isNonListDebugValue() && getDebugOffset().isImm();
1387 }
1388
1389
1390
1391 bool isIndirectDebugValue() const {
1392 return isDebugOffsetImm() && getDebugOperand(0).isReg();
1393 }
1394
1395
1396
1397 bool isDebugEntryValue() const;
1398
1399
1400
1401 bool isUndefDebugValue() const {
1402 if (!isDebugValue())
1403 return false;
1404
1405 for (const MachineOperand &Op : debug_operands())
1406 if (Op.isReg() && !Op.getReg().isValid())
1407 return true;
1408 return false;
1409 }
1410
1411 bool isJumpTableDebugInfo() const {
1412 return getOpcode() == TargetOpcode::JUMP_TABLE_DEBUG_INFO;
1413 }
1414
1415 bool isPHI() const {
1416 return getOpcode() == TargetOpcode::PHI ||
1417 getOpcode() == TargetOpcode::G_PHI;
1418 }
1419 bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
1420 bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
1421 bool isInlineAsm() const {
1422 return getOpcode() == TargetOpcode::INLINEASM ||
1423 getOpcode() == TargetOpcode::INLINEASM_BR;
1424 }
1425
1426
1427
1428 bool mayFoldInlineAsmRegOp(unsigned OpId) const;
1429
1430 bool isStackAligningInlineAsm() const;
1431 InlineAsm::AsmDialect getInlineAsmDialect() const;
1432
1433 bool isInsertSubreg() const {
1434 return getOpcode() == TargetOpcode::INSERT_SUBREG;
1435 }
1436
1437 bool isSubregToReg() const {
1438 return getOpcode() == TargetOpcode::SUBREG_TO_REG;
1439 }
1440
1441 bool isRegSequence() const {
1442 return getOpcode() == TargetOpcode::REG_SEQUENCE;
1443 }
1444
1445 bool isBundle() const {
1446 return getOpcode() == TargetOpcode::BUNDLE;
1447 }
1448
1449 bool isCopy() const {
1450 return getOpcode() == TargetOpcode::COPY;
1451 }
1452
1453 bool isFullCopy() const {
1454 return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg();
1455 }
1456
1457 bool isExtractSubreg() const {
1458 return getOpcode() == TargetOpcode::EXTRACT_SUBREG;
1459 }
1460
1461 bool isFakeUse() const { return getOpcode() == TargetOpcode::FAKE_USE; }
1462
1463
1464
1465 bool isCopyLike() const {
1466 return isCopy() || isSubregToReg();
1467 }
1468
1469
1470 bool isIdentityCopy() const {
1471 return isCopy() && getOperand(0).getReg() == getOperand(1).getReg() &&
1472 getOperand(0).getSubReg() == getOperand(1).getSubReg();
1473 }
1474
1475
1476
1477
1478 bool isTransient() const {
1479 switch (getOpcode()) {
1480 default:
1481 return isMetaInstruction();
1482
1483 case TargetOpcode::PHI:
1484 case TargetOpcode::G_PHI:
1485 case TargetOpcode::COPY:
1486 case TargetOpcode::INSERT_SUBREG:
1487 case TargetOpcode::SUBREG_TO_REG:
1488 case TargetOpcode::REG_SEQUENCE:
1489 return true;
1490 }
1491 }
1492
1493
1494
1495
1496
1497
1498 unsigned getBundleSize() const;
1499
1500
1501
1502
1503
1504
1505 bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const {
1506 return findRegisterUseOperandIdx(Reg, TRI, false) != -1;
1507 }
1508
1509
1510
1511
1512 bool readsVirtualRegister(Register Reg) const {
1513 return readsWritesVirtualRegister(Reg).first;
1514 }
1515
1516
1517
1518
1519 std::pair<bool,bool> readsWritesVirtualRegister(Register Reg,
1520 SmallVectorImpl<unsigned> *Ops = nullptr) const;
1521
1522
1523
1524
1525 bool killsRegister(Register Reg, const TargetRegisterInfo *TRI) const {
1526 return findRegisterUseOperandIdx(Reg, TRI, true) != -1;
1527 }
1528
1529
1530
1531
1532
1533 bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const {
1534 return findRegisterDefOperandIdx(Reg, TRI, false, false) != -1;
1535 }
1536
1537
1538
1539
1540 bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const {
1541 return findRegisterDefOperandIdx(Reg, TRI, false, true) != -1;
1542 }
1543
1544
1545
1546
1547 bool registerDefIsDead(Register Reg, const TargetRegisterInfo *TRI) const {
1548 return findRegisterDefOperandIdx(Reg, TRI, true, false) != -1;
1549 }
1550
1551
1552
1553 bool hasRegisterImplicitUseOperand(Register Reg) const;
1554
1555
1556
1557
1558 int findRegisterUseOperandIdx(Register Reg, const TargetRegisterInfo *TRI,
1559 bool isKill = false) const;
1560
1561
1562
1563 MachineOperand *findRegisterUseOperand(Register Reg,
1564 const TargetRegisterInfo *TRI,
1565 bool isKill = false) {
1566 int Idx = findRegisterUseOperandIdx(Reg, TRI, isKill);
1567 return (Idx == -1) ? nullptr : &getOperand(Idx);
1568 }
1569
1570 const MachineOperand *findRegisterUseOperand(Register Reg,
1571 const TargetRegisterInfo *TRI,
1572 bool isKill = false) const {
1573 return const_cast<MachineInstr *>(this)->findRegisterUseOperand(Reg, TRI,
1574 isKill);
1575 }
1576
1577
1578
1579
1580
1581
1582
1583 int findRegisterDefOperandIdx(Register Reg, const TargetRegisterInfo *TRI,
1584 bool isDead = false,
1585 bool Overlap = false) const;
1586
1587
1588
1589 MachineOperand *findRegisterDefOperand(Register Reg,
1590 const TargetRegisterInfo *TRI,
1591 bool isDead = false,
1592 bool Overlap = false) {
1593 int Idx = findRegisterDefOperandIdx(Reg, TRI, isDead, Overlap);
1594 return (Idx == -1) ? nullptr : &getOperand(Idx);
1595 }
1596
1597 const MachineOperand *findRegisterDefOperand(Register Reg,
1598 const TargetRegisterInfo *TRI,
1599 bool isDead = false,
1600 bool Overlap = false) const {
1601 return const_cast<MachineInstr *>(this)->findRegisterDefOperand(
1602 Reg, TRI, isDead, Overlap);
1603 }
1604
1605
1606
1607
1608 int findFirstPredOperandIdx() const;
1609
1610
1611
1612
1613
1614
1615
1616 int findInlineAsmFlagIdx(unsigned OpIdx, unsigned *GroupNo = nullptr) const;
1617
1618
1619
1620
1621
1622
1623
1624 const TargetRegisterClass*
1625 getRegClassConstraint(unsigned OpIdx,
1626 const TargetInstrInfo *TII,
1627 const TargetRegisterInfo *TRI) const;
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641 const TargetRegisterClass *getRegClassConstraintEffectForVReg(
1642 Register Reg, const TargetRegisterClass *CurRC,
1643 const TargetInstrInfo *TII, const TargetRegisterInfo *TRI,
1644 bool ExploreBundle = false) const;
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655 const TargetRegisterClass *
1656 getRegClassConstraintEffect(unsigned OpIdx, const TargetRegisterClass *CurRC,
1657 const TargetInstrInfo *TII,
1658 const TargetRegisterInfo *TRI) const;
1659
1660
1661
1662
1663
1664
1665
1666 void tieOperands(unsigned DefIdx, unsigned UseIdx);
1667
1668
1669
1670
1671 unsigned findTiedOperandIdx(unsigned OpIdx) const;
1672
1673
1674
1675
1676
1677 bool isRegTiedToUseOperand(unsigned DefOpIdx,
1678 unsigned *UseOpIdx = nullptr) const {
1679 const MachineOperand &MO = getOperand(DefOpIdx);
1680 if (!MO.isReg() || !MO.isDef() || !MO.isTied())
1681 return false;
1682 if (UseOpIdx)
1683 *UseOpIdx = findTiedOperandIdx(DefOpIdx);
1684 return true;
1685 }
1686
1687
1688
1689
1690 bool isRegTiedToDefOperand(unsigned UseOpIdx,
1691 unsigned *DefOpIdx = nullptr) const {
1692 const MachineOperand &MO = getOperand(UseOpIdx);
1693 if (!MO.isReg() || !MO.isUse() || !MO.isTied())
1694 return false;
1695 if (DefOpIdx)
1696 *DefOpIdx = findTiedOperandIdx(UseOpIdx);
1697 return true;
1698 }
1699
1700
1701 void clearKillInfo();
1702
1703
1704
1705 void substituteRegister(Register FromReg, Register ToReg, unsigned SubIdx,
1706 const TargetRegisterInfo &RegInfo);
1707
1708
1709
1710
1711
1712 bool addRegisterKilled(Register IncomingReg,
1713 const TargetRegisterInfo *RegInfo,
1714 bool AddIfNotFound = false);
1715
1716
1717
1718 void clearRegisterKills(Register Reg, const TargetRegisterInfo *RegInfo);
1719
1720
1721
1722
1723
1724 bool addRegisterDead(Register Reg, const TargetRegisterInfo *RegInfo,
1725 bool AddIfNotFound = false);
1726
1727
1728 void clearRegisterDeads(Register Reg);
1729
1730
1731
1732
1733 void setRegisterDefReadUndef(Register Reg, bool IsUndef = true);
1734
1735
1736
1737 void addRegisterDefined(Register Reg,
1738 const TargetRegisterInfo *RegInfo = nullptr);
1739
1740
1741
1742
1743
1744
1745 void setPhysRegsDeadExcept(ArrayRef<Register> UsedRegs,
1746 const TargetRegisterInfo &TRI);
1747
1748
1749
1750
1751 bool isSafeToMove(bool &SawStore) const;
1752
1753
1754
1755 bool wouldBeTriviallyDead() const;
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766 bool isDead(const MachineRegisterInfo &MRI,
1767 LiveRegUnits *LivePhysRegs = nullptr) const;
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779 bool mayAlias(BatchAAResults *AA, const MachineInstr &Other,
1780 bool UseTBAA) const;
1781 bool mayAlias(AAResults *AA, const MachineInstr &Other, bool UseTBAA) const;
1782
1783
1784
1785
1786
1787 bool hasOrderedMemoryRef() const;
1788
1789
1790
1791
1792
1793
1794
1795
1796 bool isDereferenceableInvariantLoad() const;
1797
1798
1799
1800 Register isConstantValuePHI() const;
1801
1802
1803
1804
1805
1806
1807
1808
1809 bool hasUnmodeledSideEffects() const;
1810
1811
1812 bool isLoadFoldBarrier() const;
1813
1814
1815 bool allDefsAreDead() const;
1816
1817
1818 bool allImplicitDefsAreDead() const;
1819
1820
1821 std::optional<LocationSize> getSpillSize(const TargetInstrInfo *TII) const;
1822
1823
1824 std::optional<LocationSize>
1825 getFoldedSpillSize(const TargetInstrInfo *TII) const;
1826
1827
1828 std::optional<LocationSize> getRestoreSize(const TargetInstrInfo *TII) const;
1829
1830
1831 std::optional<LocationSize>
1832 getFoldedRestoreSize(const TargetInstrInfo *TII) const;
1833
1834
1835
1836 void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI);
1837
1838
1839
1840
1841 LLT getTypeToPrint(unsigned OpIdx, SmallBitVector &PrintedTypes,
1842 const MachineRegisterInfo &MRI) const;
1843
1844
1845
1846
1847 bool hasComplexRegisterTies() const;
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858 void print(raw_ostream &OS, bool IsStandalone = true, bool SkipOpers = false,
1859 bool SkipDebugLoc = false, bool AddNewLine = true,
1860 const TargetInstrInfo *TII = nullptr) const;
1861 void print(raw_ostream &OS, ModuleSlotTracker &MST, bool IsStandalone = true,
1862 bool SkipOpers = false, bool SkipDebugLoc = false,
1863 bool AddNewLine = true,
1864 const TargetInstrInfo *TII = nullptr) const;
1865 void dump() const;
1866
1867
1868 void dumpr(const MachineRegisterInfo &MRI,
1869 unsigned MaxDepth = UINT_MAX) const;
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885 void addOperand(MachineFunction &MF, const MachineOperand &Op);
1886
1887
1888
1889
1890
1891
1892 void addOperand(const MachineOperand &Op);
1893
1894
1895 void insert(mop_iterator InsertBefore, ArrayRef<MachineOperand> Ops);
1896
1897
1898
1899 void setDesc(const MCInstrDesc &TID);
1900
1901
1902
1903 void setDebugLoc(DebugLoc DL) {
1904 DbgLoc = std::move(DL);
1905 assert(DbgLoc.hasTrivialDestructor() && "Expected trivial destructor");
1906 }
1907
1908
1909
1910 void removeOperand(unsigned OpNo);
1911
1912
1913
1914
1915
1916 void dropMemRefs(MachineFunction &MF);
1917
1918
1919
1920
1921
1922 void setMemRefs(MachineFunction &MF, ArrayRef<MachineMemOperand *> MemRefs);
1923
1924
1925
1926
1927 void addMemOperand(MachineFunction &MF, MachineMemOperand *MO);
1928
1929
1930
1931
1932
1933
1934
1935
1936 void cloneMemRefs(MachineFunction &MF, const MachineInstr &MI);
1937
1938
1939
1940
1941
1942
1943
1944
1945 void cloneMergedMemRefs(MachineFunction &MF,
1946 ArrayRef<const MachineInstr *> MIs);
1947
1948
1949
1950
1951
1952
1953 void setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol);
1954
1955
1956
1957
1958
1959
1960 void setPostInstrSymbol(MachineFunction &MF, MCSymbol *Symbol);
1961
1962
1963
1964 void cloneInstrSymbols(MachineFunction &MF, const MachineInstr &MI);
1965
1966
1967
1968
1969
1970 void setHeapAllocMarker(MachineFunction &MF, MDNode *MD);
1971
1972
1973
1974 void setPCSections(MachineFunction &MF, MDNode *MD);
1975
1976 void setMMRAMetadata(MachineFunction &MF, MDNode *MMRAs);
1977
1978
1979 void setCFIType(MachineFunction &MF, uint32_t Type);
1980
1981
1982
1983
1984 uint32_t mergeFlagsWith(const MachineInstr& Other) const;
1985
1986 static uint32_t copyFlagsFromInstruction(const Instruction &I);
1987
1988
1989 void copyIRFlags(const Instruction &I);
1990
1991
1992 void untieRegOperand(unsigned OpIdx) {
1993 MachineOperand &MO = getOperand(OpIdx);
1994 if (MO.isReg() && MO.isTied()) {
1995 getOperand(findTiedOperandIdx(OpIdx)).TiedTo = 0;
1996 MO.TiedTo = 0;
1997 }
1998 }
1999
2000
2001 void addImplicitDefUseOperands(MachineFunction &MF);
2002
2003
2004
2005 void collectDebugValues(SmallVectorImpl<MachineInstr *> &DbgValues);
2006
2007
2008
2009 void changeDebugValuesDefReg(Register Reg);
2010
2011
2012
2013 void setDebugValueUndef() {
2014 assert(isDebugValue() && "Must be a debug value instruction.");
2015 for (MachineOperand &MO : debug_operands()) {
2016 if (MO.isReg()) {
2017 MO.setReg(0);
2018 MO.setSubReg(0);
2019 }
2020 }
2021 }
2022
2023 std::tuple<Register, Register> getFirst2Regs() const {
2024 return std::tuple(getOperand(0).getReg(), getOperand(1).getReg());
2025 }
2026
2027 std::tuple<Register, Register, Register> getFirst3Regs() const {
2028 return std::tuple(getOperand(0).getReg(), getOperand(1).getReg(),
2029 getOperand(2).getReg());
2030 }
2031
2032 std::tuple<Register, Register, Register, Register> getFirst4Regs() const {
2033 return std::tuple(getOperand(0).getReg(), getOperand(1).getReg(),
2034 getOperand(2).getReg(), getOperand(3).getReg());
2035 }
2036
2037 std::tuple<Register, Register, Register, Register, Register>
2038 getFirst5Regs() const {
2039 return std::tuple(getOperand(0).getReg(), getOperand(1).getReg(),
2040 getOperand(2).getReg(), getOperand(3).getReg(),
2041 getOperand(4).getReg());
2042 }
2043
2044 std::tuple<LLT, LLT> getFirst2LLTs() const;
2045 std::tuple<LLT, LLT, LLT> getFirst3LLTs() const;
2046 std::tuple<LLT, LLT, LLT, LLT> getFirst4LLTs() const;
2047 std::tuple<LLT, LLT, LLT, LLT, LLT> getFirst5LLTs() const;
2048
2049 std::tuple<Register, LLT, Register, LLT> getFirst2RegLLTs() const;
2050 std::tuple<Register, LLT, Register, LLT, Register, LLT>
2051 getFirst3RegLLTs() const;
2052 std::tuple<Register, LLT, Register, LLT, Register, LLT, Register, LLT>
2053 getFirst4RegLLTs() const;
2054 std::tuple<Register, LLT, Register, LLT, Register, LLT, Register, LLT,
2055 Register, LLT>
2056 getFirst5RegLLTs() const;
2057
2058 private:
2059
2060
2061
2062 MachineRegisterInfo *getRegInfo();
2063 const MachineRegisterInfo *getRegInfo() const;
2064
2065
2066
2067
2068 void removeRegOperandsFromUseLists(MachineRegisterInfo&);
2069
2070
2071
2072
2073 void addRegOperandsToUseLists(MachineRegisterInfo&);
2074
2075
2076 bool hasPropertyInBundle(uint64_t Mask, QueryType Type) const;
2077
2078
2079
2080
2081 const TargetRegisterClass *getRegClassConstraintEffectForVRegImpl(
2082 unsigned OpIdx, Register Reg, const TargetRegisterClass *CurRC,
2083 const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const;
2084
2085
2086
2087 void setExtraInfo(MachineFunction &MF, ArrayRef<MachineMemOperand *> MMOs,
2088 MCSymbol *PreInstrSymbol, MCSymbol *PostInstrSymbol,
2089 MDNode *HeapAllocMarker, MDNode *PCSections,
2090 uint32_t CFIType, MDNode *MMRAs);
2091 };
2092
2093
2094
2095
2096
2097 struct MachineInstrExpressionTrait : DenseMapInfo<MachineInstr*> {
2098 static inline MachineInstr *getEmptyKey() {
2099 return nullptr;
2100 }
2101
2102 static inline MachineInstr *getTombstoneKey() {
2103 return reinterpret_cast<MachineInstr*>(-1);
2104 }
2105
2106 static unsigned getHashValue(const MachineInstr* const &MI);
2107
2108 static bool isEqual(const MachineInstr* const &LHS,
2109 const MachineInstr* const &RHS) {
2110 if (RHS == getEmptyKey() || RHS == getTombstoneKey() ||
2111 LHS == getEmptyKey() || LHS == getTombstoneKey())
2112 return LHS == RHS;
2113 return LHS->isIdenticalTo(*RHS, MachineInstr::IgnoreVRegDefs);
2114 }
2115 };
2116
2117
2118
2119
2120 inline raw_ostream& operator<<(raw_ostream &OS, const MachineInstr &MI) {
2121 MI.print(OS);
2122 return OS;
2123 }
2124
2125 }
2126
2127 #endif