[llvm] r339208 - [tablegen] Improve performance of -gen-register-info by replacing barely-necessary std::map with a sorted vector
Daniel Sanders via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 7 17:19:59 PDT 2018
Author: dsanders
Date: Tue Aug 7 17:19:59 2018
New Revision: 339208
URL: http://llvm.org/viewvc/llvm-project?rev=339208&view=rev
Log:
[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
Modified:
llvm/trunk/include/llvm/ADT/STLExtras.h
llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
Modified: llvm/trunk/include/llvm/ADT/STLExtras.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=339208&r1=339207&r2=339208&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/STLExtras.h (original)
+++ llvm/trunk/include/llvm/ADT/STLExtras.h Tue Aug 7 17:19:59 2018
@@ -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.
Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=339208&r1=339207&r2=339208&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Tue Aug 7 17:19:59 2018
@@ -340,11 +340,38 @@ EmitRegUnitPressure(raw_ostream &OS, con
<< "}\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::EmitRegMapping
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::EmitRegMapping
// 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::EmitRegMapping
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::EmitRegMapping
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.
More information about the llvm-commits
mailing list