[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.


16e2e7f591/lld/include/lld/Common/BPSectionOrdererBase.inc (L240-L245)


16e2e7f591/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.

16e2e7f591/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.
This commit is contained in:
Ellis Hoag 2026-02-06 09:49:37 -08:00 committed by GitHub
parent 544caa627b
commit 9f4e8bca03
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -161,7 +161,7 @@ auto BPOrderer<D>::computeOrder(
sectionToIdx.try_emplace(isec, i);
BPFunctionNode::UtilityNodeT maxUN = 0;
DenseMap<unsigned, UtilityNodes> startupSectionIdxUNs;
MapVector<unsigned, UtilityNodes> startupSectionIdxUNs;
// Used to define the initial order for startup functions.
DenseMap<unsigned, size_t> sectionIdxToTimestamp;
std::unique_ptr<InstrProfReader> reader;
@ -177,7 +177,7 @@ auto BPOrderer<D>::computeOrder(
}
auto &traces = reader->getTemporalProfTraces();
DenseMap<unsigned, BPFunctionNode::UtilityNodeT> sectionIdxToFirstUN;
MapVector<unsigned, BPFunctionNode::UtilityNodeT> sectionIdxToFirstUN;
for (size_t traceIdx = 0; traceIdx < traces.size(); traceIdx++) {
uint64_t currentSize = 0, cutoffSize = 1;
size_t cutoffTimestamp = 1;