From 1e66f2554650af5c97a9ed0857dad86d1779acfc Mon Sep 17 00:00:00 2001 From: Johan Bay Date: Thu, 7 Sep 2023 07:44:31 +0000 Subject: [PATCH] [K/N] Link small bitcode modules together first Repeatedly linking many smaller bitcode modules into one large is very slow. We are seeing a 10x improvement by instead linking all the small modules together first and link the result into the larger main module. This commit implements this optimization in the LinkBitcodeDependenciesPhase phase. ^KT-61604 Fixed Co-authored-by: Johan Bay --- .../kotlin/backend/konan/CompilerOutput.kt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt index 938e2b397f6..30c0fa9469c 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt @@ -126,10 +126,19 @@ private fun linkAllDependencies(generationState: NativeGenerationState, generate // TODO: Possibly slow, maybe to a separate phase? val optimizedRuntimeModules = RuntimeLinkageStrategy.pick(generationState, runtimeModules).run() - (optimizedRuntimeModules + additionalModules).forEach { - val failed = llvmLinkModules2(generationState, generationState.llvm.module, it) + // When the main module `generationState.llvmModule` is very large it is much faster to + // link all the auxiliary modules together first before linking with the main module. + val linkedModules = (optimizedRuntimeModules + additionalModules).reduceOrNull { acc, module -> + val failed = llvmLinkModules2(generationState, acc, module) if (failed != 0) { - error("Failed to link ${it.getName()}") + error("Failed to link ${module.getName()}") + } + return@reduceOrNull acc + } + linkedModules?.let { + val failed = llvmLinkModules2(generationState, generationState.llvmModule, it) + if (failed != 0) { + error("Failed to link runtime and additional modules into main module") } } }