From 68efc823f11b165495fa6ec0f73658a73662de36 Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Tue, 2 Apr 2019 09:41:54 +0300 Subject: [PATCH] Generate trap before each unreachable instruction in debug mode --- .../kotlin/backend/konan/llvm/CodeGenerator.kt | 3 +++ .../kotlin/backend/konan/llvm/ContextUtils.kt | 16 ++++++++++++++++ .../kotlin/backend/konan/llvm/LlvmUtils.kt | 14 +++++++------- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index ce9edbff141..43f705e2b6e 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -424,6 +424,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, call(context.llvm.allocArrayFunction, listOf(typeInfo, count), lifetime, exceptionHandler) fun unreachable(): LLVMValueRef? { + if (context.config.debug) { + call(context.llvm.llvmTrap, emptyList()) + } val res = LLVMBuildUnreachable(builder) currentPositionHolder.setAfterTerminator() return res diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index af1689a4949..e1cb88d3f4f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -296,6 +296,16 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { return LLVMAddFunction(llvmModule, "llvm.memcpy.p0i8.p0i8.i32", functionType)!! } + private fun llvmIntrinsic(name: String, type: LLVMTypeRef, vararg attributes: String): LLVMValueRef { + val result = LLVMAddFunction(llvmModule, name, type)!! + attributes.forEach { + val kindId = getLlvmAttributeKindId(it) + val attribute = LLVMCreateEnumAttribute(LLVMGetTypeContext(type), kindId, 0)!! + LLVMAddAttributeAtIndex(result, LLVMAttributeFunctionIndex, attribute) + } + return result + } + internal fun externalFunction( name: String, type: LLVMTypeRef, @@ -474,6 +484,12 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { val memsetFunction = importMemset() //val memcpyFunction = importMemcpy() + val llvmTrap = llvmIntrinsic( + "llvm.trap", + functionType(voidType, false), + "cold", "noreturn", "nounwind" + ) + val usedFunctions = mutableListOf() val usedGlobals = mutableListOf() val compilerUsedGlobals = mutableListOf() diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt index de83f75bcb5..356696bc7ac 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmUtils.kt @@ -277,15 +277,15 @@ fun parseBitcodeFile(path: String): LLVMModuleRef = memScoped { } private val nounwindAttrKindId by lazy { - getAttributeKindId("nounwind") + getLlvmAttributeKindId("nounwind") } private val noreturnAttrKindId by lazy { - getAttributeKindId("noreturn") + getLlvmAttributeKindId("noreturn") } private val signextAttrKindId by lazy { - getAttributeKindId("signext") + getLlvmAttributeKindId("signext") } @@ -294,12 +294,12 @@ fun isFunctionNoUnwind(function: LLVMValueRef): Boolean { return attribute != null } -private fun getAttributeKindId(attributeName: String): Int { - val nounwindAttrKindId = LLVMGetEnumAttributeKindForName(attributeName, attributeName.length.signExtend()) - if (nounwindAttrKindId == 0) { +internal fun getLlvmAttributeKindId(attributeName: String): Int { + val attrKindId = LLVMGetEnumAttributeKindForName(attributeName, attributeName.length.signExtend()) + if (attrKindId == 0) { throw Error("Unable to find '$attributeName' attribute kind id") } - return nounwindAttrKindId + return attrKindId } fun setFunctionNoUnwind(function: LLVMValueRef) {