Index: llvm/trunk/include/llvm/ADT/STLExtras.h =================================================================== --- llvm/trunk/include/llvm/ADT/STLExtras.h +++ llvm/trunk/include/llvm/ADT/STLExtras.h @@ -824,6 +824,19 @@ } }; +/// \brief Function object to apply a binary function to the first component of +/// a std::pair. +template +struct on_first { + FuncTy func; + + template + 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. Index: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp =================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp @@ -340,11 +340,38 @@ << "}\n\n"; } +using DwarfRegNumsMapPair = std::pair>; +using DwarfRegNumsVecTy = std::vector; + +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()); + // 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 &Regs, bool isCtor) { // Collect all information about dwarf register numbers - typedef std::map, LessRecordRegister> DwarfRegNumsMapTy; - DwarfRegNumsMapTy DwarfRegNums; + DwarfRegNumsVecTy DwarfRegNums; // First, just pull all provided information to the map unsigned maxLength = 0; @@ -352,18 +379,17 @@ Record *Reg = RE.TheDef; std::vector 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 @@ // Store the mapping sorted by the LLVM reg num so lookup can be done // with a binary search. std::map 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 @@ DefInit *DI = cast(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 @@ 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.