[lld] [lld] Report temporal BP profile resolution (PR #212127)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 26 08:33:06 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld-macho

Author: Karim Alweheshy (karim-alweheshy)

<details>
<summary>Changes</summary>

### Summary

Report how many temporal profile references and unique rooted function names resolve to live input sections when `--verbose-bp-section-orderer` is enabled.

A temporal process profile can contain functions from multiple Mach-O images. Each final lld link correctly ignores names outside that image, but the existing verbose output reports only the selected section count and page-area proxy. That makes a stale profile, a naming mismatch, and expected cross-image misses indistinguishable. The new line provides the per-link consumption signal directly from the same symbol map used by Balanced Partitioning.

The counters and unique-name sets are populated only in verbose mode, so ordinary links incur no additional profile-processing work.

### Testing

Updated `lld/test/MachO/bp-section-orderer.s` with duplicate, resolved, and missing temporal names. The reduced arm64 link reports 6/7 resolved references and 5/6 resolved unique rooted names, both with and without `--icf=all`.

The Bazel-built `ld64.lld` also compiles successfully on macOS arm64.

---
Full diff: https://github.com/llvm/llvm-project/pull/212127.diff


2 Files Affected:

- (modified) lld/include/lld/Common/BPSectionOrdererBase.inc (+19) 
- (modified) lld/test/MachO/bp-section-orderer.s (+10-1) 


``````````diff
diff --git a/lld/include/lld/Common/BPSectionOrdererBase.inc b/lld/include/lld/Common/BPSectionOrdererBase.inc
index 05a5c2446f68c..b2e87d6c240fc 100644
--- a/lld/include/lld/Common/BPSectionOrdererBase.inc
+++ b/lld/include/lld/Common/BPSectionOrdererBase.inc
@@ -24,6 +24,7 @@
 #include "lld/Common/Utils.h"
 #include "llvm/ADT/CachedHashString.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallSet.h"
@@ -173,6 +174,9 @@ auto BPOrderer<D>::computeOrder(
   MapVector<unsigned, UtilityNodes> startupSectionIdxUNs;
   // Used to define the initial order for startup functions.
   DenseMap<unsigned, size_t> sectionIdxToTimestamp;
+  uint64_t numProfiledFunctionRefs = 0, numResolvedProfiledFunctionRefs = 0;
+  DenseSet<CachedHashStringRef> uniqueProfiledFunctions;
+  DenseSet<CachedHashStringRef> uniqueResolvedProfiledFunctions;
   std::unique_ptr<InstrProfReader> reader;
   if (!profilePath.empty()) {
     auto fs = vfs::getRealFileSystem();
@@ -198,11 +202,20 @@ auto BPOrderer<D>::computeOrder(
         auto [_, parsedFuncName] = getParsedIRPGOName(
             reader->getSymtab().getFuncOrVarName(trace[timestamp]));
         parsedFuncName = lld::utils::getRootSymbol(parsedFuncName);
+        if (verbose) {
+          ++numProfiledFunctionRefs;
+          uniqueProfiledFunctions.insert(CachedHashStringRef(parsedFuncName));
+        }
 
         auto sectionIdxsIt =
             rootSymbolToSectionIdxs.find(CachedHashStringRef(parsedFuncName));
         if (sectionIdxsIt == rootSymbolToSectionIdxs.end())
           continue;
+        if (verbose) {
+          ++numResolvedProfiledFunctionRefs;
+          uniqueResolvedProfiledFunctions.insert(
+              CachedHashStringRef(parsedFuncName));
+        }
         auto &sectionIdxs = sectionIdxsIt->second;
         // If the same symbol is found in multiple sections, they might be
         // identical, so we arbitrarily use the size from the first section.
@@ -404,6 +417,12 @@ auto BPOrderer<D>::computeOrder(
            << totalOrderedSize << " bytes) using balanced partitioning:\n";
     dbgs() << "  Functions for startup: " << numStartupSections << " ("
            << startupSize << " bytes)\n";
+    if (!profilePath.empty())
+      dbgs() << "  Temporal profile function references: "
+             << numResolvedProfiledFunctionRefs << " / "
+             << numProfiledFunctionRefs << " resolved ("
+             << uniqueResolvedProfiledFunctions.size() << " / "
+             << uniqueProfiledFunctions.size() << " unique)\n";
     dbgs() << "  Sections for compression: " << numCompressionSections << " ("
            << compressionSize << " bytes)\n";
     dbgs() << "  Compression groups: " << groupsForCompression.size() << "\n";
diff --git a/lld/test/MachO/bp-section-orderer.s b/lld/test/MachO/bp-section-orderer.s
index d7de90d6cd7b3..b8c2ac6865b5b 100644
--- a/lld/test/MachO/bp-section-orderer.s
+++ b/lld/test/MachO/bp-section-orderer.s
@@ -10,6 +10,7 @@
 # RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile %t/a.profdata --bp-startup-sort=function --verbose-bp-section-orderer 2>&1 | FileCheck %s --check-prefix=STARTUP
 # RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile=%t/a.profdata --bp-startup-sort=function --verbose-bp-section-orderer --icf=all --bp-compression-sort=none 2>&1 | FileCheck %s --check-prefix=STARTUP-ICF
 # STARTUP: Ordered 5 sections ([[#]] bytes) using balanced partitioning
+# STARTUP: Temporal profile function references: 6 / 7 resolved (5 / 6 unique)
 # STARTUP-ICF: Ordered 4 sections ([[#]] bytes) using balanced partitioning
 
 # Check that orderfiles take precedence over BP
@@ -126,7 +127,7 @@ bss0:
 1
 # Weight
 1
-A, B, C.__uniq.555555555555555555555555555555555555555.llvm.6666666666666666666, merged1, merged2
+A, B, A, C.__uniq.555555555555555555555555555555555555555.llvm.6666666666666666666, merged1, merged2, Missing
 
 A
 # Func Hash:
@@ -176,6 +177,14 @@ merged2
 # Counter Values:
 1
 
+Missing
+# Func Hash:
+7777
+# Num Counters:
+1
+# Counter Values:
+1
+
 #--- a.orderfile
 A
 F

``````````

</details>


https://github.com/llvm/llvm-project/pull/212127


More information about the llvm-commits mailing list