Skip to content

Commit 7144c7d

Browse files
For test cases where comparing Simple vs EeZee - best to have as much source code compatibility as possible
WIP add support for array len and init value in new array expression WIP add support for array len and init value in new array expression WIP fix for incremental SSA
1 parent bd293df commit 7144c7d

File tree

20 files changed

+447
-52
lines changed

20 files changed

+447
-52
lines changed

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/CompiledFunction.java

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ private boolean compileArrayStoreExpr(AST.ArrayStoreExpr arrayStoreExpr) {
426426
}
427427

428428
private boolean compileNewExpr(AST.NewExpr newExpr) {
429-
codeNew(newExpr.type);
429+
codeNew(newExpr.type,newExpr.len,newExpr.initValue);
430430
return false;
431431
}
432432

@@ -644,20 +644,44 @@ else if (indexed instanceof Operand.LoadFieldOperand loadFieldOperand)
644644
codeMove(value, indexed);
645645
}
646646

647-
private void codeNew(Type type) {
647+
private void codeNew(Type type, AST.Expr len, AST.Expr initVal) {
648648
if (type instanceof Type.TypeArray typeArray)
649-
codeNewArray(typeArray);
649+
codeNewArray(typeArray, len, initVal);
650650
else if (type instanceof Type.TypeStruct typeStruct)
651651
codeNewStruct(typeStruct);
652652
else
653653
throw new CompilerException("Unexpected type: " + type);
654654
}
655655

656-
private void codeNewArray(Type.TypeArray typeArray) {
656+
private void codeNewArray(Type.TypeArray typeArray, AST.Expr len, AST.Expr initVal) {
657657
var temp = createTemp(typeArray);
658+
Operand lenOperand = null;
659+
Operand initValOperand = null;
660+
if (len != null) {
661+
boolean indexed = compileExpr(len);
662+
if (indexed)
663+
codeIndexedLoad();
664+
if (initVal != null) {
665+
indexed = compileExpr(initVal);
666+
if (indexed)
667+
codeIndexedLoad();
668+
initValOperand = pop();
669+
}
670+
lenOperand = pop();
671+
}
672+
Instruction insn;
658673
var target = (Operand.RegisterOperand) issa.write(temp);
659-
var insn = new Instruction.NewArray(typeArray, target);
674+
if (lenOperand != null) {
675+
if (initValOperand != null)
676+
insn = new Instruction.NewArray(typeArray, target, issa.read(lenOperand), issa.read(initValOperand));
677+
else
678+
insn = new Instruction.NewArray(typeArray, target, issa.read(lenOperand));
679+
}
680+
else
681+
insn = new Instruction.NewArray(typeArray, target);
660682
issa.recordDef(target, insn);
683+
if (lenOperand != null) issa.recordUse(lenOperand,insn);
684+
if (initValOperand != null) issa.recordUse(initValOperand,insn);
661685
code(insn);
662686
}
663687

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/Instruction.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,28 @@ public NewArray(Type.TypeArray type, Operand.RegisterOperand destOperand) {
124124
super(I_NEW_ARRAY, destOperand);
125125
this.type = type;
126126
}
127+
public NewArray(Type.TypeArray type, Operand.RegisterOperand destOperand, Operand len) {
128+
super(I_NEW_ARRAY, destOperand, len);
129+
this.type = type;
130+
}
131+
public NewArray(Type.TypeArray type, Operand.RegisterOperand destOperand, Operand len, Operand initValue) {
132+
super(I_NEW_ARRAY, destOperand, len, initValue);
133+
this.type = type;
134+
}
135+
public Operand len() { return uses.length > 0 ? uses[0] : null; }
136+
public Operand initValue() { return uses.length > 1 ? uses[1] : null; }
127137
public Operand.RegisterOperand destOperand() { return def; }
128138
@Override
129139
public StringBuilder toStr(StringBuilder sb) {
130-
return sb.append(def)
140+
sb.append(def)
131141
.append(" = ")
132142
.append("New(")
133-
.append(type)
134-
.append(")");
143+
.append(type);
144+
if (len() != null)
145+
sb.append(", len=").append(len());
146+
if (initValue() != null)
147+
sb.append(", initValue=").append(initValue());
148+
return sb.append(")");
135149
}
136150
}
137151

optvm/src/main/java/com/compilerprogramming/ezlang/interpreter/Interpreter.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,19 @@ else if (binaryInst.right() instanceof Operand.RegisterOperand registerOperand)
200200
}
201201
}
202202
case Instruction.NewArray newArrayInst -> {
203-
execStack.stack[base + newArrayInst.destOperand().frameSlot()] = new Value.ArrayValue(newArrayInst.type);
203+
long size = 0;
204+
Value initValue = null;
205+
if (newArrayInst.len() instanceof Operand.ConstantOperand constantOperand)
206+
size = constantOperand.value;
207+
else if (newArrayInst.len() instanceof Operand.RegisterOperand registerOperand) {
208+
Value.IntegerValue indexValue = (Value.IntegerValue) execStack.stack[base + registerOperand.frameSlot()];
209+
size = (long) indexValue.value;
210+
}
211+
if (newArrayInst.initValue() instanceof Operand.ConstantOperand constantOperand)
212+
initValue = new Value.IntegerValue(constantOperand.value);
213+
else if (newArrayInst.initValue() instanceof Operand.RegisterOperand registerOperand)
214+
initValue = execStack.stack[base + registerOperand.frameSlot()];
215+
execStack.stack[base + newArrayInst.destOperand().frameSlot()] = new Value.ArrayValue(newArrayInst.type, size, initValue);
204216
}
205217
case Instruction.NewStruct newStructInst -> {
206218
execStack.stack[base + newStructInst.destOperand().frameSlot()] = new Value.StructValue(newStructInst.type);

optvm/src/main/java/com/compilerprogramming/ezlang/interpreter/Value.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@ public NullValue() {}
1717
static public class ArrayValue extends Value {
1818
public final Type.TypeArray arrayType;
1919
public final ArrayList<Value> values;
20-
public ArrayValue(Type.TypeArray arrayType) {
20+
public ArrayValue(Type.TypeArray arrayType, long len, Value initValue) {
2121
this.arrayType = arrayType;
2222
values = new ArrayList<>();
23+
for (long i = 0; i < len; i++) {
24+
values.add(initValue);
25+
}
2326
}
2427
}
2528
static public class StructValue extends Value {

optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestCompiler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ func foo()->[Int] {
214214
String result = compileSrc(src);
215215
Assert.assertEquals("""
216216
L0:
217-
%t0 = New([Int])
217+
%t0 = New([Int], len=3)
218218
%t0[0] = 1
219219
%t0[1] = 2
220220
%t0[2] = 3
@@ -235,7 +235,7 @@ func foo(n: Int) -> [Int] {
235235
Assert.assertEquals("""
236236
L0:
237237
arg n
238-
%t1 = New([Int])
238+
%t1 = New([Int], len=1)
239239
%t1[0] = n
240240
ret %t1
241241
goto L1

optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestIncrementalSSA.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,56 @@ func merge(begin: Int,middle: Int,end: Int)
667667
L3:
668668
goto L1
669669
L1:
670+
""", result);
671+
}
672+
673+
@Test
674+
public void testSSA18()
675+
{
676+
String src = """
677+
func foo(len: Int, val: Int, x: Int, y: Int)->[Int] {
678+
if (x > y) {
679+
len=len+x
680+
val=val+x
681+
}
682+
return new [Int]{len=len,value=val}
683+
}
684+
""";
685+
String result = compileSrc(src);
686+
Assert.assertEquals("""
687+
func foo(len: Int,val: Int,x: Int,y: Int)->[Int]
688+
Reg #0 len 0
689+
Reg #1 val 1
690+
Reg #2 x 2
691+
Reg #3 y 3
692+
Reg #4 %t4 4
693+
Reg #5 %t5 5
694+
Reg #6 len_1 0
695+
Reg #7 %t7 7
696+
Reg #8 val_1 1
697+
Reg #9 %t9 9
698+
Reg #10 len_2 0
699+
Reg #11 val_2 1
700+
L0:
701+
arg len
702+
arg val
703+
arg x
704+
arg y
705+
%t4 = x>y
706+
if %t4 goto L2 else goto L3
707+
L2:
708+
%t5 = len+x
709+
len_1 = %t5
710+
%t7 = val+x
711+
val_1 = %t7
712+
goto L3
713+
L3:
714+
val_2 = phi(val, val_1)
715+
len_2 = phi(len, len_1)
716+
%t9 = New([Int], len=len_2, initValue=val_2)
717+
ret %t9
718+
goto L1
719+
L1:
670720
""", result);
671721
}
672722

optvm/src/test/java/com/compilerprogramming/ezlang/compiler/TestSSATransform.java

Lines changed: 90 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,7 @@ func foo()->Int {
16621662
Before SSA
16631663
==========
16641664
L0:
1665-
%t2 = New([Int])
1665+
%t2 = New([Int], len=2)
16661666
%t2[0] = 1
16671667
%t2[1] = 2
16681668
arr = %t2
@@ -1675,7 +1675,7 @@ func foo()->Int {
16751675
After SSA
16761676
=========
16771677
L0:
1678-
%t2_0 = New([Int])
1678+
%t2_0 = New([Int], len=2)
16791679
%t2_0[0] = 1
16801680
%t2_0[1] = 2
16811681
arr_0 = %t2_0
@@ -1688,7 +1688,7 @@ func foo()->Int {
16881688
After exiting SSA
16891689
=================
16901690
L0:
1691-
%t2_0 = New([Int])
1691+
%t2_0 = New([Int], len=2)
16921692
%t2_0[0] = 1
16931693
%t2_0[1] = 2
16941694
arr_0 = %t2_0
@@ -2781,7 +2781,7 @@ func foo()->Int
27812781
Before SSA
27822782
==========
27832783
L0:
2784-
%t1 = New([Foo?])
2784+
%t1 = New([Foo?], len=2)
27852785
%t2 = New(Foo)
27862786
%t2.i = 1
27872787
%t1[0] = %t2
@@ -2805,7 +2805,7 @@ func foo()->Int
28052805
After SSA
28062806
=========
28072807
L0:
2808-
%t1_0 = New([Foo?])
2808+
%t1_0 = New([Foo?], len=2)
28092809
%t2_0 = New(Foo)
28102810
%t2_0.i = 1
28112811
%t1_0[0] = %t2_0
@@ -2830,7 +2830,7 @@ func foo()->Int
28302830
After exiting SSA
28312831
=================
28322832
L0:
2833-
%t1_0 = New([Foo?])
2833+
%t1_0 = New([Foo?], len=2)
28342834
%t2_0 = New(Foo)
28352835
%t2_0.i = 1
28362836
%t1_0[0] = %t2_0
@@ -2973,6 +2973,90 @@ func merge(begin: Int, middle: Int, end: Int)
29732973
L3:
29742974
goto L1
29752975
L1:
2976+
""", result);
2977+
}
2978+
2979+
@Test
2980+
public void testSSA18()
2981+
{
2982+
String src = """
2983+
func foo(len: Int, val: Int, x: Int, y: Int)->[Int] {
2984+
if (x > y) {
2985+
len=len+x
2986+
val=val+x
2987+
}
2988+
return new [Int]{len=len,value=val}
2989+
}
2990+
""";
2991+
String result = compileSrc(src);
2992+
Assert.assertEquals("""
2993+
func foo
2994+
Before SSA
2995+
==========
2996+
L0:
2997+
arg len
2998+
arg val
2999+
arg x
3000+
arg y
3001+
%t4 = x>y
3002+
if %t4 goto L2 else goto L3
3003+
L2:
3004+
%t5 = len+x
3005+
len = %t5
3006+
%t6 = val+x
3007+
val = %t6
3008+
goto L3
3009+
L3:
3010+
%t7 = New([Int], len=len, initValue=val)
3011+
ret %t7
3012+
goto L1
3013+
L1:
3014+
After SSA
3015+
=========
3016+
L0:
3017+
arg len_0
3018+
arg val_0
3019+
arg x_0
3020+
arg y_0
3021+
%t4_0 = x_0>y_0
3022+
if %t4_0 goto L2 else goto L3
3023+
L2:
3024+
%t5_0 = len_0+x_0
3025+
len_1 = %t5_0
3026+
%t6_0 = val_0+x_0
3027+
val_1 = %t6_0
3028+
goto L3
3029+
L3:
3030+
val_2 = phi(val_0, val_1)
3031+
len_2 = phi(len_0, len_1)
3032+
%t7_0 = New([Int], len=len_2, initValue=val_2)
3033+
ret %t7_0
3034+
goto L1
3035+
L1:
3036+
After exiting SSA
3037+
=================
3038+
L0:
3039+
arg len_0
3040+
arg val_0
3041+
arg x_0
3042+
arg y_0
3043+
%t4_0 = x_0>y_0
3044+
val_2 = val_0
3045+
len_2 = len_0
3046+
if %t4_0 goto L2 else goto L3
3047+
L2:
3048+
%t5_0 = len_0+x_0
3049+
len_1 = %t5_0
3050+
%t6_0 = val_0+x_0
3051+
val_1 = %t6_0
3052+
val_2 = val_1
3053+
len_2 = len_1
3054+
goto L3
3055+
L3:
3056+
%t7_0 = New([Int], len=len_2, initValue=val_2)
3057+
ret %t7_0
3058+
goto L1
3059+
L1:
29763060
""", result);
29773061
}
29783062
}

parser/src/main/java/com/compilerprogramming/ezlang/parser/AST.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -545,14 +545,17 @@ public void accept(ASTVisitor visitor) {
545545
*/
546546
public static class NewExpr extends Expr {
547547
public final TypeExpr typeExpr;
548-
public final long len; // temp hack, as this needs to be an expression rather than constant
548+
public final Expr len;
549+
public final Expr initValue;
549550
public NewExpr(TypeExpr typeExpr) {
550551
this.typeExpr = typeExpr;
551-
this.len = 0;
552+
this.len = null;
553+
this.initValue = null;
552554
}
553-
public NewExpr(TypeExpr typeExpr, long len) {
555+
public NewExpr(TypeExpr typeExpr, Expr len, Expr initValue) {
554556
this.typeExpr = typeExpr;
555557
this.len = len;
558+
this.initValue = initValue;
556559
}
557560
@Override
558561
public StringBuilder toStr(StringBuilder sb) {
@@ -566,6 +569,11 @@ public void accept(ASTVisitor visitor) {
566569
if (visitor == null)
567570
return;
568571
typeExpr.accept(visitor);
572+
if (len != null) {
573+
len.accept(visitor);
574+
if (initValue != null)
575+
initValue.accept(visitor);
576+
}
569577
visitor.visit(this, false);
570578
}
571579
}
@@ -579,12 +587,7 @@ public static class InitExpr extends Expr {
579587
public final List<Expr> initExprList;
580588
public InitExpr(NewExpr newExpr, List<Expr> initExprList) {
581589
this.initExprList = initExprList;
582-
// For arrays we compute length based on number of elements
583-
// This is not actually correct - see https://github.com/CompilerProgramming/ez-lang/issues/47
584-
if (initExprList.size() != newExpr.len)
585-
this.newExpr = new NewExpr(newExpr.typeExpr,initExprList.size());
586-
else
587-
this.newExpr = newExpr;
590+
this.newExpr = newExpr;
588591
}
589592
@Override
590593
public StringBuilder toStr(StringBuilder sb) {

0 commit comments

Comments
 (0)