[llvm] [TableGen] Simplify generated code for isSubclass (PR #117351)
Jay Foad via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 27 05:08:40 PST 2024
================
@@ -2541,53 +2541,58 @@ static void emitIsSubclass(CodeGenTarget &Target,
OS << " if (A == B)\n";
OS << " return true;\n\n";
- bool EmittedSwitch = false;
+ // TODO: Use something like SequenceToOffsetTable to allow sequences to
+ // overlap in this table.
+ SmallVector<bool> SuperClassData;
+
+ OS << " [[maybe_unused]] static constexpr struct {\n";
+ OS << " uint32_t Offset;\n";
+ OS << " uint16_t Start;\n";
+ OS << " uint16_t Length;\n";
+ OS << " } Table[] = {\n";
+ OS << " {0, 0, 0},\n"; // InvalidMatchClass
+ OS << " {0, 0, 0},\n"; // OptionalMatchClass
for (const auto &A : Infos) {
- std::vector<StringRef> SuperClasses;
- if (A.IsOptional)
- SuperClasses.push_back("OptionalMatchClass");
- for (const auto &B : Infos) {
- if (&A != &B && A.isSubsetOf(B))
- SuperClasses.push_back(B.Name);
- }
-
- if (SuperClasses.empty())
- continue;
-
- // If this is the first SuperClass, emit the switch header.
- if (!EmittedSwitch) {
- OS << " switch (A) {\n";
- OS << " default:\n";
- OS << " return false;\n";
- EmittedSwitch = true;
- }
-
- OS << "\n case " << A.Name << ":\n";
-
- if (SuperClasses.size() == 1) {
- OS << " return B == " << SuperClasses.back() << ";\n";
- continue;
- }
-
- if (!SuperClasses.empty()) {
- OS << " switch (B) {\n";
- OS << " default: return false;\n";
- for (StringRef SC : SuperClasses)
- OS << " case " << SC << ": return true;\n";
- OS << " }\n";
- } else {
- // No case statement to emit
- OS << " return false;\n";
- }
+ SmallVector<bool> SuperClasses;
+ SuperClasses.push_back(false); // InvalidMatchClass
+ SuperClasses.push_back(A.IsOptional); // OptionalMatchClass
+ for (const auto &B : Infos)
+ SuperClasses.push_back(&A != &B && A.isSubsetOf(B));
+
+ // Trim leading and trailing zeros.
+ auto End = find_if(reverse(SuperClasses), [](bool B) { return B; }).base();
+ auto Start =
+ std::find_if(SuperClasses.begin(), End, [](bool B) { return B; });
+
+ unsigned Offset = SuperClassData.size();
+ SuperClassData.append(Start, End);
+
+ OS << " {" << Offset << ", " << (Start - SuperClasses.begin()) << ", "
+ << (End - Start) << "},\n";
}
+ OS << " };\n\n";
- // If there were case statements emitted into the string stream write the
- // default.
- if (EmittedSwitch)
- OS << " }\n";
- else
+ if (SuperClassData.empty()) {
OS << " return false;\n";
-
+ } else {
+ // Dump the boolean data packed into bytes.
----------------
jayfoad wrote:
Yes I looked at it but I couldn't see any way to append BitVectors, which meant I couldn't use it for SuperClassData, so I stopped looking.
https://github.com/llvm/llvm-project/pull/117351
More information about the llvm-commits
mailing list