-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV] Reduce size of CSR lookup tables. NFC #121606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Instead of storing 3 different names in each row of the table, use a separate row for each name and use a flag to indicate what type of name it is. The AltName and DeprecatedName aren't used often enough to justify storing them as a possiblity for every register. This reduces the .rodata says by 27k and reduces the number of dynamic relocations since we now only need 1 lookup by name function. The lookup by name function each contained a ~400 entry table of const char* pointing to constant strings. Each of those requires a dynamic relocation.
@llvm/pr-subscribers-backend-risc-v Author: Craig Topper (topperc) ChangesInstead of storing 3 different names in each row of the table, use a separate row for each name and use a flag to indicate what type of name it is. The AltName and DeprecatedName weren't used often enough to justify storing them as a possibility for every register. This reduces the .rodata size by 27k and reduces the number of dynamic relocations since we now only need 1 lookup by name function. The lookup by name function each contained a ~400 entry table of const char* pointing to constant strings. Each of those requires a dynamic relocation. Full diff: https://github.com/llvm/llvm-project/pull/121606.diff 4 Files Affected:
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 4c1fd5aa41e2b7..2205c67c2d21ba 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -1915,6 +1915,8 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
// Accept an immediate representing a named Sys Reg if it satisfies the
// the required features.
for (auto &Reg : Range) {
+ if (Reg.IsAltName || Reg.IsDeprecatedName)
+ continue;
if (Reg.haveRequiredFeatures(STI->getFeatureBits()))
return RISCVOperand::createSysReg(Reg.Name, S, Imm);
}
@@ -1952,22 +1954,27 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
return ParseStatus::Failure;
const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
- if (!SysReg)
- SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
- if (!SysReg)
- if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
- Warning(S, "'" + Identifier + "' is a deprecated alias for '" +
- SysReg->Name + "'");
-
- // Accept a named Sys Reg if the required features are present.
+
if (SysReg) {
+ if (SysReg->IsDeprecatedName) {
+ // Lookup the undeprecated name.
+ auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
+ for (auto &Reg : Range) {
+ if (Reg.IsAltName || Reg.IsDeprecatedName)
+ continue;
+ Warning(S, "'" + Identifier + "' is a deprecated alias for '" +
+ Reg.Name + "'");
+ }
+ }
+
+ // Accept a named Sys Reg if the required features are present.
const auto &FeatureBits = getSTI().getFeatureBits();
if (!SysReg->haveRequiredFeatures(FeatureBits)) {
const auto *Feature = llvm::find_if(RISCVFeatureKV, [&](auto Feature) {
return SysReg->FeaturesRequired[Feature.Value];
});
auto ErrorMsg = std::string("system register '") + SysReg->Name + "' ";
- if (SysReg->isRV32Only && FeatureBits[RISCV::Feature64Bit]) {
+ if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
ErrorMsg += "is RV32 only";
if (Feature != std::end(RISCVFeatureKV))
ErrorMsg += " and ";
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 7fb5fc7a831308..1c1a8b8009d2ca 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -454,8 +454,6 @@ int getLoadFPImm(APFloat FPImm);
namespace RISCVSysReg {
struct SysReg {
const char Name[32];
- const char AltName[32];
- const char DeprecatedName[32];
unsigned Encoding;
// FIXME: add these additional fields when needed.
// Privilege Access: Read, Write, Read-Only.
@@ -467,11 +465,13 @@ struct SysReg {
// Register number without the privilege bits.
// unsigned Number;
FeatureBitset FeaturesRequired;
- bool isRV32Only;
+ bool IsRV32Only;
+ bool IsAltName;
+ bool IsDeprecatedName;
bool haveRequiredFeatures(const FeatureBitset &ActiveFeatures) const {
// Not in 32-bit mode.
- if (isRV32Only && ActiveFeatures[RISCV::Feature64Bit])
+ if (IsRV32Only && ActiveFeatures[RISCV::Feature64Bit])
return false;
// No required feature associated with the system register.
if (FeaturesRequired.none())
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
index d36c0d7238cdc6..d5254719b3839e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp
@@ -121,6 +121,8 @@ void RISCVInstPrinter::printCSRSystemRegister(const MCInst *MI, unsigned OpNo,
unsigned Imm = MI->getOperand(OpNo).getImm();
auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
for (auto &Reg : Range) {
+ if (Reg.IsAltName || Reg.IsDeprecatedName)
+ continue;
if (Reg.haveRequiredFeatures(STI.getFeatureBits())) {
markup(O, Markup::Register) << Reg.Name;
return;
diff --git a/llvm/lib/Target/RISCV/RISCVSystemOperands.td b/llvm/lib/Target/RISCV/RISCVSystemOperands.td
index 72275daa1b8d16..39853cf13a920c 100644
--- a/llvm/lib/Target/RISCV/RISCVSystemOperands.td
+++ b/llvm/lib/Target/RISCV/RISCVSystemOperands.td
@@ -19,12 +19,6 @@ include "llvm/TableGen/SearchableTable.td"
class SysReg<string name, bits<12> op> {
string Name = name;
- // A maximum of one alias is supported right now.
- string AltName = name;
- // A maximum of one deprecated name is supported right now. Unlike the
- // `AltName` alias, a `DeprecatedName` generates a diagnostic when the name is
- // used to encourage software to migrate away from the name.
- string DeprecatedName = "";
bits<12> Encoding = op;
// FIXME: add these additional fields when needed.
// Privilege Access: Read and Write = 0, 1, 2; Read-Only = 3.
@@ -37,14 +31,16 @@ class SysReg<string name, bits<12> op> {
// bits<6> Number = op{5 - 0};
code FeaturesRequired = [{ {} }];
bit isRV32Only = 0;
+ bit isAltName = 0;
+ bit isDeprecatedName = 0;
}
def SysRegsList : GenericTable {
let FilterClass = "SysReg";
// FIXME: add "ReadWrite", "Mode", "Extra", "Number" fields when needed.
let Fields = [
- "Name", "AltName", "DeprecatedName", "Encoding", "FeaturesRequired",
- "isRV32Only",
+ "Name", "Encoding", "FeaturesRequired",
+ "isRV32Only", "isAltName", "isDeprecatedName"
];
let PrimaryKey = [ "Encoding" ];
@@ -57,16 +53,6 @@ def lookupSysRegByName : SearchIndex {
let Key = [ "Name" ];
}
-def lookupSysRegByAltName : SearchIndex {
- let Table = SysRegsList;
- let Key = [ "AltName" ];
-}
-
-def lookupSysRegByDeprecatedName : SearchIndex {
- let Table = SysRegsList;
- let Key = [ "DeprecatedName" ];
-}
-
// The following CSR encodings match those given in Tables 2.2,
// 2.3, 2.4, 2.5 and 2.6 in the RISC-V Instruction Set Manual
// Volume II: Privileged Architecture.
@@ -123,15 +109,17 @@ def : SysReg<"senvcfg", 0x10A>;
def : SysReg<"sscratch", 0x140>;
def : SysReg<"sepc", 0x141>;
def : SysReg<"scause", 0x142>;
-let DeprecatedName = "sbadaddr" in
def : SysReg<"stval", 0x143>;
+let isDeprecatedName = 1 in
+def : SysReg<"sbadaddr", 0x143>;
def : SysReg<"sip", 0x144>;
//===----------------------------------------------------------------------===//
// Supervisor Protection and Translation
//===----------------------------------------------------------------------===//
-let DeprecatedName = "sptbr" in
def : SysReg<"satp", 0x180>;
+let isDeprecatedName = 1 in
+def : SysReg<"sptbr", 0x180>;
//===----------------------------------------------------------------------===//
// Quality-of-Service(QoS) Identifiers (Ssqosid)
@@ -245,8 +233,9 @@ def : SysReg<"mstatush", 0x310>;
def : SysReg<"mscratch", 0x340>;
def : SysReg<"mepc", 0x341>;
def : SysReg<"mcause", 0x342>;
-let DeprecatedName = "mbadaddr" in
def : SysReg<"mtval", 0x343>;
+let isDeprecatedName = 1 in
+def : SysReg<"mbadaddr", 0x343>;
def : SysReg<"mip", 0x344>;
def : SysReg<"mtinst", 0x34A>;
def : SysReg<"mtval2", 0x34B>;
@@ -298,8 +287,9 @@ foreach i = 3...31 in
//===----------------------------------------------------------------------===//
// Machine Counter Setup
//===----------------------------------------------------------------------===//
-let AltName = "mucounteren" in // Privileged spec v1.9.1 Name
def : SysReg<"mcountinhibit", 0x320>;
+let isAltName = 1 in
+def : SysReg<"mucounteren", 0x320>;
// mhpmevent3-mhpmevent31 at 0x323-0x33F.
foreach i = 3...31 in
@@ -336,8 +326,9 @@ def : SysReg<"dpc", 0x7B1>;
// "dscratch" is an alternative name for "dscratch0" which appeared in earlier
// drafts of the RISC-V debug spec
-let AltName = "dscratch" in
def : SysReg<"dscratch0", 0x7B2>;
+let isAltName = 1 in
+def : SysReg<"dscratch", 0x7B2>;
def : SysReg<"dscratch1", 0x7B3>;
//===----------------------------------------------------------------------===//
|
@@ -1915,6 +1915,8 @@ ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { | |||
// Accept an immediate representing a named Sys Reg if it satisfies the | |||
// the required features. | |||
for (auto &Reg : Range) { | |||
if (Reg.IsAltName || Reg.IsDeprecatedName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't strictly needed, but ensures we use the required features from the primary name and not the alternate or deprecated names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, especially as this also should get rid of the "Only one alt/deprecated name" restriction from before.
Instead of storing 3 different names in each row of the table, use a separate row for each name and use a flag to indicate what type of name it is. The AltName and DeprecatedName weren't used often enough to justify storing them as a possibility for every register.
This reduces the .rodata size by 27k and reduces the number of dynamic relocations since we now only need 1 lookup by name function. The lookup by name function each contained a ~400 entry table of const char* pointing to constant strings. Each of those requires a dynamic relocation.
I also capitalized IsRV32Only in the C++ code to matching coding standards.