[llvm] [TableGen] Simplify generated code for validateOperandClass (PR #117889)
Jay Foad via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 27 06:40:25 PST 2024
https://github.com/jayfoad created https://github.com/llvm/llvm-project/pull/117889
Implement the register operand handling in validateOperandClass with a
table lookup instead of a potentially huge switch.
Part of the motivation for this is improving compile time when clang-18
is used as a host compiler, since it seems to have trouble with very
large switch statements.
>From 5def5c1e83404020a810e75afd59948413d6a309 Mon Sep 17 00:00:00 2001
From: Jay Foad <jay.foad at amd.com>
Date: Wed, 27 Nov 2024 14:22:12 +0000
Subject: [PATCH] [TableGen] Simplify generated code for validateOperandClass
Implement the register operand handling in validateOperandClass with a
table lookup instead of a potentially huge switch.
Part of the motivation for this is improving compile time when clang-18
is used as a host compiler, since it seems to have trouble with very
large switch statements.
---
llvm/utils/TableGen/AsmMatcherEmitter.cpp | 27 ++++++++++++++---------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index c2aa571b547c64..eb80bea3cfb0fe 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -2466,7 +2466,8 @@ static void emitRegisterMatchErrorFunc(AsmMatcherInfo &Info, raw_ostream &OS) {
}
/// emitValidateOperandClass - Emit the function to validate an operand class.
-static void emitValidateOperandClass(AsmMatcherInfo &Info, raw_ostream &OS) {
+static void emitValidateOperandClass(const CodeGenTarget &Target,
+ AsmMatcherInfo &Info, raw_ostream &OS) {
OS << "static unsigned validateOperandClass(MCParsedAsmOperand &GOp, "
<< "MatchClassKind Kind) {\n";
OS << " " << Info.Target.getName() << "Operand &Operand = ("
@@ -2508,15 +2509,21 @@ static void emitValidateOperandClass(AsmMatcherInfo &Info, raw_ostream &OS) {
OS << " } // end switch (Kind)\n\n";
// Check for register operands, including sub-classes.
+ const auto &Regs = Target.getRegBank().getRegisters();
+ StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");
+ SmallVector<StringRef> Table(1 + Regs.size(), "InvalidMatchClass");
+ for (const auto &RC : Info.RegisterClasses) {
+ const auto &Reg = Target.getRegBank().getReg(RC.first);
+ Table[Reg->EnumValue] = RC.second->Name;
+ }
OS << " if (Operand.isReg()) {\n";
- OS << " MatchClassKind OpKind;\n";
- OS << " switch (Operand.getReg().id()) {\n";
- OS << " default: OpKind = InvalidMatchClass; break;\n";
- for (const auto &RC : Info.RegisterClasses)
- OS << " case " << RC.first->getValueAsString("Namespace")
- << "::" << RC.first->getName() << ": OpKind = " << RC.second->Name
- << "; break;\n";
- OS << " }\n";
+ OS << " static constexpr uint16_t Table[" << Namespace
+ << "::NUM_TARGET_REGS] = {\n";
+ for (auto &MatchClassName : Table)
+ OS << " " << MatchClassName << ",\n";
+ OS << " };\n\n";
+ OS << " MatchClassKind OpKind = "
+ "(MatchClassKind)Table[Operand.getReg().id()];\n";
OS << " return isSubclass(OpKind, Kind) ? "
<< "(unsigned)MCTargetAsmParser::Match_Success :\n "
<< " getDiagKindFromRegisterClass(Kind);\n }\n\n";
@@ -3412,7 +3419,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
emitIsSubclass(Target, Info.Classes, OS);
// Emit the routine to validate an operand against a match class.
- emitValidateOperandClass(Info, OS);
+ emitValidateOperandClass(Target, Info, OS);
emitMatchClassKindNames(Info.Classes, OS);
More information about the llvm-commits
mailing list