diff --git a/native/llvm-codegen/src/partition.cpp b/native/llvm-codegen/src/partition.cpp index 066ba614c..8ad696d33 100644 --- a/native/llvm-codegen/src/partition.cpp +++ b/native/llvm-codegen/src/partition.cpp @@ -418,7 +418,12 @@ std::optional partitionProgramText(StringRef Text, // An internal function referenced by exactly one other function, and by // no global, is a whole-program inlining candidate; keep it with that - // function so its partition can inline it without importing. + // function so its partition can inline it without importing. A function + // body larger than this is past LLVM's inline cost limit even for the only + // call to a local function, so it is placed by its own name. Otherwise a + // program's module initializers, which only the entry point calls, would + // all share the entry point's partition. + constexpr size_t MaxInlinedBodyBytes = 256 * 1024; constexpr unsigned Shared = ~1u; std::vector Referrer(Symbols.size(), NoPartition); for (unsigned I = 0; I < Symbols.size(); ++I) { @@ -441,7 +446,8 @@ std::optional partitionProgramText(StringRef Text, for (unsigned Steps = 0; Steps < 1024; ++Steps) { const Symbol &S = Symbols[Root]; unsigned Parent = Referrer[Root]; - if (!S.Local || Parent == NoPartition || Parent == Shared || + if (!S.Local || S.Body.size() > MaxInlinedBodyBytes || + Parent == NoPartition || Parent == Shared || Symbols[Parent].Kind != SymbolKind::Function || Parent == I) break; Root = Parent; diff --git a/native/llvm-codegen/src/partition.h b/native/llvm-codegen/src/partition.h index 9d48548fb..838919443 100644 --- a/native/llvm-codegen/src/partition.h +++ b/native/llvm-codegen/src/partition.h @@ -22,8 +22,8 @@ struct ProgramPartitions { // Divides the LLVM assembly scriptc emits into Count modules without parsing // it, so the partitions can be parsed concurrently. Functions are placed by a // stable hash of their name; an internal function referenced by exactly one -// other function stays with that function, and a global stays with the first -// function that references it. Returns nullopt for any construct outside the +// other function stays with that function unless its body is too large to +// inline, and a global stays with the first function that references it. Returns nullopt for any construct outside the // emitter's narrow top-level grammar; callers then split a parsed module. std::optional partitionProgramText(llvm::StringRef Text, unsigned Count);