Codegen: init all slots at the beginning

This is needed for coroutines: when resuming suspend functions
all visible locals must be initialized.
This commit is contained in:
Igor Chevdar
2017-04-20 17:51:57 +03:00
parent 01b6ab74a5
commit 86449c6d04
@@ -70,10 +70,11 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
this.returnType = returnType this.returnType = returnType
this.constructedClass = null this.constructedClass = null
prologueBb = LLVMAppendBasicBlock(function, "prologue") prologueBb = LLVMAppendBasicBlock(function, "prologue")
localsInitBb = LLVMAppendBasicBlock(function, "locals_init")
entryBb = LLVMAppendBasicBlock(function, "entry") entryBb = LLVMAppendBasicBlock(function, "entry")
epilogueBb = LLVMAppendBasicBlock(function, "epilogue") epilogueBb = LLVMAppendBasicBlock(function, "epilogue")
cleanupLandingpad = LLVMAppendBasicBlock(function, "cleanup_landingpad")!! cleanupLandingpad = LLVMAppendBasicBlock(function, "cleanup_landingpad")!!
positionAtEnd(entryBb!!) positionAtEnd(localsInitBb!!)
locationInfo?.let { locationInfo?.let {
debugLocation(it) debugLocation(it)
} }
@@ -84,6 +85,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
// Is removed by DCE trivially, if not needed. // Is removed by DCE trivially, if not needed.
arenaSlot = intToPtr( arenaSlot = intToPtr(
or(ptrToInt(slotsPhi, intPtrType), immOneIntPtrType), kObjHeaderPtrPtr) or(ptrToInt(slotsPhi, intPtrType), immOneIntPtrType), kObjHeaderPtrPtr)
positionAtEnd(entryBb!!)
} }
fun epilogue(locationInfo: LocationInfo? = null) { fun epilogue(locationInfo: LocationInfo? = null) {
@@ -106,6 +108,10 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
Int1(0).llvm)) Int1(0).llvm))
} }
addPhiIncoming(slotsPhi!!, prologueBb!! to slots) addPhiIncoming(slotsPhi!!, prologueBb!! to slots)
br(localsInitBb!!)
}
appendingTo(localsInitBb!!) {
br(entryBb!!) br(entryBb!!)
} }
@@ -156,6 +162,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
} }
private var prologueBb: LLVMBasicBlockRef? = null private var prologueBb: LLVMBasicBlockRef? = null
private var localsInitBb: LLVMBasicBlockRef? = null
private var entryBb: LLVMBasicBlockRef? = null private var entryBb: LLVMBasicBlockRef? = null
private var epilogueBb: LLVMBasicBlockRef? = null private var epilogueBb: LLVMBasicBlockRef? = null
private var cleanupLandingpad: LLVMBasicBlockRef? = null private var cleanupLandingpad: LLVMBasicBlockRef? = null
@@ -191,7 +198,9 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
fun alloca(type: LLVMTypeRef?, name: String = ""): LLVMValueRef { fun alloca(type: LLVMTypeRef?, name: String = ""): LLVMValueRef {
if (isObjectType(type!!)) { if (isObjectType(type!!)) {
return gep(slotsPhi!!, Int32(slotCount++).llvm) appendingTo(localsInitBb!!) {
return gep(slotsPhi!!, Int32(slotCount++).llvm, name)
}
} }
appendingTo(prologueBb!!) { appendingTo(prologueBb!!) {
return LLVMBuildAlloca(builder, type, name)!! return LLVMBuildAlloca(builder, type, name)!!
@@ -241,8 +250,8 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
} }
} }
fun gep(base: LLVMValueRef, index: LLVMValueRef): LLVMValueRef { fun gep(base: LLVMValueRef, index: LLVMValueRef, name: String = ""): LLVMValueRef {
return LLVMBuildGEP(builder, base, cValuesOf(index), 1, "")!! return LLVMBuildGEP(builder, base, cValuesOf(index), 1, name)!!
} }
fun updateReturnRef(value: LLVMValueRef, address: LLVMValueRef) { fun updateReturnRef(value: LLVMValueRef, address: LLVMValueRef) {