From dbdbf1e63d735eada7c9e4ff42ac0e56f56f5774 Mon Sep 17 00:00:00 2001 From: Andrew Ng 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. --- 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 5cd7c33bc55d..b9ed964b8c72 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 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 @@ -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.