From 96a2da490616902e73b2a7b575b2e9eaa04546bb Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Tue, 19 Sep 2023 13:22:40 +0200 Subject: [PATCH] [JVM] Split `mergeControlFlowEdge` into `full` and `fast` versions This is needed because for `FastStackAnalyzer` we actually will use only `fast` version, that can potentially improve overall performance. --- .../optimization/common/FastAnalyzer.kt | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastAnalyzer.kt index c995eb27d88..a1e763ab56d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastAnalyzer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastAnalyzer.kt @@ -209,12 +209,20 @@ abstract class FastAnalyzer>( } } + private fun mergeControlFlowEdge(dest: Int, frame: F, canReuse: Boolean = false) { + if (useFastMergeControlFlowEdge) { + fastMergeControlFlowEdge(dest, frame, canReuse) + } else { + fullMergeControlFlowEdge(dest, frame, canReuse) + } + } + /** * Updates frame at the index [dest] with its old value if provided and previous control flow node frame [frame]. * Reuses old frame when possible and when [canReuse] is true. * If updated, adds the frame to the queue */ - private fun mergeControlFlowEdge(dest: Int, frame: F, canReuse: Boolean = false) { + private fun fullMergeControlFlowEdge(dest: Int, frame: F, canReuse: Boolean = false) { val oldFrame = frames[dest] val changes = when { canReuse && !isMergeNode[dest] -> { @@ -229,12 +237,26 @@ abstract class FastAnalyzer>( oldFrame.init(frame) true } - !useFastMergeControlFlowEdge -> - try { - oldFrame.merge(frame, interpreter) - } catch (e: AnalyzerException) { - throw AnalyzerException(null, "${e.message}\nframe: ${frame.dump()}\noldFrame: ${oldFrame.dump()}") + else -> try { + oldFrame.merge(frame, interpreter) + } catch (e: AnalyzerException) { + throw AnalyzerException(null, "${e.message}\nframe: ${frame.dump()}\noldFrame: ${oldFrame.dump()}") + } + } + updateQueue(changes, dest) + } + + private fun fastMergeControlFlowEdge(dest: Int, frame: F, canReuse: Boolean) { + val oldFrame = frames[dest] + val changes = when { + oldFrame == null -> { + frames[dest] = if (canReuse && !isMergeNode[dest]) { + frame + } else { + newFrame(frame.locals, frame.maxStackSize).apply { init(frame) } } + true + } else -> false } updateQueue(changes, dest)