diff --git a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt index de76943e28d..f821ba49521 100644 --- a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt +++ b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt @@ -175,6 +175,7 @@ class K2Native : CLICompiler() { arguments.manifestFile ?.let{ put(MANIFEST_FILE, it) } arguments.runtimeFile ?.let{ put(RUNTIME_FILE, it) } arguments.temporaryFilesDir?.let { put(TEMPORARY_FILES_DIR, it) } + put(SAVE_LLVM_IR, arguments.saveLlvmIr) put(LIST_TARGETS, arguments.listTargets) put(OPTIMIZATION, arguments.optimization) diff --git a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt index 686de3583b9..08bc03c41f7 100644 --- a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt +++ b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt @@ -255,6 +255,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() { @Argument(value = "-Xtemporary-files-dir", deprecatedName = "--temporary_files_dir", valueDescription = "", description = "Save temporary files to the given directory") var temporaryFilesDir: String? = null + @Argument(value = "-Xsave-llvm-ir", description = "Save result of Kotlin IR to LLVM IR translation to the temporary files directory.") + var saveLlvmIr: Boolean = false + @Argument(value = "-Xverify-bitcode", deprecatedName = "--verify_bitcode", description = "Verify llvm bitcode after each method") var verifyBitCode: Boolean = false diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt index 3de7226ecd6..3704d6f842c 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfigurationKeys.kt @@ -134,6 +134,8 @@ class KonanConfigKeys { = CompilerConfigurationKey.create("target we compile for") val TEMPORARY_FILES_DIR: CompilerConfigurationKey = CompilerConfigurationKey.create("directory for temporary files") + val SAVE_LLVM_IR: CompilerConfigurationKey + = CompilerConfigurationKey.create("save LLVM IR") val VERIFY_BITCODE: CompilerConfigurationKey = CompilerConfigurationKey.create("verify bitcode") val VERIFY_IR: CompilerConfigurationKey diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt index 5d07650ed9a..1b2518af1e6 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt @@ -5,6 +5,10 @@ package org.jetbrains.kotlin.backend.konan.llvm +import kotlinx.cinterop.alloc +import kotlinx.cinterop.memScoped +import kotlinx.cinterop.ptr +import kotlinx.cinterop.toKStringFromUtf8 import llvm.* import org.jetbrains.kotlin.backend.common.phaser.CompilerPhase import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig @@ -12,7 +16,6 @@ import org.jetbrains.kotlin.backend.common.phaser.PhaserState import org.jetbrains.kotlin.backend.common.phaser.namedUnitPhase import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.descriptors.GlobalHierarchyAnalysis -import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD import org.jetbrains.kotlin.backend.konan.lower.InlineClassPropertyAccessorsLowering import org.jetbrains.kotlin.backend.konan.lower.RedundantCoercionsCleaner import org.jetbrains.kotlin.backend.konan.lower.ReturnsInsertionLowering @@ -27,7 +30,6 @@ import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.utils.addToStdlib.cast -import org.jetbrains.kotlin.utils.addToStdlib.safeAs internal val contextLLVMSetupPhase = makeKonanModuleOpPhase( name = "ContextLLVMSetup", @@ -325,6 +327,17 @@ internal val codegenPhase = makeKonanModuleOpPhase( description = "Code generation", op = { context, irModule -> irModule.acceptVoid(context.codegenVisitor) + // TODO: Consider adding LLVM_IR compiler output kind. + if (context.configuration.getBoolean(KonanConfigKeys.SAVE_LLVM_IR)) { + val moduleName: String = memScoped { + val sizeVar = alloc() + LLVMGetModuleIdentifier(context.llvmModule, sizeVar.ptr)!!.toKStringFromUtf8() + } + val output = context.config.tempFiles.create(moduleName,".ll") + if (LLVMPrintModuleToFile(context.llvmModule, output.absolutePath, null) != 0) { + error("Can't dump LLVM IR to ${output.absolutePath}") + } + } } )