Added Global hierarchy analysis phase
This commit is contained in:
committed by
Igor Chevdar
parent
2195687f63
commit
afe9f07cbc
+1
@@ -435,6 +435,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
fun shouldContainAnyDebugInfo() = shouldContainDebugInfo() || shouldContainLocationDebugInfo()
|
||||
|
||||
fun shouldOptimize() = config.configuration.getBoolean(KonanConfigKeys.OPTIMIZATION)
|
||||
fun ghaEnabled() = ::globalHierarchyAnalysisResult.isInitialized
|
||||
|
||||
val memoryModel = config.memoryModel
|
||||
|
||||
|
||||
+2
@@ -361,6 +361,7 @@ internal val bitcodePhase = namedIrModulePhase(
|
||||
devirtualizationPhase then
|
||||
dcePhase then
|
||||
contextLLVMSetupPhase then
|
||||
ghaPhase then
|
||||
RTTIPhase then
|
||||
generateDebugInfoHeaderPhase then
|
||||
escapeAnalysisPhase then
|
||||
@@ -424,6 +425,7 @@ internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) {
|
||||
disableUnless(buildDFGPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
|
||||
disableUnless(devirtualizationPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
|
||||
disableUnless(dcePhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
|
||||
disableUnless(ghaPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
|
||||
disableUnless(verifyBitcodePhase, config.needCompilerVerification || getBoolean(KonanConfigKeys.VERIFY_BITCODE))
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -93,7 +93,7 @@ internal class ClassGlobalHierarchyInfo(val classIdLo: Int, val classIdHi: Int,
|
||||
|
||||
internal class GlobalHierarchyAnalysisResult(val bitsPerColor: Int)
|
||||
|
||||
internal class GlobalHierarchyAnalysis(val context: Context) {
|
||||
internal class GlobalHierarchyAnalysis(val context: Context, val irModule: IrModuleFragment) {
|
||||
fun run() {
|
||||
/*
|
||||
* The algorithm for fast interface call and check:
|
||||
@@ -142,7 +142,7 @@ internal class GlobalHierarchyAnalysis(val context: Context) {
|
||||
val root = context.irBuiltIns.anyClass.owner
|
||||
val immediateInheritors = mutableMapOf<IrClass, MutableList<IrClass>>()
|
||||
val allClasses = mutableListOf<IrClass>()
|
||||
context.irModule!!.acceptVoid(object: IrElementVisitorVoid {
|
||||
irModule.acceptVoid(object: IrElementVisitorVoid {
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
@@ -251,7 +251,7 @@ internal class GlobalHierarchyAnalysis(val context: Context) {
|
||||
}
|
||||
|
||||
private fun assignColorsToInterfaces(): Map<IrClass, Int> {
|
||||
val graph = InterfacesForbiddennessGraph.build(context.irModule!!)
|
||||
val graph = InterfacesForbiddennessGraph.build(irModule)
|
||||
val coloring = graph.computeColoringGreedy()
|
||||
return graph.nodes.mapIndexed { v, irClass -> irClass to coloring[v] }.toMap()
|
||||
}
|
||||
|
||||
+7
-5
@@ -38,11 +38,7 @@ internal val contextLLVMSetupPhase = makeKonanModuleOpPhase(
|
||||
internal val RTTIPhase = makeKonanModuleOpPhase(
|
||||
name = "RTTI",
|
||||
description = "RTTI generation",
|
||||
op = { context, irModule ->
|
||||
if (context.shouldOptimize())
|
||||
GlobalHierarchyAnalysis(context).run()
|
||||
irModule.acceptVoid(RTTIGeneratorVisitor(context))
|
||||
}
|
||||
op = { context, irModule -> irModule.acceptVoid(RTTIGeneratorVisitor(context)) }
|
||||
)
|
||||
|
||||
internal val generateDebugInfoHeaderPhase = makeKonanModuleOpPhase(
|
||||
@@ -82,6 +78,12 @@ internal val devirtualizationPhase = makeKonanModuleOpPhase(
|
||||
}
|
||||
)
|
||||
|
||||
internal val ghaPhase = makeKonanModuleOpPhase(
|
||||
name = "GHAPhase",
|
||||
description = "Global hierarchy analysis",
|
||||
op = { context, irModule -> GlobalHierarchyAnalysis(context, irModule).run() }
|
||||
)
|
||||
|
||||
internal val IrFunction.longName: String
|
||||
get() = "${(parent as? IrClass)?.name?.asString() ?: "<root>"}.${(this as? IrSimpleFunction)?.name ?: "<init>"}"
|
||||
|
||||
|
||||
+1
-1
@@ -779,7 +779,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
|
||||
load(slot)
|
||||
}
|
||||
|
||||
!context.shouldOptimize() -> call(context.llvm.lookupOpenMethodFunction, listOf(typeInfoPtr, methodHash))
|
||||
!context.ghaEnabled() -> call(context.llvm.lookupOpenMethodFunction, listOf(typeInfoPtr, methodHash))
|
||||
|
||||
else -> {
|
||||
// Essentially: typeInfo.itable[place(interfaceId)].vtable[method]
|
||||
|
||||
+1
-1
@@ -1392,7 +1392,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
|
||||
val srcObjInfoPtr = functionGenerationContext.bitcast(codegen.kObjHeaderPtr, obj)
|
||||
|
||||
return if (!context.shouldOptimize()) {
|
||||
return if (!context.ghaEnabled()) {
|
||||
call(context.llvm.isInstanceFunction, listOf(srcObjInfoPtr, codegen.typeInfoValue(dstClass)))
|
||||
} else {
|
||||
val dstHierarchyInfo = context.getLayoutBuilder(dstClass).hierarchyInfo
|
||||
|
||||
+4
-4
@@ -225,7 +225,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
val reflectionInfo = getReflectionInfo(irClass)
|
||||
val typeInfoGlobal = llvmDeclarations.typeInfoGlobal
|
||||
val hierarchyInfo =
|
||||
if (context.shouldOptimize())
|
||||
if (context.ghaEnabled())
|
||||
context.getLayoutBuilder(irClass).hierarchyInfo
|
||||
else ClassGlobalHierarchyInfo.DUMMY
|
||||
val typeInfo = TypeInfo(
|
||||
@@ -302,7 +302,7 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
}
|
||||
|
||||
private fun interfaceTable(irClass: IrClass): Pair<ConstPointer?, Int> {
|
||||
val needInterfaceTable = context.shouldOptimize() && !irClass.isInterface
|
||||
val needInterfaceTable = context.ghaEnabled() && !irClass.isInterface
|
||||
&& !irClass.isAbstract() && !irClass.isObjCClass()
|
||||
if (!needInterfaceTable) return Pair(null, 0)
|
||||
// The details are in ClassLayoutBuilder.
|
||||
@@ -484,12 +484,12 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
|
||||
val typeInfoWithVtableType = structType(runtime.typeInfoType, vtable.llvmType)
|
||||
val typeInfoWithVtableGlobal = staticData.createGlobal(typeInfoWithVtableType, "", isExported = false)
|
||||
val result = typeInfoWithVtableGlobal.pointer.getElementPtr(0)
|
||||
val typeHierarchyInfo = if (!context.shouldOptimize())
|
||||
val typeHierarchyInfo = if (!context.ghaEnabled())
|
||||
ClassGlobalHierarchyInfo.DUMMY
|
||||
else
|
||||
ClassGlobalHierarchyInfo(-1, -1, 0, 0)
|
||||
|
||||
val interfaceTable = if (!context.shouldOptimize()) null else {
|
||||
val interfaceTable = if (!context.ghaEnabled()) null else {
|
||||
val layoutBuilder = context.getLayoutBuilder(irClass)
|
||||
val vtableEntries = layoutBuilder.interfaceTableEntries.map { methodImpls[it]!!.bitcast(int8TypePtr) }
|
||||
val interfaceVTable = staticData.placeGlobalArray("", kInt8Ptr, vtableEntries)
|
||||
|
||||
+1
-1
@@ -932,7 +932,7 @@ private fun ObjCExportCodeGenerator.vtableIndex(irFunction: IrSimpleFunction): I
|
||||
private fun ObjCExportCodeGenerator.itablePlace(irFunction: IrSimpleFunction): ClassLayoutBuilder.InterfaceTablePlace? {
|
||||
assert(irFunction.isOverridable)
|
||||
val irClass = irFunction.parentAsClass
|
||||
return if (irClass.isInterface && context.shouldOptimize()
|
||||
return if (irClass.isInterface && context.ghaEnabled()
|
||||
&& (irFunction.isReal || irFunction.resolveFakeOverrideMaybeAbstract().parent != context.irBuiltIns.anyClass.owner)) {
|
||||
context.getLayoutBuilder(irClass).itablePlace(irFunction)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user