File indexing completed on 2026-05-10 08:43:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CODEGEN_MACHINEOPERAND_H
0014 #define LLVM_CODEGEN_MACHINEOPERAND_H
0015
0016 #include "llvm/ADT/DenseMapInfo.h"
0017 #include "llvm/CodeGen/Register.h"
0018 #include "llvm/IR/Intrinsics.h"
0019 #include <cassert>
0020
0021 namespace llvm {
0022
0023 class LLT;
0024 class BlockAddress;
0025 class Constant;
0026 class ConstantFP;
0027 class ConstantInt;
0028 class GlobalValue;
0029 class MachineBasicBlock;
0030 class MachineInstr;
0031 class MachineRegisterInfo;
0032 class MCCFIInstruction;
0033 class MDNode;
0034 class ModuleSlotTracker;
0035 class TargetIntrinsicInfo;
0036 class TargetRegisterInfo;
0037 class hash_code;
0038 class raw_ostream;
0039 class MCSymbol;
0040
0041
0042
0043
0044
0045
0046
0047
0048 class MachineOperand {
0049 public:
0050 enum MachineOperandType : unsigned char {
0051 MO_Register,
0052 MO_Immediate,
0053 MO_CImmediate,
0054 MO_FPImmediate,
0055 MO_MachineBasicBlock,
0056 MO_FrameIndex,
0057 MO_ConstantPoolIndex,
0058 MO_TargetIndex,
0059 MO_JumpTableIndex,
0060 MO_ExternalSymbol,
0061 MO_GlobalAddress,
0062 MO_BlockAddress,
0063 MO_RegisterMask,
0064 MO_RegisterLiveOut,
0065 MO_Metadata,
0066 MO_MCSymbol,
0067 MO_CFIIndex,
0068 MO_IntrinsicID,
0069 MO_Predicate,
0070 MO_ShuffleMask,
0071 MO_DbgInstrRef,
0072 MO_Last = MO_DbgInstrRef
0073 };
0074
0075 private:
0076
0077
0078 unsigned OpKind : 8;
0079
0080
0081
0082
0083
0084 unsigned SubReg_TargetFlags : 12;
0085
0086
0087
0088
0089 unsigned TiedTo : 4;
0090
0091
0092
0093
0094 unsigned IsDef : 1;
0095
0096
0097
0098
0099 unsigned IsImp : 1;
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110 unsigned IsDeadOrKill : 1;
0111
0112
0113 unsigned IsRenamable : 1;
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 unsigned IsUndef : 1;
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143 unsigned IsInternalRead : 1;
0144
0145
0146
0147
0148 unsigned IsEarlyClobber : 1;
0149
0150
0151
0152 unsigned IsDebug : 1;
0153
0154
0155
0156
0157
0158 union {
0159 unsigned RegNo;
0160 unsigned OffsetLo;
0161 } SmallContents;
0162
0163
0164
0165 MachineInstr *ParentMI = nullptr;
0166
0167
0168 union ContentsUnion {
0169 ContentsUnion() {}
0170 MachineBasicBlock *MBB;
0171 const ConstantFP *CFP;
0172 const ConstantInt *CI;
0173 int64_t ImmVal;
0174 const uint32_t *RegMask;
0175 const MDNode *MD;
0176 MCSymbol *Sym;
0177 unsigned CFIIndex;
0178 Intrinsic::ID IntrinsicID;
0179 unsigned Pred;
0180 ArrayRef<int> ShuffleMask;
0181
0182 struct {
0183
0184 MachineOperand *Prev;
0185 MachineOperand *Next;
0186 } Reg;
0187
0188 struct {
0189 unsigned InstrIdx;
0190 unsigned OpIdx;
0191 } InstrRef;
0192
0193
0194
0195 struct {
0196 union {
0197 int Index;
0198 const char *SymbolName;
0199 const GlobalValue *GV;
0200 const BlockAddress *BA;
0201 } Val;
0202
0203 int OffsetHi;
0204 } OffsetedInfo;
0205 } Contents;
0206
0207 explicit MachineOperand(MachineOperandType K)
0208 : OpKind(K), SubReg_TargetFlags(0) {
0209
0210 static_assert(alignof(MachineOperand) <= alignof(int64_t),
0211 "MachineOperand shouldn't be more than 8 byte aligned");
0212 static_assert(sizeof(Contents) <= 2 * sizeof(void *),
0213 "Contents should be at most two pointers");
0214 static_assert(sizeof(MachineOperand) <=
0215 alignTo<alignof(int64_t)>(2 * sizeof(unsigned) +
0216 3 * sizeof(void *)),
0217 "MachineOperand too big. Should be Kind, SmallContents, "
0218 "ParentMI, and Contents");
0219 }
0220
0221 public:
0222
0223
0224 MachineOperandType getType() const { return (MachineOperandType)OpKind; }
0225
0226 unsigned getTargetFlags() const {
0227 return isReg() ? 0 : SubReg_TargetFlags;
0228 }
0229 void setTargetFlags(unsigned F) {
0230 assert(!isReg() && "Register operands can't have target flags");
0231 SubReg_TargetFlags = F;
0232 assert(SubReg_TargetFlags == F && "Target flags out of range");
0233 }
0234 void addTargetFlag(unsigned F) {
0235 assert(!isReg() && "Register operands can't have target flags");
0236 SubReg_TargetFlags |= F;
0237 assert((SubReg_TargetFlags & F) && "Target flags out of range");
0238 }
0239
0240
0241
0242
0243 MachineInstr *getParent() { return ParentMI; }
0244 const MachineInstr *getParent() const { return ParentMI; }
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 void clearParent() { ParentMI = nullptr; }
0255
0256
0257 unsigned getOperandNo() const;
0258
0259
0260
0261
0262
0263 static void printSubRegIdx(raw_ostream &OS, uint64_t Index,
0264 const TargetRegisterInfo *TRI);
0265
0266
0267 static void printTargetFlags(raw_ostream& OS, const MachineOperand &Op);
0268
0269
0270 static void printSymbol(raw_ostream &OS, MCSymbol &Sym);
0271
0272
0273 static void printStackObjectReference(raw_ostream &OS, unsigned FrameIndex,
0274 bool IsFixed, StringRef Name);
0275
0276
0277 static void printOperandOffset(raw_ostream &OS, int64_t Offset);
0278
0279
0280 static void printIRSlotNumber(raw_ostream &OS, int Slot);
0281
0282
0283
0284
0285
0286 void print(raw_ostream &os, const TargetRegisterInfo *TRI = nullptr,
0287 const TargetIntrinsicInfo *IntrinsicInfo = nullptr) const;
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310 void print(raw_ostream &os, ModuleSlotTracker &MST, LLT TypeToPrint,
0311 std::optional<unsigned> OpIdx, bool PrintDef, bool IsStandalone,
0312 bool ShouldPrintRegisterTies, unsigned TiedOperandIdx,
0313 const TargetRegisterInfo *TRI,
0314 const TargetIntrinsicInfo *IntrinsicInfo) const;
0315
0316
0317
0318 void print(raw_ostream &os, LLT TypeToPrint,
0319 const TargetRegisterInfo *TRI = nullptr,
0320 const TargetIntrinsicInfo *IntrinsicInfo = nullptr) const;
0321
0322 void dump() const;
0323
0324
0325
0326
0327
0328
0329 bool isReg() const { return OpKind == MO_Register; }
0330
0331 bool isImm() const { return OpKind == MO_Immediate; }
0332
0333 bool isCImm() const { return OpKind == MO_CImmediate; }
0334
0335 bool isFPImm() const { return OpKind == MO_FPImmediate; }
0336
0337 bool isMBB() const { return OpKind == MO_MachineBasicBlock; }
0338
0339 bool isFI() const { return OpKind == MO_FrameIndex; }
0340
0341 bool isCPI() const { return OpKind == MO_ConstantPoolIndex; }
0342
0343 bool isTargetIndex() const { return OpKind == MO_TargetIndex; }
0344
0345 bool isJTI() const { return OpKind == MO_JumpTableIndex; }
0346
0347 bool isGlobal() const { return OpKind == MO_GlobalAddress; }
0348
0349 bool isSymbol() const { return OpKind == MO_ExternalSymbol; }
0350
0351 bool isBlockAddress() const { return OpKind == MO_BlockAddress; }
0352
0353 bool isRegMask() const { return OpKind == MO_RegisterMask; }
0354
0355 bool isRegLiveOut() const { return OpKind == MO_RegisterLiveOut; }
0356
0357 bool isMetadata() const { return OpKind == MO_Metadata; }
0358 bool isMCSymbol() const { return OpKind == MO_MCSymbol; }
0359 bool isDbgInstrRef() const { return OpKind == MO_DbgInstrRef; }
0360 bool isCFIIndex() const { return OpKind == MO_CFIIndex; }
0361 bool isIntrinsicID() const { return OpKind == MO_IntrinsicID; }
0362 bool isPredicate() const { return OpKind == MO_Predicate; }
0363 bool isShuffleMask() const { return OpKind == MO_ShuffleMask; }
0364
0365
0366
0367
0368
0369 Register getReg() const {
0370 assert(isReg() && "This is not a register operand!");
0371 return Register(SmallContents.RegNo);
0372 }
0373
0374 unsigned getSubReg() const {
0375 assert(isReg() && "Wrong MachineOperand accessor");
0376 return SubReg_TargetFlags;
0377 }
0378
0379 bool isUse() const {
0380 assert(isReg() && "Wrong MachineOperand accessor");
0381 return !IsDef;
0382 }
0383
0384 bool isDef() const {
0385 assert(isReg() && "Wrong MachineOperand accessor");
0386 return IsDef;
0387 }
0388
0389 bool isImplicit() const {
0390 assert(isReg() && "Wrong MachineOperand accessor");
0391 return IsImp;
0392 }
0393
0394 bool isDead() const {
0395 assert(isReg() && "Wrong MachineOperand accessor");
0396 return IsDeadOrKill & IsDef;
0397 }
0398
0399 bool isKill() const {
0400 assert(isReg() && "Wrong MachineOperand accessor");
0401 return IsDeadOrKill & !IsDef;
0402 }
0403
0404 bool isUndef() const {
0405 assert(isReg() && "Wrong MachineOperand accessor");
0406 return IsUndef;
0407 }
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438 bool isRenamable() const;
0439
0440 bool isInternalRead() const {
0441 assert(isReg() && "Wrong MachineOperand accessor");
0442 return IsInternalRead;
0443 }
0444
0445 bool isEarlyClobber() const {
0446 assert(isReg() && "Wrong MachineOperand accessor");
0447 return IsEarlyClobber;
0448 }
0449
0450 bool isTied() const {
0451 assert(isReg() && "Wrong MachineOperand accessor");
0452 return TiedTo;
0453 }
0454
0455 bool isDebug() const {
0456 assert(isReg() && "Wrong MachineOperand accessor");
0457 return IsDebug;
0458 }
0459
0460
0461
0462
0463
0464
0465
0466
0467 bool readsReg() const {
0468 assert(isReg() && "Wrong MachineOperand accessor");
0469 return !isUndef() && !isInternalRead() && (isUse() || getSubReg());
0470 }
0471
0472
0473
0474 bool isValidExcessOperand() const {
0475 if ((isReg() && isImplicit()) || isRegMask())
0476 return true;
0477
0478
0479 return isMetadata() || isMCSymbol();
0480 }
0481
0482
0483
0484
0485
0486
0487
0488 void setReg(Register Reg);
0489
0490 void setSubReg(unsigned subReg) {
0491 assert(isReg() && "Wrong MachineOperand mutator");
0492 SubReg_TargetFlags = subReg;
0493 assert(SubReg_TargetFlags == subReg && "SubReg out of range");
0494 }
0495
0496
0497
0498
0499
0500
0501 void substVirtReg(Register Reg, unsigned SubIdx, const TargetRegisterInfo&);
0502
0503
0504
0505
0506
0507 void substPhysReg(MCRegister Reg, const TargetRegisterInfo&);
0508
0509 void setIsUse(bool Val = true) { setIsDef(!Val); }
0510
0511
0512 void setIsDef(bool Val = true);
0513
0514 void setImplicit(bool Val = true) {
0515 assert(isReg() && "Wrong MachineOperand mutator");
0516 IsImp = Val;
0517 }
0518
0519 void setIsKill(bool Val = true) {
0520 assert(isReg() && !IsDef && "Wrong MachineOperand mutator");
0521 assert((!Val || !isDebug()) && "Marking a debug operation as kill");
0522 IsDeadOrKill = Val;
0523 }
0524
0525 void setIsDead(bool Val = true) {
0526 assert(isReg() && IsDef && "Wrong MachineOperand mutator");
0527 IsDeadOrKill = Val;
0528 }
0529
0530 void setIsUndef(bool Val = true) {
0531 assert(isReg() && "Wrong MachineOperand mutator");
0532 IsUndef = Val;
0533 }
0534
0535 void setIsRenamable(bool Val = true);
0536
0537 void setIsInternalRead(bool Val = true) {
0538 assert(isReg() && "Wrong MachineOperand mutator");
0539 IsInternalRead = Val;
0540 }
0541
0542 void setIsEarlyClobber(bool Val = true) {
0543 assert(isReg() && IsDef && "Wrong MachineOperand mutator");
0544 IsEarlyClobber = Val;
0545 }
0546
0547 void setIsDebug(bool Val = true) {
0548 assert(isReg() && !IsDef && "Wrong MachineOperand mutator");
0549 IsDebug = Val;
0550 }
0551
0552
0553
0554
0555
0556 int64_t getImm() const {
0557 assert(isImm() && "Wrong MachineOperand accessor");
0558 return Contents.ImmVal;
0559 }
0560
0561 const ConstantInt *getCImm() const {
0562 assert(isCImm() && "Wrong MachineOperand accessor");
0563 return Contents.CI;
0564 }
0565
0566 const ConstantFP *getFPImm() const {
0567 assert(isFPImm() && "Wrong MachineOperand accessor");
0568 return Contents.CFP;
0569 }
0570
0571 MachineBasicBlock *getMBB() const {
0572 assert(isMBB() && "Wrong MachineOperand accessor");
0573 return Contents.MBB;
0574 }
0575
0576 int getIndex() const {
0577 assert((isFI() || isCPI() || isTargetIndex() || isJTI()) &&
0578 "Wrong MachineOperand accessor");
0579 return Contents.OffsetedInfo.Val.Index;
0580 }
0581
0582 const GlobalValue *getGlobal() const {
0583 assert(isGlobal() && "Wrong MachineOperand accessor");
0584 return Contents.OffsetedInfo.Val.GV;
0585 }
0586
0587 const BlockAddress *getBlockAddress() const {
0588 assert(isBlockAddress() && "Wrong MachineOperand accessor");
0589 return Contents.OffsetedInfo.Val.BA;
0590 }
0591
0592 MCSymbol *getMCSymbol() const {
0593 assert(isMCSymbol() && "Wrong MachineOperand accessor");
0594 return Contents.Sym;
0595 }
0596
0597 unsigned getInstrRefInstrIndex() const {
0598 assert(isDbgInstrRef() && "Wrong MachineOperand accessor");
0599 return Contents.InstrRef.InstrIdx;
0600 }
0601
0602 unsigned getInstrRefOpIndex() const {
0603 assert(isDbgInstrRef() && "Wrong MachineOperand accessor");
0604 return Contents.InstrRef.OpIdx;
0605 }
0606
0607 unsigned getCFIIndex() const {
0608 assert(isCFIIndex() && "Wrong MachineOperand accessor");
0609 return Contents.CFIIndex;
0610 }
0611
0612 Intrinsic::ID getIntrinsicID() const {
0613 assert(isIntrinsicID() && "Wrong MachineOperand accessor");
0614 return Contents.IntrinsicID;
0615 }
0616
0617 unsigned getPredicate() const {
0618 assert(isPredicate() && "Wrong MachineOperand accessor");
0619 return Contents.Pred;
0620 }
0621
0622 ArrayRef<int> getShuffleMask() const {
0623 assert(isShuffleMask() && "Wrong MachineOperand accessor");
0624 return Contents.ShuffleMask;
0625 }
0626
0627
0628
0629 int64_t getOffset() const {
0630 assert((isGlobal() || isSymbol() || isMCSymbol() || isCPI() ||
0631 isTargetIndex() || isBlockAddress()) &&
0632 "Wrong MachineOperand accessor");
0633 return int64_t(uint64_t(Contents.OffsetedInfo.OffsetHi) << 32) |
0634 SmallContents.OffsetLo;
0635 }
0636
0637 const char *getSymbolName() const {
0638 assert(isSymbol() && "Wrong MachineOperand accessor");
0639 return Contents.OffsetedInfo.Val.SymbolName;
0640 }
0641
0642
0643
0644
0645
0646 static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg) {
0647
0648 assert((!PhysReg.isValid() || PhysReg.isPhysical()) &&
0649 "Not a physical register");
0650 return !(RegMask[PhysReg.id() / 32] & (1u << PhysReg.id() % 32));
0651 }
0652
0653
0654 bool clobbersPhysReg(MCRegister PhysReg) const {
0655 return clobbersPhysReg(getRegMask(), PhysReg);
0656 }
0657
0658
0659
0660 const uint32_t *getRegMask() const {
0661 assert(isRegMask() && "Wrong MachineOperand accessor");
0662 return Contents.RegMask;
0663 }
0664
0665
0666 static unsigned getRegMaskSize(unsigned NumRegs) {
0667 return (NumRegs + 31) / 32;
0668 }
0669
0670
0671 const uint32_t *getRegLiveOut() const {
0672 assert(isRegLiveOut() && "Wrong MachineOperand accessor");
0673 return Contents.RegMask;
0674 }
0675
0676 const MDNode *getMetadata() const {
0677 assert(isMetadata() && "Wrong MachineOperand accessor");
0678 return Contents.MD;
0679 }
0680
0681
0682
0683
0684
0685 void setImm(int64_t immVal) {
0686 assert(isImm() && "Wrong MachineOperand mutator");
0687 Contents.ImmVal = immVal;
0688 }
0689
0690 void setCImm(const ConstantInt *CI) {
0691 assert(isCImm() && "Wrong MachineOperand mutator");
0692 Contents.CI = CI;
0693 }
0694
0695 void setFPImm(const ConstantFP *CFP) {
0696 assert(isFPImm() && "Wrong MachineOperand mutator");
0697 Contents.CFP = CFP;
0698 }
0699
0700 void setOffset(int64_t Offset) {
0701 assert((isGlobal() || isSymbol() || isMCSymbol() || isCPI() ||
0702 isTargetIndex() || isBlockAddress()) &&
0703 "Wrong MachineOperand mutator");
0704 SmallContents.OffsetLo = unsigned(Offset);
0705 Contents.OffsetedInfo.OffsetHi = int(Offset >> 32);
0706 }
0707
0708 void setIndex(int Idx) {
0709 assert((isFI() || isCPI() || isTargetIndex() || isJTI()) &&
0710 "Wrong MachineOperand mutator");
0711 Contents.OffsetedInfo.Val.Index = Idx;
0712 }
0713
0714 void setMetadata(const MDNode *MD) {
0715 assert(isMetadata() && "Wrong MachineOperand mutator");
0716 Contents.MD = MD;
0717 }
0718
0719 void setInstrRefInstrIndex(unsigned InstrIdx) {
0720 assert(isDbgInstrRef() && "Wrong MachineOperand mutator");
0721 Contents.InstrRef.InstrIdx = InstrIdx;
0722 }
0723 void setInstrRefOpIndex(unsigned OpIdx) {
0724 assert(isDbgInstrRef() && "Wrong MachineOperand mutator");
0725 Contents.InstrRef.OpIdx = OpIdx;
0726 }
0727
0728 void setMBB(MachineBasicBlock *MBB) {
0729 assert(isMBB() && "Wrong MachineOperand mutator");
0730 Contents.MBB = MBB;
0731 }
0732
0733
0734
0735
0736
0737 void setRegMask(const uint32_t *RegMaskPtr) {
0738 assert(isRegMask() && "Wrong MachineOperand mutator");
0739 Contents.RegMask = RegMaskPtr;
0740 }
0741
0742 void setIntrinsicID(Intrinsic::ID IID) {
0743 assert(isIntrinsicID() && "Wrong MachineOperand mutator");
0744 Contents.IntrinsicID = IID;
0745 }
0746
0747 void setPredicate(unsigned Predicate) {
0748 assert(isPredicate() && "Wrong MachineOperand mutator");
0749 Contents.Pred = Predicate;
0750 }
0751
0752
0753
0754
0755
0756
0757
0758
0759 bool isIdenticalTo(const MachineOperand &Other) const;
0760
0761
0762
0763
0764
0765
0766
0767 friend hash_code hash_value(const MachineOperand &MO);
0768
0769
0770
0771
0772 void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags = 0);
0773
0774
0775
0776
0777 void ChangeToFPImmediate(const ConstantFP *FPImm, unsigned TargetFlags = 0);
0778
0779
0780 void ChangeToES(const char *SymName, unsigned TargetFlags = 0);
0781
0782
0783 void ChangeToGA(const GlobalValue *GV, int64_t Offset,
0784 unsigned TargetFlags = 0);
0785
0786
0787 void ChangeToBA(const BlockAddress *BA, int64_t Offset,
0788 unsigned TargetFlags = 0);
0789
0790
0791 void ChangeToMCSymbol(MCSymbol *Sym, unsigned TargetFlags = 0);
0792
0793
0794 void ChangeToFrameIndex(int Idx, unsigned TargetFlags = 0);
0795
0796
0797 void ChangeToTargetIndex(unsigned Idx, int64_t Offset,
0798 unsigned TargetFlags = 0);
0799
0800
0801 void ChangeToDbgInstrRef(unsigned InstrIdx, unsigned OpIdx,
0802 unsigned TargetFlags = 0);
0803
0804
0805
0806
0807 void ChangeToRegister(Register Reg, bool isDef, bool isImp = false,
0808 bool isKill = false, bool isDead = false,
0809 bool isUndef = false, bool isDebug = false);
0810
0811
0812
0813
0814 const char *getTargetIndexName() const;
0815
0816
0817
0818
0819
0820 static MachineOperand CreateImm(int64_t Val) {
0821 MachineOperand Op(MachineOperand::MO_Immediate);
0822 Op.setImm(Val);
0823 return Op;
0824 }
0825
0826 static MachineOperand CreateCImm(const ConstantInt *CI) {
0827 MachineOperand Op(MachineOperand::MO_CImmediate);
0828 Op.Contents.CI = CI;
0829 return Op;
0830 }
0831
0832 static MachineOperand CreateFPImm(const ConstantFP *CFP) {
0833 MachineOperand Op(MachineOperand::MO_FPImmediate);
0834 Op.Contents.CFP = CFP;
0835 return Op;
0836 }
0837
0838 static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp = false,
0839 bool isKill = false, bool isDead = false,
0840 bool isUndef = false,
0841 bool isEarlyClobber = false,
0842 unsigned SubReg = 0, bool isDebug = false,
0843 bool isInternalRead = false,
0844 bool isRenamable = false) {
0845 assert(!(isDead && !isDef) && "Dead flag on non-def");
0846 assert(!(isKill && isDef) && "Kill flag on def");
0847 MachineOperand Op(MachineOperand::MO_Register);
0848 Op.IsDef = isDef;
0849 Op.IsImp = isImp;
0850 Op.IsDeadOrKill = isKill | isDead;
0851 Op.IsRenamable = isRenamable;
0852 Op.IsUndef = isUndef;
0853 Op.IsInternalRead = isInternalRead;
0854 Op.IsEarlyClobber = isEarlyClobber;
0855 Op.TiedTo = 0;
0856 Op.IsDebug = isDebug;
0857 Op.SmallContents.RegNo = Reg.id();
0858 Op.Contents.Reg.Prev = nullptr;
0859 Op.Contents.Reg.Next = nullptr;
0860 Op.setSubReg(SubReg);
0861 return Op;
0862 }
0863 static MachineOperand CreateMBB(MachineBasicBlock *MBB,
0864 unsigned TargetFlags = 0) {
0865 MachineOperand Op(MachineOperand::MO_MachineBasicBlock);
0866 Op.setMBB(MBB);
0867 Op.setTargetFlags(TargetFlags);
0868 return Op;
0869 }
0870 static MachineOperand CreateFI(int Idx) {
0871 MachineOperand Op(MachineOperand::MO_FrameIndex);
0872 Op.setIndex(Idx);
0873 return Op;
0874 }
0875 static MachineOperand CreateCPI(unsigned Idx, int Offset,
0876 unsigned TargetFlags = 0) {
0877 MachineOperand Op(MachineOperand::MO_ConstantPoolIndex);
0878 Op.setIndex(Idx);
0879 Op.setOffset(Offset);
0880 Op.setTargetFlags(TargetFlags);
0881 return Op;
0882 }
0883 static MachineOperand CreateTargetIndex(unsigned Idx, int64_t Offset,
0884 unsigned TargetFlags = 0) {
0885 MachineOperand Op(MachineOperand::MO_TargetIndex);
0886 Op.setIndex(Idx);
0887 Op.setOffset(Offset);
0888 Op.setTargetFlags(TargetFlags);
0889 return Op;
0890 }
0891 static MachineOperand CreateJTI(unsigned Idx, unsigned TargetFlags = 0) {
0892 MachineOperand Op(MachineOperand::MO_JumpTableIndex);
0893 Op.setIndex(Idx);
0894 Op.setTargetFlags(TargetFlags);
0895 return Op;
0896 }
0897 static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset,
0898 unsigned TargetFlags = 0) {
0899 MachineOperand Op(MachineOperand::MO_GlobalAddress);
0900 Op.Contents.OffsetedInfo.Val.GV = GV;
0901 Op.setOffset(Offset);
0902 Op.setTargetFlags(TargetFlags);
0903 return Op;
0904 }
0905 static MachineOperand CreateES(const char *SymName,
0906 unsigned TargetFlags = 0) {
0907 MachineOperand Op(MachineOperand::MO_ExternalSymbol);
0908 Op.Contents.OffsetedInfo.Val.SymbolName = SymName;
0909 Op.setOffset(0);
0910 Op.setTargetFlags(TargetFlags);
0911 return Op;
0912 }
0913 static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset,
0914 unsigned TargetFlags = 0) {
0915 MachineOperand Op(MachineOperand::MO_BlockAddress);
0916 Op.Contents.OffsetedInfo.Val.BA = BA;
0917 Op.setOffset(Offset);
0918 Op.setTargetFlags(TargetFlags);
0919 return Op;
0920 }
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933 static MachineOperand CreateRegMask(const uint32_t *Mask) {
0934 assert(Mask && "Missing register mask");
0935 MachineOperand Op(MachineOperand::MO_RegisterMask);
0936 Op.Contents.RegMask = Mask;
0937 return Op;
0938 }
0939 static MachineOperand CreateRegLiveOut(const uint32_t *Mask) {
0940 assert(Mask && "Missing live-out register mask");
0941 MachineOperand Op(MachineOperand::MO_RegisterLiveOut);
0942 Op.Contents.RegMask = Mask;
0943 return Op;
0944 }
0945 static MachineOperand CreateMetadata(const MDNode *Meta) {
0946 MachineOperand Op(MachineOperand::MO_Metadata);
0947 Op.Contents.MD = Meta;
0948 return Op;
0949 }
0950
0951 static MachineOperand CreateMCSymbol(MCSymbol *Sym,
0952 unsigned TargetFlags = 0) {
0953 MachineOperand Op(MachineOperand::MO_MCSymbol);
0954 Op.Contents.Sym = Sym;
0955 Op.setOffset(0);
0956 Op.setTargetFlags(TargetFlags);
0957 return Op;
0958 }
0959
0960 static MachineOperand CreateDbgInstrRef(unsigned InstrIdx, unsigned OpIdx) {
0961 MachineOperand Op(MachineOperand::MO_DbgInstrRef);
0962 Op.Contents.InstrRef.InstrIdx = InstrIdx;
0963 Op.Contents.InstrRef.OpIdx = OpIdx;
0964 return Op;
0965 }
0966
0967 static MachineOperand CreateCFIIndex(unsigned CFIIndex) {
0968 MachineOperand Op(MachineOperand::MO_CFIIndex);
0969 Op.Contents.CFIIndex = CFIIndex;
0970 return Op;
0971 }
0972
0973 static MachineOperand CreateIntrinsicID(Intrinsic::ID ID) {
0974 MachineOperand Op(MachineOperand::MO_IntrinsicID);
0975 Op.Contents.IntrinsicID = ID;
0976 return Op;
0977 }
0978
0979 static MachineOperand CreatePredicate(unsigned Pred) {
0980 MachineOperand Op(MachineOperand::MO_Predicate);
0981 Op.Contents.Pred = Pred;
0982 return Op;
0983 }
0984
0985 static MachineOperand CreateShuffleMask(ArrayRef<int> Mask) {
0986 MachineOperand Op(MachineOperand::MO_ShuffleMask);
0987 Op.Contents.ShuffleMask = Mask;
0988 return Op;
0989 }
0990
0991 friend class MachineInstr;
0992 friend class MachineRegisterInfo;
0993
0994 private:
0995
0996
0997 void removeRegFromUses();
0998
0999
1000 enum : unsigned char {
1001 MO_Empty = MO_Last + 1,
1002 MO_Tombstone,
1003 };
1004
1005 friend struct DenseMapInfo<MachineOperand>;
1006
1007
1008
1009
1010
1011
1012
1013
1014 bool isOnRegUseList() const {
1015 assert(isReg() && "Can only add reg operand to use lists");
1016 return Contents.Reg.Prev != nullptr;
1017 }
1018 };
1019
1020 template <> struct DenseMapInfo<MachineOperand> {
1021 static MachineOperand getEmptyKey() {
1022 return MachineOperand(static_cast<MachineOperand::MachineOperandType>(
1023 MachineOperand::MO_Empty));
1024 }
1025 static MachineOperand getTombstoneKey() {
1026 return MachineOperand(static_cast<MachineOperand::MachineOperandType>(
1027 MachineOperand::MO_Tombstone));
1028 }
1029 static unsigned getHashValue(const MachineOperand &MO) {
1030 return hash_value(MO);
1031 }
1032 static bool isEqual(const MachineOperand &LHS, const MachineOperand &RHS) {
1033 if (LHS.getType() == static_cast<MachineOperand::MachineOperandType>(
1034 MachineOperand::MO_Empty) ||
1035 LHS.getType() == static_cast<MachineOperand::MachineOperandType>(
1036 MachineOperand::MO_Tombstone))
1037 return LHS.getType() == RHS.getType();
1038 return LHS.isIdenticalTo(RHS);
1039 }
1040 };
1041
1042 inline raw_ostream &operator<<(raw_ostream &OS, const MachineOperand &MO) {
1043 MO.print(OS);
1044 return OS;
1045 }
1046
1047
1048
1049 hash_code hash_value(const MachineOperand &MO);
1050 }
1051
1052 #endif