[llvm-branch-commits] [lld] release/22.x: [LLD][ELF] Fix performance regression when using linker scripts (#194668) (PR #194915)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Apr 30 20:59:49 PDT 2026


https://github.com/dyung updated https://github.com/llvm/llvm-project/pull/194915

>From 19f65f31105c0efeb000dda091b5eed0716b2f09 Mon Sep 17 00:00:00 2001
From: Andrew Ng <andrew.ng at sony.com>
Date: Wed, 29 Apr 2026 11:29:43 +0100
Subject: [PATCH] [LLD][ELF] Fix performance regression when using linker
 scripts (#194668)

The addition of the support for `--enable-non-contiguous-regions` from
PR #90007 moved an "early out" condition in
`LinkerScript::computeInputSections()`. This could result in other
relatively expensive checks, i.e. `pat.sectionPat.match`,
`cmd->matchesFile`, `pat.excludesFile` and `flagsMatch`, 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.

(cherry picked from commit dbdbf1e63d735eada7c9e4ff42ac0e56f56f5774)
---
 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 218c9d3a86184..dd478846edc73 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -548,14 +548,17 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
           ctx.arg.sortSection, SortSectionPolicy::None);
     };
 
+    bool enableNonContiguousRegions = 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, 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() || seen.contains(i))
+        if (!sec->isLive() || (!enableNonContiguousRegions && sec->parent) ||
+            seen.contains(i))
           continue;
 
         // For --emit-relocs we have to ignore entries like
@@ -576,9 +579,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.



More information about the llvm-branch-commits mailing list