[lld] [LLD][ELF] Fix performance regression when using linker scripts (PR #194668)
Andrew Ng via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 28 10:46:04 PDT 2026
https://github.com/nga888 updated https://github.com/llvm/llvm-project/pull/194668
>From 928b2f9870918a703b9c076d9a1283db17798b69 Mon Sep 17 00:00:00 2001
From: Andrew Ng <andrew.ng at sony.com>
Date: Tue, 28 Apr 2026 16:33:21 +0100
Subject: [PATCH 1/2] [LLD][ELF] Fix performance regression when using linker
scripts
The addition of the support for `--enable-non-contiguous-regions` moved
an "early out" condition in `LinkerScript::computeInputSections()`. This
resulted in other relatively expensive checks to be performed
unnecessarily in the default situation where
`--enable-non-contiguous-regions` is disabled.
This fix restores the "early out" condition and shows an ~14%
improvement for the Linux kernel benchmark link and has been seen to
improve performance by up to ~30% for a large UE5 link.
---
lld/ELF/LinkerScript.cpp | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 5cd7c33bc55db..cca2d01b7f35e 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -558,14 +558,17 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
ctx.arg.sortSection, SortSectionPolicy::None);
};
+ bool contiguousRegions = !ctx.arg.enableNonContiguousRegions;
for (const SectionPattern &pat : cmd->sectionPatterns) {
size_t sizeBeforeCurrPat = ret.size();
for (size_t i = 0, e = sections.size(); i != e; ++i) {
- // Skip if the section is dead or has been matched by a previous pattern
- // in this input section description.
+ // Skip if the section is dead or has been matched by a previous input
+ // section description with contiguous regions or has been matched by a
+ // previous pattern in this input section description.
InputSectionBase *sec = sections[i];
- if (!sec->isLive() || seen.contains(i))
+ if (!sec->isLive() || (contiguousRegions && sec->parent) ||
+ seen.contains(i))
continue;
// For --emit-relocs we have to ignore entries like
@@ -586,9 +589,7 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
continue;
if (sec->parent) {
- // Skip if not allowing multiple matches.
- if (!ctx.arg.enableNonContiguousRegions)
- continue;
+ assert(ctx.arg.enableNonContiguousRegions);
// Disallow spilling into /DISCARD/; special handling would be needed
// for this in address assignment, and the semantics are nebulous.
>From e49de8e24ac520369263e60996b2d6761acdeef3 Mon Sep 17 00:00:00 2001
From: Andrew Ng <andrew.ng at sony.com>
Date: Tue, 28 Apr 2026 18:44:37 +0100
Subject: [PATCH 2/2] Address review comments
* Remove manual hoist
* Update comment
---
lld/ELF/LinkerScript.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index cca2d01b7f35e..370e58eb73a49 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -558,16 +558,16 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
ctx.arg.sortSection, SortSectionPolicy::None);
};
- bool contiguousRegions = !ctx.arg.enableNonContiguousRegions;
for (const SectionPattern &pat : cmd->sectionPatterns) {
size_t sizeBeforeCurrPat = ret.size();
for (size_t i = 0, e = sections.size(); i != e; ++i) {
- // Skip if the section is dead or has been matched by a previous input
- // section description with contiguous regions or has been matched by a
- // previous pattern in this input section description.
+ // Skip if the section is dead, has been matched by a previous input
+ // section description with non-contiguous regions disabled, or has been
+ // matched by a previous pattern in this input section description.
InputSectionBase *sec = sections[i];
- if (!sec->isLive() || (contiguousRegions && sec->parent) ||
+ if (!sec->isLive() ||
+ (!ctx.arg.enableNonContiguousRegions && sec->parent) ||
seen.contains(i))
continue;
More information about the llvm-commits
mailing list