[llvm] add RegisterBankInfo support to RegisterBankEmitter (PR #70895)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 31 22:36:21 PDT 2023


https://github.com/CBSears created https://github.com/llvm/llvm-project/pull/70895

TableGen generates boilerplate code from definition files. It already has some RegisterBankInfo support: TargetGenRegisterBankInfo(), RegBankIDs enum, RegBanks and Sizes. But it is missing support for PartialMappingIdx and PartMappings. This adds support for that. It is discussed in

https://discourse.llvm.org/t/rfc-tablegen-support-for-registerbankinfo/

>From 25352cd3588e72b51b5a5862322d8528068e4dc4 Mon Sep 17 00:00:00 2001
From: Chris Sears <chris at doublewide.io>
Date: Tue, 31 Oct 2023 22:25:08 -0700
Subject: [PATCH] add RegisterBankInfo support to RegisterBankEmitter

---
 llvm/utils/TableGen/RegisterBankEmitter.cpp | 96 +++++++++++++++++++--
 1 file changed, 89 insertions(+), 7 deletions(-)

diff --git a/llvm/utils/TableGen/RegisterBankEmitter.cpp b/llvm/utils/TableGen/RegisterBankEmitter.cpp
index 60c3fcdba70ed88..e6433e2b16e6769 100644
--- a/llvm/utils/TableGen/RegisterBankEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterBankEmitter.cpp
@@ -7,7 +7,7 @@
 //===----------------------------------------------------------------------===//
 //
 // This tablegen backend is responsible for emitting a description of a target
-// register bank for a code generator.
+// register bank and register bank info for a code generator.
 //
 //===----------------------------------------------------------------------===//
 
@@ -112,7 +112,11 @@ class RegisterBankEmitter {
   void emitBaseClassDefinition(raw_ostream &OS, const StringRef TargetName,
                                const std::vector<RegisterBank> &Banks);
   void emitBaseClassImplementation(raw_ostream &OS, const StringRef TargetName,
-                                   std::vector<RegisterBank> &Banks);
+                                   const std::vector<RegisterBank> &Banks);
+  void emitRBIHeader(raw_ostream &OS, const StringRef TargetName,
+                     const std::vector<RegisterBank> &Banks);
+  void emitRBIIMPL(raw_ostream &OS, const StringRef TargetName,
+                   const std::vector<RegisterBank> &Banks);
 
 public:
   RegisterBankEmitter(RecordKeeper &R) : Target(R), Records(R) {}
@@ -127,7 +131,7 @@ class RegisterBankEmitter {
 void RegisterBankEmitter::emitHeader(raw_ostream &OS,
                                      const StringRef TargetName,
                                      const std::vector<RegisterBank> &Banks) {
-  // <Target>RegisterBankInfo.h
+  // <Target>RegisterBank.h
   OS << "namespace llvm {\n"
      << "namespace " << TargetName << " {\n"
      << "enum : unsigned {\n";
@@ -213,7 +217,7 @@ static void visitRegisterBankClasses(
 
 void RegisterBankEmitter::emitBaseClassImplementation(
     raw_ostream &OS, StringRef TargetName,
-    std::vector<RegisterBank> &Banks) {
+    const std::vector<RegisterBank> &Banks) {
   const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
   const CodeGenHwModes &CGH = Target.getHwModes();
 
@@ -289,6 +293,73 @@ void RegisterBankEmitter::emitBaseClassImplementation(
      << "} // end namespace llvm\n";
 }
 
+void RegisterBankEmitter::emitRBIHeader(
+    raw_ostream &OS, const StringRef TargetName,
+    const std::vector<RegisterBank> &Banks) {
+  const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
+
+  OS << "namespace llvm {\n"
+     << "namespace " << TargetName << " {\n"
+     << "enum PartialMappingIdx {\n"
+     << "  PMI_None = -1,\n";
+
+  // Banks and Register Classes are *not* emitted in their original text order
+  int ID = 0;
+  for (const auto &Bank : Banks) {
+    for (const CodeGenRegisterClass *RC :
+         Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)) {
+      OS << "  PMI_" << RC->getName() << " = " << ID++ << ",\n";
+    }
+  }
+  OS << "};\n";
+  OS << "} // end namespace " << TargetName << "\n"
+     << "} // end namespace llvm\n";
+}
+
+void RegisterBankEmitter::emitRBIIMPL(raw_ostream &OS,
+                                      const StringRef TargetName,
+                                      const std::vector<RegisterBank> &Banks) {
+  const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
+
+  // Is StartIdx RC->RSI.getSimple().SpillAlignment ?
+  // StartIdx is 0 in all of the in-tree backends
+  OS << "namespace llvm {\n"
+     << "namespace " << TargetName << " {\n"
+     << "RegisterBankInfo::PartialMapping PartMappings[] = {\n";
+  for (const auto &Bank : Banks) {
+    for (const CodeGenRegisterClass *RC :
+         Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)) {
+      if (RC->RSI.isSimple()) // FIXME: dumb workaround for RISCV for now
+        OS << "  { 0, " << RC->RSI.getSimple().RegSize << ", "
+           << Bank.getInstanceVarName() << " },\n";
+    }
+  }
+  OS << "};\n\n";
+
+  // emit PartialMappingIdx of the first Register Class of each Register Bank
+  OS << "PartialMappingIdx BankIDToFirstRegisterClassIdx[] = {\n";
+  for (const auto &Bank : Banks) {
+    OS << "  PMI_"
+       << Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)[0]
+              ->getName()
+       << ",\n";
+  }
+  OS << "};\n\n";
+
+  // emit count of Register Classes of each Register Bank
+  OS << "int BankIDToRegisterClassCount[] = {\n";
+  for (const auto &Bank : Banks) {
+    OS << "  "
+       << Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)
+              .size()
+       << ",\n";
+  }
+
+  OS << "};\n"
+     << "} // end namespace " << TargetName << "\n"
+     << "} // end namespace llvm\n";
+}
+
 void RegisterBankEmitter::run(raw_ostream &OS) {
   StringRef TargetName = Target.getName();
   const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
@@ -330,7 +401,9 @@ void RegisterBankEmitter::run(raw_ostream &OS) {
   }
 
   Records.startTimer("Emit output");
-  emitSourceFileHeader("Register Bank Source Fragments", OS);
+  emitSourceFileHeader("Register Bank And Register Bank Info Source Fragments",
+                       OS);
+
   OS << "#ifdef GET_REGBANK_DECLARATIONS\n"
      << "#undef GET_REGBANK_DECLARATIONS\n";
   emitHeader(OS, TargetName, Banks);
@@ -342,8 +415,17 @@ void RegisterBankEmitter::run(raw_ostream &OS) {
      << "#ifdef GET_TARGET_REGBANK_IMPL\n"
      << "#undef GET_TARGET_REGBANK_IMPL\n";
   emitBaseClassImplementation(OS, TargetName, Banks);
-  OS << "#endif // GET_TARGET_REGBANK_IMPL\n";
+  OS << "#endif // GET_TARGET_REGBANK_IMPL\n\n"
+     << "#ifdef GET_REGBANKINFO_DECLARATIONS\n"
+     << "#undef GET_REGBANKINFO_DECLARATIONS\n";
+  emitRBIHeader(OS, TargetName, Banks);
+  OS << "#endif // GET_REGBANKINFO_DECLARATIONS\n\n"
+     << "#ifdef GET_REGBANKINFO_IMPL\n"
+     << "#undef GET_REGBANKINFO_IMPL\n";
+  emitRBIIMPL(OS, TargetName, Banks);
+  OS << "#endif // GET_REGBANKINFO_IMPL\n";
 }
 
 static TableGen::Emitter::OptClass<RegisterBankEmitter>
-    X("gen-register-bank", "Generate registers bank descriptions");
+    X("gen-register-bank",
+      "Generate register bank and register bank info descriptions");



More information about the llvm-commits mailing list