From 6381f9b86daa3393e706304e33ce7840d18bdabf Mon Sep 17 00:00:00 2001 From: dibyendumajumdar Date: 2025年3月30日 10:39:36 +0100 Subject: [PATCH 1/2] Bug fix - incorrect frame size calculation --- .../ezlang/compiler/ChaitinGraphColoringRegisterAllocator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/ChaitinGraphColoringRegisterAllocator.java b/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/ChaitinGraphColoringRegisterAllocator.java index a2a4840..93183b9 100644 --- a/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/ChaitinGraphColoringRegisterAllocator.java +++ b/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/ChaitinGraphColoringRegisterAllocator.java @@ -45,7 +45,7 @@ public Map assignRegisters(CompiledFunction function, int numR * Frame size = max number of registers needed to execute the function */ private int computeFrameSize(Map assignments) { - return assignments.values().stream().mapToInt(k->k).max().orElse(0); + return assignments.values().stream().mapToInt(k->k).max().orElse(-1)+1; } /** From ddb5e2ce942b8fec198343616744920aefcdfd24 Mon Sep 17 00:00:00 2001 From: dibyendumajumdar Date: 2025年3月30日 18:39:01 +0100 Subject: [PATCH 2/2] #16 Do a liveness check before inserting a phi --- .../ezlang/compiler/CompiledFunction.java | 2 +- .../ezlang/compiler/EnterSSA.java | 17 +- .../ezlang/compiler/TestIncrementalSSA.java | 149 +++++++ .../ezlang/compiler/TestSSATransform.java | 376 +++++++++++++----- .../ezlang/interpreter/TestInterpreter.java | 88 ++++ 5 files changed, 520 insertions(+), 112 deletions(-) diff --git a/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java b/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java index 19a4818..48526e6 100644 --- a/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java +++ b/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java @@ -17,7 +17,7 @@ public class CompiledFunction { public BasicBlock currentBlock; private BasicBlock currentBreakTarget; private BasicBlock currentContinueTarget; - private Type.TypeFunction functionType; + public Type.TypeFunction functionType; public final RegisterPool registerPool; private final TypeDictionary typeDictionary; diff --git a/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/EnterSSA.java b/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/EnterSSA.java index fc1d275..83e7c24 100644 --- a/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/EnterSSA.java +++ b/optvm/src/main/java/com/compilerprogramming/ezlang/compiler/EnterSSA.java @@ -43,6 +43,7 @@ public EnterSSA(CompiledFunction bytecodeFunction, EnumSet options) { } this.blocks = domTree.blocks; // the blocks are ordered reverse post order findNonLocalNames(); + new Liveness(bytecodeFunction); // EWe require liveness info to construct pruned ssa insertPhis(); renameVars(); bytecodeFunction.isSSA = true; @@ -94,12 +95,16 @@ void insertPhis() { while (b != null) { visited.set(b.bid); for (BasicBlock d: b.dominationFrontier) { - if (d == function.exit) // The exit block does not need any phis as it has no instructions - continue; - // insert phi for x in d - d.insertPhiFor(x); - if (!visited.get(d.bid)) - worklist.push(d); + // Perform a liveness check to avoid inserting + // phi when variable is dead + // Inserting dead phis causes problems during renaming + // because there will not be a definition available + if (d.liveIn.contains(x)) { + // insert phi for x in d + d.insertPhiFor(x); + if (!visited.get(d.bid)) + worklist.push(d); + } } b = worklist.pop(); } diff --git a/optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestIncrementalSSA.java b/optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestIncrementalSSA.java index 546425d..e4f9b93 100644 --- a/optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestIncrementalSSA.java +++ b/optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestIncrementalSSA.java @@ -520,5 +520,154 @@ func foo(x: Int,y: Int)->Int """, result); } + @Test + public void testSSA10() { + String src = """ + func main()->Int { + var sum = 0 + var i = 0 + var j = 0 + while (i < 5) { + j = 0 + while (j < 5) { + if (j % 2 == 0) + sum = sum + j + j = j + 1 + } + i = i + 1 + } + return sum + } +"""; + String result = compileSrc(src); + Assert.assertEquals(""" +func main()->Int +Reg #0 sum 0 +Reg #1 i 1 +Reg #2 j 2 +Reg #3 %t3 3 +Reg #4 i_1 1 +Reg #5 j_1 2 +Reg #6 %t6 6 +Reg #7 j_2 2 +Reg #8 %t8 8 +Reg #9 %t9 9 +Reg #10 %t10 10 +Reg #11 sum_1 0 +Reg #12 sum_2 0 +Reg #13 %t13 13 +Reg #14 j_3 2 +Reg #15 j_4 2 +Reg #16 sum_3 0 +Reg #17 sum_4 0 +Reg #18 %t18 18 +Reg #19 i_2 1 +Reg #20 i_3 1 +Reg #21 i_4 1 +L0: + sum = 0 + i = 0 + j = 0 + goto L2 +L2: + sum_3 = phi(sum, sum_1) + i_1 = phi(i, i_4) + %t3 = i_1<5 + if %t3 goto L3 else goto L4 +L3: + j_1 = 0 + goto L5 +L5: + sum_1 = phi(sum_3, sum_4) + j_2 = phi(j_1, j_4) + %t6 = j_2<5 + if %t6 goto L6 else goto L7 +L6: + %t8 = j_2%2 + %t9 = %t8==0 + if %t9 goto L8 else goto L9 +L8: + %t10 = sum_1+j_2 + sum_2 = %t10 + goto L9 +L9: + sum_4 = phi(sum_1, sum_2) + %t13 = j_2+1 + j_4 = %t13 + goto L5 +L7: + %t18 = i_1+1 + i_4 = %t18 + goto L2 +L4: + ret sum_3 + goto L1 +L1: +""", result); + } + + @Test + public void testSSA17() { + String src = """ +func merge(begin: Int, middle: Int, end: Int) +{ + if (begin < end) { + var cond = 0 + if (begin < middle) { + if (begin>= end) cond = 1; + } + if (cond) + { + cond = 0 + } + } +} +"""; + String result = compileSrc(src); + Assert.assertEquals(""" +func merge(begin: Int,middle: Int,end: Int) +Reg #0 begin 0 +Reg #1 middle 1 +Reg #2 end 2 +Reg #3 cond 3 +Reg #4 %t4 4 +Reg #5 %t5 5 +Reg #6 %t6 6 +Reg #7 cond_1 3 +Reg #8 cond_2 3 +Reg #9 cond_3 3 +Reg #10 cond_4 3 +L0: + arg begin + arg middle + arg end + %t4 = begin=end + if %t6 goto L6 else goto L7 +L6: + cond_1 = 1 + goto L7 +L7: + cond_3 = phi(cond, cond_1) + goto L5 +L5: + cond_2 = phi(cond, cond_3) + if cond_2 goto L8 else goto L9 +L8: + cond_4 = 0 + goto L9 +L9: + goto L3 +L3: + goto L1 +L1: +""", result); + } } \ No newline at end of file diff --git a/optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestSSATransform.java b/optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestSSATransform.java index a605c93..c8b5d6a 100644 --- a/optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestSSATransform.java +++ b/optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestSSATransform.java @@ -462,10 +462,6 @@ func example14_66(p: Int, q: Int, r: Int, s: Int, t: Int) { L18: goto L4 L4: - l_10 = phi(l_1, l_9) - k_5 = phi(k_1, k_4) - j_4 = phi(j_1, j_3) - i_3 = phi(i_1, i_2) goto L1 L1: L19: @@ -497,10 +493,6 @@ func example14_66(p: Int, q: Int, r: Int, s: Int, t: Int) { i_1 = i_0 goto L2 L2: - l_10 = l_1 - k_5 = k_1 - j_4 = j_1 - i_3 = i_1 if 1 goto L3 else goto L4 L3: if p_0 goto L5 else goto L6 @@ -549,10 +541,6 @@ func example14_66(p: Int, q: Int, r: Int, s: Int, t: Int) { %t18_0 = !t_0 if %t18_0 goto L18 else goto L19 L18: - l_10 = l_9 - k_5 = k_4 - j_4 = j_3 - i_3 = i_2 goto L4 L4: goto L1 @@ -803,7 +791,6 @@ func foo()->Int { } @Test - @Ignore public void testInit() { // see issue #16 String src = """ @@ -818,7 +805,81 @@ func foo(x: Int) { } """; String result = compileSrc(src); - System.out.println(result); + Assert.assertEquals(""" +func foo +Before SSA +========== +L0: + arg x + goto L2 +L2: + %t2 = x>0 + if %t2 goto L3 else goto L4 +L3: + z = 5 + %t3 = x==1 + if %t3 goto L5 else goto L6 +L5: + %t4 = z+1 + z = %t4 + goto L6 +L6: + %t5 = x-1 + x = %t5 + goto L2 +L4: + goto L1 +L1: +After SSA +========= +L0: + arg x_0 + goto L2 +L2: + x_1 = phi(x_0, x_2) + %t2_0 = x_1>0 + if %t2_0 goto L3 else goto L4 +L3: + z_0 = 5 + %t3_0 = x_1==1 + if %t3_0 goto L5 else goto L6 +L5: + %t4_0 = z_0+1 + z_1 = %t4_0 + goto L6 +L6: + %t5_0 = x_1-1 + x_2 = %t5_0 + goto L2 +L4: + goto L1 +L1: +After exiting SSA +================= +L0: + arg x_0 + x_1 = x_0 + goto L2 +L2: + %t2_0 = x_1>0 + if %t2_0 goto L3 else goto L4 +L3: + z_0 = 5 + %t3_0 = x_1==1 + if %t3_0 goto L5 else goto L6 +L5: + %t4_0 = z_0+1 + z_1 = %t4_0 + goto L6 +L6: + %t5_0 = x_1-1 + x_2 = %t5_0 + x_1 = x_2 + goto L2 +L4: + goto L1 +L1: +""", result); } // http://users.csc.calpoly.edu/~akeen/courses/csc431/handouts/references/ssa_example.pdf @@ -1897,24 +1958,23 @@ func main()->Int { j_0 = 0 goto L2 L2: - j_1 = phi(j_0, j_2) i_1 = phi(i_0, i_3) b_1 = phi(b_0, b_2) a_1 = phi(a_0, a_2) %t4_0 = i_1<3 if %t4_0 goto L3 else goto L4 L3: - j_2 = 0 + j_1 = 0 goto L5 L5: i_2 = phi(i_1, i_4) a_2 = phi(a_1, a_3) - %t5_0 = j_2<2 + %t5_0 = j_1<2 if %t5_0 goto L6 else goto L7 L6: %t6_0 = a_2+1 a_3 = %t6_0 - %t7_0 = j_2+1 + %t7_0 = j_1+1 i_4 = %t7_0 goto L5 L7: @@ -1935,7 +1995,6 @@ func main()->Int { b_0 = 0 i_0 = 0 j_0 = 0 - j_1 = j_0 i_1 = i_0 b_1 = b_0 a_1 = a_0 @@ -1944,17 +2003,17 @@ func main()->Int { %t4_0 = i_1<3 if %t4_0 goto L3 else goto L4 L3: - j_2 = 0 + j_1 = 0 i_2 = i_1 a_2 = a_1 goto L5 L5: - %t5_0 = j_2<2 + %t5_0 = j_1<2 if %t5_0 goto L6 else goto L7 L6: %t6_0 = a_2+1 a_3 = %t6_0 - %t7_0 = j_2+1 + %t7_0 = j_1+1 i_4 = %t7_0 i_2 = i_4 a_2 = a_3 @@ -1964,7 +2023,6 @@ func main()->Int { b_2 = %t8_0 %t9_0 = i_2+1 i_3 = %t9_0 - j_1 = j_2 i_1 = i_3 b_1 = b_2 a_1 = a_2 @@ -2043,31 +2101,30 @@ func main()->Int { j_0 = 0 goto L2 L2: - j_1 = phi(j_0, j_3) i_1 = phi(i_0, i_2) sum_1 = phi(sum_0, sum_2) %t3_0 = i_1<5 if %t3_0 goto L3 else goto L4 L3: - j_2 = 0 + j_1 = 0 goto L5 L5: - j_3 = phi(j_2, j_4) + j_2 = phi(j_1, j_3) sum_2 = phi(sum_1, sum_4) - %t4_0 = j_3<5 + %t4_0 = j_2<5 if %t4_0 goto L6 else goto L7 L6: - %t5_0 = j_3%2 + %t5_0 = j_2%2 %t6_0 = %t5_0==0 if %t6_0 goto L8 else goto L9 L8: - %t7_0 = sum_2+j_3 + %t7_0 = sum_2+j_2 sum_3 = %t7_0 goto L9 L9: sum_4 = phi(sum_2, sum_3) - %t8_0 = j_3+1 - j_4 = %t8_0 + %t8_0 = j_2+1 + j_3 = %t8_0 goto L5 L7: %t9_0 = i_1+1 @@ -2083,7 +2140,6 @@ func main()->Int { sum_0 = 0 i_0 = 0 j_0 = 0 - j_1 = j_0 i_1 = i_0 sum_1 = sum_0 goto L2 @@ -2091,33 +2147,32 @@ func main()->Int { %t3_0 = i_1<5 if %t3_0 goto L3 else goto L4 L3: - j_2 = 0 - j_3 = j_2 + j_1 = 0 + j_2 = j_1 sum_2 = sum_1 goto L5 L5: - %t4_0 = j_3<5 + %t4_0 = j_2<5 if %t4_0 goto L6 else goto L7 L6: - %t5_0 = j_3%2 + %t5_0 = j_2%2 %t6_0 = %t5_0==0 sum_4 = sum_2 if %t6_0 goto L8 else goto L9 L8: - %t7_0 = sum_2+j_3 + %t7_0 = sum_2+j_2 sum_3 = %t7_0 sum_4 = sum_3 goto L9 L9: - %t8_0 = j_3+1 - j_4 = %t8_0 - j_3 = j_4 + %t8_0 = j_2+1 + j_3 = %t8_0 + j_2 = j_3 sum_2 = sum_4 goto L5 L7: %t9_0 = i_1+1 i_2 = %t9_0 - j_1 = j_3 i_1 = i_2 sum_1 = sum_2 goto L2 @@ -2205,34 +2260,33 @@ else if (i> j) j_0 = 0 goto L2 L2: - j_1 = phi(j_0, j_3) i_1 = phi(i_0, i_2) a_1 = phi(a_0, a_2) %t3_0 = i_1<3 if %t3_0 goto L3 else goto L4 L3: - j_2 = 0 + j_1 = 0 goto L5 L5: - j_3 = phi(j_2, j_4) + j_2 = phi(j_1, j_3) a_2 = phi(a_1, a_6) - %t4_0 = j_3<3 + %t4_0 = j_2<3 if %t4_0 goto L6 else goto L7 L6: - %t5_0 = i_1==j_3 + %t5_0 = i_1==j_2 if %t5_0 goto L8 else goto L9 L8: %t6_0 = a_4+i_1 - %t7_0 = %t6_0+j_3 + %t7_0 = %t6_0+j_2 a_5 = %t7_0 goto L10 L10: a_6 = phi(a_5, a_4) - %t10_0 = j_3+1 - j_4 = %t10_0 + %t10_0 = j_2+1 + j_3 = %t10_0 goto L5 L9: - %t8_0 = i_1>j_3 + %t8_0 = i_1>j_2 if %t8_0 goto L11 else goto L12 L11: %t9_0 = a_2-1 @@ -2255,7 +2309,6 @@ else if (i> j) a_0 = 0 i_0 = 0 j_0 = 0 - j_1 = j_0 i_1 = i_0 a_1 = a_0 goto L2 @@ -2263,30 +2316,30 @@ else if (i> j) %t3_0 = i_1<3 if %t3_0 goto L3 else goto L4 L3: - j_2 = 0 - j_3 = j_2 + j_1 = 0 + j_2 = j_1 a_2 = a_1 goto L5 L5: - %t4_0 = j_3<3 + %t4_0 = j_2<3 if %t4_0 goto L6 else goto L7 L6: - %t5_0 = i_1==j_3 + %t5_0 = i_1==j_2 if %t5_0 goto L8 else goto L9 L8: %t6_0 = a_4+i_1 - %t7_0 = %t6_0+j_3 + %t7_0 = %t6_0+j_2 a_5 = %t7_0 a_6 = a_5 goto L10 L10: - %t10_0 = j_3+1 - j_4 = %t10_0 - j_3 = j_4 + %t10_0 = j_2+1 + j_3 = %t10_0 + j_2 = j_3 a_2 = a_6 goto L5 L9: - %t8_0 = i_1>j_3 + %t8_0 = i_1>j_2 a_4 = a_2 if %t8_0 goto L11 else goto L12 L11: @@ -2300,7 +2353,6 @@ else if (i> j) L7: %t11_0 = i_1+1 i_2 = %t11_0 - j_1 = j_3 i_1 = i_2 a_1 = a_2 goto L2 @@ -2389,21 +2441,20 @@ func main()->Int { j_0 = 0 goto L2 L2: - j_1 = phi(j_0, j_3) i_1 = phi(i_0, i_2) count_1 = phi(count_0, count_2) %t3_0 = i_1<5 if %t3_0 goto L3 else goto L4 L3: - j_2 = 0 + j_1 = 0 goto L5 L5: - j_3 = phi(j_2, j_5, j_4) + j_2 = phi(j_1, j_4, j_3) count_2 = phi(count_1, count_2, count_3) - %t4_0 = j_3<5 + %t4_0 = j_2<5 if %t4_0 goto L6 else goto L7 L6: - %t5_0 = i_1+j_3 + %t5_0 = i_1+j_2 %t6_0 = %t5_0>5 if %t6_0 goto L8 else goto L9 L8: @@ -2413,17 +2464,17 @@ func main()->Int { i_2 = %t11_0 goto L2 L9: - %t7_0 = i_1==j_3 + %t7_0 = i_1==j_2 if %t7_0 goto L10 else goto L11 L10: - %t8_0 = j_3+1 - j_5 = %t8_0 + %t8_0 = j_2+1 + j_4 = %t8_0 goto L5 L11: %t9_0 = count_2+1 count_3 = %t9_0 - %t10_0 = j_3+1 - j_4 = %t10_0 + %t10_0 = j_2+1 + j_3 = %t10_0 goto L5 L4: ret count_1 @@ -2435,7 +2486,6 @@ func main()->Int { count_0 = 0 i_0 = 0 j_0 = 0 - j_1 = j_0 i_1 = i_0 count_1 = count_0 goto L2 @@ -2443,16 +2493,16 @@ func main()->Int { %t3_0 = i_1<5 if %t3_0 goto L3 else goto L4 L3: - j_2 = 0 - j_3 = j_2 + j_1 = 0 + j_2 = j_1 count_2 = count_1 goto L5 L5: - count_2_35 = count_2 - %t4_0 = j_3<5 + count_2_34 = count_2 + %t4_0 = j_2<5 if %t4_0 goto L6 else goto L7 L6: - %t5_0 = i_1+j_3 + %t5_0 = i_1+j_2 %t6_0 = %t5_0>5 if %t6_0 goto L8 else goto L9 L8: @@ -2460,26 +2510,25 @@ func main()->Int { L7: %t11_0 = i_1+1 i_2 = %t11_0 - j_1 = j_3 i_1 = i_2 count_1 = count_2 goto L2 L9: - %t7_0 = i_1==j_3 + %t7_0 = i_1==j_2 if %t7_0 goto L10 else goto L11 L10: - %t8_0 = j_3+1 - j_5 = %t8_0 - j_3 = j_5 - count_2_34 = count_2 - count_2 = count_2_34 + %t8_0 = j_2+1 + j_4 = %t8_0 + j_2 = j_4 + count_2_33 = count_2 + count_2 = count_2_33 goto L5 L11: %t9_0 = count_2+1 count_3 = %t9_0 - %t10_0 = j_3+1 - j_4 = %t10_0 - j_3 = j_4 + %t10_0 = j_2+1 + j_3 = %t10_0 + j_2 = j_3 count_2 = count_3 goto L5 L4: @@ -2562,33 +2611,32 @@ func main()->Int { j_0 = 0 goto L2 L2: - j_1 = phi(j_0, j_3) i_1 = phi(i_0, i_2) innerSum_1 = phi(innerSum_0, innerSum_2) outerSum_1 = phi(outerSum_0, outerSum_2) %t4_0 = i_1<4 if %t4_0 goto L3 else goto L4 L3: - j_2 = 0 + j_1 = 0 goto L5 L5: - j_3 = phi(j_2, j_4) + j_2 = phi(j_1, j_3) innerSum_2 = phi(innerSum_1, innerSum_4) - %t5_0 = j_3<4 + %t5_0 = j_2<4 if %t5_0 goto L6 else goto L7 L6: - %t6_0 = i_1+j_3 + %t6_0 = i_1+j_2 %t7_0 = %t6_0%2 %t8_0 = %t7_0==0 if %t8_0 goto L8 else goto L9 L8: - %t9_0 = innerSum_2+j_3 + %t9_0 = innerSum_2+j_2 innerSum_3 = %t9_0 goto L9 L9: innerSum_4 = phi(innerSum_2, innerSum_3) - %t10_0 = j_3+1 - j_4 = %t10_0 + %t10_0 = j_2+1 + j_3 = %t10_0 goto L5 L7: %t11_0 = outerSum_1+innerSum_2 @@ -2607,7 +2655,6 @@ func main()->Int { innerSum_0 = 0 i_0 = 0 j_0 = 0 - j_1 = j_0 i_1 = i_0 innerSum_1 = innerSum_0 outerSum_1 = outerSum_0 @@ -2616,28 +2663,28 @@ func main()->Int { %t4_0 = i_1<4 if %t4_0 goto L3 else goto L4 L3: - j_2 = 0 - j_3 = j_2 + j_1 = 0 + j_2 = j_1 innerSum_2 = innerSum_1 goto L5 L5: - %t5_0 = j_3<4 + %t5_0 = j_2<4 if %t5_0 goto L6 else goto L7 L6: - %t6_0 = i_1+j_3 + %t6_0 = i_1+j_2 %t7_0 = %t6_0%2 %t8_0 = %t7_0==0 innerSum_4 = innerSum_2 if %t8_0 goto L8 else goto L9 L8: - %t9_0 = innerSum_2+j_3 + %t9_0 = innerSum_2+j_2 innerSum_3 = %t9_0 innerSum_4 = innerSum_3 goto L9 L9: - %t10_0 = j_3+1 - j_4 = %t10_0 - j_3 = j_4 + %t10_0 = j_2+1 + j_3 = %t10_0 + j_2 = j_3 innerSum_2 = innerSum_4 goto L5 L7: @@ -2645,7 +2692,6 @@ func main()->Int { outerSum_2 = %t11_0 %t12_0 = i_1+1 i_2 = %t12_0 - j_1 = j_3 i_1 = i_2 innerSum_1 = innerSum_2 outerSum_1 = outerSum_2 @@ -2807,6 +2853,126 @@ func foo()->Int %t7_0 = 0 %t7_2 = %t7_0 goto L4 +""", result); + } + + + @Test + public void testSSA17() { + String src = """ +func merge(begin: Int, middle: Int, end: Int) +{ + if (begin < end) { + var cond = 0 + if (begin < middle) { + if (begin>= end) cond = 1; + } + if (cond) + { + cond = 0 + } + } +} +"""; + String result = compileSrc(src); + Assert.assertEquals(""" +func merge +Before SSA +========== +L0: + arg begin + arg middle + arg end + %t4 = begin=end + if %t6 goto L6 else goto L7 +L6: + cond = 1 + goto L7 +L7: + goto L5 +L5: + if cond goto L8 else goto L9 +L8: + cond = 0 + goto L9 +L9: + goto L3 +L3: + goto L1 +L1: +After SSA +========= +L0: + arg begin_0 + arg middle_0 + arg end_0 + %t4_0 = begin_0=end_0 + if %t6_0 goto L6 else goto L7 +L6: + cond_1 = 1 + goto L7 +L7: + cond_2 = phi(cond_0, cond_1) + goto L5 +L5: + cond_3 = phi(cond_0, cond_2) + if cond_3 goto L8 else goto L9 +L8: + cond_4 = 0 + goto L9 +L9: + goto L3 +L3: + goto L1 +L1: +After exiting SSA +================= +L0: + arg begin_0 + arg middle_0 + arg end_0 + %t4_0 = begin_0=end_0 + cond_2 = cond_0 + if %t6_0 goto L6 else goto L7 +L6: + cond_1 = 1 + cond_2 = cond_1 + goto L7 +L7: + cond_3 = cond_2 + goto L5 +L5: + if cond_3 goto L8 else goto L9 +L8: + cond_4 = 0 + goto L9 +L9: + goto L3 +L3: + goto L1 +L1: """, result); } } \ No newline at end of file diff --git a/optvm/src/test/java/com/compilerprogramming/ezlang/interpreter/TestInterpreter.java b/optvm/src/test/java/com/compilerprogramming/ezlang/interpreter/TestInterpreter.java index acb583c..a00d48d 100644 --- a/optvm/src/test/java/com/compilerprogramming/ezlang/interpreter/TestInterpreter.java +++ b/optvm/src/test/java/com/compilerprogramming/ezlang/interpreter/TestInterpreter.java @@ -608,4 +608,92 @@ func foo()->Int integerValue.value == 1); } + @Test + public void testMergeSort() { + String src = """ +// based on the top-down version from https://en.wikipedia.org/wiki/Merge_sort +// via https://github.com/SeaOfNodes/Simple +func merge_sort(a: [Int], b: [int], n: Int) +{ + copy_array(a, 0, n, b) + split_merge(a, 0, n, b) +} + +func split_merge(b: [Int], begin: Int, end: Int, a: [Int]) +{ + if (end - begin <= 1) + return; + var middle = (end + begin) / 2 + split_merge(a, begin, middle, b) + split_merge(a, middle, end, b) + merge(b, begin, middle, end, a) +} + +func merge(b: [Int], begin: Int, middle: Int, end: Int, a: [Int]) +{ + var i = begin + var j = middle + var k = begin + while (k < end) { + // && and || + var cond = 0 + if (i < middle) { + if (j>= end) cond = 1; + else if (a[i] <= a[j]) cond = 1; + } + if (cond) + { + b[k] = a[i] + i = i + 1 + } + else + { + b[k] = a[j] + j = j + 1 + } + k = k + 1 + } +} + +func copy_array(a: [Int], begin: Int, end: Int, b: [Int]) +{ + var k = begin + while (k < end) + { + b[k] = a[k] + k = k + 1 + } +} + +func eq(a: [Int], b: [Int], n: Int)->Int +{ + var result = 1 + var i = 0 + while (i < n) + { + if (a[i] != b[i]) + { + result = 0 + break + } + i = i + 1 + } + return result +} + +func main()->Int +{ + var a = new [Int]{10,9,8,7,6,5,4,3,2,1} + var b = new [Int]{ 0,0,0,0,0,0,0,0,0,0} + var expect = new [Int]{1,2,3,4,5,6,7,8,9,10} + merge_sort(a, b, 10) + return eq(a,expect,10) +} +"""; + var value = compileAndRun(src, "main", Options.OPT); + Assert.assertNotNull(value); + Assert.assertTrue(value instanceof Value.IntegerValue integerValue && + integerValue.value == 1); + } + }

AltStyle によって変換されたページ (->オリジナル) /