[llvm] TableGen support for RegisterBankInfo (PR #71357)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 9 00:53:27 PST 2023


================
@@ -289,6 +299,141 @@ void RegisterBankEmitter::emitBaseClassImplementation(
      << "} // end namespace llvm\n";
 }
 
+// TableGen already had some RegisterBankInfo support:
+// TargetGenRegisterBankInfo(), RegBankIDs enum, RegBanks and Sizes.
+// This emitter adds support for PartialMappings, PartialMappingIdx
+// and BankIDToCopyMapIdx.
+//
+// The original implementation was supposed to infer RegisterClasses.
+// But since that wasn't finished, backends instead embedded hand crafted
+// tables and enums. This emitter generates them from .td files
+// but requires that the .td files fully describe their RegisterBanks.
+//
+// These tables and enums are enabled by GET_REGBANKINFO_DECLARATIONS,
+// GET_REGBANKINFO_PARTIALMAPPINGS and GET_REGBANKINFO_VALUEMAPPINGS
+//
+// This was discussed in https://discourse.llvm.org/t/74459
+void RegisterBankEmitter::emitRBIHeader(
+    raw_ostream &OS, 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::emitRBIPartialMappings(
+    raw_ostream &OS, StringRef TargetName,
+    const std::vector<RegisterBank> &Banks) {
+  const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
+
+  OS << "namespace llvm {\n"
+     << "namespace " << TargetName << " {\n"
+     << "const RegisterBankInfo::PartialMapping PartialMappings[] = {\n";
+  for (const auto &Bank : Banks) {
+    for (const CodeGenRegisterClass *RC :
+         Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)) {
+      if (!RC->RSI.isSimple()) {
+        OS << "  #error non-Simple() RegisterClass " << RC->getName() << "\n";
+      } else if (RC->getValueTypes()[0].getSimple() == MVT::Untyped) {
+        OS << "  #error Untyped RegisterClass " << RC->getName() << "\n";
+      } else {
+        // StartIdx is currently 0 in all of the in-tree backends
+        OS << "  { 0, " << RC->RSI.getSimple().RegSize << ", "
+           << Bank.getInstanceVarName() << " },\n";
+      }
+    }
+  }
+  OS << "};\n\n";
+
+  // emit PartialMappingIdx of the first Register Class of each Register Bank
+  OS << "const 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 << "const int BankIDToRegisterClassCount[] = {\n";
+  for (const auto &Bank : Banks) {
+    OS << "  "
+       << Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)
+              .size()
+       << ",\n";
+  }
+  OS << "};\n\n";
+
+  OS << "} // end namespace " << TargetName << "\n"
+     << "} // end namespace llvm\n";
+}
+
+// This supports ValueMappings for the simple cases.
+// For the complex cases, GET_REGBANKINFO_VALUEMAPPINGS should be left
+// undefined and the ValueMapping tables and enums must be hand crafted.
+void RegisterBankEmitter::emitRBIValueMappings(
+    raw_ostream &OS, StringRef TargetName,
+    const std::vector<RegisterBank> &Banks) {
+  const CodeGenRegBank &RegisterClassHierarchy = Target.getRegBank();
+
+  OS << "namespace llvm {\n"
+     << "namespace " << TargetName << " {\n"
+     << "const RegisterBankInfo::ValueMapping ValueMappings[] = {\n"
+     << "  { nullptr, 0 },\n";
+  for (const auto &Bank : Banks) {
+    for (const CodeGenRegisterClass *RC :
+         Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)) {
+      if (!RC->RSI.isSimple()) {
+        OS << "  #error non-Simple() RegisterClass " << RC->getName() << "\n";
+      } else if (RC->getValueTypes()[0].getSimple() == MVT::Untyped) {
+        OS << "  #error Untyped RegisterClass " << RC->getName() << "\n";
+      } else {
+        OS << "  { &PartialMappings[PMI_" << RC->getName() << "], 1},\n"
+           << "  { &PartialMappings[PMI_" << RC->getName() << "], 1},\n"
+           << "  { &PartialMappings[PMI_" << RC->getName() << "], 1},\n";
+      }
+    }
+  }
+  OS << "};\n\n";
+
+  OS << "enum ValueMappingIdx = {\n"
+     << "  VMI_Invalid = 0,\n";
+  int Offset = 1;
+  for (const auto &Bank : Banks) {
+    for (const CodeGenRegisterClass *RC :
+         Bank.getExplicitlySpecifiedRegisterClasses(RegisterClassHierarchy)) {
+      if (!RC->RSI.isSimple()) {
+        OS << "  #error non-Simple() RegisterClass " << RC->getName() << "\n";
+      } else if (RC->getValueTypes()[0].getSimple() == MVT::Untyped) {
+        OS << "  #error Untyped RegisterClass " << RC->getName() << "\n";
----------------
arsenm wrote:

Single quotes for single characters 

https://github.com/llvm/llvm-project/pull/71357


More information about the llvm-commits mailing list