Generate trap before each unreachable instruction in debug mode

This commit is contained in:
Svyatoslav Scherbina
2019-04-02 09:41:54 +03:00
committed by SvyatoslavScherbina
parent 9cc6000237
commit 68efc823f1
3 changed files with 26 additions and 7 deletions
@@ -424,6 +424,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
call(context.llvm.allocArrayFunction, listOf(typeInfo, count), lifetime, exceptionHandler) call(context.llvm.allocArrayFunction, listOf(typeInfo, count), lifetime, exceptionHandler)
fun unreachable(): LLVMValueRef? { fun unreachable(): LLVMValueRef? {
if (context.config.debug) {
call(context.llvm.llvmTrap, emptyList())
}
val res = LLVMBuildUnreachable(builder) val res = LLVMBuildUnreachable(builder)
currentPositionHolder.setAfterTerminator() currentPositionHolder.setAfterTerminator()
return res return res
@@ -296,6 +296,16 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
return LLVMAddFunction(llvmModule, "llvm.memcpy.p0i8.p0i8.i32", functionType)!! 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( internal fun externalFunction(
name: String, name: String,
type: LLVMTypeRef, type: LLVMTypeRef,
@@ -474,6 +484,12 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
val memsetFunction = importMemset() val memsetFunction = importMemset()
//val memcpyFunction = importMemcpy() //val memcpyFunction = importMemcpy()
val llvmTrap = llvmIntrinsic(
"llvm.trap",
functionType(voidType, false),
"cold", "noreturn", "nounwind"
)
val usedFunctions = mutableListOf<LLVMValueRef>() val usedFunctions = mutableListOf<LLVMValueRef>()
val usedGlobals = mutableListOf<LLVMValueRef>() val usedGlobals = mutableListOf<LLVMValueRef>()
val compilerUsedGlobals = mutableListOf<LLVMValueRef>() val compilerUsedGlobals = mutableListOf<LLVMValueRef>()
@@ -277,15 +277,15 @@ fun parseBitcodeFile(path: String): LLVMModuleRef = memScoped {
} }
private val nounwindAttrKindId by lazy { private val nounwindAttrKindId by lazy {
getAttributeKindId("nounwind") getLlvmAttributeKindId("nounwind")
} }
private val noreturnAttrKindId by lazy { private val noreturnAttrKindId by lazy {
getAttributeKindId("noreturn") getLlvmAttributeKindId("noreturn")
} }
private val signextAttrKindId by lazy { private val signextAttrKindId by lazy {
getAttributeKindId("signext") getLlvmAttributeKindId("signext")
} }
@@ -294,12 +294,12 @@ fun isFunctionNoUnwind(function: LLVMValueRef): Boolean {
return attribute != null return attribute != null
} }
private fun getAttributeKindId(attributeName: String): Int { internal fun getLlvmAttributeKindId(attributeName: String): Int {
val nounwindAttrKindId = LLVMGetEnumAttributeKindForName(attributeName, attributeName.length.signExtend()) val attrKindId = LLVMGetEnumAttributeKindForName(attributeName, attributeName.length.signExtend())
if (nounwindAttrKindId == 0) { if (attrKindId == 0) {
throw Error("Unable to find '$attributeName' attribute kind id") throw Error("Unable to find '$attributeName' attribute kind id")
} }
return nounwindAttrKindId return attrKindId
} }
fun setFunctionNoUnwind(function: LLVMValueRef) { fun setFunctionNoUnwind(function: LLVMValueRef) {