Avoid unneeded frame entering/leaving when there's no slots to release. (#2854)
This commit is contained in:
+9
-5
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-6
@@ -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) }
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user