diff --git a/lld/Common/BPSectionOrdererBase.cpp b/lld/Common/BPSectionOrdererBase.cpp index 75be4f6aa9bc0..7d26a5fb84483 100644 --- a/lld/Common/BPSectionOrdererBase.cpp +++ b/lld/Common/BPSectionOrdererBase.cpp @@ -96,11 +96,10 @@ static SmallVector> getUnsForCompression( return sectionUns; } -llvm::DenseMap +llvm::DenseMap BPSectionBase::reorderSectionsByBalancedPartitioning( - size_t &highestAvailablePriority, llvm::StringRef profilePath, - bool forFunctionCompression, bool forDataCompression, - bool compressionSortStartupFunctions, bool verbose, + llvm::StringRef profilePath, bool forFunctionCompression, + bool forDataCompression, bool compressionSortStartupFunctions, bool verbose, SmallVector> &inputSections) { TimeTraceScope timeScope("Setup Balanced Partitioning"); SmallVector sections; @@ -364,8 +363,9 @@ BPSectionBase::reorderSectionsByBalancedPartitioning( } } - DenseMap sectionPriorities; + DenseMap sectionPriorities; + int prio = -orderedSections.size(); for (const auto *isec : orderedSections) - sectionPriorities[isec] = --highestAvailablePriority; + sectionPriorities[isec] = prio++; return sectionPriorities; } diff --git a/lld/MachO/BPSectionOrderer.cpp b/lld/MachO/BPSectionOrderer.cpp index 0ffbf16007fda..18c8aad58344f 100644 --- a/lld/MachO/BPSectionOrderer.cpp +++ b/lld/MachO/BPSectionOrderer.cpp @@ -15,9 +15,8 @@ using namespace llvm; using namespace lld::macho; -DenseMap lld::macho::runBalancedPartitioning( - size_t &highestAvailablePriority, StringRef profilePath, - bool forFunctionCompression, bool forDataCompression, +DenseMap lld::macho::runBalancedPartitioning( + StringRef profilePath, bool forFunctionCompression, bool forDataCompression, bool compressionSortStartupFunctions, bool verbose) { SmallVector> sections; @@ -34,10 +33,10 @@ DenseMap lld::macho::runBalancedPartitioning( } auto reorderedSections = BPSectionBase::reorderSectionsByBalancedPartitioning( - highestAvailablePriority, profilePath, forFunctionCompression, - forDataCompression, compressionSortStartupFunctions, verbose, sections); + profilePath, forFunctionCompression, forDataCompression, + compressionSortStartupFunctions, verbose, sections); - DenseMap result; + DenseMap result; for (const auto &[sec, priority] : reorderedSections) { if (auto *machoSection = dyn_cast(sec)) { result.try_emplace( diff --git a/lld/MachO/BPSectionOrderer.h b/lld/MachO/BPSectionOrderer.h index 8ba911fcc546b..4facb652d4c87 100644 --- a/lld/MachO/BPSectionOrderer.h +++ b/lld/MachO/BPSectionOrderer.h @@ -145,9 +145,8 @@ class BPSectionMacho : public BPSectionBase { /// /// It is important that .subsections_via_symbols is used to ensure functions /// and data are in their own sections and thus can be reordered. -llvm::DenseMap -runBalancedPartitioning(size_t &highestAvailablePriority, - llvm::StringRef profilePath, +llvm::DenseMap +runBalancedPartitioning(llvm::StringRef profilePath, bool forFunctionCompression, bool forDataCompression, bool compressionSortStartupFunctions, bool verbose); diff --git a/lld/MachO/SectionPriorities.cpp b/lld/MachO/SectionPriorities.cpp index 0a15112c1250d..7a4a5d8465f64 100644 --- a/lld/MachO/SectionPriorities.cpp +++ b/lld/MachO/SectionPriorities.cpp @@ -38,9 +38,6 @@ using namespace lld::macho; PriorityBuilder macho::priorityBuilder; namespace { - -size_t highestAvailablePriority = std::numeric_limits::max(); - struct Edge { int from; uint64_t weight; @@ -67,7 +64,7 @@ class CallGraphSort { public: CallGraphSort(const MapVector &profile); - DenseMap run(); + DenseMap run(); private: std::vector clusters; @@ -157,7 +154,7 @@ static void mergeClusters(std::vector &cs, Cluster &into, int intoIdx, // Group InputSections into clusters using the Call-Chain Clustering heuristic // then sort the clusters by density. -DenseMap CallGraphSort::run() { +DenseMap CallGraphSort::run() { const uint64_t maxClusterSize = target->getPageSize(); // Cluster indices sorted by density. @@ -205,16 +202,14 @@ DenseMap CallGraphSort::run() { return clusters[a].getDensity() > clusters[b].getDensity(); }); - DenseMap orderMap; + DenseMap orderMap; // Sections will be sorted by decreasing order. Absent sections will have // priority 0 and be placed at the end of sections. - // NB: This is opposite from COFF/ELF to be compatible with the existing - // order-file code. - int curOrder = highestAvailablePriority; + int curOrder = -clusters.size(); for (int leader : sorted) { for (int i = leader;;) { - orderMap[sections[i]] = curOrder--; + orderMap[sections[i]] = curOrder++; i = clusters[i].next; if (i == leader) break; @@ -250,7 +245,7 @@ DenseMap CallGraphSort::run() { return orderMap; } -std::optional +std::optional macho::PriorityBuilder::getSymbolPriority(const Defined *sym) { if (sym->isAbsolute()) return std::nullopt; @@ -270,7 +265,7 @@ macho::PriorityBuilder::getSymbolPriority(const Defined *sym) { else filename = saver().save(path::filename(f->archiveName) + "(" + path::filename(f->getName()) + ")"); - return std::max(entry.objectFiles.lookup(filename), entry.anyObjectFile); + return std::min(entry.objectFiles.lookup(filename), entry.anyObjectFile); } void macho::PriorityBuilder::extractCallGraphProfile() { @@ -302,6 +297,7 @@ void macho::PriorityBuilder::parseOrderFile(StringRef path) { return; } + int prio = std::numeric_limits::min(); MemoryBufferRef mbref = *buffer; for (StringRef line : args::getLines(mbref)) { StringRef objectFile, symbol; @@ -339,25 +335,22 @@ void macho::PriorityBuilder::parseOrderFile(StringRef path) { if (!symbol.empty()) { SymbolPriorityEntry &entry = priorities[symbol]; if (!objectFile.empty()) - entry.objectFiles.insert( - std::make_pair(objectFile, highestAvailablePriority)); + entry.objectFiles.insert(std::make_pair(objectFile, prio)); else - entry.anyObjectFile = - std::max(entry.anyObjectFile, highestAvailablePriority); + entry.anyObjectFile = std::min(entry.anyObjectFile, prio); } - --highestAvailablePriority; + ++prio; } } -DenseMap +DenseMap macho::PriorityBuilder::buildInputSectionPriorities() { - DenseMap sectionPriorities; + DenseMap sectionPriorities; if (config->bpStartupFunctionSort || config->bpFunctionOrderForCompression || config->bpDataOrderForCompression) { TimeTraceScope timeScope("Balanced Partitioning Section Orderer"); sectionPriorities = runBalancedPartitioning( - highestAvailablePriority, config->bpStartupFunctionSort ? config->irpgoProfilePath : "", config->bpFunctionOrderForCompression, config->bpDataOrderForCompression, @@ -378,11 +371,11 @@ macho::PriorityBuilder::buildInputSectionPriorities() { return sectionPriorities; auto addSym = [&](const Defined *sym) { - std::optional symbolPriority = getSymbolPriority(sym); + std::optional symbolPriority = getSymbolPriority(sym); if (!symbolPriority) return; - size_t &priority = sectionPriorities[sym->isec()]; - priority = std::max(priority, *symbolPriority); + int &priority = sectionPriorities[sym->isec()]; + priority = std::min(priority, *symbolPriority); }; // TODO: Make sure this handles weak symbols correctly. diff --git a/lld/MachO/SectionPriorities.h b/lld/MachO/SectionPriorities.h index 83cfe354e7263..44fb101990c51 100644 --- a/lld/MachO/SectionPriorities.h +++ b/lld/MachO/SectionPriorities.h @@ -53,24 +53,20 @@ class PriorityBuilder { // // Each section gets assigned the priority of the highest-priority symbol it // contains. - llvm::DenseMap buildInputSectionPriorities(); + llvm::DenseMap buildInputSectionPriorities(); private: - // The symbol with the highest priority should be ordered first in the output - // section (modulo input section contiguity constraints). Using priority - // (highest first) instead of order (lowest first) has the convenient property - // that the default-constructed zero priority -- for symbols/sections without - // a user-defined order -- naturally ends up putting them at the end of the - // output. + // The symbol with the smallest priority should be ordered first in the output + // section (modulo input section contiguity constraints). struct SymbolPriorityEntry { // The priority given to a matching symbol, regardless of which object file // it originated from. - size_t anyObjectFile = 0; + int anyObjectFile = 0; // The priority given to a matching symbol from a particular object file. - llvm::DenseMap objectFiles; + llvm::DenseMap objectFiles; }; - std::optional getSymbolPriority(const Defined *sym); + std::optional getSymbolPriority(const Defined *sym); llvm::DenseMap priorities; llvm::MapVector callGraphProfile; }; diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp index 6a1dd0ae7ecaf..bec980e18e18b 100644 --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -975,7 +975,7 @@ static void sortSegmentsAndSections() { TimeTraceScope timeScope("Sort segments and sections"); sortOutputSegments(); - DenseMap isecPriorities = + DenseMap isecPriorities = priorityBuilder.buildInputSectionPriorities(); uint32_t sectionIndex = 0; @@ -1008,7 +1008,7 @@ static void sortSegmentsAndSections() { if (auto *merged = dyn_cast(osec)) { llvm::stable_sort( merged->inputs, [&](InputSection *a, InputSection *b) { - return isecPriorities.lookup(a) > isecPriorities.lookup(b); + return isecPriorities.lookup(a) < isecPriorities.lookup(b); }); } } diff --git a/lld/include/lld/Common/BPSectionOrdererBase.h b/lld/include/lld/Common/BPSectionOrdererBase.h index e2cb41f69cc68..bd5bd638ccd2a 100644 --- a/lld/include/lld/Common/BPSectionOrdererBase.h +++ b/lld/include/lld/Common/BPSectionOrdererBase.h @@ -66,11 +66,11 @@ class BPSectionBase { /// Reorders sections using balanced partitioning algorithm based on profile /// data. - static llvm::DenseMap + static llvm::DenseMap reorderSectionsByBalancedPartitioning( - size_t &highestAvailablePriority, llvm::StringRef profilePath, - bool forFunctionCompression, bool forDataCompression, - bool compressionSortStartupFunctions, bool verbose, + llvm::StringRef profilePath, bool forFunctionCompression, + bool forDataCompression, bool compressionSortStartupFunctions, + bool verbose, llvm::SmallVector> &inputSections); };