Skip to content

Commit 3e5035b

Browse files
committed
Use bit table lookup
1 parent 912547b commit 3e5035b

File tree

1 file changed

+45
-27
lines changed

1 file changed

+45
-27
lines changed

llvm/utils/TableGen/AsmMatcherEmitter.cpp

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2541,39 +2541,57 @@ static void emitIsSubclass(CodeGenTarget &Target,
25412541
OS << " if (A == B)\n";
25422542
OS << " return true;\n\n";
25432543

2544+
// TODO: Use something like SequenceToOffsetTable to allow sequences to
2545+
// overlap in this table.
2546+
SmallVector<bool> SuperClassData;
2547+
2548+
OS << " [[maybe_unused]] static constexpr struct {\n";
2549+
OS << " uint32_t Offset;\n";
2550+
OS << " uint16_t Start;\n";
2551+
OS << " uint16_t Length;\n";
2552+
OS << " } Table[] = {\n";
2553+
OS << " {0, 0, 0},\n"; // InvalidMatchClass
2554+
OS << " {0, 0, 0},\n"; // OptionalMatchClass
25442555
for (const auto &A : Infos) {
2545-
std::vector<StringRef> SuperClasses;
2546-
if (A.IsOptional)
2547-
SuperClasses.push_back("OptionalMatchClass");
2548-
for (const auto &B : Infos) {
2549-
if (&A != &B && A.isSubsetOf(B))
2550-
SuperClasses.push_back(B.Name);
2551-
}
2556+
SmallVector<bool> SuperClasses;
2557+
SuperClasses.push_back(false); // InvalidMatchClass
2558+
SuperClasses.push_back(A.IsOptional); // OptionalMatchClass
2559+
for (const auto &B : Infos)
2560+
SuperClasses.push_back(&A != &B && A.isSubsetOf(B));
25522561

2553-
if (SuperClasses.empty()) {
2554-
OS << " static constexpr ArrayRef<uint16_t> " << A.Name
2555-
<< "_SuperClasses;\n";
2556-
continue;
2557-
}
2562+
// Trim leading and trailing zeros.
2563+
auto End = find_if(reverse(SuperClasses), [](bool B){ return B; }).base();
2564+
auto Start = std::find_if(SuperClasses.begin(), End, [](bool B){ return B; });
25582565

2559-
OS << " static constexpr uint16_t " << A.Name << "_SuperClasses[] = {";
2560-
ListSeparator LS;
2561-
for (auto &SC : SuperClasses)
2562-
OS << LS << SC;
2563-
OS << "};\n";
2564-
}
2565-
OS << "\n";
2566+
unsigned Offset = SuperClassData.size();
2567+
SuperClassData.append(Start, End);
25662568

2567-
OS << " static constexpr ArrayRef<uint16_t> SuperClassTable[] = {\n";
2568-
OS << " {}, // InvalidMatchClass\n";
2569-
OS << " {}, // OptionalMatchClass\n";
2570-
for (const auto &A : Infos)
2571-
OS << " " << A.Name << "_SuperClasses,\n";
2569+
OS << " {" << Offset << ", " << (Start - SuperClasses.begin()) << ", " <<
2570+
(End - Start) << "},\n";
2571+
}
25722572
OS << " };\n\n";
25732573

2574-
OS << " ArrayRef<uint16_t> SuperClasses = SuperClassTable[A];\n";
2575-
OS << " return binary_search(SuperClasses, B);\n";
2576-
2574+
if (SuperClassData.empty()) {
2575+
OS << " return false;\n";
2576+
} else {
2577+
// Dump the boolean data packed into bytes.
2578+
SuperClassData.append(-SuperClassData.size() % 8, false);
2579+
OS << " static constexpr uint8_t Data[] = {\n";
2580+
for (unsigned I = 0, E = SuperClassData.size(); I < E; I += 8) {
2581+
unsigned Byte = 0;
2582+
for (unsigned J = 0; J < 8; ++J)
2583+
Byte |= (unsigned)SuperClassData[I + J] << J;
2584+
OS << formatv(" {:X2},\n", Byte);
2585+
}
2586+
OS << " };\n\n";
2587+
2588+
OS << " auto &Entry = Table[A];\n";
2589+
OS << " unsigned Idx = B - Entry.Start;\n";
2590+
OS << " if (Idx >= Entry.Length)\n";
2591+
OS << " return false;\n";
2592+
OS << " Idx += Entry.Offset;\n";
2593+
OS << " return (Data[Idx / 8] >> (Idx % 8)) & 1;\n";
2594+
}
25772595
OS << "}\n\n";
25782596
}
25792597

0 commit comments

Comments
 (0)