From 9f4e8bca0394972bed475bf3046a55744a5794a5 Mon Sep 17 00:00:00 2001 From: Ellis Hoag Date: Fri, 6 Feb 2026 09:49:37 -0800 Subject: [PATCH] [lld][BP] Fix nondeterministic function order by using MapVector (#179841) There are two places where the nondeterministic iteration order of `DenseMap` (the original type of `startupSectionIdxUNs`) causes the output function order to be nondeterministic. https://github.com/llvm/llvm-project/blob/16e2e7f59134e63810228c9a0dc990bfd96f9a1f/lld/include/lld/Common/BPSectionOrdererBase.inc#L240-L245 https://github.com/llvm/llvm-project/blob/16e2e7f59134e63810228c9a0dc990bfd96f9a1f/lld/include/lld/Common/BPSectionOrdererBase.inc#L267-L268 The fix is to use `MapVector` whose iteration order is guaranteed to be deterministic. To test, I built a large binary several times and observed this value no longer changes. https://github.com/llvm/llvm-project/blob/16e2e7f59134e63810228c9a0dc990bfd96f9a1f/lld/include/lld/Common/BPSectionOrdererBase.inc#L410-L411 It seems that this regresses linktime by a few seconds, but I believe the tradeoff is worthwhile. --- lld/include/lld/Common/BPSectionOrdererBase.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lld/include/lld/Common/BPSectionOrdererBase.inc b/lld/include/lld/Common/BPSectionOrdererBase.inc index 43de0f722a30..7d13cd25c0e7 100644 --- a/lld/include/lld/Common/BPSectionOrdererBase.inc +++ b/lld/include/lld/Common/BPSectionOrdererBase.inc @@ -161,7 +161,7 @@ auto BPOrderer::computeOrder( sectionToIdx.try_emplace(isec, i); BPFunctionNode::UtilityNodeT maxUN = 0; - DenseMap startupSectionIdxUNs; + MapVector startupSectionIdxUNs; // Used to define the initial order for startup functions. DenseMap sectionIdxToTimestamp; std::unique_ptr reader; @@ -177,7 +177,7 @@ auto BPOrderer::computeOrder( } auto &traces = reader->getTemporalProfTraces(); - DenseMap sectionIdxToFirstUN; + MapVector sectionIdxToFirstUN; for (size_t traceIdx = 0; traceIdx < traces.size(); traceIdx++) { uint64_t currentSize = 0, cutoffSize = 1; size_t cutoffTimestamp = 1;