Skip to content

Commit 4822e9d

Browse files
authored
[llvm] use 64-bit types for result of getDwarfRegNum (NFC) (#109494)
The register encoding used by NVPTX and cuda-gdb basically use strings encoded as numbers. They are always within 64-bits, but typically outside of 32-bits, since they often need at least 5 characters. This patch changes the signature of `MCRegisterInfo::getDwarfRegNum` and some related data structures to use 64-bit numbers to accommodate encodings like this. Additionally, `MCRegisterInfo::getDwarfRegNum` is marked as virtual, so that targets with peculiar dwarf register mapping schemes (such as NVPTX) can override its behavior. I originally tried to do a broader switch to 64-bit types for registers, but it caused many problems. There are various places in code generation where registers are not just treated as 32-bit numbers, but also treat certain bit offsets as flags. So I limited the change as much as possible to just the output of `getDwarfRegNum`. Keeping the types used by `DwarfLLVMRegPair` as unsigned preserves the current behaviors. The only way to give a 64-bit output from `getDwarfRegNum` that actually needs more than 32-bits is to override `getDwarfRegNum` and provide an implementation that sidesteps the use of the `DwarfLLVMRegPair` maps defined in tablegen files. First layer of stack supporting: #109495
1 parent 68ed172 commit 4822e9d

File tree

6 files changed

+24
-22
lines changed

6 files changed

+24
-22
lines changed

llvm/include/llvm/MC/MCRegisterInfo.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -418,15 +418,15 @@ class MCRegisterInfo {
418418
/// number. Returns -1 if there is no equivalent value. The second
419419
/// parameter allows targets to use different numberings for EH info and
420420
/// debugging info.
421-
int getDwarfRegNum(MCRegister RegNum, bool isEH) const;
421+
virtual int64_t getDwarfRegNum(MCRegister RegNum, bool isEH) const;
422422

423423
/// Map a dwarf register back to a target register. Returns std::nullopt if
424424
/// there is no mapping.
425-
std::optional<MCRegister> getLLVMRegNum(unsigned RegNum, bool isEH) const;
425+
std::optional<MCRegister> getLLVMRegNum(uint64_t RegNum, bool isEH) const;
426426

427427
/// Map a target EH register number to an equivalent DWARF register
428428
/// number.
429-
int getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const;
429+
int64_t getDwarfRegNumFromDwarfEHRegNum(uint64_t RegNum) const;
430430

431431
/// Map a target register to an equivalent SEH register
432432
/// number. Returns LLVM register number if there is no equivalent value.

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,15 +570,15 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
570570
/// debug expression to a register in the forwarded register worklist.
571571
struct FwdRegParamInfo {
572572
/// The described parameter register.
573-
unsigned ParamReg;
573+
uint64_t ParamReg;
574574

575575
/// Debug expression that has been built up when walking through the
576576
/// instruction chain that produces the parameter's value.
577577
const DIExpression *Expr;
578578
};
579579

580580
/// Register worklist for finding call site values.
581-
using FwdRegWorklist = MapVector<unsigned, SmallVector<FwdRegParamInfo, 2>>;
581+
using FwdRegWorklist = MapVector<uint64_t, SmallVector<FwdRegParamInfo, 2>>;
582582
/// Container for the set of registers known to be clobbered on the path to a
583583
/// call site.
584584
using ClobberedRegSet = SmallSet<Register, 16>;

llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void DwarfExpression::emitConstu(uint64_t Value) {
4040
}
4141
}
4242

43-
void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
43+
void DwarfExpression::addReg(int64_t DwarfReg, const char *Comment) {
4444
assert(DwarfReg >= 0 && "invalid negative dwarf register number");
4545
assert((isUnknownLocation() || isRegisterLocation()) &&
4646
"location description already locked down");
@@ -53,7 +53,7 @@ void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
5353
}
5454
}
5555

