diff options
| author | Daniel Sanders <daniel_l_sanders@apple.com> | 2018-08-08 00:19:59 +0000 |
|---|---|---|
| committer | Daniel Sanders <daniel_l_sanders@apple.com> | 2018-08-08 00:19:59 +0000 |
| commit | 944fbb1475219e637f9a6031841db6d7ecdc9d18 (patch) | |
| tree | 98be8778fa833fd2cd4878a4a6bc5994af2cab89 | |
| parent | 749e8285a5dd8a59db309bbef8239f709ab5b43e (diff) | |
| download | bcm5719-llvm-944fbb1475219e637f9a6031841db6d7ecdc9d18.tar.gz bcm5719-llvm-944fbb1475219e637f9a6031841db6d7ecdc9d18.zip | |
[tablegen] Improve performance of -gen-register-info by replacing barely-necessary std::map with a sorted vector
Summary:
This particular map is hardly ever queried and has a phased usage pattern (insert,
iterate, query, insert, iterate) so it's a good candidate for a sorted vector and
std::lower_bound.
This significantly reduces the run time of runTargetDesc() in some circumstances.
One llvm-tblgen invocation in my build improves the time spent in runTargetDesc()
from 9.86s down to 0.80s (~92%) without changing the output. The same invocation
also has 2GB less allocation churn.
Reviewers: bogner, rtereshin, aditya_nandakumar, volkan
Reviewed By: rtereshin
Subscribers: mgrang, dexonsmith, llvm-commits
Differential Revision: https://reviews.llvm.org/D50272
llvm-svn: 339208
| -rw-r--r-- | llvm/include/llvm/ADT/STLExtras.h | 13 | ||||
| -rw-r--r-- | llvm/utils/TableGen/RegisterInfoEmitter.cpp | 62 |
2 files changed, 64 insertions, 11 deletions
diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h index 7be9127f05d..03109a078ed 100644 --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -824,6 +824,19 @@ struct less_second { } }; +/// \brief Function object to apply a binary function to the first component of +/// a std::pair. +template<typename FuncTy> +struct on_first { + FuncTy func; + + template <typename T> + auto operator()(const T &lhs, const T &rhs) const + -> decltype(func(lhs.first, rhs.first)) { + return func(lhs.first, rhs.first); + } +}; + // A subset of N3658. More stuff can be added as-needed. /// Represents a compile-time sequence of integers. diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp index 49016cca799..532426c3fe9 100644 --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -340,11 +340,38 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, << "}\n\n"; } +using DwarfRegNumsMapPair = std::pair<Record*, std::vector<int64_t>>; +using DwarfRegNumsVecTy = std::vector<DwarfRegNumsMapPair>; + +void finalizeDwarfRegNumsKeys(DwarfRegNumsVecTy &DwarfRegNums) { + // Sort and unique to get a map-like vector. We want the last assignment to + // match previous behaviour. + std::stable_sort(DwarfRegNums.begin(), DwarfRegNums.end(), + on_first<LessRecordRegister>()); + // Warn about duplicate assignments. + const Record *LastSeenReg = nullptr; + for (const auto &X : DwarfRegNums) { + const auto &Reg = X.first; + // The only way LessRecordRegister can return equal is if they're the same + // string. Use simple equality instead. + if (LastSeenReg && Reg->getName() == LastSeenReg->getName()) + PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") + + getQualifiedName(Reg) + + "specified multiple times"); + LastSeenReg = Reg; + } + auto Last = std::unique( + DwarfRegNums.begin(), DwarfRegNums.end(), + [](const DwarfRegNumsMapPair &A, const DwarfRegNumsMapPair &B) { + return A.first->getName() == B.first->getName(); + }); + DwarfRegNums.erase(Last, DwarfRegNums.end()); +} + void RegisterInfoEmitter::EmitRegMappingTables( raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) { // Collect all information about dwarf register numbers - typedef std::map<Record*, std::vector<int64_t>, LessRecordRegister> DwarfRegNumsMapTy; - DwarfRegNumsMapTy DwarfRegNums; + DwarfRegNumsVecTy DwarfRegNums; // First, just pull all provided information to the map unsigned maxLength = 0; @@ -352,18 +379,17 @@ void RegisterInfoEmitter::EmitRegMappingTables( Record *Reg = RE.TheDef; std::vector<int64_t> RegNums = Reg->getValueAsListOfInts("DwarfNumbers"); maxLength = std::max((size_t)maxLength, RegNums.size()); - if (DwarfRegNums.count(Reg)) - PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") + - getQualifiedName(Reg) + "specified multiple times"); - DwarfRegNums[Reg] = RegNums; + DwarfRegNums.emplace_back(Reg, std::move(RegNums)); } + finalizeDwarfRegNumsKeys(DwarfRegNums); if (!maxLength) return; // Now we know maximal length of number list. Append -1's, where needed - for (DwarfRegNumsMapTy::iterator - I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) + for (DwarfRegNumsVecTy::iterator I = DwarfRegNums.begin(), + E = DwarfRegNums.end(); + I != E; ++I) for (unsigned i = I->second.size(), e = maxLength; i != e; ++i) I->second.push_back(-1); @@ -384,7 +410,7 @@ void RegisterInfoEmitter::EmitRegMappingTables( // Store the mapping sorted by the LLVM reg num so lookup can be done // with a binary search. std::map<uint64_t, Record*> Dwarf2LMap; - for (DwarfRegNumsMapTy::iterator + for (DwarfRegNumsVecTy::iterator I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { int DwarfRegNo = I->second[i]; if (DwarfRegNo < 0) @@ -423,7 +449,21 @@ void RegisterInfoEmitter::EmitRegMappingTables( DefInit *DI = cast<DefInit>(V->getValue()); Record *Alias = DI->getDef(); - DwarfRegNums[Reg] = DwarfRegNums[Alias]; + const auto &AliasIter = + std::lower_bound(DwarfRegNums.begin(), DwarfRegNums.end(), Alias, + [](const DwarfRegNumsMapPair &A, const Record *B) { + return LessRecordRegister()(A.first, B); + }); + assert(AliasIter != DwarfRegNums.end() && AliasIter->first == Alias && + "Expected Alias to be present in map"); + const auto &RegIter = + std::lower_bound(DwarfRegNums.begin(), DwarfRegNums.end(), Reg, + [](const DwarfRegNumsMapPair &A, const Record *B) { + return LessRecordRegister()(A.first, B); + }); + assert(RegIter != DwarfRegNums.end() && RegIter->first == Reg && + "Expected Reg to be present in map"); + RegIter->second = AliasIter->second; } // Emit information about the dwarf register numbers. @@ -436,7 +476,7 @@ void RegisterInfoEmitter::EmitRegMappingTables( OS << " = {\n"; // Store the mapping sorted by the Dwarf reg num so lookup can be done // with a binary search. - for (DwarfRegNumsMapTy::iterator + for (DwarfRegNumsVecTy::iterator I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { int RegNo = I->second[i]; if (RegNo == -1) // -1 is the default value, don't emit a mapping. |

