diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -1703,6 +1703,7 @@ std::string InputFilename; RecordMap Classes, Defs; + mutable StringMap> ClassRecordsMap; FoldingSet RecordTypePool; std::map> ExtraGlobals; unsigned AnonCounter = 0; @@ -1801,17 +1802,14 @@ //===--------------------------------------------------------------------===// // High-level helper methods, useful for tablegen backends. - /// 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)); - } + /// Get all the concrete records that inherit from all the specified + /// classes. The classes must be defined. + std::vector getAllDerivedDefinitions( + ArrayRef ClassNames) const; void dump() const; }; diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -2595,8 +2595,20 @@ } } +// We cache the record vectors for single classes. Many backends request +// the same vectors multiple times. std::vector RecordKeeper::getAllDerivedDefinitions( - const ArrayRef ClassNames) const { + StringRef ClassName) const { + + auto Pair = ClassRecordsMap.try_emplace(ClassName); + if (Pair.second) + Pair.first->second = getAllDerivedDefinitions(makeArrayRef(ClassName)); + + return Pair.first->second; +} + +std::vector RecordKeeper::getAllDerivedDefinitions( + ArrayRef ClassNames) const { SmallVector ClassRecs; std::vector Defs; diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp --- a/llvm/utils/TableGen/InstrInfoEmitter.cpp +++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp @@ -532,6 +532,7 @@ unsigned ListNumber = 0; // Emit all of the instruction's implicit uses and defs. + Records.startTimer("Emit uses/defs"); for (const CodeGenInstruction *II : Target.getInstructionsByEnumValue()) { Record *Inst = II->TheDef; std::vector Uses = Inst->getValueAsListOfDefs("Uses"); @@ -549,10 +550,12 @@ OperandInfoMapTy OperandInfoIDs; // Emit all of the operand info records. + Records.startTimer("Emit operand info"); EmitOperandInfo(OS, OperandInfoIDs); // Emit all of the MCInstrDesc records in their ENUM ordering. // + Records.startTimer("Emit InstrDesc records"); OS << "\nextern const MCInstrDesc " << TargetName << "Insts[] = {\n"; ArrayRef NumberedInstructions = Target.getInstructionsByEnumValue(); @@ -568,6 +571,7 @@ OS << "};\n\n"; // Emit the array of instruction names. + Records.startTimer("Emit instruction names"); InstrNames.layout(); InstrNames.emitStringLiteralDef(OS, Twine("extern const char ") + TargetName + "InstrNameData[]"); @@ -628,6 +632,7 @@ } // MCInstrInfo initialization routine. + Records.startTimer("Emit initialization routine"); OS << "static inline void Init" << TargetName << "MCInstrInfo(MCInstrInfo *II) {\n"; OS << " II->InitMCInstrInfo(" << TargetName << "Insts, " << TargetName @@ -706,10 +711,13 @@ OS << "#endif // GET_INSTRINFO_CTOR_DTOR\n\n"; + Records.startTimer("Emit operand name mappings"); emitOperandNameMappings(OS, Target, NumberedInstructions); + Records.startTimer("Emit operand type mappings"); emitOperandTypeMappings(OS, Target, NumberedInstructions); + Records.startTimer("Emit helper methods"); emitMCIIHelperMethods(OS, TargetName); } @@ -862,7 +870,9 @@ namespace llvm { void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) { + RK.startTimer("Analyze DAG patterns"); InstrInfoEmitter(RK).run(OS); + RK.startTimer("Emit map table"); EmitMapTable(RK, OS); }