Index: include/llvm/ADT/STLExtras.h =================================================================== --- include/llvm/ADT/STLExtras.h +++ include/llvm/ADT/STLExtras.h @@ -740,6 +740,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: utils/TableGen/RegisterInfoEmitter.cpp =================================================================== --- utils/TableGen/RegisterInfoEmitter.cpp +++ utils/TableGen/RegisterInfoEmitter.cpp @@ -343,8 +343,9 @@ 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; + typedef std::pair> DwarfRegNumsMapPair; + typedef std::vector DwarfRegNumsVecTy; + DwarfRegNumsVecTy DwarfRegNums; // First, just pull all provided information to the map unsigned maxLength = 0; @@ -352,18 +353,37 @@ 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, RegNums); } + // Sort and unique to get a map-like vector. We want the last assignment to + // match previous behaviour. + { + std::reverse(DwarfRegNums.begin(), DwarfRegNums.end()); + 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; + if (LastSeenReg && !LessRecordRegister()(Reg, LastSeenReg) && + !LessRecordRegister()(LastSeenReg, Reg)) + PrintWarning(Reg->getLoc(), Twine("DWARF numbers for register ") + + getQualifiedName(Reg) + + "specified multiple times"); + LastSeenReg = Reg; + } + auto Last = std::unique(DwarfRegNums.begin(), DwarfRegNums.end(), + on_first()); + DwarfRegNums.erase(Last, DwarfRegNums.end()); + } 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 +404,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,8 +443,17 @@ DefInit *DI = cast(V->getValue()); Record *Alias = DI->getDef(); - DwarfRegNums[Reg] = DwarfRegNums[Alias]; + const auto &Tmp = + std::lower_bound(DwarfRegNums.begin(), DwarfRegNums.end(), Alias, + [](const DwarfRegNumsMapPair &A, const Record *B) { + return LessRecordRegister()(A.first, B); + }); + assert(Tmp != DwarfRegNums.end() && Tmp->first == Alias && + "Expected Alias to be present in map"); + DwarfRegNums.emplace_back(Reg, Tmp->second); } + std::sort(DwarfRegNums.begin(), DwarfRegNums.end(), + on_first()); // Emit information about the dwarf register numbers. for (unsigned j = 0; j < 2; ++j) { @@ -436,7 +465,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.