summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/ADT/STLExtras.h13
-rw-r--r--llvm/utils/TableGen/RegisterInfoEmitter.cpp62
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.
OpenPOWER on IntegriCloud