Lines Matching +full:enum +full:- +full:name
1 //===- SearchableTableEmitter.cpp - Generate efficiently searchable tables -==//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
14 //===----------------------------------------------------------------------===//
32 #define DEBUG_TYPE "searchable-table-emitter"
38 B->convertInitializerTo(IntRecTy::get(B->getRecordKeeper()))) in getAsInt()
39 ->getValue(); in getAsInt()
42 return getAsInt(R->getValueInit(Field)); in getInt()
48 std::string Name; member
56 std::string Name; member
61 GenericEnum *Enum = nullptr; member
63 GenericField(StringRef Name) : Name(std::string(Name)) {} in GenericField()
67 std::string Name; member
75 std::string Name; member
85 const GenericField *getFieldByName(StringRef Name) const { in getFieldByName()
87 if (Name == Field.Name) in getFieldByName()
110 enum TypeContext {
119 if (Field.IsCode || SI->hasCodeFormat()) in primaryRepresentation()
120 return std::string(SI->getValue()); in primaryRepresentation()
122 return SI->getAsString(); in primaryRepresentation()
126 return BI->getValue() ? "true" : "false"; in primaryRepresentation()
130 return I->getAsString(); in primaryRepresentation()
131 else if (Field.Enum) { in primaryRepresentation()
132 auto *Entry = Field.Enum->EntryMap[cast<DefInit>(I)->getDef()]; in primaryRepresentation()
135 Twine("Entry for field '") + Field.Name + "' is null"); in primaryRepresentation()
136 return std::string(Entry->first); in primaryRepresentation()
138 PrintFatalError(Loc, Twine("invalid field type for field '") + Field.Name + in primaryRepresentation()
144 return DI->getDef()->isSubClassOf("Intrinsic"); in isIntrinsic()
151 Intr = std::make_unique<CodeGenIntrinsic>(cast<DefInit>(I)->getDef(), in getIntrinsic()
168 unsigned NumBits = BI->getNumBits(); in searchableFieldType()
177 PrintFatalError(Index.Loc, Twine("In table '") + Table.Name + in searchableFieldType()
178 "' lookup method '" + Index.Name + in searchableFieldType()
179 "', key field '" + Field.Name + in searchableFieldType()
183 } else if (Field.Enum || Field.IsIntrinsic || Field.IsInstruction) in searchableFieldType()
186 Twine("In table '") + Table.Name + "' lookup method '" + in searchableFieldType()
187 Index.Name + "', key field '" + Field.Name + in searchableFieldType()
188 "' has invalid type: " + Field.RecType->getAsString()); in searchableFieldType()
192 void emitGenericEnum(const GenericEnum &Enum, raw_ostream &OS);
201 parseSearchIndex(GenericTable &Table, const RecordVal *RecVal, StringRef Name,
204 void collectEnumEntries(GenericEnum &Enum, StringRef NameField,
221 // we check for IsInstruction before Enum-- these fields are not exclusive. in getNumericKey()
223 Record *TheDef = Rec->getValueAsDef(Index.Fields[0].Name); in getNumericKey()
224 return Target->getInstrIntValue(TheDef); in getNumericKey()
226 if (Index.Fields[0].Enum) { in getNumericKey()
227 Record *EnumEntry = Rec->getValueAsDef(Index.Fields[0].Name); in getNumericKey()
228 return Index.Fields[0].Enum->EntryMap[EnumEntry]->second; in getNumericKey()
231 return getInt(Rec, Index.Fields[0].Name); in getNumericKey()
234 /// Less-than style comparison between \p LHS and \p RHS according to the
239 Init *LHSI = LHS->getValueInit(Field.Name); in compareBy()
240 Init *RHSI = RHS->getValueInit(Field.Name); in compareBy()
252 if (std::tie(LHSi.TargetPrefix, LHSi.Name) < in compareBy()
253 std::tie(RHSi.TargetPrefix, RHSi.Name)) in compareBy()
255 if (std::tie(LHSi.TargetPrefix, LHSi.Name) > in compareBy()
256 std::tie(RHSi.TargetPrefix, RHSi.Name)) in compareBy()
260 Record *LHSr = cast<DefInit>(LHSI)->getDef(); in compareBy()
261 Record *RHSr = cast<DefInit>(RHSI)->getDef(); in compareBy()
263 bool LHSpseudo = LHSr->getValueAsBit("isPseudo"); in compareBy()
264 bool RHSpseudo = RHSr->getValueAsBit("isPseudo"); in compareBy()
270 int comp = LHSr->getName().compare(RHSr->getName()); in compareBy()
275 } else if (Field.Enum) { in compareBy()
276 auto LHSr = cast<DefInit>(LHSI)->getDef(); in compareBy()
277 auto RHSr = cast<DefInit>(RHSI)->getDef(); in compareBy()
278 int64_t LHSv = Field.Enum->EntryMap[LHSr]->second; in compareBy()
279 int64_t RHSv = Field.Enum->EntryMap[RHSr]->second; in compareBy()
308 /// Emit a generic enum.
309 void SearchableTableEmitter::emitGenericEnum(const GenericEnum &Enum, in emitGenericEnum() argument
311 emitIfdef((Twine("GET_") + Enum.PreprocessorGuard + "_DECL").str(), OS); in emitGenericEnum()
313 OS << "enum " << Enum.Name << " {\n"; in emitGenericEnum()
314 for (const auto &Entry : Enum.Entries) in emitGenericEnum()
315 OS << " " << Entry->first << " = " << Entry->second << ",\n"; in emitGenericEnum()
336 IndexName = Table.Name; in emitLookupFunction()
343 << Field.Name << ";\n"; in emitLookupFunction()
368 Index.Loc, Field, Entry.first->getValueInit(Field.Name)); in emitLookupFunction()
386 (Index.Fields[0].Enum || isa<BitsRecTy>(Index.Fields[0].RecType) || in emitLookupFunction()
401 Index.Loc, Field, IndexRows[0]->getValueInit(Field.Name)); in emitLookupFunction()
403 Index.Loc, Field, IndexRows.back()->getValueInit(Field.Name)); in emitLookupFunction()
404 OS << " if ((" << Field.Name << " < " << FirstRepr << ") ||\n"; in emitLookupFunction()
405 OS << " (" << Field.Name << " > " << LastRepr << "))\n"; in emitLookupFunction()
408 OS << " size_t Idx = " << Index.Fields[0].Name << " - " << FirstRepr in emitLookupFunction()
414 OS << "&" << Table.Name << "[Table[Idx]._index]"; in emitLookupFunction()
423 Index.Loc, Field, IndexRows[0]->getValueInit(Field.Name)); in emitLookupFunction()
425 Index.Loc, Field, IndexRows.back()->getValueInit(Field.Name)); in emitLookupFunction()
426 OS << " if ((" << Field.Name << " < " << FirstRepr << ") ||\n"; in emitLookupFunction()
427 OS << " (" << Field.Name << " > " << LastRepr << "))\n"; in emitLookupFunction()
434 << " " << Field.Name << ";\n"; in emitLookupFunction()
440 OS << LS << Field.Name; in emitLookupFunction()
445 Twine("In table '") + Table.Name + in emitLookupFunction()
447 "case-insensitive comparison of field '" + in emitLookupFunction()
448 Field.Name + "'"); in emitLookupFunction()
460 OS << " int Cmp" << Field.Name << " = StringRef(LHS." << Field.Name in emitLookupFunction()
461 << ").compare(RHS." << Field.Name << ");\n"; in emitLookupFunction()
462 OS << " if (Cmp" << Field.Name << " < 0) return true;\n"; in emitLookupFunction()
463 OS << " if (Cmp" << Field.Name << " > 0) return false;\n"; in emitLookupFunction()
464 } else if (Field.Enum) { in emitLookupFunction()
466 // compiler-dependent. in emitLookupFunction()
467 OS << " if ((unsigned)LHS." << Field.Name << " < (unsigned)RHS." in emitLookupFunction()
468 << Field.Name << ")\n"; in emitLookupFunction()
470 OS << " if ((unsigned)LHS." << Field.Name << " > (unsigned)RHS." in emitLookupFunction()
471 << Field.Name << ")\n"; in emitLookupFunction()
474 OS << " if (LHS." << Field.Name << " < RHS." << Field.Name in emitLookupFunction()
477 OS << " if (LHS." << Field.Name << " > RHS." << Field.Name in emitLookupFunction()
504 OS << " ||\n Key." << Field.Name << " != Idx->" << Field.Name; in emitLookupFunction()
514 OS << " return &" << Table.Name << "[Idx->_index];\n"; in emitLookupFunction()
527 OS << Index.Name << "("; in emitLookupDeclaration()
531 << Field.Name; in emitLookupDeclaration()
554 OS << "constexpr " << Table.CppTypeName << " " << Table.Name << "[] = {\n"; in emitGenericTable()
563 Entry->getValueInit(Field.Name)); in emitGenericTable()
581 if (Type->getValue() == "code") { in parseFieldType()
585 if (Record *TypeRec = Records.getDef(Type->getValue())) { in parseFieldType()
586 if (TypeRec->isSubClassOf("GenericEnum")) { in parseFieldType()
587 Field.Enum = EnumMap[TypeRec]; in parseFieldType()
588 Field.RecType = RecordRecTy::get(Field.Enum->Class); in parseFieldType()
599 GenericTable &Table, const RecordVal *KeyRecVal, StringRef Name, in parseSearchIndex() argument
602 Index->Name = std::string(Name); in parseSearchIndex()
603 Index->Loc = KeyRecVal->getLoc(); in parseSearchIndex()
604 Index->EarlyOut = EarlyOut; in parseSearchIndex()
605 Index->ReturnRange = ReturnRange; in parseSearchIndex()
612 Twine("In table '") + Table.Name + in parseSearchIndex()
616 Index->Fields.push_back(*Field); in parseSearchIndex()
619 if (EarlyOut && isa<StringRecTy>(Index->Fields[0].RecType)) { in parseSearchIndex()
621 KeyRecVal, Twine("In lookup method '") + Name + "', early-out is not " + in parseSearchIndex()
629 GenericEnum &Enum, StringRef NameField, StringRef ValueField, in collectEnumEntries() argument
632 StringRef Name; in collectEnumEntries() local
634 Name = EntryRec->getName(); in collectEnumEntries()
636 Name = EntryRec->getValueAsString(NameField); in collectEnumEntries()
642 Enum.Entries.push_back(std::make_unique<GenericEnum::Entry>(Name, Value)); in collectEnumEntries()
643 Enum.EntryMap.insert(std::pair(EntryRec, Enum.Entries.back().get())); in collectEnumEntries()
647 llvm::stable_sort(Enum.Entries, in collectEnumEntries()
650 return LHS->first < RHS->first; in collectEnumEntries()
653 for (size_t i = 0; i < Enum.Entries.size(); ++i) in collectEnumEntries()
654 Enum.Entries[i]->second = i; in collectEnumEntries()
662 Twine("Table '") + Table.Name + "' has no entries"); in collectTableEntries()
666 auto TI = dyn_cast<TypedInit>(EntryRec->getValueInit(Field.Name)); in collectTableEntries()
667 if (!TI || !TI->isComplete()) { in collectTableEntries()
668 PrintFatalError(EntryRec, Twine("Record '") + EntryRec->getName() + in collectTableEntries()
669 "' for table '" + Table.Name + in collectTableEntries()
670 "' is missing field '" + Field.Name + in collectTableEntries()
674 Field.RecType = TI->getType(); in collectTableEntries()
676 RecTy *Ty = resolveTypes(Field.RecType, TI->getType()); in collectTableEntries()
678 PrintFatalError(EntryRec->getValue(Field.Name), in collectTableEntries()
679 Twine("Field '") + Field.Name + "' of table '" + in collectTableEntries()
680 Table.Name + "' entry has incompatible type: " + in collectTableEntries()
681 TI->getType()->getAsString() + " vs. " + in collectTableEntries()
682 Field.RecType->getAsString()); in collectTableEntries()
694 PrintFatalError(Twine("Cannot determine type of field '") + Field.Name + in collectTableEntries()
695 "' in table '" + Table.Name + "'. Maybe it is not used?"); in collectTableEntries()
698 if (IntrinsicClass && RecordTy->isSubClassOf(IntrinsicClass)) in collectTableEntries()
700 else if (InstructionClass && RecordTy->isSubClassOf(InstructionClass)) in collectTableEntries()
723 if (!EnumRec->isValueUnset("NameField")) in run()
724 NameField = EnumRec->getValueAsString("NameField"); in run()
727 if (!EnumRec->isValueUnset("ValueField")) in run()
728 ValueField = EnumRec->getValueAsString("ValueField"); in run()
730 auto Enum = std::make_unique<GenericEnum>(); in run() local
731 Enum->Name = std::string(EnumRec->getName()); in run()
732 Enum->PreprocessorGuard = std::string(EnumRec->getName()); in run()
734 StringRef FilterClass = EnumRec->getValueAsString("FilterClass"); in run()
735 Enum->Class = Records.getClass(FilterClass); in run()
736 if (!Enum->Class) in run()
737 PrintFatalError(EnumRec->getValue("FilterClass"), in run()
738 Twine("Enum FilterClass '") + FilterClass + in run()
741 collectEnumEntries(*Enum, NameField, ValueField, in run()
743 EnumMap.insert(std::pair(EnumRec, Enum.get())); in run()
744 Enums.emplace_back(std::move(Enum)); in run()
749 Table->Name = std::string(TableRec->getName()); in run()
750 Table->Locs = TableRec->getLoc(); in run()
751 Table->PreprocessorGuard = std::string(TableRec->getName()); in run()
752 Table->CppTypeName = std::string(TableRec->getValueAsString("CppTypeName")); in run()
754 std::vector<StringRef> Fields = TableRec->getValueAsListOfStrings("Fields"); in run()
756 Table->Fields.emplace_back(FieldName); // Construct a GenericField. in run()
759 TableRec->getValue(("TypeOf_" + FieldName).str())) { in run()
760 if (!parseFieldType(Table->Fields.back(), in run()
761 TypeOfRecordVal->getValue())) { in run()
763 Twine("Table '") + Table->Name + "' has invalid 'TypeOf_" + in run()
765 "': " + TypeOfRecordVal->getValue()->getAsString()); in run()
772 StringRef FilterClass = TableRec->getValueAsString("FilterClass"); in run()
774 PrintFatalError(TableRec->getValue("FilterClass"), in run()
778 RecordVal *FilterClassFieldVal = TableRec->getValue("FilterClassField"); in run()
782 dyn_cast<StringInit>(FilterClassFieldVal->getValue())) { in run()
783 StringRef FilterClassField = FilterClassFieldInit->getValue(); in run()
785 const RecordVal *Filter = R->getValue(FilterClassField); in run()
786 if (auto *BitV = dyn_cast<BitInit>(Filter->getValue())) in run()
787 return !BitV->getValue(); in run()
796 if (!TableRec->isValueUnset("PrimaryKey")) { in run()
797 Table->PrimaryKey = in run()
798 parseSearchIndex(*Table, TableRec->getValue("PrimaryKey"), in run()
799 TableRec->getValueAsString("PrimaryKeyName"), in run()
800 TableRec->getValueAsListOfStrings("PrimaryKey"), in run()
801 TableRec->getValueAsBit("PrimaryKeyEarlyOut"), in run()
802 TableRec->getValueAsBit("PrimaryKeyReturnRange")); in run()
804 llvm::stable_sort(Table->Entries, [&](Record *LHS, Record *RHS) { in run()
805 return compareBy(LHS, RHS, *Table->PrimaryKey); in run()
814 Record *TableRec = IndexRec->getValueAsDef("Table"); in run()
817 PrintFatalError(IndexRec->getValue("Table"), in run()
818 Twine("SearchIndex '") + IndexRec->getName() + in run()
820 TableRec->getName()); in run()
822 GenericTable &Table = *It->second; in run()
824 Table, IndexRec->getValue("Key"), IndexRec->getName(), in run()
825 IndexRec->getValueAsListOfStrings("Key"), in run()
826 IndexRec->getValueAsBit("EarlyOut"), /*ReturnRange*/ false)); in run()
833 if (Class->getSuperClasses().size() != 1 || in run()
834 !Class->isSubClassOf(SearchableTable)) in run()
837 StringRef TableName = Class->getName(); in run()
839 if (!Class->isValueUnset("EnumNameField")) { in run()
840 StringRef NameField = Class->getValueAsString("EnumNameField"); in run()
842 if (!Class->isValueUnset("EnumValueField")) in run()
843 ValueField = Class->getValueAsString("EnumValueField"); in run()
845 auto Enum = std::make_unique<GenericEnum>(); in run() local
846 Enum->Name = (Twine(Class->getName()) + "Values").str(); in run()
847 Enum->PreprocessorGuard = Class->getName().upper(); in run()
848 Enum->Class = Class; in run()
850 collectEnumEntries(*Enum, NameField, ValueField, Items); in run()
852 Enums.emplace_back(std::move(Enum)); in run()
856 Table->Name = (Twine(Class->getName()) + "sList").str(); in run()
857 Table->Locs = Class->getLoc(); in run()
858 Table->PreprocessorGuard = Class->getName().upper(); in run()
859 Table->CppTypeName = std::string(Class->getName()); in run()
861 for (const RecordVal &Field : Class->getValues()) { in run()
871 Table->Fields.emplace_back(FieldName); in run()
877 Class->getValueAsListOfStrings("SearchableFields")) { in run()
878 std::string Name = in run() local
879 (Twine("lookup") + Table->CppTypeName + "By" + Field).str(); in run()
880 Table->Indices.push_back( in run()
881 parseSearchIndex(*Table, Class->getValue(Field), Name, {Field}, in run()
889 for (const auto &Enum : Enums) in run() local
890 emitGenericEnum(*Enum, OS); in run()
902 X("gen-searchable-tables", "Generate generic binary-searchable table");