Avoid unneeded frame entering/leaving when there's no slots to release. (#2854)

This commit is contained in:
Nikolay Igotti
2019-04-09 10:37:15 +02:00
committed by GitHub
parent 4b8001404c
commit 4dd94d7f26
3 changed files with 16 additions and 14 deletions
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.*
import llvm.*
import org.jetbrains.kotlin.backend.common.serialization.KotlinMangler
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
import org.jetbrains.kotlin.backend.konan.llvm.objc.*
@@ -875,7 +874,6 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
private fun position() = basicBlockToLastLocation[currentBlock]
internal fun mapParameterForDebug(index: Int, value: LLVMValueRef) {
appendingTo(localsInitBb) {
LLVMBuildStore(builder, value, vars.addressOf(index))
@@ -897,7 +895,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
internal fun epilogue() {
appendingTo(prologueBb) {
val slots = if (needSlots)
val slots = if (needSlotsPhi)
LLVMBuildArrayAlloca(builder, kObjHeaderPtr, Int32(slotCount).llvm, "")!!
else
kNullObjHeaderPtrPtr
@@ -909,7 +907,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
Int32(slotCount * codegen.runtime.pointerSize).llvm,
Int32(codegen.runtime.pointerAlignment).llvm,
Int1(0).llvm))
call(context.llvm.enterFrameFunction, listOf(slots, Int32(vars.skip).llvm, Int32(slotCount).llvm))
call(context.llvm.enterFrameFunction, listOf(slots, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm))
}
addPhiIncoming(slotsPhi!!, prologueBb to slots)
memScoped {
@@ -1096,14 +1094,20 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
}
private val needSlots: Boolean
get() {
return slotCount - vars.skipSlots > frameOverlaySlotCount
}
private val needSlotsPhi: Boolean
get() {
return slotCount > frameOverlaySlotCount || localAllocs > 0
}
private fun releaseVars() {
if (needSlots) {
call(context.llvm.leaveFrameFunction,
listOf(slotsPhi!!, Int32(vars.skip).llvm, Int32(slotCount).llvm))
listOf(slotsPhi!!, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm))
}
}
}
@@ -562,11 +562,9 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
if (function != null) {
parameters.forEach{
val parameter = it.key
val local = functionGenerationContext.vars.createParameter(parameter,
debugInfoIfNeeded(function, parameter))
val local = functionGenerationContext.vars.createParameter(
parameter, debugInfoIfNeeded(function, parameter))
functionGenerationContext.mapParameterForDebug(local, it.value)
}
}
}
@@ -586,7 +584,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
*/
private inner class FunctionScope(val declaration: IrFunction?, val functionGenerationContext: FunctionGenerationContext) : InnerScopeImpl() {
constructor(llvmFunction:LLVMValueRef, name:String, functionGenerationContext: FunctionGenerationContext):
this(null, functionGenerationContext) {
this.llvmFunction = llvmFunction
@@ -597,7 +594,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
codegen.llvmFunction(it)
}
val coverageInstrumentation: LLVMCoverageInstrumentation? =
context.coverage.tryGetInstrumentation(declaration) { function, args -> functionGenerationContext.call(function, args) }
@@ -48,6 +48,7 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration
// Clears inner state of variable manager.
fun clear() {
skipSlots = 0
variables.clear()
contextVariablesToIndex.clear()
}
@@ -78,17 +79,18 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration
return index
}
internal var skip = 0
internal var skipSlots = 0
internal fun createParameter(valueDeclaration: IrValueDeclaration, variableLocation: VariableDebugLocation?) : Int {
assert(!contextVariablesToIndex.contains(valueDeclaration))
val index = variables.size
val type = functionGenerationContext.getLLVMType(valueDeclaration.type)
val slot = functionGenerationContext.alloca(type, "p-${valueDeclaration.name.asString()}", variableLocation)
val slot = functionGenerationContext.alloca(
type, "p-${valueDeclaration.name.asString()}", variableLocation)
val isObject = functionGenerationContext.isObjectType(type)
variables.add(ParameterRecord(slot, isObject))
contextVariablesToIndex[valueDeclaration] = index
if (isObject)
skip++
skipSlots++
return index
}