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 kotlinx.cinterop.*
import llvm.* import llvm.*
import org.jetbrains.kotlin.backend.common.serialization.KotlinMangler
import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.isInterface import org.jetbrains.kotlin.backend.konan.descriptors.isInterface
import org.jetbrains.kotlin.backend.konan.llvm.objc.* import org.jetbrains.kotlin.backend.konan.llvm.objc.*
@@ -875,7 +874,6 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
private fun position() = basicBlockToLastLocation[currentBlock] private fun position() = basicBlockToLastLocation[currentBlock]
internal fun mapParameterForDebug(index: Int, value: LLVMValueRef) { internal fun mapParameterForDebug(index: Int, value: LLVMValueRef) {
appendingTo(localsInitBb) { appendingTo(localsInitBb) {
LLVMBuildStore(builder, value, vars.addressOf(index)) LLVMBuildStore(builder, value, vars.addressOf(index))
@@ -897,7 +895,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
internal fun epilogue() { internal fun epilogue() {
appendingTo(prologueBb) { appendingTo(prologueBb) {
val slots = if (needSlots) val slots = if (needSlotsPhi)
LLVMBuildArrayAlloca(builder, kObjHeaderPtr, Int32(slotCount).llvm, "")!! LLVMBuildArrayAlloca(builder, kObjHeaderPtr, Int32(slotCount).llvm, "")!!
else else
kNullObjHeaderPtrPtr kNullObjHeaderPtrPtr
@@ -909,7 +907,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
Int32(slotCount * codegen.runtime.pointerSize).llvm, Int32(slotCount * codegen.runtime.pointerSize).llvm,
Int32(codegen.runtime.pointerAlignment).llvm, Int32(codegen.runtime.pointerAlignment).llvm,
Int1(0).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) addPhiIncoming(slotsPhi!!, prologueBb to slots)
memScoped { memScoped {
@@ -1096,14 +1094,20 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
} }
private val needSlots: Boolean private val needSlots: Boolean
get() {
return slotCount - vars.skipSlots > frameOverlaySlotCount
}
private val needSlotsPhi: Boolean
get() { get() {
return slotCount > frameOverlaySlotCount || localAllocs > 0 return slotCount > frameOverlaySlotCount || localAllocs > 0
} }
private fun releaseVars() { private fun releaseVars() {
if (needSlots) { if (needSlots) {
call(context.llvm.leaveFrameFunction, 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) { if (function != null) {
parameters.forEach{ parameters.forEach{
val parameter = it.key val parameter = it.key
val local = functionGenerationContext.vars.createParameter(
val local = functionGenerationContext.vars.createParameter(parameter, parameter, debugInfoIfNeeded(function, parameter))
debugInfoIfNeeded(function, parameter))
functionGenerationContext.mapParameterForDebug(local, it.value) 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() { private inner class FunctionScope(val declaration: IrFunction?, val functionGenerationContext: FunctionGenerationContext) : InnerScopeImpl() {
constructor(llvmFunction:LLVMValueRef, name:String, functionGenerationContext: FunctionGenerationContext): constructor(llvmFunction:LLVMValueRef, name:String, functionGenerationContext: FunctionGenerationContext):
this(null, functionGenerationContext) { this(null, functionGenerationContext) {
this.llvmFunction = llvmFunction this.llvmFunction = llvmFunction
@@ -597,7 +594,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
codegen.llvmFunction(it) codegen.llvmFunction(it)
} }
val coverageInstrumentation: LLVMCoverageInstrumentation? = val coverageInstrumentation: LLVMCoverageInstrumentation? =
context.coverage.tryGetInstrumentation(declaration) { function, args -> functionGenerationContext.call(function, args) } 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. // Clears inner state of variable manager.
fun clear() { fun clear() {
skipSlots = 0
variables.clear() variables.clear()
contextVariablesToIndex.clear() contextVariablesToIndex.clear()
} }
@@ -78,17 +79,18 @@ internal class VariableManager(val functionGenerationContext: FunctionGeneration
return index return index
} }
internal var skip = 0 internal var skipSlots = 0
internal fun createParameter(valueDeclaration: IrValueDeclaration, variableLocation: VariableDebugLocation?) : Int { internal fun createParameter(valueDeclaration: IrValueDeclaration, variableLocation: VariableDebugLocation?) : Int {
assert(!contextVariablesToIndex.contains(valueDeclaration)) assert(!contextVariablesToIndex.contains(valueDeclaration))
val index = variables.size val index = variables.size
val type = functionGenerationContext.getLLVMType(valueDeclaration.type) 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) val isObject = functionGenerationContext.isObjectType(type)
variables.add(ParameterRecord(slot, isObject)) variables.add(ParameterRecord(slot, isObject))
contextVariablesToIndex[valueDeclaration] = index contextVariablesToIndex[valueDeclaration] = index
if (isObject) if (isObject)
skip++ skipSlots++
return index return index
} }