Index: llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h =================================================================== --- llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h +++ llvm/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h @@ -599,7 +599,6 @@ /// that are used in the description of instruction. In other words, /// there are just a handful of them and we do not want to waste space. /// - /// \todo This should be TableGen'ed. virtual const RegisterBank & getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const { llvm_unreachable("The target must override this method"); Index: llvm/test/TableGen/RegisterBankEmitter.td =================================================================== --- llvm/test/TableGen/RegisterBankEmitter.td +++ llvm/test/TableGen/RegisterBankEmitter.td @@ -4,12 +4,27 @@ def MyTarget : Target; def R0 : Register<"r0">; +def F1 : Register<"f1">; + let Size = 32 in { def ClassA : RegisterClass<"MyTarget", [i32], 32, (add R0)>; def ClassB : RegisterClass<"MyTarget", [i1], 32, (add ClassA)>; + def ClassC : RegisterClass<"MyTarget", [i32], 32, (add R0)>; + + def ClassD : RegisterClass<"MyTarget", [i32], 32, (add F1)>; } // CHECK: GPRRegBankCoverageData // CHECK: MyTarget::ClassARegClassID // CHECK: MyTarget::ClassBRegClassID + +// CHECK: MyTargetGenRegisterBankInfo::getRegBankFromRegClass +// CHECK: case MyTarget::ClassDRegClassID: +// CHECK-NEXT: return getRegBank(MyTarget::FPRRegBankID); + +// CHECK: case MyTarget::ClassARegClassID: +// CHECK-NEXT: case MyTarget::ClassBRegClassID: +// CHECK-NEXT: case MyTarget::ClassCRegClassID: +// CHECK-NEXT: return getRegBank(MyTarget::GPRRegBankID); def GPRRegBank : RegisterBank<"GPR", [ClassA]>; +def FPRRegBank : RegisterBank<"FPR", [ClassA, ClassD]>; Index: llvm/utils/TableGen/RegisterBankEmitter.cpp =================================================================== --- llvm/utils/TableGen/RegisterBankEmitter.cpp +++ llvm/utils/TableGen/RegisterBankEmitter.cpp @@ -149,6 +149,10 @@ << "protected:\n" << " " << TargetName << "GenRegisterBankInfo();\n" << "\n"; + + OS << " virtual const RegisterBank &\n" + << " getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const override;\n" + << "\n"; } /// Visit each register class belonging to the given register bank. @@ -271,8 +275,34 @@ << " for (const auto &RB : RegBanks)\n" << " assert(Index++ == RB->getID() && \"Index != ID\");\n" << "#endif // NDEBUG\n" - << "}\n" - << "} // end namespace llvm\n"; + << "}\n\n"; + + // generate getRegBankFromRegClass + { + OS << "const RegisterBank &\n" + << TargetName << "GenRegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, LLT Ty) const {\n" + << " switch (RC.getID()) {\n"; + + for (const auto &Bank : Banks) { + std::string QualifiedBankID = + (TargetName + "::" + Bank.getEnumeratorName()).str(); + for (const auto &RC : Bank.register_classes()) { + std::string QualifiedRegClassID = + (Twine(RC->Namespace) + "::" + RC->getName() + "RegClassID").str(); + OS << " case " << QualifiedRegClassID << ":\n"; + } + OS << " return getRegBank("<< QualifiedBankID << ");\n"; + } + + OS << "" + << " default:\n" + << " llvm_unreachable(\"Register class not supported\");\n" + << " }\n" + << "}\n"; + } + + + OS << "} // end namespace llvm\n"; } void RegisterBankEmitter::run(raw_ostream &OS) {