diff --git a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/FunctionGenerator.kt b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/FunctionGenerator.kt index d1cce279f01..b7f04b3a7f8 100644 --- a/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/FunctionGenerator.kt +++ b/compiler/ir/ir.ir2cfg/src/org/jetbrains/kotlin/ir2cfg/generators/FunctionGenerator.kt @@ -126,6 +126,23 @@ class FunctionGenerator(val function: IrFunction) { return whenExit } + override fun visitWhileLoop(loop: IrWhileLoop, data: Boolean): IrElement? { + if (data) { + builder.add(loop) + } + val entry = MergeCfgElement(loop, "While entry") + builder.jump(entry) + val condition = loop.condition + condition.process(includeSelf = false) + builder.jump(condition) + val body = loop.body + if (!body?.process().isNothing()) { + builder.jump(entry) + } + builder.move(condition) + return condition + } + override fun visitElement(element: IrElement, data: Boolean): IrElement? { TODO("not implemented") } diff --git a/compiler/testData/ir/irCfg/loop/factorial.kt b/compiler/testData/ir/irCfg/loop/factorial.kt new file mode 100644 index 00000000000..b3ed56563ab --- /dev/null +++ b/compiler/testData/ir/irCfg/loop/factorial.kt @@ -0,0 +1,7 @@ +fun factorial(i: Int): Int { + var result = 1 + for (j in 2..i) { + result *= j + } + return result +} \ No newline at end of file diff --git a/compiler/testData/ir/irCfg/loop/factorial.txt b/compiler/testData/ir/irCfg/loop/factorial.txt new file mode 100644 index 00000000000..db484e902e9 --- /dev/null +++ b/compiler/testData/ir/irCfg/loop/factorial.txt @@ -0,0 +1,40 @@ +// FILE: /factorial.kt +// FUN: factorial +BB 0 +CONTENT + 1 FUN public fun factorial(i: kotlin.Int): kotlin.Int + 2 CONST Int type=kotlin.Int value='1' + 3 VAR var result: kotlin.Int + 4 CALL 'iterator(): IntIterator' type=kotlin.collections.IntIterator origin=FOR_LOOP_ITERATOR + 5 VAR IR_TEMPORARY_VARIABLE val tmp0_iterator: kotlin.collections.IntIterator + 6 WHILE label=null origin=FOR_LOOP_INNER_WHILE +OUTGOING -> BB 1 + While entry: WHILE label=null origin=FOR_LOOP_INNER_WHILE +BB 1 +INCOMING <- BB 0, 2 + While entry: WHILE label=null origin=FOR_LOOP_INNER_WHILE +CONTENT +OUTGOING -> BB 2, 3 + CALL 'hasNext(): Boolean' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT +BB 2 +INCOMING <- BB 1 + CALL 'hasNext(): Boolean' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT +CONTENT + 1 CALL 'next(): Int' type=kotlin.Int origin=FOR_LOOP_NEXT + 2 VAR val j: kotlin.Int + 3 SET_VAR 'result: Int' type=kotlin.Unit origin=MULTEQ +OUTGOING -> BB 1 + While entry: WHILE label=null origin=FOR_LOOP_INNER_WHILE +BB 3 +INCOMING <- BB 1 + CALL 'hasNext(): Boolean' type=kotlin.Boolean origin=FOR_LOOP_HAS_NEXT +CONTENT + 1 GET_VAR 'result: Int' type=kotlin.Int origin=null + 2 RETURN type=kotlin.Nothing from='factorial(Int): Int' +OUTGOING -> NONE + Function exit: FUN public fun factorial(i: kotlin.Int): kotlin.Int + +// END FUN: factorial + +// END FILE: /factorial.kt + diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrCfgTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrCfgTestCaseGenerated.java index 0c46977f6fd..7b804912345 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrCfgTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrCfgTestCaseGenerated.java @@ -71,6 +71,21 @@ public class IrCfgTestCaseGenerated extends AbstractIrCfgTestCase { doTest(fileName); } + @TestMetadata("compiler/testData/ir/irCfg/loop") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Loop extends AbstractIrCfgTestCase { + public void testAllFilesPresentInLoop() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/ir/irCfg/loop"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("factorial.kt") + public void testFactorial() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irCfg/loop/factorial.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/ir/irCfg/when") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)