File indexing completed on 2026-05-10 08:44:14
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_MC_MCREGISTERINFO_H
0016 #define LLVM_MC_MCREGISTERINFO_H
0017
0018 #include "llvm/ADT/DenseMap.h"
0019 #include "llvm/ADT/iterator.h"
0020 #include "llvm/ADT/iterator_range.h"
0021 #include "llvm/MC/LaneBitmask.h"
0022 #include "llvm/MC/MCRegister.h"
0023 #include <cassert>
0024 #include <cstdint>
0025 #include <iterator>
0026 #include <utility>
0027
0028 namespace llvm {
0029
0030 class MCRegUnitIterator;
0031 class MCSubRegIterator;
0032 class MCSuperRegIterator;
0033
0034
0035 class MCRegisterClass {
0036 public:
0037 using iterator = const MCPhysReg*;
0038 using const_iterator = const MCPhysReg*;
0039
0040 const iterator RegsBegin;
0041 const uint8_t *const RegSet;
0042 const uint32_t NameIdx;
0043 const uint16_t RegsSize;
0044 const uint16_t RegSetSize;
0045 const uint16_t ID;
0046 const uint16_t RegSizeInBits;
0047 const int8_t CopyCost;
0048 const bool Allocatable;
0049 const bool BaseClass;
0050
0051
0052
0053 unsigned getID() const { return ID; }
0054
0055
0056
0057 iterator begin() const { return RegsBegin; }
0058 iterator end() const { return RegsBegin + RegsSize; }
0059
0060
0061
0062 unsigned getNumRegs() const { return RegsSize; }
0063
0064
0065
0066 unsigned getRegister(unsigned i) const {
0067 assert(i < getNumRegs() && "Register number out of range!");
0068 return RegsBegin[i];
0069 }
0070
0071
0072
0073 bool contains(MCRegister Reg) const {
0074 unsigned RegNo = Reg.id();
0075 unsigned InByte = RegNo % 8;
0076 unsigned Byte = RegNo / 8;
0077 if (Byte >= RegSetSize)
0078 return false;
0079 return (RegSet[Byte] & (1 << InByte)) != 0;
0080 }
0081
0082
0083 bool contains(MCRegister Reg1, MCRegister Reg2) const {
0084 return contains(Reg1) && contains(Reg2);
0085 }
0086
0087
0088
0089
0090
0091 unsigned getSizeInBits() const { return RegSizeInBits; }
0092
0093
0094
0095
0096 int getCopyCost() const { return CopyCost; }
0097
0098
0099
0100 bool isAllocatable() const { return Allocatable; }
0101
0102
0103 bool isBaseClass() const { return BaseClass; }
0104 };
0105
0106
0107
0108
0109
0110
0111
0112
0113 struct MCRegisterDesc {
0114 uint32_t Name;
0115 uint32_t SubRegs;
0116 uint32_t SuperRegs;
0117
0118
0119
0120 uint32_t SubRegIndices;
0121
0122
0123
0124 uint32_t RegUnits;
0125
0126
0127
0128 uint16_t RegUnitLaneMasks;
0129
0130
0131 bool IsConstant;
0132
0133
0134 bool IsArtificial;
0135 };
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149 class MCRegisterInfo {
0150 public:
0151 using regclass_iterator = const MCRegisterClass *;
0152
0153
0154
0155 struct DwarfLLVMRegPair {
0156 unsigned FromReg;
0157 unsigned ToReg;
0158
0159 bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromReg; }
0160 };
0161
0162 private:
0163 const MCRegisterDesc *Desc;
0164 unsigned NumRegs;
0165 MCRegister RAReg;
0166 MCRegister PCReg;
0167 const MCRegisterClass *Classes;
0168 unsigned NumClasses;
0169 unsigned NumRegUnits;
0170 const MCPhysReg (*RegUnitRoots)[2];
0171 const int16_t *DiffLists;
0172 const LaneBitmask *RegUnitMaskSequences;
0173
0174 const char *RegStrings;
0175 const char *RegClassStrings;
0176 const uint16_t *SubRegIndices;
0177
0178 unsigned NumSubRegIndices;
0179 const uint16_t *RegEncodingTable;
0180
0181
0182 unsigned L2DwarfRegsSize;
0183 unsigned EHL2DwarfRegsSize;
0184 unsigned Dwarf2LRegsSize;
0185 unsigned EHDwarf2LRegsSize;
0186 const DwarfLLVMRegPair *L2DwarfRegs;
0187 const DwarfLLVMRegPair *EHL2DwarfRegs;
0188 const DwarfLLVMRegPair *Dwarf2LRegs;
0189 const DwarfLLVMRegPair *EHDwarf2LRegs;
0190 DenseMap<MCRegister, int> L2SEHRegs;
0191 DenseMap<MCRegister, int> L2CVRegs;
0192
0193 mutable std::vector<std::vector<MCPhysReg>> RegAliasesCache;
0194 ArrayRef<MCPhysReg> getCachedAliasesOf(MCRegister R) const;
0195
0196
0197
0198 class DiffListIterator
0199 : public iterator_facade_base<DiffListIterator, std::forward_iterator_tag,
0200 unsigned> {
0201 unsigned Val = 0;
0202 const int16_t *List = nullptr;
0203
0204 public:
0205
0206
0207 DiffListIterator() = default;
0208
0209
0210 void init(unsigned InitVal, const int16_t *DiffList) {
0211 Val = InitVal;
0212 List = DiffList;
0213 }
0214
0215
0216 bool isValid() const { return List; }
0217
0218
0219 const unsigned &operator*() const { return Val; }
0220
0221 using DiffListIterator::iterator_facade_base::operator++;
0222
0223 DiffListIterator &operator++() {
0224 assert(isValid() && "Cannot move off the end of the list.");
0225 int16_t D = *List++;
0226 Val += D;
0227
0228 if (!D)
0229 List = nullptr;
0230 return *this;
0231 }
0232
0233 bool operator==(const DiffListIterator &Other) const {
0234 return List == Other.List;
0235 }
0236 };
0237
0238 public:
0239
0240
0241 iterator_range<MCSubRegIterator> subregs(MCRegister Reg) const;
0242
0243
0244
0245 iterator_range<MCSubRegIterator> subregs_inclusive(MCRegister Reg) const;
0246
0247
0248
0249 iterator_range<MCSuperRegIterator> superregs(MCRegister Reg) const;
0250
0251
0252
0253 iterator_range<MCSuperRegIterator> superregs_inclusive(MCRegister Reg) const;
0254
0255
0256
0257 detail::concat_range<const MCPhysReg, iterator_range<MCSubRegIterator>,
0258 iterator_range<MCSuperRegIterator>>
0259 sub_and_superregs_inclusive(MCRegister Reg) const;
0260
0261
0262 iterator_range<MCRegUnitIterator> regunits(MCRegister Reg) const;
0263
0264
0265
0266 friend class MCSubRegIterator;
0267 friend class MCSubRegIndexIterator;
0268 friend class MCSuperRegIterator;
0269 friend class MCRegUnitIterator;
0270 friend class MCRegUnitMaskIterator;
0271 friend class MCRegUnitRootIterator;
0272 friend class MCRegAliasIterator;
0273
0274 virtual ~MCRegisterInfo() {}
0275
0276
0277
0278 void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
0279 unsigned PC, const MCRegisterClass *C, unsigned NC,
0280 const MCPhysReg (*RURoots)[2], unsigned NRU,
0281 const int16_t *DL, const LaneBitmask *RUMS,
0282 const char *Strings, const char *ClassStrings,
0283 const uint16_t *SubIndices, unsigned NumIndices,
0284 const uint16_t *RET) {
0285 Desc = D;
0286 NumRegs = NR;
0287 RAReg = RA;
0288 PCReg = PC;
0289 Classes = C;
0290 DiffLists = DL;
0291 RegUnitMaskSequences = RUMS;
0292 RegStrings = Strings;
0293 RegClassStrings = ClassStrings;
0294 NumClasses = NC;
0295 RegUnitRoots = RURoots;
0296 NumRegUnits = NRU;
0297 SubRegIndices = SubIndices;
0298 NumSubRegIndices = NumIndices;
0299 RegEncodingTable = RET;
0300
0301
0302 EHL2DwarfRegs = nullptr;
0303 EHL2DwarfRegsSize = 0;
0304 L2DwarfRegs = nullptr;
0305 L2DwarfRegsSize = 0;
0306 EHDwarf2LRegs = nullptr;
0307 EHDwarf2LRegsSize = 0;
0308 Dwarf2LRegs = nullptr;
0309 Dwarf2LRegsSize = 0;
0310
0311 RegAliasesCache.resize(NumRegs);
0312 }
0313
0314
0315
0316
0317 void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size,
0318 bool isEH) {
0319 if (isEH) {
0320 EHL2DwarfRegs = Map;
0321 EHL2DwarfRegsSize = Size;
0322 } else {
0323 L2DwarfRegs = Map;
0324 L2DwarfRegsSize = Size;
0325 }
0326 }
0327
0328
0329
0330
0331 void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size,
0332 bool isEH) {
0333 if (isEH) {
0334 EHDwarf2LRegs = Map;
0335 EHDwarf2LRegsSize = Size;
0336 } else {
0337 Dwarf2LRegs = Map;
0338 Dwarf2LRegsSize = Size;
0339 }
0340 }
0341
0342
0343
0344
0345
0346
0347 void mapLLVMRegToSEHReg(MCRegister LLVMReg, int SEHReg) {
0348 L2SEHRegs[LLVMReg] = SEHReg;
0349 }
0350
0351 void mapLLVMRegToCVReg(MCRegister LLVMReg, int CVReg) {
0352 L2CVRegs[LLVMReg] = CVReg;
0353 }
0354
0355
0356
0357 MCRegister getRARegister() const {
0358 return RAReg;
0359 }
0360
0361
0362 MCRegister getProgramCounter() const {
0363 return PCReg;
0364 }
0365
0366 const MCRegisterDesc &operator[](MCRegister Reg) const {
0367 assert(Reg.id() < NumRegs &&
0368 "Attempting to access record for invalid register number!");
0369 return Desc[Reg.id()];
0370 }
0371
0372
0373
0374 const MCRegisterDesc &get(MCRegister Reg) const {
0375 return operator[](Reg);
0376 }
0377
0378
0379
0380
0381 MCRegister getSubReg(MCRegister Reg, unsigned Idx) const;
0382
0383
0384
0385 MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx,
0386 const MCRegisterClass *RC) const;
0387
0388
0389
0390
0391 unsigned getSubRegIndex(MCRegister RegNo, MCRegister SubRegNo) const;
0392
0393
0394
0395 const char *getName(MCRegister RegNo) const {
0396 return RegStrings + get(RegNo).Name;
0397 }
0398
0399
0400 bool isConstant(MCRegister RegNo) const { return get(RegNo).IsConstant; }
0401
0402
0403
0404
0405 bool isArtificial(MCRegister RegNo) const { return get(RegNo).IsArtificial; }
0406
0407
0408
0409
0410 bool isArtificialRegUnit(MCRegUnit Unit) const;
0411
0412
0413
0414 unsigned getNumRegs() const {
0415 return NumRegs;
0416 }
0417
0418
0419
0420
0421 unsigned getNumSubRegIndices() const {
0422 return NumSubRegIndices;
0423 }
0424
0425
0426
0427
0428 unsigned getNumRegUnits() const {
0429 return NumRegUnits;
0430 }
0431
0432
0433
0434
0435
0436 virtual int64_t getDwarfRegNum(MCRegister RegNum, bool isEH) const;
0437
0438
0439
0440 std::optional<MCRegister> getLLVMRegNum(uint64_t RegNum, bool isEH) const;
0441
0442
0443
0444 int64_t getDwarfRegNumFromDwarfEHRegNum(uint64_t RegNum) const;
0445
0446
0447
0448 int getSEHRegNum(MCRegister RegNum) const;
0449
0450
0451
0452 int getCodeViewRegNum(MCRegister RegNum) const;
0453
0454 regclass_iterator regclass_begin() const { return Classes; }
0455 regclass_iterator regclass_end() const { return Classes+NumClasses; }
0456 iterator_range<regclass_iterator> regclasses() const {
0457 return make_range(regclass_begin(), regclass_end());
0458 }
0459
0460 unsigned getNumRegClasses() const {
0461 return (unsigned)(regclass_end()-regclass_begin());
0462 }
0463
0464
0465
0466 const MCRegisterClass& getRegClass(unsigned i) const {
0467 assert(i < getNumRegClasses() && "Register Class ID out of range");
0468 return Classes[i];
0469 }
0470
0471 const char *getRegClassName(const MCRegisterClass *Class) const {
0472 return RegClassStrings + Class->NameIdx;
0473 }
0474
0475
0476 uint16_t getEncodingValue(MCRegister Reg) const {
0477 assert(Reg.id() < NumRegs &&
0478 "Attempting to get encoding for invalid register number!");
0479 return RegEncodingTable[Reg.id()];
0480 }
0481
0482
0483 bool isSubRegister(MCRegister RegA, MCRegister RegB) const {
0484 return isSuperRegister(RegB, RegA);
0485 }
0486
0487
0488 bool isSuperRegister(MCRegister RegA, MCRegister RegB) const;
0489
0490
0491 bool isSubRegisterEq(MCRegister RegA, MCRegister RegB) const {
0492 return isSuperRegisterEq(RegB, RegA);
0493 }
0494
0495
0496
0497 bool isSuperRegisterEq(MCRegister RegA, MCRegister RegB) const {
0498 return RegA == RegB || isSuperRegister(RegA, RegB);
0499 }
0500
0501
0502
0503 bool isSuperOrSubRegisterEq(MCRegister RegA, MCRegister RegB) const {
0504 return isSubRegisterEq(RegA, RegB) || isSuperRegister(RegA, RegB);
0505 }
0506
0507
0508 bool regsOverlap(MCRegister RegA, MCRegister RegB) const;
0509 };
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520 class MCSubRegIterator
0521 : public iterator_adaptor_base<MCSubRegIterator,
0522 MCRegisterInfo::DiffListIterator,
0523 std::forward_iterator_tag, const MCPhysReg> {
0524
0525 MCPhysReg Val;
0526
0527 public:
0528
0529 MCSubRegIterator() = default;
0530
0531 MCSubRegIterator(MCRegister Reg, const MCRegisterInfo *MCRI,
0532 bool IncludeSelf = false) {
0533 assert(Reg.isPhysical());
0534 I.init(Reg.id(), MCRI->DiffLists + MCRI->get(Reg).SubRegs);
0535
0536 Val = MCPhysReg(*I);
0537 if (!IncludeSelf)
0538 ++*this;
0539 }
0540
0541 const MCPhysReg &operator*() const { return Val; }
0542
0543 using iterator_adaptor_base::operator++;
0544 MCSubRegIterator &operator++() {
0545 Val = MCPhysReg(*++I);
0546 return *this;
0547 }
0548
0549
0550 bool isValid() const { return I.isValid(); }
0551 };
0552
0553
0554
0555 class MCSubRegIndexIterator {
0556 MCSubRegIterator SRIter;
0557 const uint16_t *SRIndex;
0558
0559 public:
0560
0561
0562 MCSubRegIndexIterator(MCRegister Reg, const MCRegisterInfo *MCRI)
0563 : SRIter(Reg, MCRI) {
0564 SRIndex = MCRI->SubRegIndices + MCRI->get(Reg).SubRegIndices;
0565 }
0566
0567
0568 MCRegister getSubReg() const {
0569 return *SRIter;
0570 }
0571
0572
0573 unsigned getSubRegIndex() const {
0574 return *SRIndex;
0575 }
0576
0577
0578 bool isValid() const { return SRIter.isValid(); }
0579
0580
0581 MCSubRegIndexIterator &operator++() {
0582 ++SRIter;
0583 ++SRIndex;
0584 return *this;
0585 }
0586 };
0587
0588
0589
0590 class MCSuperRegIterator
0591 : public iterator_adaptor_base<MCSuperRegIterator,
0592 MCRegisterInfo::DiffListIterator,
0593 std::forward_iterator_tag, const MCPhysReg> {
0594
0595 MCPhysReg Val;
0596
0597 public:
0598
0599 MCSuperRegIterator() = default;
0600
0601 MCSuperRegIterator(MCRegister Reg, const MCRegisterInfo *MCRI,
0602 bool IncludeSelf = false) {
0603 assert(Reg.isPhysical());
0604 I.init(Reg.id(), MCRI->DiffLists + MCRI->get(Reg).SuperRegs);
0605
0606 Val = MCPhysReg(*I);
0607 if (!IncludeSelf)
0608 ++*this;
0609 }
0610
0611 const MCPhysReg &operator*() const { return Val; }
0612
0613 using iterator_adaptor_base::operator++;
0614 MCSuperRegIterator &operator++() {
0615 Val = MCPhysReg(*++I);
0616 return *this;
0617 }
0618
0619
0620 bool isValid() const { return I.isValid(); }
0621 };
0622
0623
0624
0625 inline bool MCRegisterInfo::isSuperRegister(MCRegister RegA, MCRegister RegB) const{
0626 return is_contained(superregs(RegA), RegB);
0627 }
0628
0629
0630
0631
0632
0633
0634
0635 class MCRegUnitIterator
0636 : public iterator_adaptor_base<MCRegUnitIterator,
0637 MCRegisterInfo::DiffListIterator,
0638 std::forward_iterator_tag, const MCRegUnit> {
0639
0640 static constexpr unsigned RegUnitBits = 12;
0641
0642 MCRegUnit Val;
0643
0644 public:
0645
0646 MCRegUnitIterator() = default;
0647
0648 MCRegUnitIterator(MCRegister Reg, const MCRegisterInfo *MCRI) {
0649 assert(Reg.isPhysical());
0650
0651 unsigned RU = MCRI->get(Reg).RegUnits;
0652 unsigned FirstRU = RU & ((1u << RegUnitBits) - 1);
0653 unsigned Offset = RU >> RegUnitBits;
0654 I.init(FirstRU, MCRI->DiffLists + Offset);
0655 Val = MCRegUnit(*I);
0656 }
0657
0658 const MCRegUnit &operator*() const { return Val; }
0659
0660 using iterator_adaptor_base::operator++;
0661 MCRegUnitIterator &operator++() {
0662 Val = MCRegUnit(*++I);
0663 return *this;
0664 }
0665
0666
0667 bool isValid() const { return I.isValid(); }
0668 };
0669
0670
0671
0672
0673 class MCRegUnitMaskIterator {
0674 MCRegUnitIterator RUIter;
0675 const LaneBitmask *MaskListIter;
0676
0677 public:
0678 MCRegUnitMaskIterator() = default;
0679
0680
0681
0682 MCRegUnitMaskIterator(MCRegister Reg, const MCRegisterInfo *MCRI)
0683 : RUIter(Reg, MCRI) {
0684 uint16_t Idx = MCRI->get(Reg).RegUnitLaneMasks;
0685 MaskListIter = &MCRI->RegUnitMaskSequences[Idx];
0686 }
0687
0688
0689 std::pair<unsigned,LaneBitmask> operator*() const {
0690 return std::make_pair(*RUIter, *MaskListIter);
0691 }
0692
0693
0694 bool isValid() const { return RUIter.isValid(); }
0695
0696
0697 MCRegUnitMaskIterator &operator++() {
0698 ++MaskListIter;
0699 ++RUIter;
0700 return *this;
0701 }
0702 };
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714 class MCRegUnitRootIterator {
0715 uint16_t Reg0 = 0;
0716 uint16_t Reg1 = 0;
0717
0718 public:
0719 MCRegUnitRootIterator() = default;
0720
0721 MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) {
0722 assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit");
0723 Reg0 = MCRI->RegUnitRoots[RegUnit][0];
0724 Reg1 = MCRI->RegUnitRoots[RegUnit][1];
0725 }
0726
0727
0728 unsigned operator*() const {
0729 return Reg0;
0730 }
0731
0732
0733 bool isValid() const {
0734 return Reg0;
0735 }
0736
0737
0738 MCRegUnitRootIterator &operator++() {
0739 assert(isValid() && "Cannot move off the end of the list.");
0740 Reg0 = Reg1;
0741 Reg1 = 0;
0742 return *this;
0743 }
0744 };
0745
0746
0747 class MCRegAliasIterator {
0748 private:
0749 const MCPhysReg *It = nullptr;
0750 const MCPhysReg *End = nullptr;
0751
0752 public:
0753 MCRegAliasIterator(MCRegister Reg, const MCRegisterInfo *MCRI,
0754 bool IncludeSelf) {
0755 ArrayRef<MCPhysReg> Cache = MCRI->getCachedAliasesOf(Reg);
0756 assert(Cache.back() == Reg);
0757 It = Cache.begin();
0758 End = Cache.end();
0759 if (!IncludeSelf)
0760 --End;
0761 }
0762
0763 bool isValid() const { return It != End; }
0764
0765 MCRegister operator*() const { return *It; }
0766
0767 MCRegAliasIterator &operator++() {
0768 assert(isValid() && "Cannot move off the end of the list.");
0769 ++It;
0770 return *this;
0771 }
0772 };
0773
0774 inline iterator_range<MCSubRegIterator>
0775 MCRegisterInfo::subregs(MCRegister Reg) const {
0776 return make_range({Reg, this, false}, MCSubRegIterator());
0777 }
0778
0779 inline iterator_range<MCSubRegIterator>
0780 MCRegisterInfo::subregs_inclusive(MCRegister Reg) const {
0781 return make_range({Reg, this, true}, MCSubRegIterator());
0782 }
0783
0784 inline iterator_range<MCSuperRegIterator>
0785 MCRegisterInfo::superregs(MCRegister Reg) const {
0786 return make_range({Reg, this, false}, MCSuperRegIterator());
0787 }
0788
0789 inline iterator_range<MCSuperRegIterator>
0790 MCRegisterInfo::superregs_inclusive(MCRegister Reg) const {
0791 return make_range({Reg, this, true}, MCSuperRegIterator());
0792 }
0793
0794 inline detail::concat_range<const MCPhysReg, iterator_range<MCSubRegIterator>,
0795 iterator_range<MCSuperRegIterator>>
0796 MCRegisterInfo::sub_and_superregs_inclusive(MCRegister Reg) const {
0797 return concat<const MCPhysReg>(subregs_inclusive(Reg), superregs(Reg));
0798 }
0799
0800 inline iterator_range<MCRegUnitIterator>
0801 MCRegisterInfo::regunits(MCRegister Reg) const {
0802 return make_range({Reg, this}, MCRegUnitIterator());
0803 }
0804
0805 }
0806
0807 #endif