Made handling of inconsistent DFG layout softer

Turn off devirtualization and report a warning instead of crashing.
This commit is contained in:
Igor Chevdar
2018-08-08 17:07:54 +03:00
parent 562c1f3961
commit bcbcaa5d7c
2 changed files with 36 additions and 29 deletions
@@ -86,37 +86,41 @@ internal fun emitLLVM(context: Context, phaser: PhaseManager) {
@Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE") @Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
var devirtualizationAnalysisResult: Devirtualization.AnalysisResult? = null var devirtualizationAnalysisResult: Devirtualization.AnalysisResult? = null
phaser.phase(KonanPhase.DEVIRTUALIZATION) { phaser.phase(KonanPhase.DEVIRTUALIZATION) {
devirtualizationAnalysisResult = Devirtualization.run(irModule, context, moduleDFG!!, externalModulesDFG!!) externalModulesDFG?.let { externalModulesDFG ->
devirtualizationAnalysisResult = Devirtualization.run(irModule, context, moduleDFG!!, externalModulesDFG)
val privateFunctions = moduleDFG!!.symbolTable.getPrivateFunctionsTableForExport() val privateFunctions = moduleDFG!!.symbolTable.getPrivateFunctionsTableForExport()
privateFunctions.forEachIndexed { index, it -> privateFunctions.forEachIndexed { index, it ->
val function = codegenVisitor.codegen.llvmFunction(it.first) val function = codegenVisitor.codegen.llvmFunction(it.first)
LLVMAddAlias( LLVMAddAlias(
context.llvmModule, context.llvmModule,
function.type, function.type,
function, function,
irModule.descriptor.privateFunctionSymbolName(index, it.second.name) irModule.descriptor.privateFunctionSymbolName(index, it.second.name)
)!! )!!
}
context.privateFunctions = privateFunctions
val privateClasses = moduleDFG!!.symbolTable.getPrivateClassesTableForExport()
privateClasses.forEachIndexed { index, it ->
val typeInfoPtr = codegenVisitor.codegen.typeInfoValue(it.first)
LLVMAddAlias(
context.llvmModule,
typeInfoPtr.type,
typeInfoPtr,
irModule.descriptor.privateClassSymbolName(index, it.second.name)
)!!
}
context.privateClasses = privateClasses
} }
context.privateFunctions = privateFunctions
val privateClasses = moduleDFG!!.symbolTable.getPrivateClassesTableForExport()
privateClasses.forEachIndexed { index, it ->
val typeInfoPtr = codegenVisitor.codegen.typeInfoValue(it.first)
LLVMAddAlias(
context.llvmModule,
typeInfoPtr.type,
typeInfoPtr,
irModule.descriptor.privateClassSymbolName(index, it.second.name)
)!!
}
context.privateClasses = privateClasses
} }
phaser.phase(KonanPhase.ESCAPE_ANALYSIS) { phaser.phase(KonanPhase.ESCAPE_ANALYSIS) {
val callGraph = CallGraphBuilder(context, moduleDFG!!, externalModulesDFG!!, devirtualizationAnalysisResult, false).build() externalModulesDFG?.let { externalModulesDFG ->
EscapeAnalysis.computeLifetimes(context, moduleDFG!!, externalModulesDFG!!, callGraph, lifetimes) val callGraph = CallGraphBuilder(context, moduleDFG!!, externalModulesDFG, devirtualizationAnalysisResult, false).build()
EscapeAnalysis.computeLifetimes(context, moduleDFG!!, externalModulesDFG, callGraph, lifetimes)
}
} }
phaser.phase(KonanPhase.SERIALIZE_DFG) { phaser.phase(KonanPhase.SERIALIZE_DFG) {
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.backend.konan.optimizations package org.jetbrains.kotlin.backend.konan.optimizations
import org.jetbrains.kotlin.backend.common.reportWarning
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.PrimitiveBinaryType import org.jetbrains.kotlin.backend.konan.PrimitiveBinaryType
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
@@ -929,7 +930,7 @@ internal object DFGSerializer {
} }
// TODO: Deserialize functions bodies lazily. // TODO: Deserialize functions bodies lazily.
fun deserialize(context: Context, startPrivateTypeIndex: Int, startPrivateFunIndex: Int): ExternalModulesDFG { fun deserialize(context: Context, startPrivateTypeIndex: Int, startPrivateFunIndex: Int): ExternalModulesDFG? {
var privateTypeIndex = startPrivateTypeIndex var privateTypeIndex = startPrivateTypeIndex
var privateFunIndex = startPrivateFunIndex var privateFunIndex = startPrivateFunIndex
val publicTypesMap = mutableMapOf<Long, DataFlowIR.Type.Public>() val publicTypesMap = mutableMapOf<Long, DataFlowIR.Type.Public>()
@@ -949,8 +950,10 @@ internal object DFGSerializer {
val reader = ArraySlice(libraryDataFlowGraph) val reader = ArraySlice(libraryDataFlowGraph)
val dataLayoutHash = reader.readLong() val dataLayoutHash = reader.readLong()
val expectedHash = computeDataLayoutHash(Module::class) val expectedHash = computeDataLayoutHash(Module::class)
if (dataLayoutHash != expectedHash) if (dataLayoutHash != expectedHash) {
error("Expected data layout hash: $expectedHash but actual is: $dataLayoutHash") context.report(null, null, "Expected data layout hash: $expectedHash but actual is: $dataLayoutHash", false)
return null
}
val moduleDataFlowGraph = Module(reader) val moduleDataFlowGraph = Module(reader)
val symbolTable = moduleDataFlowGraph.symbolTable val symbolTable = moduleDataFlowGraph.symbolTable