Index: llvm/docs/TableGen/BackGuide.rst =================================================================== --- llvm/docs/TableGen/BackGuide.rst +++ llvm/docs/TableGen/BackGuide.rst @@ -571,7 +571,7 @@ * ``getAllDerivedDefinitionsTwo(``\ *classname1*\ ``,`` *classname2*\ ``)`` returns a vector of ``Record`` references for the concrete records that derive from - *both* of the given classes. [function to come] + *both* 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 @@ -1788,6 +1788,11 @@ /// class. The class must be defined. std::vector getAllDerivedDefinitions(StringRef ClassName) const; + /// Get all the concrete records that inherit from both of the specified + /// classes. The classes must be defined. + std::vector getAllDerivedDefinitionsTwo(StringRef ClassName1, + StringRef ClassName2) const; + void dump() const; }; Index: llvm/lib/TableGen/Record.cpp =================================================================== --- llvm/lib/TableGen/Record.cpp +++ llvm/lib/TableGen/Record.cpp @@ -2474,7 +2474,7 @@ RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const { Record *Class = getClass(ClassName); if (!Class) - PrintFatalError("ERROR: Couldn't find the `" + ClassName + "' class!\n"); + PrintFatalError("The class '" + ClassName + "' is not defined\n"); std::vector Defs; for (const auto &D : getDefs()) @@ -2484,6 +2484,24 @@ return Defs; } +std::vector +RecordKeeper::getAllDerivedDefinitionsTwo(StringRef ClassName1, + StringRef ClassName2) const { + Record *Class1 = getClass(ClassName1); + Record *Class2 = getClass(ClassName2); + if (!Class1) + PrintFatalError("The class '" + ClassName1 + "' is not defined\n"); + if (!Class2) + PrintFatalError("The class '" + ClassName2 + "' is not defined\n"); + + std::vector Defs; + for (const auto &D : getDefs()) + if (D.second->isSubClassOf(Class1) && D.second->isSubClassOf(Class2)) + Defs.push_back(D.second.get()); + + return Defs; +} + 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,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()); - } + + std::vector Insts = + Records.getAllDerivedDefinitionsTwo("PseudoInstExpansion", "Instruction"); // 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,8 @@ } 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)