LLVM 20.0.0git
MCRegisterInfo.cpp
Go to the documentation of this file.
1//===- MC/MCRegisterInfo.cpp - Target Register Description ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements MCRegisterInfo functions.
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/ADT/DenseMap.h"
15#include "llvm/ADT/Twine.h"
17#include <algorithm>
18#include <cassert>
19#include <cstdint>
20
21using namespace llvm;
22
23namespace {
24/// MCRegAliasIterator enumerates all registers aliasing Reg. This iterator
25/// does not guarantee any ordering or that entries are unique.
26class MCRegAliasIteratorImpl {
27private:
29 const MCRegisterInfo *MCRI;
30
34
35public:
36 MCRegAliasIteratorImpl(MCRegister Reg, const MCRegisterInfo *MCRI)
37 : Reg(Reg), MCRI(MCRI) {
38
39 // Initialize the iterators.
40 for (RI = MCRegUnitIterator(Reg, MCRI); RI.isValid(); ++RI) {
41 for (RRI = MCRegUnitRootIterator(*RI, MCRI); RRI.isValid(); ++RRI) {
42 for (SI = MCSuperRegIterator(*RRI, MCRI, true); SI.isValid(); ++SI) {
43 if (Reg != *SI)
44 return;
45 }
46 }
47 }
48 }
49
50 bool isValid() const { return RI.isValid(); }
51
52 MCRegister operator*() const {
53 assert(SI.isValid() && "Cannot dereference an invalid iterator.");
54 return *SI;
55 }
56
57 void advance() {
58 // Assuming SI is valid.
59 ++SI;
60 if (SI.isValid())
61 return;
62
63 ++RRI;
64 if (RRI.isValid()) {
65 SI = MCSuperRegIterator(*RRI, MCRI, true);
66 return;
67 }
68
69 ++RI;
70 if (RI.isValid()) {
71 RRI = MCRegUnitRootIterator(*RI, MCRI);
72 SI = MCSuperRegIterator(*RRI, MCRI, true);
73 }
74 }
75
76 MCRegAliasIteratorImpl &operator++() {
77 assert(isValid() && "Cannot move off the end of the list.");
78 do
79 advance();
80 while (isValid() && *SI == Reg);
81 return *this;
82 }
83};
84} // namespace
85
86ArrayRef<MCPhysReg> MCRegisterInfo::getCachedAliasesOf(MCPhysReg R) const {
87 auto &Aliases = RegAliasesCache[R];
88 if (!Aliases.empty())
89 return Aliases;
90
91 for (MCRegAliasIteratorImpl It(R, this); It.isValid(); ++It)
92 Aliases.push_back(*It);
93
94 sort(Aliases);
95 Aliases.erase(unique(Aliases), Aliases.end());
96 assert(none_of(Aliases, [&](auto &Cur) { return R == Cur; }) &&
97 "MCRegAliasIteratorImpl includes Self!");
98
99 // Always put "self" at the end, so the iterator can choose to ignore it.
100 // For registers without aliases, it also serves as a sentinel value that
101 // tells us to not recompute the alias set.
102 Aliases.push_back(R);
103 Aliases.shrink_to_fit();
104 return Aliases;
105}
106
109 const MCRegisterClass *RC) const {
110 for (MCPhysReg Super : superregs(Reg))
111 if (RC->contains(Super) && Reg == getSubReg(Super, SubIdx))
112 return Super;
113 return 0;
114}
115
118 "This is not a subregister index");
119 // Get a pointer to the corresponding SubRegIndices list. This list has the
120 // name of each sub-register in the same order as MCSubRegIterator.
121 const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;
122 for (MCPhysReg Sub : subregs(Reg)) {
123 if (*SRI == Idx)
124 return Sub;
125 ++SRI;
126 }
127 return 0;
128}
129
131 MCRegister SubReg) const {
132 assert(SubReg && SubReg < getNumRegs() && "This is not a register");
133 // Get a pointer to the corresponding SubRegIndices list. This list has the
134 // name of each sub-register in the same order as MCSubRegIterator.
135 const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;
136 for (MCPhysReg Sub : subregs(Reg)) {
137 if (Sub == SubReg)
138 return *SRI;
139 ++SRI;
140 }
141 return 0;
142}
143
144int MCRegisterInfo::getDwarfRegNum(MCRegister RegNum, bool isEH) const {
145 const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
146 unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;
147
148 if (!M)
149 return -1;
150 DwarfLLVMRegPair Key = { RegNum, 0 };
151 const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
152 if (I == M+Size || I->FromReg != RegNum)
153 return -1;
154 return I->ToReg;
155}
156
157std::optional<unsigned> MCRegisterInfo::getLLVMRegNum(unsigned RegNum,
158 bool isEH) const {
159 const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
160 unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize;
161
162 if (!M)
163 return std::nullopt;
164 DwarfLLVMRegPair Key = { RegNum, 0 };
165 const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
166 if (I != M + Size && I->FromReg == RegNum)
167 return I->ToReg;
168 return std::nullopt;
169}
170
172 // On ELF platforms, DWARF EH register numbers are the same as DWARF
173 // other register numbers. On Darwin x86, they differ and so need to be
174 // mapped. The .cfi_* directives accept integer literals as well as
175 // register names and should generate exactly what the assembly code
176 // asked for, so there might be DWARF/EH register numbers that don't have
177 // a corresponding LLVM register number at all. So if we can't map the
178 // EH register number to an LLVM register number, assume it's just a
179 // valid DWARF register number as is.
180 if (std::optional<unsigned> LRegNum = getLLVMRegNum(RegNum, true)) {
181 int DwarfRegNum = getDwarfRegNum(*LRegNum, false);
182 if (DwarfRegNum == -1)
183 return RegNum;
184 else
185 return DwarfRegNum;
186 }
187 return RegNum;
188}
189
191 const DenseMap<MCRegister, int>::const_iterator I = L2SEHRegs.find(RegNum);
192 if (I == L2SEHRegs.end()) return (int)RegNum;
193 return I->second;
194}
195
197 if (L2CVRegs.empty())
198 report_fatal_error("target does not implement codeview register mapping");
199 const DenseMap<MCRegister, int>::const_iterator I = L2CVRegs.find(RegNum);
200 if (I == L2CVRegs.end())
201 report_fatal_error("unknown codeview register " + (RegNum < getNumRegs()
202 ? getName(RegNum)
203 : Twine(RegNum)));
204 return I->second;
205}
206
208 // Regunits are numerically ordered. Find a common unit.
209 auto RangeA = regunits(RegA);
210 MCRegUnitIterator IA = RangeA.begin(), EA = RangeA.end();
211 auto RangeB = regunits(RegB);
212 MCRegUnitIterator IB = RangeB.begin(), EB = RangeB.end();
213 do {
214 if (*IA == *IB)
215 return true;
216 } while (*IA < *IB ? ++IA != EA : ++IB != EB);
217 return false;
218}
unsigned SubReg
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
bool isValid() const
Returns true if this iterator is not yet at the end.
MCRegUnitRootIterator enumerates the root registers of a register unit.
bool isValid() const
Check if the iterator is at the end of the list.
MCRegisterClass - Base class of TargetRegisterClass.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
unsigned getNumSubRegIndices() const
Return the number of sub-register indices understood by the target.
int getDwarfRegNum(MCRegister RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
bool regsOverlap(MCRegister RegA, MCRegister RegB) const
Returns true if the two registers are equal or alias each other.
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
int getCodeViewRegNum(MCRegister RegNum) const
Map a target register to an equivalent CodeView register number.
std::optional< unsigned > getLLVMRegNum(unsigned RegNum, bool isEH) const
Map a dwarf register back to a target register.
const MCRegisterDesc & get(MCRegister RegNo) const
Provide a get method, equivalent to [], but more useful with a pointer to this object.
int getSEHRegNum(MCRegister RegNum) const
Map a target register to an equivalent SEH register number.
iterator_range< MCSuperRegIterator > superregs(MCRegister Reg) const
Return an iterator range over all super-registers of Reg, excluding Reg.
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
int getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const
Map a target EH register number to an equivalent DWARF register number.
iterator_range< MCSubRegIterator > subregs(MCRegister Reg) const
Return an iterator range over all sub-registers of Reg, excluding Reg.
unsigned getSubRegIndex(MCRegister RegNo, MCRegister SubRegNo) const
For a given register pair, return the sub-register index if the second register is a sub-register of ...
iterator_range< MCRegUnitIterator > regunits(MCRegister Reg) const
Returns an iterator range over all regunits for Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
MCSuperRegIterator enumerates all super-registers of Reg.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
APInt operator*(APInt a, uint64_t RHS)
Definition: APInt.h:2174
auto unique(Range &&R, Predicate P)
Definition: STLExtras.h:2038
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1647
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1736
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
DwarfLLVMRegPair - Emitted by tablegen so Dwarf<->LLVM reg mappings can be performed with a binary se...