From d6942973ad81b04e47f88d57c9d3fc96fb949b75 Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Mon, 20 Oct 2025 14:17:17 -0400 Subject: [PATCH 1/6] [lld-macho]Define a macro to allow specifying the slop size at build time. We're seeing thunk size overrun in our large builds and it would be helpful to be able to increase the slop size. However, this should probably not be changed between different runs of LLD, hence making it a build option so that it's fixed per lld binary. --- lld/MachO/CMakeLists.txt | 5 +++++ lld/MachO/ConcatOutputSection.cpp | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lld/MachO/CMakeLists.txt b/lld/MachO/CMakeLists.txt index 3cd94ced75cc0..5ad12eb04f4c3 100644 --- a/lld/MachO/CMakeLists.txt +++ b/lld/MachO/CMakeLists.txt @@ -1,3 +1,8 @@ + +option(LLD_MACHO_SLOP_FACTOR + "Specify the slop factor. For very large build, the default of 256 might be too small, which can cause thunk-range overrun. Recommend increasing this value to 1024 or higher as needed.", 256) +add_definitions("-DLLD_MACHO_SLOP_FACTOR=${LLD_MACHO_SLOP_FACTOR}") + set(LLVM_TARGET_DEFINITIONS Options.td) tablegen(LLVM Options.inc -gen-opt-parser-defs) add_public_tablegen_target(MachOOptionsTableGen) diff --git a/lld/MachO/ConcatOutputSection.cpp b/lld/MachO/ConcatOutputSection.cpp index 8067d23fa6faf..7a3476a145f0b 100644 --- a/lld/MachO/ConcatOutputSection.cpp +++ b/lld/MachO/ConcatOutputSection.cpp @@ -306,7 +306,12 @@ void TextOutputSection::finalize() { // contains several branch instructions in succession, then the distance // from the current position to the position where the thunks are inserted // grows. So leave room for a bunch of thunks. - unsigned slop = 256 * thunkSize; +#ifdef LLD_MACHO_SLOP_FACTOR + const unsigned kSlopFact = LLD_MACHO_SLOP_FACTOR; +#else + const unsigned kSlopFact = 256; +#endif + unsigned slop = kSlopFact * thunkSize; while (finalIdx < endIdx) { uint64_t expectedNewSize = alignToPowerOf2(addr + size, inputs[finalIdx]->align) + From f3ddb559fa7db14825e2b6cfbf6cb1b4d935c64e Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Wed, 22 Oct 2025 14:32:46 -0400 Subject: [PATCH 2/6] make slop-scale a linker option instead of build-time flag + update docs --- lld/MachO/CMakeLists.txt | 5 ----- lld/MachO/ConcatOutputSection.cpp | 11 ++++------- lld/MachO/Config.h | 1 + lld/MachO/Driver.cpp | 9 +++++++++ lld/MachO/Options.td | 8 ++++++++ 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/lld/MachO/CMakeLists.txt b/lld/MachO/CMakeLists.txt index 5ad12eb04f4c3..3cd94ced75cc0 100644 --- a/lld/MachO/CMakeLists.txt +++ b/lld/MachO/CMakeLists.txt @@ -1,8 +1,3 @@ - -option(LLD_MACHO_SLOP_FACTOR - "Specify the slop factor. For very large build, the default of 256 might be too small, which can cause thunk-range overrun. Recommend increasing this value to 1024 or higher as needed.", 256) -add_definitions("-DLLD_MACHO_SLOP_FACTOR=${LLD_MACHO_SLOP_FACTOR}") - set(LLVM_TARGET_DEFINITIONS Options.td) tablegen(LLVM Options.inc -gen-opt-parser-defs) add_public_tablegen_target(MachOOptionsTableGen) diff --git a/lld/MachO/ConcatOutputSection.cpp b/lld/MachO/ConcatOutputSection.cpp index 7a3476a145f0b..e559676ef5e9b 100644 --- a/lld/MachO/ConcatOutputSection.cpp +++ b/lld/MachO/ConcatOutputSection.cpp @@ -306,12 +306,7 @@ void TextOutputSection::finalize() { // contains several branch instructions in succession, then the distance // from the current position to the position where the thunks are inserted // grows. So leave room for a bunch of thunks. -#ifdef LLD_MACHO_SLOP_FACTOR - const unsigned kSlopFact = LLD_MACHO_SLOP_FACTOR; -#else - const unsigned kSlopFact = 256; -#endif - unsigned slop = kSlopFact * thunkSize; + unsigned slop = config->slopScale * thunkSize; while (finalIdx < endIdx) { uint64_t expectedNewSize = alignToPowerOf2(addr + size, inputs[finalIdx]->align) + @@ -389,7 +384,9 @@ void TextOutputSection::finalize() { // above. If you hit this: For the current algorithm, just bumping up // slop above and trying again is probably simplest. (See also PR51578 // comment 5). - fatal(Twine(__FUNCTION__) + ": FIXME: thunk range overrun"); + fatal(Twine(__FUNCTION__) + + ": FIXME: thunk range overrun. Consider increasing the " + "slop-scale with `--slop-scale=`."); } thunkInfo.isec = makeSyntheticInputSection(isec->getSegName(), isec->getName()); diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h index a2ca5770bf952..759a8cbe3d353 100644 --- a/lld/MachO/Config.h +++ b/lld/MachO/Config.h @@ -224,6 +224,7 @@ struct Configuration { bool disableVerify; bool separateCstringLiteralSections; bool tailMergeStrings; + unsigned slopScale = 256; bool callGraphProfileSort = false; llvm::StringRef printSymbolOrder; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 9b67db9fa55cf..dd481793e1655 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1995,6 +1995,15 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, OPT_no_separate_cstring_literal_sections, false); config->tailMergeStrings = args.hasFlag(OPT_tail_merge_strings, OPT_no_tail_merge_strings, false); + if (auto *arg = args.getLastArg(OPT_slop_scale_eq)) { + StringRef v(arg->getValue()); + unsigned slop = 0; + if (!llvm::to_integer(v, slop, 0)) + error(arg->getSpelling() + + ": expected a non-negative integer, but got '" + arg->getValue() + + "'"); + config->slopScale = slop; + } auto IncompatWithCGSort = [&](StringRef firstArgStr) { // Throw an error only if --call-graph-profile-sort is explicitly specified diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index be1a1cc2963d9..188dc0a501552 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -1095,6 +1095,14 @@ defm tail_merge_strings : BB<"tail-merge-strings", "Enable string tail merging", "Disable string tail merging to improve link-time performance">, Group; +def slop_scale_eq + : Joined<["--"], "slop_scale=">, + MetaVarName<"">, + HelpText<"Specify the slop scale. Default value is 256. If your binary " + "has too many consec branch instructions resulting in " + "thunk-range overrun, then you need to increase this value to a " + "higher value, such as 512 or 1024, etc">, + Group; def grp_deprecated : OptionGroup<"deprecated">, HelpText<"DEPRECATED">; From a9b939edc9bd73c7affcd9498c350006d175911b Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Tue, 28 Oct 2025 13:11:06 -0700 Subject: [PATCH 3/6] Update lld/MachO/Driver.cpp Co-authored-by: Ellis Hoag --- lld/MachO/Driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index dd481793e1655..90d223fcbef01 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -2000,7 +2000,7 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, unsigned slop = 0; if (!llvm::to_integer(v, slop, 0)) error(arg->getSpelling() + - ": expected a non-negative integer, but got '" + arg->getValue() + + ": expected a non-negative integer, but got '" + v + "'"); config->slopScale = slop; } From 1436606c6037f797a301cabffd6bd82b0857b827 Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Tue, 28 Oct 2025 13:11:53 -0700 Subject: [PATCH 4/6] Update lld/MachO/Driver.cpp Co-authored-by: Ellis Hoag --- lld/MachO/Driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 90d223fcbef01..aa6d3675563fc 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1998,7 +1998,7 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, if (auto *arg = args.getLastArg(OPT_slop_scale_eq)) { StringRef v(arg->getValue()); unsigned slop = 0; - if (!llvm::to_integer(v, slop, 0)) + if (!llvm::to_integer(v, slop)) error(arg->getSpelling() + ": expected a non-negative integer, but got '" + v + "'"); From cb0f3fbba7a01d8ca85b21f4d117ed3a12cb517c Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Tue, 28 Oct 2025 16:23:25 -0400 Subject: [PATCH 5/6] reformat --- lld/MachO/Driver.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index aa6d3675563fc..72e37ea43d7cc 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -2000,8 +2000,7 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, unsigned slop = 0; if (!llvm::to_integer(v, slop)) error(arg->getSpelling() + - ": expected a non-negative integer, but got '" + v + - "'"); + ": expected a non-negative integer, but got '" + v +"'"); config->slopScale = slop; } From 0ddc94039a248444d4829c5395d8270785010d75 Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Tue, 28 Oct 2025 16:42:35 -0400 Subject: [PATCH 6/6] reformat again --- lld/MachO/Driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 72e37ea43d7cc..17f3d097d4fde 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -2000,7 +2000,7 @@ bool link(ArrayRef argsArr, llvm::raw_ostream &stdoutOS, unsigned slop = 0; if (!llvm::to_integer(v, slop)) error(arg->getSpelling() + - ": expected a non-negative integer, but got '" + v +"'"); + ": expected a non-negative integer, but got '" + v + "'"); config->slopScale = slop; }