diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt index 6d8639475d9..2505bbe74bc 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/CoroutineTransformerMethodVisitor.kt @@ -573,11 +573,9 @@ class CoroutineTransformerMethodVisitor( return false } - val starts = methodNode.instructions.asSequence().filter { - isBeforeSuspendMarker(it) && - cfg.getPredecessorsIndices(it).isNotEmpty() // Ignore unreachable start markers - }.toList() - return starts.mapNotNull { start -> + return methodNode.instructions.asSequence().filter { + isBeforeSuspendMarker(it) + }.mapNotNull { start -> val ends = mutableSetOf() if (collectSuspensionPointEnds(start, mutableSetOf(), ends)) return@mapNotNull null // Ignore suspension points, if the suspension call begin is alive and suspension call end is dead @@ -586,7 +584,7 @@ class CoroutineTransformerMethodVisitor( // this is an exit point for the corresponding coroutine. val end = ends.find { isAfterSuspendMarker(it) } ?: return@mapNotNull null SuspensionPoint(start.previous, end) - } + }.toList() } private fun dropSuspensionMarkers(methodNode: MethodNode) { @@ -983,7 +981,7 @@ private class MethodNodeExaminer( val typedFrames = basicAnalyser.frames val isReferenceMap = popsBeforeSafeUnitInstances - .map { it to (!isUnreachable(it.index(), sourceFrames) && typedFrames[it.index()]?.top()?.isReference == true) } + .map { it to (typedFrames[it.index()]?.top()?.isReference == true) } .toMap() for (pop in popsBeforeSafeUnitInstances) { @@ -1008,8 +1006,6 @@ private class MethodNodeExaminer( val beginIndex = instructions.indexOf(suspensionPoint.suspensionCallBegin) val endIndex = instructions.indexOf(suspensionPoint.suspensionCallEnd) - if (isUnreachable(endIndex, sourceFrames)) return@all true - val insideTryBlock = methodNode.tryCatchBlocks.any { block -> val tryBlockStartIndex = instructions.indexOf(block.start) val tryBlockEndIndex = instructions.indexOf(block.end) @@ -1043,7 +1039,6 @@ private class MethodNodeExaminer( val insn = insns[index] if (insn.opcode == Opcodes.ARETURN && !insn.isAreturnAfterSafeUnitInstance()) { - if (isUnreachable(index, sourceFrames)) return@init null return@init setOf(index) } @@ -1215,10 +1210,6 @@ internal class IgnoringCopyOperationSourceInterpreter : SourceInterpreter(Opcode override fun copyOperation(insn: AbstractInsnNode?, value: SourceValue?) = value } -// Check whether this instruction is unreachable, i.e. there is no path leading to this instruction -internal fun isUnreachable(index: Int, sourceFrames: Array?>): Boolean = - sourceFrames.size <= index || sourceFrames[index] == null - private fun AbstractInsnNode?.isInvisibleInDebugVarInsn(methodNode: MethodNode): Boolean { val insns = methodNode.instructions val index = insns.indexOf(this) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt index 36a03e2db76..564c9ab333a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt @@ -121,6 +121,16 @@ internal class RedundantLocalsEliminationMethodTransformer(private val suspensio } } + // Remove unreachable instructions to simplify further analyses + for (index in frames.indices) { + if (frames[index] == null) { + val insn = methodNode.instructions[index] + if (insn !is LabelNode) { + toDelete.add(insn) + } + } + } + methodNode.instructions.removeAll(toDelete) }