Added Global hierarchy analysis phase

This commit is contained in:
Igor Chevdar
2019-09-24 13:57:36 +03:00
committed by Igor Chevdar
parent 2195687f63
commit afe9f07cbc
8 changed files with 20 additions and 15 deletions
@@ -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
@@ -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))
}
}
@@ -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()
}
@@ -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>"}"
@@ -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]
@@ -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
@@ -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)
@@ -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 {