From ba2aadcb818c2b05fd9a9d077e6d5c5fb98b8eae Mon Sep 17 00:00:00 2001 From: Chris Tate Date: Mon, 26 Oct 2026 03:32:39 -0500 Subject: [PATCH] Import callees of up to 40 instructions across program partitions The thin link imported a callee of up to 100 instructions, LLVM's default, into every partition that calls it, and each partition then optimized and compiled its imported copies again. Partitioned programs now import callees of up to 40 instructions. Programs that compile as one module are unchanged. --- native/llvm-codegen/src/emit.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/native/llvm-codegen/src/emit.cpp b/native/llvm-codegen/src/emit.cpp index 4a7e2333b..c7efef13f 100644 --- a/native/llvm-codegen/src/emit.cpp +++ b/native/llvm-codegen/src/emit.cpp @@ -64,6 +64,9 @@ static constexpr size_t MaxPartitions = 64; // multiple of the usual size limit, in builds with a profile. See // limitProfileImports(). static constexpr const char *ProfileImportMultiplier = "2"; +// The thin link's size limit, in instructions, for a callee it imports into +// a partition that calls it. See limitImports(). +static constexpr const char *ImportInstructionLimit = "40"; std::optional parseEmitOptions(int Argc, char **Argv) { EmitOptions Options; @@ -173,6 +176,22 @@ void limitProfileImports() { (void)Limited; } +// The thin link imports a callee of up to 100 instructions, LLVM's default, +// into every partition that calls it, and each partition then optimizes and +// compiles its imported copies again. On tsc-ts (64 partitions) a limit of 40 +// takes about 7% off the helper's time, and the program runs as fast; 30 and +// below made it run 1-8% slower. The limit is a process-wide option; the +// helper sets it once. +void limitImports() { + static const bool Limited = [] { + if (cl::Option *Option = + cl::getRegisteredOptions().lookup("import-instr-limit")) + Option->addOccurrence(0, "import-instr-limit", ImportInstructionLimit); + return true; + }(); + (void)Limited; +} + // Drops the names of a partition's struct types before its summary is // written. Every partition declares the program's types under the same // names, and a thin link loads the importing partition and the partitions @@ -852,6 +871,7 @@ compileOptimizedPartitions(const EmitOptions &Options, std::vector Names(Count); for (size_t I = 0; I < Count; ++I) Names[I] = "partition-" + std::to_string(I); + limitImports(); if (!Options.ProfileUse.empty()) limitProfileImports(); lto::LTO Link(std::move(Config),