@@ -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