Index: llvm/docs/TableGen/BackGuide.rst =================================================================== --- llvm/docs/TableGen/BackGuide.rst +++ llvm/docs/TableGen/BackGuide.rst @@ -562,16 +562,16 @@ * ``getDefs()`` returns a ``RecordMap`` reference for all the concrete records. -* ``getDef(``\ *name*\ ``)`` return a ``Record`` reference for the named +* ``getDef(``\ *name*\ ``)`` returns a ``Record`` reference for the named concrete record. * ``getAllDerivedDefinitions(``\ *classname*\ ``)`` returns a vector of ``Record`` references for the concrete records that derive from the given class. -* ``getAllDerivedDefinitionsTwo(``\ *classname1*\ ``,`` *classname2*\ ``)`` returns +* ``getAllDerivedDefinitions(``\ *classvector*\ ``)`` returns a vector of ``Record`` references for the concrete records that derive from - *both* of the given classes. [function to come] + *all* of the given classes. This statement obtains all the records that derive from the ``Attribute`` class and iterates over them. @@ -701,7 +701,7 @@ defined through a sequence of multiclasses. Because of this, it can be difficult for backends to report clear error messages with accurate source file locations. To make error reporting easier, five error reporting -functions are provided, each with four overloads. [all combinations to come] +functions are provided, each with four overloads. * ``PrintWarning`` prints a message tagged as a warning. Index: llvm/include/llvm/TableGen/Record.h =================================================================== --- llvm/include/llvm/TableGen/Record.h +++ llvm/include/llvm/TableGen/Record.h @@ -1784,7 +1784,12 @@ //===--------------------------------------------------------------------===// // High-level helper methods, useful for tablegen backends. - /// Get all the concrete records that inherit from the specified + /// Get all the concrete records that inherit from all the specified + /// classes. The classes must be defined. + std::vector + getAllDerivedDefinitions(const std::vector &Classes) const; + + /// Get all the concrete records that inherit from the one specified /// class. The class must be defined. std::vector getAllDerivedDefinitions(StringRef ClassName) const; Index: llvm/lib/TableGen/Record.cpp =================================================================== --- llvm/lib/TableGen/Record.cpp +++ llvm/lib/TableGen/Record.cpp @@ -2319,10 +2319,10 @@ "' exists but does not have a list value"); } -std::vector +std::vector Record::getValueAsListOfDefs(StringRef FieldName) const { ListInit *List = getValueAsListInit(FieldName); - std::vector Defs; + std::vector Defs; for (Init *I : List->getValues()) { if (DefInit *DI = dyn_cast(I)) Defs.push_back(DI->getDef()); @@ -2470,20 +2470,50 @@ return StringInit::get("anonymous_" + utostr(AnonCounter++)); } +/// Get all the concrete records that inherit from all the specified +/// classes. The classes must be defined. std::vector -RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const { - Record *Class = getClass(ClassName); - if (!Class) - PrintFatalError("ERROR: Couldn't find the `" + ClassName + "' class!\n"); - - std::vector Defs; - for (const auto &D : getDefs()) - if (D.second->isSubClassOf(Class)) - Defs.push_back(D.second.get()); +RecordKeeper::getAllDerivedDefinitions(const std::vector &Classes) const { + SmallVector ClassRecs; + std::vector Defs; + bool AddDef; + + // First get the class records for the specified classes and make + // sure they exist. + assert(Classes.size() > 0 && "At least one class must be passed."); + for (const auto ClassName : Classes) { + Record *Class = getClass(ClassName); + if (!Class) + PrintFatalError("The class '" + ClassName + "' is not defined\n"); + ClassRecs.push_back(Class); + } + + // Now scan all the concrete records and build the vector of records + // that inherit from all the classes. + for (const auto &OneDef : getDefs()) { + AddDef = true; + for (const auto Class : ClassRecs) + if (!OneDef.second->isSubClassOf(Class)) { + AddDef = false; + break; + } + if (AddDef) + Defs.push_back(OneDef.second.get()); + } return Defs; } +/// Get all the concrete records that inherit from the one specified +/// class. The class must be defined. +std::vector +RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const { + std::vector ClassVec; + ClassVec.push_back(ClassName.str()); + + return getAllDerivedDefinitions(ClassVec); +} + Init *MapResolver::resolve(Init *VarName) { auto It = Map.find(VarName); if (It == Map.end()) Index: llvm/utils/TableGen/PseudoLoweringEmitter.cpp =================================================================== --- llvm/utils/TableGen/PseudoLoweringEmitter.cpp +++ llvm/utils/TableGen/PseudoLoweringEmitter.cpp @@ -293,17 +293,8 @@ } void PseudoLoweringEmitter::run(raw_ostream &o) { - Record *ExpansionClass = Records.getClass("PseudoInstExpansion"); - Record *InstructionClass = Records.getClass("Instruction"); - assert(ExpansionClass && "PseudoInstExpansion class definition missing!"); - assert(InstructionClass && "Instruction class definition missing!"); - - std::vector Insts; - for (const auto &D : Records.getDefs()) { - if (D.second->isSubClassOf(ExpansionClass) && - D.second->isSubClassOf(InstructionClass)) - Insts.push_back(D.second.get()); - } + std::vector Classes = {"PseudoInstExpansion", "Instruction"}; + std::vector Insts = Records.getAllDerivedDefinitions(Classes); // Process the pseudo expansion definitions, validating them as we do so. for (unsigned i = 0, e = Insts.size(); i != e; ++i) Index: llvm/utils/TableGen/RISCVCompressInstEmitter.cpp =================================================================== --- llvm/utils/TableGen/RISCVCompressInstEmitter.cpp +++ llvm/utils/TableGen/RISCVCompressInstEmitter.cpp @@ -884,13 +884,7 @@ } void RISCVCompressInstEmitter::run(raw_ostream &o) { - Record *CompressClass = Records.getClass("CompressPat"); - assert(CompressClass && "Compress class definition missing!"); - std::vector Insts; - for (const auto &D : Records.getDefs()) { - if (D.second->isSubClassOf(CompressClass)) - Insts.push_back(D.second.get()); - } + std::vector Insts = Records.getAllDerivedDefinitions("CompressPat"); // Process the CompressPat definitions, validating them as we do so. for (unsigned i = 0, e = Insts.size(); i != e; ++i)