Index: llvm/docs/TableGen/BackGuide.rst =================================================================== --- llvm/docs/TableGen/BackGuide.rst +++ llvm/docs/TableGen/BackGuide.rst @@ -52,14 +52,7 @@ There are two maps in the recordkeeper, one for classes and one for records (the latter often referred to as *defs*). Each map maps the class or record name to an instance of the ``Record`` class (see `Record`_), which contains -all the information about that class or record. The ``RecordKeeper`` class -defines a type that must be used to declare these maps if they are requested -directly. - -.. code-block:: text - - using RecordMap = std::map, - std::less<>>; +all the information about that class or record. In addition to the two maps, the ``RecordKeeper`` instance contains: @@ -562,16 +555,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(``\ *classvnames*\ ``)`` 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 +694,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,9 +1784,17 @@ //===--------------------------------------------------------------------===// // 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 ArrayRef ClassNames) const; + + /// Get all the concrete records that inherit from the one specified /// class. The class must be defined. - std::vector getAllDerivedDefinitions(StringRef ClassName) const; + std::vector getAllDerivedDefinitions(StringRef ClassName) const { + + return getAllDerivedDefinitions(makeArrayRef(ClassName)); + } void dump() const; }; Index: llvm/lib/TableGen/Record.cpp =================================================================== --- llvm/lib/TableGen/Record.cpp +++ llvm/lib/TableGen/Record.cpp @@ -2470,16 +2470,25 @@ return StringInit::get("anonymous_" + utostr(AnonCounter++)); } -std::vector -RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const { - Record *Class = getClass(ClassName); - if (!Class) - PrintFatalError("ERROR: Couldn't find the `" + ClassName + "' class!\n"); +std::vector RecordKeeper::getAllDerivedDefinitions( + const ArrayRef ClassNames) const { + SmallVector ClassRecs; + std::vector Defs; - std::vector Defs; - for (const auto &D : getDefs()) - if (D.second->isSubClassOf(Class)) - Defs.push_back(D.second.get()); + assert(ClassNames.size() > 0 && "At least one class must be passed."); + for (const auto &ClassName : ClassNames) { + Record *Class = getClass(ClassName); + if (!Class) + PrintFatalError("The class '" + ClassName + "' is not defined\n"); + ClassRecs.push_back(Class); + } + + for (const auto &OneDef : getDefs()) { + if (all_of(ClassRecs, [&OneDef](const Record *Class) { + return OneDef.second->isSubClassOf(Class); + })) + Defs.push_back(OneDef.second.get()); + } return Defs; } Index: llvm/utils/TableGen/PseudoLoweringEmitter.cpp =================================================================== --- llvm/utils/TableGen/PseudoLoweringEmitter.cpp +++ llvm/utils/TableGen/PseudoLoweringEmitter.cpp @@ -293,17 +293,9 @@ } 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()); - } + StringRef Classes[] = {"PseudoInstExpansion", "Instruction"}; + std::vector Insts = + Records.getAllDerivedDefinitions(makeArrayRef(Classes)); // Process the pseudo expansion definitions, validating them as we do so. for (unsigned i = 0, e = Insts.size(); i != e; ++i)