From c86989f833dc49484dfddc61cadc6ae444392f76 Mon Sep 17 00:00:00 2001 From: dibyendumajumdar Date: Sat, 26 Apr 2025 23:48:17 +0100 Subject: [PATCH] Sync with final ch21 --- .../ezlang/parser/AST.java | 13 +++- .../ezlang/compiler/Compiler.java | 3 +- seaofnodes/src/test/cases/mergsort/sort.smp | 64 +++++++++++++++++++ .../ezlang/compiler/Simple.java | 31 +++++---- 4 files changed, 98 insertions(+), 13 deletions(-) create mode 100644 seaofnodes/src/test/cases/mergsort/sort.smp diff --git a/parser/src/main/java/com/compilerprogramming/ezlang/parser/AST.java b/parser/src/main/java/com/compilerprogramming/ezlang/parser/AST.java index 81a0015..46bcf78 100644 --- a/parser/src/main/java/com/compilerprogramming/ezlang/parser/AST.java +++ b/parser/src/main/java/com/compilerprogramming/ezlang/parser/AST.java @@ -545,8 +545,14 @@ public void accept(ASTVisitor visitor) { */ public static class NewExpr extends Expr { public final TypeExpr typeExpr; + public final long len; // temp hack, as this needs to be an expression rather than constant public NewExpr(TypeExpr typeExpr) { this.typeExpr = typeExpr; + this.len = 0; + } + public NewExpr(TypeExpr typeExpr, long len) { + this.typeExpr = typeExpr; + this.len = len; } @Override public StringBuilder toStr(StringBuilder sb) { @@ -572,8 +578,13 @@ public static class InitExpr extends Expr { public final NewExpr newExpr; public final List initExprList; public InitExpr(NewExpr newExpr, List initExprList) { - this.newExpr = newExpr; this.initExprList = initExprList; + // For arrays we compute length based on number of elements + // This is not actually correct - see https://github.com/CompilerProgramming/ez-lang/issues/47 + if (initExprList.size() != newExpr.len) + this.newExpr = new NewExpr(newExpr.typeExpr,initExprList.size()); + else + this.newExpr = newExpr; } @Override public StringBuilder toStr(StringBuilder sb) { diff --git a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/Compiler.java b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/Compiler.java index b93dda1..46805d5 100644 --- a/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/Compiler.java +++ b/seaofnodes/src/main/java/com/compilerprogramming/ezlang/compiler/Compiler.java @@ -554,7 +554,7 @@ private Node compileNewExpr(AST.NewExpr newExpr) { Type type = newExpr.type; if (type instanceof Type.TypeArray typeArray) { SONTypeMemPtr tarray = (SONTypeMemPtr) TYPES.get(typeArray.name()); - return newArray(tarray._obj,ZERO); + return newArray(tarray._obj,newExpr.len==0?ZERO:con(newExpr.len)); } else if (type instanceof Type.TypeStruct typeStruct) { SONTypeMemPtr tptr = (SONTypeMemPtr) TYPES.get(typeStruct.name()); @@ -686,6 +686,7 @@ private Node compileCallExpr(AST.CallExpr callExpr) { // Post-call setup CallEndNode cend = (CallEndNode)new CallEndNode(call).peephole(); + call.peephole(); // Rerun peeps after CallEnd, allows early inlining // Control from CallEnd ctrl(new CProjNode(cend,0,ScopeNode.CTRL).peephole()); // Memory from CallEnd diff --git a/seaofnodes/src/test/cases/mergsort/sort.smp b/seaofnodes/src/test/cases/mergsort/sort.smp new file mode 100644 index 0000000..b82b3f4 --- /dev/null +++ b/seaofnodes/src/test/cases/mergsort/sort.smp @@ -0,0 +1,64 @@ +// -*- mode: java; -*- +// based on the top-down version from https://en.wikipedia.org/wiki/Merge_sort + +val merge_sort = { int[] a, int[] b, int n -> + copy_array (a, 0, n, b); + split_merge(a, 0, n, b); +}; + +val split_merge = { int[] b, int begin, int end, int[] a -> + if (end - begin <= 1) + return 0; + int middle = (end + begin) / 2; + split_merge(a, begin, middle, b); + split_merge(a, middle, end, b); + merge(b, begin, middle, end, a); + return 0; +}; + +val merge = { int[] b, int begin, int middle, int end, int[] a -> + int i = begin, j = middle; + + for (int k = begin; k < end; k++) { + // && and || + bool cond = false; + if (i < middle) { + if (j >= end) cond = true; + else if (a[i] <= a[j]) cond = true; + } + if (cond) b[k] = a[i++]; + else b[k] = a[j++]; + } +}; + +val copy_array = { int[] a, int begin, int end, int[] b -> + for (int k = begin; k < end; k++) + b[k] = a[k]; +}; + +val eq = { int[] a, int[] b, int n -> + int result = 1; + int i = 0; + while (i < n) { + if (a[i] != b[i]) { + result = 0; + break; + } + i = i + 1; + } + return result; +}; + +val main = { -> + int[] !a = new int[10]; + a[0] = 10; a[1] = 9; a[2] = 8; a[3] = 7; a[4] = 6; + a[5] = 5; a[6] = 4; a[7] = 3; a[8] = 2; a[9] = 1; + int[] !b = new int[10]; + b[0] = 0; b[1] = 0; b[2] = 0; b[3] = 0; b[4] = 0; + b[5] = 0; b[6] = 0; b[7] = 0; b[8] = 0; b[9] = 0; + int[] !expect = new int[10]; + expect[0] = 1; expect[1] = 2; expect[2] = 3; expect[3] = 4; expect[4] = 5; + expect[5] = 6; expect[6] = 7; expect[7] = 8; expect[8] = 9; expect[9] = 10; + merge_sort(a, b, 10); + return eq(a,expect,10); +}; diff --git a/seaofnodes/src/test/java/com/compilerprogramming/ezlang/compiler/Simple.java b/seaofnodes/src/test/java/com/compilerprogramming/ezlang/compiler/Simple.java index 2fa8e9d..712b539 100644 --- a/seaofnodes/src/test/java/com/compilerprogramming/ezlang/compiler/Simple.java +++ b/seaofnodes/src/test/java/com/compilerprogramming/ezlang/compiler/Simple.java @@ -16,11 +16,12 @@ public class Simple { static final int DUMP_AFTER_PARSE = 1<<0; static final int DUMP_AFTER_OPTO = 1<<1; static final int DUMP_AFTER_TYPE_CHECK = 1<<2; - static final int DUMP_AFTER_INSTR_SELECT = 1<<3; - static final int DUMP_AFTER_GCM = 1<<4; - static final int DUMP_AFTER_LOCAL_SCHED = 1<<5; - static final int DUMP_AFTER_REG_ALLOC = 1<<6; - static final int DUMP_AFTER_ENCODE = 1<<7; + static final int DUMP_AFTER_LOOP_TREE = 1<<3; + static final int DUMP_AFTER_INSTR_SELECT = 1<<4; + static final int DUMP_AFTER_GCM = 1<<5; + static final int DUMP_AFTER_LOCAL_SCHED = 1<<6; + static final int DUMP_AFTER_REG_ALLOC = 1<<7; + static final int DUMP_AFTER_ENCODE = 1<<8; static final int DUMP_FINAL = 1<<16; @@ -88,12 +89,13 @@ static void dump(CodeGen code, int dump, int pass) { case DUMP_AFTER_PARSE -> "01-parse.dot"; case DUMP_AFTER_OPTO -> "02-opto.dot"; case DUMP_AFTER_TYPE_CHECK -> "03-type_check.dot"; - case DUMP_AFTER_INSTR_SELECT -> "04-instr_select.dot"; - case DUMP_AFTER_GCM -> "05-gcm.dot"; - case DUMP_AFTER_LOCAL_SCHED -> "06-local_sched.dot"; - case DUMP_AFTER_REG_ALLOC -> "07-reg_allos.dot"; - case DUMP_AFTER_ENCODE -> "08-local_sched.dot"; - case DUMP_FINAL -> "09-final.dot"; + case DUMP_AFTER_LOOP_TREE -> "04-loop_tree.dot"; + case DUMP_AFTER_INSTR_SELECT -> "05-instr_select.dot"; + case DUMP_AFTER_GCM -> "06-gcm.dot"; + case DUMP_AFTER_LOCAL_SCHED -> "07-local_sched.dot"; + case DUMP_AFTER_REG_ALLOC -> "08-reg_allos.dot"; + case DUMP_AFTER_ENCODE -> "09-local_sched.dot"; + case DUMP_FINAL -> "10-final.dot"; default -> throw Utils.TODO(); }; @@ -110,6 +112,7 @@ static void dump(CodeGen code, int dump, int pass) { case DUMP_AFTER_PARSE -> "After Parse:"; case DUMP_AFTER_OPTO -> "After OPTO:"; case DUMP_AFTER_TYPE_CHECK -> "After Type Check:"; + case DUMP_AFTER_LOOP_TREE -> "After Loop Tree:"; case DUMP_AFTER_INSTR_SELECT -> "After Instruction Selection:"; case DUMP_AFTER_GCM -> "After GCM:"; case DUMP_AFTER_LOCAL_SCHED -> "After Local Scheduling:"; @@ -134,6 +137,8 @@ static void print_compilation_times(CodeGen code) { System.out.println(String.format("Optimization Time: %.3f sec", t)); total += t = code._tTypeCheck / 1e3; System.out.println(String.format("Type Checking Time: %.3f sec", t)); + total += t = code._tLoopTree / 1e3; + System.out.println(String.format("Loop Tree Time: %.3f sec", t)); total += t = code._tInsSel / 1e3; System.out.println(String.format("Instruction Selection Time: %.3f sec", t)); total += t = code._tGCM / 1e3; @@ -180,6 +185,7 @@ public static void main(String[] args) throws Exception { case "--dump-after-parse": dump |= DUMP_AFTER_PARSE; break; case "--dump-after-opto": dump |= DUMP_AFTER_OPTO; break; case "--dump-after-type-check": dump |= DUMP_AFTER_TYPE_CHECK; break; + case "--dump-after-loop-tree": dump |= DUMP_AFTER_LOOP_TREE; break; case "--dump-after-instr-select": dump |= DUMP_AFTER_INSTR_SELECT; break; case "--dump-after-gcm": dump |= DUMP_AFTER_GCM; break; case "--dump-after-local-sched": dump |= DUMP_AFTER_LOCAL_SCHED; break; @@ -250,6 +256,9 @@ public static void main(String[] args) throws Exception { code.typeCheck(); dump(code, dump, DUMP_AFTER_TYPE_CHECK); + code.loopTree(); + dump(code, dump, DUMP_AFTER_LOOP_TREE); + if (do_codegen) { code.instSelect(cpu, abi); dump(code, dump, DUMP_AFTER_INSTR_SELECT);