From 431a7c9ba9c2b808722546f16f11e35be46f9ade Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Fri, 16 Oct 2020 13:44:53 +0700 Subject: [PATCH] [KT-42234] Moved optimization flags to konan.properties Combined with KT-40670, it simplifies tuning of LLVM optimization and compilation pipeline. --- .../backend/konan/OptimizationPipeline.kt | 61 ++++------------- kotlin-native/konan/konan.properties | 66 ++++++++++++------- .../kotlin/konan/target/Configurables.kt | 5 +- 3 files changed, 59 insertions(+), 73 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt index ca4546c47b7..b2a97da9263 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.konan.llvm.makeVisibilityHiddenLikeLlvmInter import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.Configurables import org.jetbrains.kotlin.konan.target.KonanTarget -import org.jetbrains.kotlin.konan.target.ZephyrConfigurables private fun initializeLlvmGlobalPassRegistry() { val passRegistry = LLVMGetGlobalPassRegistry() @@ -46,53 +45,26 @@ private class LlvmPipelineConfiguration(context: Context) { val targetTriple: String = context.llvm.targetTriple - // Some of these values are copied from corresponding runtime.bc - // which is using "generic" target CPU for many case. - // This approach is suboptimal because target-cpu="generic" limits - // the set of used cpu features. - // TODO: refactor KonanTarget so that we can explicitly specify - // target cpu or arch+features combination in a single place. - val cpuModel: String = when (target) { - KonanTarget.IOS_ARM32 -> "generic" - KonanTarget.IOS_ARM64 -> "cyclone" - KonanTarget.IOS_X64 -> "core2" - KonanTarget.TVOS_ARM64 -> "cyclone" - KonanTarget.TVOS_X64 -> "core2" - KonanTarget.WATCHOS_X86 -> "i386" - KonanTarget.WATCHOS_X64 -> "core2" - KonanTarget.WATCHOS_ARM64, - KonanTarget.WATCHOS_ARM32 -> "cortex-a7" - KonanTarget.LINUX_X64 -> "x86-64" - KonanTarget.MINGW_X86 -> "pentium4" - KonanTarget.MINGW_X64 -> "x86-64" - KonanTarget.MACOS_X64 -> "core2" - KonanTarget.LINUX_ARM32_HFP -> "arm1136jf-s" - KonanTarget.LINUX_ARM64 -> "generic" - KonanTarget.ANDROID_ARM32 -> "arm7tdmi" - KonanTarget.ANDROID_ARM64 -> "cortex-a57" - KonanTarget.ANDROID_X64 -> "x86-64" - KonanTarget.ANDROID_X86 -> "i686" - KonanTarget.LINUX_MIPS32 -> "mips32r2" - KonanTarget.LINUX_MIPSEL32 -> "mips32r2" - KonanTarget.WASM32 -> "generic" - is KonanTarget.ZEPHYR -> (configurables as ZephyrConfigurables).targetCpu ?: run { - context.reportCompilationWarning("targetCpu for target $target was not set. Targeting `generic` cpu.") - "generic" - } + val cpuModel: String = configurables.targetCpu ?: run { + context.reportCompilationWarning("targetCpu for target $target was not set. Targeting `generic` cpu.") + "generic" } - val cpuFeatures: String = when (target) { - KonanTarget.LINUX_ARM32_HFP -> "+dsp,+strict-align,+vfp2,-crypto,-d16,-fp-armv8,-fp-only-sp,-fp16,-neon,-thumb-mode,-vfp3,-vfp4" - KonanTarget.ANDROID_ARM32 -> "+soft-float,+strict-align,-crypto,-neon,-thumb-mode" - else -> "" - } + val cpuFeatures: String = configurables.targetCpuFeatures ?: "" /** * Null value means that LLVM should use default inliner params * for the provided optimization and size level. */ val customInlineThreshold: Int? = when { - context.shouldOptimize() -> INLINE_THRESHOLD_OPT + context.shouldOptimize() -> configurables.llvmInlineThreshold?.let { + it.toIntOrNull() ?: run { + context.reportCompilationWarning( + "`llvmInlineThreshold` should be an integer. Got `$it` instead. Using default value." + ) + null + } + } context.shouldContainDebugInfo() -> null else -> null } @@ -122,15 +94,6 @@ private class LlvmPipelineConfiguration(context: Context) { val codeModel: LLVMCodeModel = LLVMCodeModel.LLVMCodeModelDefault - companion object { - // By default LLVM uses 250 for -03 builds. - // We use a smaller value since default value leads to - // unreasonably bloated runtime code without any measurable - // performance benefits. - // This value still has to be tuned for different targets, though. - private const val INLINE_THRESHOLD_OPT = 100 - } - enum class LlvmOptimizationLevel(val value: Int) { NONE(0), DEFAULT(1), diff --git a/kotlin-native/konan/konan.properties b/kotlin-native/konan/konan.properties index 20741278b7a..c86daed3449 100644 --- a/kotlin-native/konan/konan.properties +++ b/kotlin-native/konan/konan.properties @@ -49,7 +49,14 @@ llvm.mingw_x64.user = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 llvm.macos_x64.dev = clang-llvm-apple-8.0.0-darwin-macos llvm.macos_x64.user = clang-llvm-apple-8.0.0-darwin-macos +# By default LLVM uses 250 for -03 builds. +# We use a smaller value since default value leads to +# unreasonably bloated runtime code without any measurable +# performance benefits. +# This value still has to be tuned for different targets, though. +llvmInlineThreshold = 100 clangDebugFlags = -O0 + llvmVersion.linux_x64 = 8.0.0 llvmVersion.mingw_x64 = 8.0.1 llvmVersion.macos_x64 = 8.0.0 @@ -63,7 +70,7 @@ additionalToolsDir.macos_x64 = xcode-addon-xcode_12_0-macos_x64 arch.macos_x64 = x86_64 targetSysRoot.macos_x64 = target-sysroot-xcode_12_0-macos_x64 - +targetCpu.macos_x64 = core2 clangFlags.macos_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.macos_x64 = -O1 clangOptFlags.macos_x64 = -O3 @@ -105,7 +112,7 @@ target-sysroot-xcode_12_0-ios_arm32.default = \ arch.ios_arm32 = armv7 # Shared with 64-bit version. targetSysRoot.ios_arm32 = target-sysroot-xcode_12_0-ios_arm64 - +targetCpu.ios_arm32 = generic clangFlags.ios_arm32 = -cc1 -emit-obj -disable-llvm-optzns -x ir clangNooptFlags.ios_arm32 = -O1 clangOptFlags.ios_arm32 = -O3 @@ -137,7 +144,7 @@ target-sysroot-xcode_12_0-ios_arm64.default = \ arch.ios_arm64 = arm64 targetSysRoot.ios_arm64 = target-sysroot-xcode_12_0-ios_arm64 - +targetCpu.ios_arm64 = cyclone clangFlags.ios_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.ios_arm64 = -O1 clangOptFlags.ios_arm64 = -O3 @@ -167,7 +174,7 @@ target-sysroot-xcode_12_0-ios_x64.default = \ arch.ios_x64 = x86_64 targetSysRoot.ios_x64 = target-sysroot-xcode_12_0-ios_x64 - +targetCpu.ios_x64 = core2 clangFlags.ios_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.ios_x64 = -O1 clangOptFlags.ios_x64 = -O3 @@ -194,7 +201,7 @@ target-sysroot-xcode_12_0-tvos_x64.default = \ arch.tvos_x64 = x86_64 targetSysRoot.tvos_x64 = target-sysroot-xcode_12_0-tvos_x64 - +targetCpu.tvos_x64 = core2 clangFlags.tvos_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.tvos_x64 = -O1 clangOptFlags.tvos_x64 = -O3 @@ -221,7 +228,7 @@ target-sysroot-xcode_12_0-tvos_arm64.default = \ arch.tvos_arm64 = arm64 targetSysRoot.tvos_arm64 = target-sysroot-xcode_12_0-tvos_arm64 - +targetCpu.tvos_arm64 = cyclone clangFlags.tvos_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.tvos_arm64 = -O1 clangOptFlags.tvos_arm64 = -O3 @@ -248,7 +255,7 @@ target-sysroot-xcode_12_0-watchos_arm32.default = \ arch.watchos_arm32 = armv7k targetSysRoot.watchos_arm32 = target-sysroot-xcode_12_0-watchos_arm32 - +targetCpu.watchos_arm32 = cortex-a7 clangFlags.watchos_arm32 = -cc1 -emit-obj -disable-llvm-passes -x ir clangNooptFlags.watchos_arm32 = -O1 clangOptFlags.watchos_arm32 = -O3 @@ -277,7 +284,7 @@ target-sysroot-xcode_12_0-watchos_arm64.default = \ arch.watchos_arm64 = arm64_32 targetSysRoot.watchos_arm64 = target-sysroot-xcode_12_0-watchos_arm32 - +targetCpu.watchos_arm64 = cortex-a7 clangFlags.watchos_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir -mllvm -aarch64-watch-bitcode-compatibility \ -mllvm -arm-bitcode-compatibility -mllvm -fast-isel=false -mllvm -global-isel=false clangNooptFlags.watchos_arm64 = -O1 @@ -307,12 +314,12 @@ target-sysroot-xcode_12_0-watchos_x86.default = \ arch.watchos_x86 = i386 targetSysRoot.watchos_x86 = target-sysroot-xcode_12_0-watchos_x86 - -# -target-cpu pentium4 makes sure that cogenerator knows which CPU flavour to emit code for. +# -target-cpu pentium4 makes sure that code-generator knows which CPU flavour to emit code for. # Can be seen on optimized build and FP tests, where value is passed on stack # by Kotlin and taken from SSE registers by C code. # TODO: once this information is available in function attributes, we can remove this flag. -clangFlags.watchos_x86 = -cc1 -emit-obj -disable-llvm-passes -x ir -target-cpu pentium4 +targetCpu.watchos_x86 = pentium4 +clangFlags.watchos_x86 = -cc1 -emit-obj -disable-llvm-passes -x ir -target-cpu $targetCpu.watchos_x86 clangNooptFlags.watchos_x86 = -O1 clangOptFlags.watchos_x86 = -O3 clangDebugFlags.watchos_x86 = -O0 @@ -355,7 +362,8 @@ quadruple.linux_x64 = x86_64-unknown-linux-gnu targetSysRoot.linux_x64 = target-gcc-toolchain-3-linux-x86-64/x86_64-unknown-linux-gnu/sysroot # targetSysroot-relative. libGcc.linux_x64 = ../../lib/gcc/x86_64-unknown-linux-gnu/4.8.5 -clangFlags.linux_x64 = -cc1 -target-cpu x86-64 -emit-obj -disable-llvm-optzns -x ir +targetCpu.linux_x64 = x86-64 +clangFlags.linux_x64 = -cc1 -target-cpu $targetCpu.linux_x64 -emit-obj -disable-llvm-optzns -x ir clangNooptFlags.linux_x64 = -O1 clangOptFlags.linux_x64 = -O3 -ffunction-sections clangDebugFlags.linux_x64 = -O0 @@ -398,7 +406,9 @@ linkerKonanFlags.linux_arm32_hfp = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthrea --defsym __cxa_demangle=Konan_cxa_demangle --no-threads # targetSysroot-relative. libGcc.linux_arm32_hfp = lib/gcc/arm-linux-gnueabihf/4.8.3 -clangFlags.linux_arm32_hfp = -cc1 -target-cpu arm1136jf-s -mfloat-abi hard -emit-obj -disable-llvm-optzns -x ir +targetCpu.linux_arm32_hfp = arm1136jf-s +targetCpuFeatures.linux_arm32_hfp = +dsp,+strict-align,+vfp2,-crypto,-d16,-fp-armv8,-fp-only-sp,-fp16,-neon,-thumb-mode,-vfp3,-vfp4 +clangFlags.linux_arm32_hfp = -cc1 -target-cpu $targetCpu.linux_arm32_hfp -mfloat-abi hard -emit-obj -disable-llvm-optzns -x ir clangNooptFlags.linux_arm32_hfp = -O1 clangOptFlags.linux_arm32_hfp = -O3 -ffunction-sections clangDebugFlags.linux_arm32_hfp = -O0 @@ -440,6 +450,7 @@ linkerKonanFlags.linux_arm64 = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread \ --defsym __cxa_demangle=Konan_cxa_demangle --no-threads # targetSysroot-relative. libGcc.linux_arm64 = usr/lib +targetCpu.linux_arm64 = generic clangFlags.linux_arm64 = -cc1 -target-cpu cortex-a57 -emit-obj -disable-llvm-optzns -x ir clangNooptFlags.linux_arm64 = -O1 clangOptFlags.linux_arm64 = -O3 -ffunction-sections @@ -470,7 +481,8 @@ linkerKonanFlags.linux_mips32 = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread \ --defsym __cxa_demangle=Konan_cxa_demangle -z notext # targetSysroot-relative. libGcc.linux_mips32 = lib/gcc/mips-unknown-linux-gnu/4.9.4 -clangFlags.linux_mips32 = -cc1 -emit-obj -disable-llvm-optzns -x ir -target-cpu mips32r2 +targetCpu.linux_mips32 = mips32r2 +clangFlags.linux_mips32 = -cc1 -emit-obj -disable-llvm-optzns -x ir -target-cpu $targetCpu.linux_mips32 clangNooptFlags.linux_mips32 = -O1 clangOptFlags.linux_mips32 = -O3 -ffunction-sections clangDebugFlags.linux_mips32 = -O0 @@ -498,7 +510,8 @@ linkerKonanFlags.linux_mipsel32 = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread --defsym __cxa_demangle=Konan_cxa_demangle -z notext # targetSysroot-relative. libGcc.linux_mipsel32 = lib/gcc/mipsel-unknown-linux-gnu/4.9.4 -clangFlags.linux_mipsel32 = -cc1 -emit-obj -disable-llvm-optzns -x ir -target-cpu mips32r2 +targetCpu.linux_mipsel32 = mips32r2 +clangFlags.linux_mipsel32 = -cc1 -emit-obj -disable-llvm-optzns -x ir -target-cpu targetCpu.linux_mipsel32 clangNooptFlags.linux_mipsel32 = -O1 clangOptFlags.linux_mipsel32 = -O3 -ffunction-sections clangDebugFlags.linux_mipsel32 = -O0 @@ -528,7 +541,9 @@ dependencies.mingw_x64-android_arm32 = \ libffi-3.2.1-mingw-w64-x86-64 quadruple.android_arm32 = arm-linux-androideabi -clangFlags.android_arm32 = -cc1 -target-cpu arm7tdmi -emit-obj -disable-llvm-optzns -x ir -femulated-tls -mrelocation-model pic +targetCpu.android_arm32 = arm7tdmi +targetCpuFeatures.android_arm32 = +soft-float,+strict-align,-crypto,-neon,-thumb-mode +clangFlags.android_arm32 = -cc1 -target-cpu $targetCpu.android_arm32 -emit-obj -disable-llvm-optzns -x ir -femulated-tls -mrelocation-model pic clangOptFlags.android_arm32 = -O3 -ffunction-sections linkerNoDebugFlags.android_arm32 = -Wl,-S clangNooptFlags.android_arm32 = -O1 @@ -555,7 +570,8 @@ dependencies.mingw_x64-android_arm64 = \ libffi-3.2.1-mingw-w64-x86-64 quadruple.android_arm64 = aarch64-linux-android -clangFlags.android_arm64 = -cc1 -target-cpu cortex-a57 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic +targetCpu.android_arm64 = cortex-a57 +clangFlags.android_arm64 = -cc1 -target-cpu $targetCpu.android_arm64 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic clangOptFlags.android_arm64 = -O3 -ffunction-sections clangNooptFlags.android_arm64 = -O1 targetSysRoot.android_arm64 = target-sysroot-1-android_ndk @@ -582,12 +598,12 @@ dependencies.mingw_x64-android_x86 = \ libffi-3.2.1-mingw-w64-x86-64 quadruple.android_x86 = i686-linux-android - # -target-cpu pentium4 makes sure that cogenerator knows which CPU flavour to emit code for. # Can be seen on optimized build and FP tests, where value is passed on stack # by Kotlin and taken from SSE registers by C code. # TODO: once this information is available in function attributes, we can set target CPU to i686. -clangFlags.android_x86 = -cc1 -target-cpu pentium4 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic +targetCpu.android_x86 = pentium4 +clangFlags.android_x86 = -cc1 -target-cpu targetCpu.android_x86 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic clangOptFlags.android_x86 = -O3 -ffunction-sections clangNooptFlags.android_x86 = -O1 targetSysRoot.android_x86 = target-sysroot-1-android_ndk @@ -614,7 +630,8 @@ dependencies.mingw_x64-android_x64 = \ libffi-3.2.1-mingw-w64-x86-64 quadruple.android_x64 = x86_64-linux-android -clangFlags.android_x64 = -cc1 -target-cpu x86-64 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic +targetCpu.android_x64 = x86-64 +clangFlags.android_x64 = -cc1 -target-cpu $targetCpu.android_x64 -emit-obj -disable-llvm-passes -x ir -femulated-tls -mrelocation-model pic clangOptFlags.android_x64 = -O3 -ffunction-sections clangNooptFlags.android_x64 = -O1 targetSysRoot.android_x64 = target-sysroot-1-android_ndk @@ -641,10 +658,11 @@ dependencies.macos_x64-mingw_x64 = \ quadruple.mingw_x64 = x86_64-w64-mingw32 targetSysRoot.mingw_x64 = msys2-mingw-w64-x86_64-clang-llvm-lld-compiler_rt-8.0.1 +targetCpu.mingw_x64 = x86-64 # For using with Universal Windows Platform (UWP) we need to use this slower option. # See https://youtrack.jetbrains.com/issue/KT-27654. # TODO: remove, once fixed in mingw, check with the bug testcase. -clangFlags.mingw_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir -femulated-tls -target-cpu x86-64 +clangFlags.mingw_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir -femulated-tls -target-cpu $targetCpu.mingw_x64 clangOptFlags.mingw_x64 = -O3 -ffunction-sections clangNooptFlags.mingw_x64 = -O1 linkerNoDebugFlags.mingw_x64 = -Wl,-S @@ -677,11 +695,12 @@ targetSysRoot.mingw_x86 = msys2-mingw-w64-i686-clang-llvm-lld-compiler_rt-8.0.1 # For using with Universal Windows Platform (UWP) we need to use slower -emulated-tls option. # See https://youtrack.jetbrains.com/issue/KT-27654. # TODO: remove, once fixed in mingw, check with the bug testcase. -# -target-cpu pentium4 makes sure that cogenerator knows which CPU flavour to emit code for. +# -target-cpu pentium4 makes sure that code-generator knows which CPU flavour to emit code for. # Can be seen on optimized build and FP tests, where value is passed in coprocessor registers # by Kotlin and taken from SSE registers by C code. # TODO: once this information is available in function attributes, we can remove this flag. -clangFlags.mingw_x86 = -cc1 -emit-obj -disable-llvm-passes -x ir -femulated-tls -target-cpu pentium4 +targetCpu.mingw_x86 = pentium4 +clangFlags.mingw_x86 = -cc1 -emit-obj -disable-llvm-passes -x ir -femulated-tls -target-cpu $targetCpu.mingw_x86 clangOptFlags.mingw_x86 = -O3 -ffunction-sections clangNooptFlags.mingw_x86 = -O1 linkerNoDebugFlags.mingw_x86 = -Wl,-S @@ -716,6 +735,7 @@ dependencies.mingw_x64-wasm32 = \ quadruple.wasm32 = wasm32-unknown-unknown targetSysRoot.wasm32 = target-sysroot-4-embedded +targetCpu.wasm32 = generic clangFlags.wasm32 = -cc1 -emit-obj -disable-llvm-optzns -x ir clangNooptFlags.wasm32 = -O1 clangOptFlags.wasm32 = -O3 diff --git a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Configurables.kt b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Configurables.kt index b9165e57345..bea69aac0ce 100644 --- a/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Configurables.kt +++ b/kotlin-native/shared/src/main/kotlin/org/jetbrains/kotlin/konan/target/Configurables.kt @@ -53,6 +53,10 @@ interface Configurables : TargetableExternalStorage { val absoluteTargetToolchain get() = absolute(targetToolchain) val absoluteLlvmHome get() = absolute(llvmHome) + val targetCpu get() = targetString("targetCpu") + val targetCpuFeatures get() = targetString("targetCpuFeatures") + val llvmInlineThreshold get() = targetString("llvmInlineThreshold") + val runtimeDefinitions get() = targetList("runtimeDefinitions") } @@ -85,6 +89,5 @@ interface WasmConfigurables : TargetableConfigurables, ClangFlags, LldFlags interface ZephyrConfigurables : TargetableConfigurables, ClangFlags { val boardSpecificClangFlags get() = targetList("boardSpecificClangFlags") - val targetCpu get() = targetString("targetCpu") val targetAbi get() = targetString("targetAbi") } \ No newline at end of file