56-
void DwarfExpression::addBReg(int DwarfReg, int Offset) {
56+
void DwarfExpression::addBReg(int64_t DwarfReg, int64_t Offset) {
5757
assert(DwarfReg >= 0 && "invalid negative dwarf register number");
5858
assert(!isRegisterLocation() && "location description already locked down");
5959
if (DwarfReg < 32) {
@@ -65,7 +65,7 @@ void DwarfExpression::addBReg(int DwarfReg, int Offset) {
6565
emitSigned(Offset);
6666
}
6767

68-
void DwarfExpression::addFBReg(int Offset) {
68+
void DwarfExpression::addFBReg(int64_t Offset) {
6969
emitOp(dwarf::DW_OP_fbreg);
7070
emitSigned(Offset);
7171
}
@@ -108,7 +108,7 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
108108
return false;
109109
}
110110

111-
int Reg = TRI.getDwarfRegNum(MachineReg, false);
111+
int64_t Reg = TRI.getDwarfRegNum(MachineReg, false);
112112

113113
// If this is a valid register number, emit it.
114114
if (Reg >= 0) {

llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,17 @@ class DwarfExpression {
4545
protected:
4646
/// Holds information about all subregisters comprising a register location.
4747
struct Register {
48-
int DwarfRegNo;
48+
int64_t DwarfRegNo;
4949
unsigned SubRegSize;
5050
const char *Comment;
5151

5252
/// Create a full register, no extra DW_OP_piece operators necessary.
53-
static Register createRegister(int RegNo, const char *Comment) {
53+
static Register createRegister(int64_t RegNo, const char *Comment) {
5454
return {RegNo, 0, Comment};
5555
}
5656

5757
/// Create a subregister that needs a DW_OP_piece operator with SizeInBits.
58-
static Register createSubRegister(int RegNo, unsigned SizeInBits,
58+
static Register createSubRegister(int64_t RegNo, unsigned SizeInBits,
5959
const char *Comment) {
6060
return {RegNo, SizeInBits, Comment};
6161
}
@@ -161,13 +161,13 @@ class DwarfExpression {
161161

162162
/// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
163163
/// register location description.
164-
void addReg(int DwarfReg, const char *Comment = nullptr);
164+
void addReg(int64_t DwarfReg, const char *Comment = nullptr);
165165

166166
/// Emit a DW_OP_breg operation.
167-
void addBReg(int DwarfReg, int Offset);
167+
void addBReg(int64_t DwarfReg, int64_t Offset);
168168

169169
/// Emit DW_OP_fbreg <Offset>.
170-
void addFBReg(int Offset);
170+
void addFBReg(int64_t Offset);
171171

172172
/// Emit a partial DWARF register operation.
173173
///

llvm/lib/MC/MCRegisterInfo.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ unsigned MCRegisterInfo::getSubRegIndex(MCRegister Reg,
141141
return 0;
142142
}
143143

144-
int MCRegisterInfo::getDwarfRegNum(MCRegister RegNum, bool isEH) const {
144+
int64_t MCRegisterInfo::getDwarfRegNum(MCRegister RegNum, bool isEH) const {
145145
const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
146146
unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;
147147

@@ -151,24 +151,28 @@ int MCRegisterInfo::getDwarfRegNum(MCRegister RegNum, bool isEH) const {
151151
const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
152152
if (I == M+Size || I->FromReg != RegNum)
153153
return -1;
154-
return I->ToReg;
154+
// Consumers need to be able to detect -1 and -2, but at various points
155+
// the numbers move between unsigned and signed representations, as well as
156+
// between 32- and 64-bit representations. We need to convert first to int
157+
// before int64_t for proper sign handling.
158+
return int64_t(int(I->ToReg));
155159
}
156160

157-
std::optional<MCRegister> MCRegisterInfo::getLLVMRegNum(unsigned RegNum,
161+
std::optional<MCRegister> MCRegisterInfo::getLLVMRegNum(uint64_t RegNum,
158162
bool isEH) const {
159163
const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
160164
unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize;
161165

162166
if (!M)
163167
return std::nullopt;
164-
DwarfLLVMRegPair Key = { RegNum, 0 };
168+
DwarfLLVMRegPair Key = {unsigned(RegNum), 0};
165169
const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
166170
if (I != M + Size && I->FromReg == RegNum)
167171
return MCRegister::from(I->ToReg);
168172
return std::nullopt;
169173
}
170174

171-
int MCRegisterInfo::getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const {
175+
int64_t MCRegisterInfo::getDwarfRegNumFromDwarfEHRegNum(uint64_t RegNum) const {
172176
// On ELF platforms, DWARF EH register numbers are the same as DWARF
173177
// other register numbers. On Darwin x86, they differ and so need to be
174178
// mapped. The .cfi_* directives accept integer literals as well as

llvm/lib/Target/Lanai/LanaiRegisterInfo.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ struct LanaiRegisterInfo : public LanaiGenRegisterInfo {
4343
Register getFrameRegister(const MachineFunction &MF) const override;
4444
Register getBaseRegister() const;
4545
bool hasBasePointer(const MachineFunction &MF) const;
46-
47-
int getDwarfRegNum(unsigned RegNum, bool IsEH) const;
4846
};
4947

5048
} // end namespace llvm

0 commit comments

Comments
 (0)