llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Rahul Joshi (jurahul) <details> <summary>Changes</summary> Change SeachableTableEmitter to use const RecordKeeper. Also change RecordRecTy to use const Record pointers for its classes. This is a part of effort to have better const correctness in TableGen backends: https://discourse.llvm.org/t/psa-planned-changes-to-tablegen-getallderiveddefinitions-api-potential-downstream-breakages/81089 --- Patch is 26.79 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/110032.diff 7 Files Affected: - (modified) clang/utils/TableGen/ClangAttrEmitter.cpp (+1-1) - (modified) llvm/include/llvm/TableGen/Record.h (+12-11) - (modified) llvm/lib/TableGen/Record.cpp (+25-25) - (modified) llvm/lib/TableGen/TGParser.cpp (+1-1) - (modified) llvm/utils/TableGen/SearchableTableEmitter.cpp (+73-65) - (modified) mlir/tools/mlir-tblgen/OmpOpGen.cpp (+1-1) - (modified) mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp (+3-3) ``````````diff diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 87be48c215e230..7f950c3b08a4b0 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -1866,7 +1866,7 @@ static LateAttrParseKind getLateAttrParseKind(const Record *Attr) { auto *LAPK = Attr->getValueAsDef(LateParsedStr); // Typecheck the `LateParsed` field. - SmallVector<Record *, 1> SuperClasses; + SmallVector<const Record *, 1> SuperClasses; LAPK->getDirectSuperClasses(SuperClasses); if (SuperClasses.size() != 1) PrintFatalError(Attr, "Field `" + Twine(LateParsedStr) + diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h index 4cd73c3f675527..b68fff605d12dd 100644 --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -226,8 +226,9 @@ class DagRecTy : public RecTy { /// /// The list of superclasses is non-redundant, i.e. only contains classes that /// are not the superclass of some other listed class. -class RecordRecTy final : public RecTy, public FoldingSetNode, - public TrailingObjects<RecordRecTy, Record *> { +class RecordRecTy final : public RecTy, + public FoldingSetNode, + public TrailingObjects<RecordRecTy, const Record *> { friend class Record; friend detail::RecordKeeperImpl; @@ -248,23 +249,23 @@ class RecordRecTy final : public RecTy, public FoldingSetNode, } /// Get the record type with the given non-redundant list of superclasses. - static RecordRecTy *get(RecordKeeper &RK, ArrayRef<Record *> Classes); - static RecordRecTy *get(Record *Class); + static RecordRecTy *get(RecordKeeper &RK, ArrayRef<const Record *> Classes); + static RecordRecTy *get(const Record *Class); void Profile(FoldingSetNodeID &ID) const; - ArrayRef<Record *> getClasses() const { - return ArrayRef(getTrailingObjects<Record *>(), NumClasses); + ArrayRef<const Record *> getClasses() const { + return ArrayRef(getTrailingObjects<const Record *>(), NumClasses); } - using const_record_iterator = Record * const *; + using const_record_iterator = const Record *const *; const_record_iterator classes_begin() const { return getClasses().begin(); } const_record_iterator classes_end() const { return getClasses().end(); } std::string getAsString() const override; - bool isSubClassOf(Record *Class) const; + bool isSubClassOf(const Record *Class) const; bool typeIsConvertibleTo(const RecTy *RHS) const override; bool typeIsA(const RecTy *RHS) const override; @@ -1556,7 +1557,7 @@ class RecordVal { bool IsUsed = false; /// Reference locations to this record value. - SmallVector<SMRange> ReferenceLocs; + mutable SmallVector<SMRange> ReferenceLocs; public: RecordVal(Init *N, RecTy *T, FieldKind K); @@ -1605,7 +1606,7 @@ class RecordVal { bool setValue(Init *V, SMLoc NewLoc); /// Add a reference to this record value. - void addReferenceLoc(SMRange Loc) { ReferenceLocs.push_back(Loc); } + void addReferenceLoc(SMRange Loc) const { ReferenceLocs.push_back(Loc); } /// Return the references of this record value. ArrayRef<SMRange> getReferenceLocs() const { return ReferenceLocs; } @@ -1763,7 +1764,7 @@ class Record { bool hasDirectSuperClass(const Record *SuperClass) const; /// Append the direct superclasses of this record to Classes. - void getDirectSuperClasses(SmallVectorImpl<Record *> &Classes) const; + void getDirectSuperClasses(SmallVectorImpl<const Record *> &Classes) const; bool isTemplateArg(Init *Name) const { return llvm::is_contained(TemplateArgs, Name); diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 0f99b4a13d2f95..2973ef40642554 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -226,22 +226,22 @@ std::string DagRecTy::getAsString() const { } static void ProfileRecordRecTy(FoldingSetNodeID &ID, - ArrayRef<Record *> Classes) { + ArrayRef<const Record *> Classes) { ID.AddInteger(Classes.size()); - for (Record *R : Classes) + for (const Record *R : Classes) ID.AddPointer(R); } RecordRecTy *RecordRecTy::get(RecordKeeper &RK, - ArrayRef<Record *> UnsortedClasses) { + ArrayRef<const Record *> UnsortedClasses) { detail::RecordKeeperImpl &RKImpl = RK.getImpl(); if (UnsortedClasses.empty()) return &RKImpl.AnyRecord; FoldingSet<RecordRecTy> &ThePool = RKImpl.RecordTypePool; - SmallVector<Record *, 4> Classes(UnsortedClasses); - llvm::sort(Classes, [](Record *LHS, Record *RHS) { + SmallVector<const Record *, 4> Classes(UnsortedClasses); + llvm::sort(Classes, [](const Record *LHS, const Record *RHS) { return LHS->getNameInitAsString() < RHS->getNameInitAsString(); }); @@ -263,16 +263,16 @@ RecordRecTy *RecordRecTy::get(RecordKeeper &RK, #endif void *Mem = RKImpl.Allocator.Allocate( - totalSizeToAlloc<Record *>(Classes.size()), alignof(RecordRecTy)); + totalSizeToAlloc<const Record *>(Classes.size()), alignof(RecordRecTy)); RecordRecTy *Ty = new (Mem) RecordRecTy(RK, Classes.size()); std::uninitialized_copy(Classes.begin(), Classes.end(), - Ty->getTrailingObjects<Record *>()); + Ty->getTrailingObjects<const Record *>()); ThePool.InsertNode(Ty, IP); return Ty; } -RecordRecTy *RecordRecTy::get(Record *Class) { +RecordRecTy *RecordRecTy::get(const Record *Class) { assert(Class && "unexpected null class"); - return get(Class->getRecords(), Class); + return get(Class->getRecords(), {Class}); } void RecordRecTy::Profile(FoldingSetNodeID &ID) const { @@ -285,7 +285,7 @@ std::string RecordRecTy::getAsString() const { std::string Str = "{"; bool First = true; - for (Record *R : getClasses()) { + for (const Record *R : getClasses()) { if (!First) Str += ", "; First = false; @@ -295,11 +295,10 @@ std::string RecordRecTy::getAsString() const { return Str; } -bool RecordRecTy::isSubClassOf(Record *Class) const { - return llvm::any_of(getClasses(), [Class](Record *MySuperClass) { - return MySuperClass == Class || - MySuperClass->isSubClassOf(Class); - }); +bool RecordRecTy::isSubClassOf(const Record *Class) const { + return llvm::any_of(getClasses(), [Class](const Record *MySuperClass) { + return MySuperClass == Class || MySuperClass->isSubClassOf(Class); + }); } bool RecordRecTy::typeIsConvertibleTo(const RecTy *RHS) const { @@ -310,9 +309,9 @@ bool RecordRecTy::typeIsConvertibleTo(const RecTy *RHS) const { if (!RTy) return false; - return llvm::all_of(RTy->getClasses(), [this](Record *TargetClass) { - return isSubClassOf(TargetClass); - }); + return llvm::all_of(RTy->getClasses(), [this](const Record *TargetClass) { + return isSubClassOf(TargetClass); + }); } bool RecordRecTy::typeIsA(const RecTy *RHS) const { @@ -320,11 +319,11 @@ bool RecordRecTy::typeIsA(const RecTy *RHS) const { } static RecordRecTy *resolveRecordTypes(RecordRecTy *T1, RecordRecTy *T2) { - SmallVector<Record *, 4> CommonSuperClasses; - SmallVector<Record *, 4> Stack(T1->getClasses()); + SmallVector<const Record *, 4> CommonSuperClasses; + SmallVector<const Record *, 4> Stack(T1->getClasses()); while (!Stack.empty()) { - Record *R = Stack.pop_back_val(); + const Record *R = Stack.pop_back_val(); if (T2->isSubClassOf(R)) { CommonSuperClasses.push_back(R); @@ -2162,8 +2161,8 @@ std::string ExistsOpInit::getAsString() const { RecTy *TypedInit::getFieldType(StringInit *FieldName) const { if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) { - for (Record *Rec : RecordType->getClasses()) { - if (RecordVal *Field = Rec->getValue(FieldName)) + for (const Record *Rec : RecordType->getClasses()) { + if (const RecordVal *Field = Rec->getValue(FieldName)) return Field->getType(); } } @@ -2831,7 +2830,7 @@ void Record::checkName() { } RecordRecTy *Record::getType() const { - SmallVector<Record *, 4> DirectSCs; + SmallVector<const Record *, 4> DirectSCs; getDirectSuperClasses(DirectSCs); return RecordRecTy::get(TrackedRecords, DirectSCs); } @@ -2882,7 +2881,8 @@ bool Record::hasDirectSuperClass(const Record *Superclass) const { return false; } -void Record::getDirectSuperClasses(SmallVectorImpl<Record *> &Classes) const { +void Record::getDirectSuperClasses( + SmallVectorImpl<const Record *> &Classes) const { ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses(); while (!SCs.empty()) { diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp index 54c9a902ec27a1..288bb8a4ed1a61 100644 --- a/llvm/lib/TableGen/TGParser.cpp +++ b/llvm/lib/TableGen/TGParser.cpp @@ -3004,7 +3004,7 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { DI->getDef()->getValue(FieldName)->addReferenceLoc(FieldNameLoc); } else if (auto *TI = dyn_cast<TypedInit>(Result)) { if (auto *RecTy = dyn_cast<RecordRecTy>(TI->getType())) { - for (Record *R : RecTy->getClasses()) + for (const Record *R : RecTy->getClasses()) if (auto *RV = R->getValue(FieldName)) RV->addReferenceLoc(FieldNameLoc); } diff --git a/llvm/utils/TableGen/SearchableTableEmitter.cpp b/llvm/utils/TableGen/SearchableTableEmitter.cpp index b5bf621b057383..549929d7a33820 100644 --- a/llvm/utils/TableGen/SearchableTableEmitter.cpp +++ b/llvm/utils/TableGen/SearchableTableEmitter.cpp @@ -48,10 +48,10 @@ struct GenericEnum { using Entry = std::pair<StringRef, int64_t>; std::string Name; - Record *Class = nullptr; + const Record *Class = nullptr; std::string PreprocessorGuard; std::vector<std::unique_ptr<Entry>> Entries; - DenseMap<Record *, Entry *> EntryMap; + DenseMap<const Record *, Entry *> EntryMap; }; struct GenericField { @@ -79,7 +79,7 @@ struct GenericTable { std::string PreprocessorGuard; std::string CppTypeName; SmallVector<GenericField, 2> Fields; - std::vector<Record *> Entries; + std::vector<const Record *> Entries; std::unique_ptr<SearchIndex> PrimaryKey; SmallVector<std::unique_ptr<SearchIndex>, 2> Indices; @@ -94,20 +94,20 @@ struct GenericTable { }; class SearchableTableEmitter { - RecordKeeper &Records; + const RecordKeeper &Records; std::unique_ptr<CodeGenTarget> Target; std::unique_ptr<CodeGenIntrinsicMap> Intrinsics; std::vector<std::unique_ptr<GenericEnum>> Enums; - DenseMap<Record *, GenericEnum *> EnumMap; + DenseMap<const Record *, GenericEnum *> EnumMap; std::set<std::string> PreprocessorGuards; public: - SearchableTableEmitter(RecordKeeper &R) : Records(R) {} + explicit SearchableTableEmitter(const RecordKeeper &R) : Records(R) {} void run(raw_ostream &OS); private: - typedef std::pair<Init *, int> SearchTableEntry; + typedef std::pair<const Init *, int> SearchTableEntry; enum TypeContext { TypeInStaticStruct, @@ -116,15 +116,15 @@ class SearchableTableEmitter { }; std::string primaryRepresentation(SMLoc Loc, const GenericField &Field, - Init *I) { - if (StringInit *SI = dyn_cast<StringInit>(I)) { + const Init *I) { + if (const StringInit *SI = dyn_cast<StringInit>(I)) { if (Field.IsCode || SI->hasCodeFormat()) return std::string(SI->getValue()); else return SI->getAsString(); - } else if (BitsInit *BI = dyn_cast<BitsInit>(I)) + } else if (const BitsInit *BI = dyn_cast<BitsInit>(I)) return "0x" + utohexstr(getAsInt(BI)); - else if (BitInit *BI = dyn_cast<BitInit>(I)) + else if (const BitInit *BI = dyn_cast<BitInit>(I)) return BI->getValue() ? "true" : "false"; else if (Field.IsIntrinsic) return "Intrinsic::" + getIntrinsic(I).EnumName.str(); @@ -152,7 +152,8 @@ class SearchableTableEmitter { return Target->getIntrinsic(Def); } - bool compareBy(Record *LHS, Record *RHS, const SearchIndex &Index); + bool compareBy(const Record *LHS, const Record *RHS, + const SearchIndex &Index); std::string searchableFieldType(const GenericTable &Table, const SearchIndex &Index, @@ -163,7 +164,7 @@ class SearchableTableEmitter { if (Ctx == TypeInTempStruct) return "std::string"; return "StringRef"; - } else if (BitsRecTy *BI = dyn_cast<BitsRecTy>(Field.RecType)) { + } else if (const BitsRecTy *BI = dyn_cast<BitsRecTy>(Field.RecType)) { unsigned NumBits = BI->getNumBits(); if (NumBits <= 8) return "uint8_t"; @@ -198,14 +199,11 @@ class SearchableTableEmitter { bool parseFieldType(GenericField &Field, Init *II); std::unique_ptr<SearchIndex> parseSearchIndex(GenericTable &Table, const RecordVal *RecVal, StringRef Name, - const std::vector<StringRef> &Key, bool EarlyOut, - bool ReturnRange); + ArrayRef<StringRef> Key, bool EarlyOut, bool ReturnRange); void collectEnumEntries(GenericEnum &Enum, StringRef NameField, - StringRef ValueField, - const std::vector<Record *> &Items); - void collectTableEntries(GenericTable &Table, - const std::vector<Record *> &Items); - int64_t getNumericKey(const SearchIndex &Index, Record *Rec); + StringRef ValueField, ArrayRef<const Record *> Items); + void collectTableEntries(GenericTable &Table, ArrayRef<const Record *> Items); + int64_t getNumericKey(const SearchIndex &Index, const Record *Rec); }; } // End anonymous namespace. @@ -213,17 +211,17 @@ class SearchableTableEmitter { // For search indices that consists of a single field whose numeric value is // known, return that numeric value. int64_t SearchableTableEmitter::getNumericKey(const SearchIndex &Index, - Record *Rec) { + const Record *Rec) { assert(Index.Fields.size() == 1); // To be consistent with compareBy and primaryRepresentation elsewhere, // we check for IsInstruction before Enum-- these fields are not exclusive. if (Index.Fields[0].IsInstruction) { - Record *TheDef = Rec->getValueAsDef(Index.Fields[0].Name); + const Record *TheDef = Rec->getValueAsDef(Index.Fields[0].Name); return Target->getInstrIntValue(TheDef); } if (Index.Fields[0].Enum) { - Record *EnumEntry = Rec->getValueAsDef(Index.Fields[0].Name); + const Record *EnumEntry = Rec->getValueAsDef(Index.Fields[0].Name); return Index.Fields[0].Enum->EntryMap[EnumEntry]->second; } @@ -232,7 +230,7 @@ int64_t SearchableTableEmitter::getNumericKey(const SearchIndex &Index, /// Less-than style comparison between \p LHS and \p RHS according to the /// key of \p Index. -bool SearchableTableEmitter::compareBy(Record *LHS, Record *RHS, +bool SearchableTableEmitter::compareBy(const Record *LHS, const Record *RHS, const SearchIndex &Index) { for (const auto &Field : Index.Fields) { Init *LHSI = LHS->getValueInit(Field.Name); @@ -256,8 +254,8 @@ bool SearchableTableEmitter::compareBy(Record *LHS, Record *RHS, return false; } else if (Field.IsInstruction) { // This does not correctly compare the predefined instructions! - Record *LHSr = cast<DefInit>(LHSI)->getDef(); - Record *RHSr = cast<DefInit>(RHSI)->getDef(); + const Record *LHSr = cast<DefInit>(LHSI)->getDef(); + const Record *RHSr = cast<DefInit>(RHSI)->getDef(); bool LHSpseudo = LHSr->getValueAsBit("isPseudo"); bool RHSpseudo = RHSr->getValueAsBit("isPseudo"); @@ -325,8 +323,8 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table, emitLookupDeclaration(Table, Index, OS); OS << " {\n"; - std::vector<Record *> IndexRowsStorage; - ArrayRef<Record *> IndexRows; + std::vector<const Record *> IndexRowsStorage; + ArrayRef<const Record *> IndexRows; StringRef IndexTypeName; StringRef IndexName; @@ -346,15 +344,16 @@ void SearchableTableEmitter::emitLookupFunction(const GenericTable &Table, OS << " static const struct IndexType Index[] = {\n"; - std::vector<std::pair<Record *, unsigned>> Entries; + std::vector<std::pair<const Record *, unsigned>> Entries; Entries.reserve(Table.Entries.size()); for (unsigned i = 0; i < Table.Entries.size(); ++i) Entries.emplace_back(Table.Entries[i], i); - llvm::stable_sort(Entries, [&](const std::pair<Record *, unsigned> &LHS, - const std::pair<Record *, unsigned> &RHS) { - return compareBy(LHS.first, RHS.first, Index); - }); + llvm::stable_sort(Entries, + [&](const std::pair<const Record *, unsigned> &LHS, + const std::pair<const Record *, unsigned> &RHS) { + return compareBy(LHS.first, RHS.first, Index); + }); IndexRowsStorage.reserve(Entries.size()); for (const auto &Entry : Entries) { @@ -552,7 +551,7 @@ void SearchableTableEmitter::emitGenericTable(const GenericTable &Table, // The primary data table contains all the fields defined for this map. OS << "constexpr " << Table.CppTypeName << " " << Table.Name << "[] = {\n"; for (unsigned i = 0; i < Table.Entries.size(); ++i) { - Record *Entry = Table.Entries[i]; + const Record *Entry = Table.Entries[i]; OS << " { "; ListSeparator LS; @@ -576,18 +575,22 @@ void SearchableTableEmitter::emitGenericTable(const GenericTable &Table, } bool SearchableTableEmitter::parseFieldType(GenericField &Field, Init *TypeOf) { - if (auto Type = dyn_cast<StringInit>(TypeOf)) { - if (Type->getValue() == "code") { - Field.IsCode = true; + auto Type = dyn_cast<StringInit>(TypeOf); + if (!Type) + return false; + + StringRef TypeStr = Type->getValue(); + + if (TypeStr == "code") { + Field.IsCode = true; + return true; + } + + if (const Record *TypeRec = Records.getDef(TypeStr)) { + if (TypeRec->isSubClassOf("GenericEnum")) { + Field.Enum = EnumMap[TypeRec]; + Field.RecType = RecordRecTy::get(Field.Enum->Class); return true; - } else { - if (Record *TypeRec = Records.getDef(Type->getValue())) { - if (TypeRec->isSubClassOf("GenericEnum")) { - Field.Enum = EnumMap[TypeRec]; - Field.RecType = RecordRecTy::get(Field.Enum->Class); - return true; - } - } } } @@ -596,7 +599,7 @@ bool SearchableTableEmitter::parseFieldType(GenericField &Field, Init *TypeOf) { std::unique_ptr<SearchIndex> SearchableTableEmitter::parseSearchIndex( GenericTable &Table, const RecordVal *KeyRecVal, StringRef Name, - const std::vector<StringRef> &Key, bool EarlyOut, bool ReturnRange) { + ArrayRef<StringRef> Key, bool EarlyOut, bool ReturnRange) { auto Index = std::make_unique<SearchIndex>(); Index->Name = std::string(Name); Index->Loc = KeyRecVal->getLoc(); @@ -626,8 +629,8 @@ std::unique_ptr<SearchIndex> SearchableTableEmitter::parseSearchIndex( void SearchableTableEmitter::collectEnumEntries( GenericEnum &Enum, StringRef NameField, StringRef ValueField, - const std::vector<Record *> &Items) { - for (auto *EntryRec : Items) { + ArrayRef<const Record *> Items) { + for (const Record *EntryRec : Items) { StringRef Name; if (NameField.empty()) Name = EntryRec->getName(); @@ -655,7 +658,7 @@ void SearchableTableEmitter::collectEnumEntries( } void SearchableTableEmitter::collectTableEntries( - GenericTable &Table, const std::vector<Record *> &Items) { + GenericTable &Table, ArrayRef<const Record *> Items) { if (Items.empty()) PrintFatalError(Table.Locs, Twine("Table '") + Table.Name + "' has no entries"); @@ -686,8 +689,8 @@ void Searchable... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/110032 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits