[K/N] Support escape analysis with new mm

This commit is contained in:
Pavel Kunyavskiy
2021-07-23 10:55:09 +03:00
committed by Space
parent f671061328
commit be0a0a7784
4 changed files with 94 additions and 9 deletions
@@ -463,8 +463,6 @@ internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) {
disableUnless(buildDFGPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
disableUnless(devirtualizationPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
disableUnless(escapeAnalysisPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
// TODO: Support escape analysis with experimental MM.
disableIf(escapeAnalysisPhase, config.memoryModel == MemoryModel.EXPERIMENTAL)
// Inline accessors only in optimized builds due to separate compilation and possibility to get broken
// debug information.
disableUnless(propertyAccessorInlinePhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
@@ -255,12 +255,16 @@ internal class StackLocalsManagerImpl(
val bbInitStackLocals: LLVMBasicBlockRef
) : StackLocalsManager {
private class StackLocal(val isArray: Boolean, val irClass: IrClass,
val bodyPtr: LLVMValueRef, val objHeaderPtr: LLVMValueRef)
val bodyPtr: LLVMValueRef, val objHeaderPtr: LLVMValueRef,
val gcRootSetSlot: LLVMValueRef?)
private val stackLocals = mutableListOf<StackLocal>()
fun isEmpty() = stackLocals.isEmpty()
private fun FunctionGenerationContext.createRootSetSlot() =
if (context.memoryModel == MemoryModel.EXPERIMENTAL) alloca(kObjHeaderPtr) else null
override fun alloc(irClass: IrClass, cleanFieldsExplicitly: Boolean): LLVMValueRef = with(functionGenerationContext) {
val type = context.llvmDeclarations.forClass(irClass).bodyType
val stackLocal = appendingTo(bbInitStackLocals) {
@@ -271,12 +275,16 @@ internal class StackLocalsManagerImpl(
val objectHeader = structGep(stackSlot, 0, "objHeader")
val typeInfo = codegen.typeInfoForAllocation(irClass)
setTypeInfoForLocalObject(objectHeader, typeInfo)
StackLocal(false, irClass, stackSlot, objectHeader)
val gcRootSetSlot = createRootSetSlot()
StackLocal(false, irClass, stackSlot, objectHeader, gcRootSetSlot)
}
stackLocals += stackLocal
if (cleanFieldsExplicitly)
clean(stackLocal, false)
if (stackLocal.gcRootSetSlot != null) {
storeStackRef(stackLocal.objHeaderPtr, stackLocal.gcRootSetSlot)
}
stackLocal.objHeaderPtr
}
@@ -323,11 +331,16 @@ internal class StackLocalsManagerImpl(
0,
constCount * LLVMSizeOfTypeInBits(codegen.llvmTargetData, arrayToElementType[irClass.symbol]).toInt() / 8
)
StackLocal(true, irClass, arraySlot, arrayHeaderSlot)
val gcRootSetSlot = createRootSetSlot()
StackLocal(true, irClass, arraySlot, arrayHeaderSlot, gcRootSetSlot)
}
stackLocals += stackLocal
bitcast(kObjHeaderPtr, stackLocal.objHeaderPtr)
val result = bitcast(kObjHeaderPtr, stackLocal.objHeaderPtr)
if (stackLocal.gcRootSetSlot != null) {
storeStackRef(result, stackLocal.gcRootSetSlot)
}
result
}
override fun clean(refsOnly: Boolean) = stackLocals.forEach { clean(it, refsOnly) }
@@ -360,6 +373,9 @@ internal class StackLocalsManagerImpl(
memset(bodyWithSkippedServiceInfoPtr, 0, bodySize - serviceInfoSize)
}
}
if (stackLocal.gcRootSetSlot != null) {
storeStackRef(kNullObjHeaderPtr, stackLocal.gcRootSetSlot)
}
}
private fun setTypeInfoForLocalObject(objectHeader: LLVMValueRef, typeInfoPointer: LLVMValueRef) = with(functionGenerationContext) {