[lld] [LLD][ELF] Fix performance regression when using linker scripts (PR #194668)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 28 09:24:18 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld-elf

Author: Andrew Ng (nga888)

<details>
<summary>Changes</summary>

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.

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


1 Files Affected:

- (modified) lld/ELF/LinkerScript.cpp (+7-6) 


``````````diff
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.

``````````

</details>


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


More information about the llvm-commits mailing list