From df97ef75c9741d00276da7e2ec9fd31c5e41e27c Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Thu, 22 Feb 2018 19:14:42 +0300 Subject: [PATCH] Fixed bug in devirtualization All final return types of external functions are instantiated --- .../konan/optimizations/Devirtualization.kt | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/Devirtualization.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/Devirtualization.kt index 70821413e65..8f3b341e8cd 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/Devirtualization.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/Devirtualization.kt @@ -246,7 +246,7 @@ internal object Devirtualization { .forEach { addInstantiatingClass(it) } } // Traverse call graph from the roots. - rootSet.forEach { dfs(it) } + rootSet.forEach { dfs(it, functions[it]!!.returnType) } return instantiatingClasses } @@ -275,7 +275,7 @@ internal object Devirtualization { else -> error("Unreachable") } - dfs(callee) + dfs(callee, virtualCall.returnType) } private fun checkSupertypes(type: DataFlowIR.Type.Declared, @@ -310,12 +310,19 @@ internal object Devirtualization { .forEach { checkSupertypes(it, inheritor, seenTypes) } } - private fun dfs(symbol: DataFlowIR.FunctionSymbol) { + private fun dfs(symbol: DataFlowIR.FunctionSymbol, returnType: DataFlowIR.Type) { val resolvedFunctionSymbol = symbol.resolved() if (resolvedFunctionSymbol is DataFlowIR.FunctionSymbol.External) { DEBUG_OUTPUT(1) { println("Function $resolvedFunctionSymbol is external") } + val resolvedReturnType = returnType.resolved() + if (resolvedReturnType.isFinal) { + + DEBUG_OUTPUT(1) { println("Adding return type as it is final") } + + addInstantiatingClass(resolvedReturnType) + } return } if (!visited.add(resolvedFunctionSymbol)) return @@ -330,17 +337,18 @@ internal object Devirtualization { when (node) { is DataFlowIR.Node.NewObject -> { addInstantiatingClass(node.returnType) - dfs(node.callee) + dfs(node.callee, node.returnType) } is DataFlowIR.Node.Singleton -> { addInstantiatingClass(node.type) - node.constructor?.let { dfs(it) } + node.constructor?.let { dfs(it, node.type) } } is DataFlowIR.Node.Const -> addInstantiatingClass(node.type) - is DataFlowIR.Node.StaticCall -> dfs(node.callee) + is DataFlowIR.Node.StaticCall -> + dfs(node.callee, node.returnType) is DataFlowIR.Node.VirtualCall -> { if (node.receiverType == DataFlowIR.Type.Virtual)