From bacd900a9b163a140d7827e02a8cc599d4bcec87 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sun, 20 Oct 2019 14:06:54 +0200 Subject: [PATCH] Added test for __ssa / __notssa. Made literal char ConstantEnumerable. --- .../fragment/AsmFragmentInstanceSpec.java | 2 +- .../model/operators/OperatorCastByte.java | 2 +- .../kickc/model/values/ConstantChar.java | 5 +- .../dk/camelot64/kickc/test/TestPrograms.java | 5 + src/test/kc/declared-ssa-var-0.kc | 37 + src/test/ref/declared-ssa-var-0.asm | 80 ++ src/test/ref/declared-ssa-var-0.cfg | 67 + src/test/ref/declared-ssa-var-0.log | 1148 +++++++++++++++++ src/test/ref/declared-ssa-var-0.sym | 46 + 9 files changed, 1388 insertions(+), 4 deletions(-) create mode 100644 src/test/kc/declared-ssa-var-0.kc create mode 100644 src/test/ref/declared-ssa-var-0.asm create mode 100644 src/test/ref/declared-ssa-var-0.cfg create mode 100644 src/test/ref/declared-ssa-var-0.log create mode 100644 src/test/ref/declared-ssa-var-0.sym diff --git a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpec.java b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpec.java index 9f0d017a2..0e9c9f779 100644 --- a/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpec.java +++ b/src/main/java/dk/camelot64/kickc/fragment/AsmFragmentInstanceSpec.java @@ -99,7 +99,7 @@ public class AsmFragmentInstanceSpec { if(constantLiteral instanceof ConstantInteger) { constIntValue = ((ConstantInteger) constantLiteral).getValue(); } else if(constantLiteral instanceof ConstantChar) { - constIntValue = ((ConstantChar) constantLiteral).getIntValue(); + constIntValue = ((ConstantChar) constantLiteral).getInteger(); } if(constIntValue != null) { List types = getVariationTypes(constIntValue); diff --git a/src/main/java/dk/camelot64/kickc/model/operators/OperatorCastByte.java b/src/main/java/dk/camelot64/kickc/model/operators/OperatorCastByte.java index 701ecddbd..e1069ffc8 100644 --- a/src/main/java/dk/camelot64/kickc/model/operators/OperatorCastByte.java +++ b/src/main/java/dk/camelot64/kickc/model/operators/OperatorCastByte.java @@ -22,7 +22,7 @@ public class OperatorCastByte extends OperatorCast { } else if(value instanceof ConstantPointer) { return new ConstantInteger(0xff & ((ConstantPointer) value).getLocation(), SymbolType.BYTE); } else if(value instanceof ConstantChar) { - return new ConstantInteger(((ConstantChar) value).getIntValue(), SymbolType.BYTE); + return new ConstantInteger(((ConstantChar) value).getInteger(), SymbolType.BYTE); } throw new CompileError("Calculation not implemented " + getOperator() + " " + value ); } diff --git a/src/main/java/dk/camelot64/kickc/model/values/ConstantChar.java b/src/main/java/dk/camelot64/kickc/model/values/ConstantChar.java index b729c4c93..dc9ba0b72 100644 --- a/src/main/java/dk/camelot64/kickc/model/values/ConstantChar.java +++ b/src/main/java/dk/camelot64/kickc/model/values/ConstantChar.java @@ -10,7 +10,7 @@ import kickass.nonasm.c64.CharToPetsciiConverter; /** * SSA form constant char value (a byte) */ -public class ConstantChar implements ConstantLiteral { +public class ConstantChar implements ConstantEnumerable { /** The character. */ private Character value; @@ -41,7 +41,8 @@ public class ConstantChar implements ConstantLiteral { * Get the integer value of the character * @return The integer value (taking encoding into account) */ - public Long getIntValue() { + @Override + public Long getInteger() { Byte constCharIntValue = null; if(ConstantString.Encoding.SCREENCODE_MIXED.equals(encoding)) { constCharIntValue = CharToPetsciiConverter.charToScreenCode_mixed.get(value); diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 89f590acd..d2d44f4d2 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -37,6 +37,11 @@ public class TestPrograms { public TestPrograms() { } + @Test + public void testDeclaredSsaVar8() throws IOException, URISyntaxException { + compileAndCompare("declared-ssa-var-0"); + } + @Test public void testDeclaredMemoryVar8() throws IOException, URISyntaxException { compileAndCompare("declared-memory-var-8"); diff --git a/src/test/kc/declared-ssa-var-0.kc b/src/test/kc/declared-ssa-var-0.kc new file mode 100644 index 000000000..41996335c --- /dev/null +++ b/src/test/kc/declared-ssa-var-0.kc @@ -0,0 +1,37 @@ +// Tests declaring variables as __ssa / __notssa + +char __ssa idx_ssa_g; +char __notssa idx_nssa_g; + +const char* SCREEN1 = 0x0400; +const char* SCREEN2 = 0x0400+40; +const char* SCREEN3 = 0x0400+80; +const char* SCREEN4 = 0x0400+120; + +void main() { + char __ssa idx_ssa_l; + char __notssa idx_nssa_l; + + SCREEN1[idx_ssa_g++] = 'C'; + for( char i: 'M'..'L') + SCREEN1[idx_ssa_g++] = i; + SCREEN1[idx_ssa_g++] = '!'; + + SCREEN2[idx_nssa_g++] = 'C'; + for( char i: 'M'..'L') + SCREEN2[idx_nssa_g++] = i; + SCREEN2[idx_nssa_g++] = '!'; + + SCREEN3[idx_ssa_l++] = 'C'; + for( char i: 'M'..'L') + SCREEN3[idx_ssa_l++] = i; + SCREEN3[idx_ssa_l++] = '!'; + + SCREEN4[idx_nssa_l++] = 'C'; + for( char i: 'M'..'L') + SCREEN4[idx_nssa_l++] = i; + SCREEN4[idx_nssa_l++] = '!'; + + + +} \ No newline at end of file diff --git a/src/test/ref/declared-ssa-var-0.asm b/src/test/ref/declared-ssa-var-0.asm new file mode 100644 index 000000000..5c1ccb961 --- /dev/null +++ b/src/test/ref/declared-ssa-var-0.asm @@ -0,0 +1,80 @@ +// Tests declaring variables as __ssa / __notssa +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + .label SCREEN1 = $400 + .label SCREEN2 = $400+$28 + .label SCREEN3 = $400+$50 + .label SCREEN4 = $400+$78 + .label idx_nssa_g = 2 +__bbegin: + lda #0 + sta.z idx_nssa_g + jsr main + rts +main: { + .label idx_nssa_l = 3 + lda #0 + sta.z idx_nssa_l + lda #'C' + sta SCREEN1 + ldy #1 + ldx #'M' + __b1: + txa + sta SCREEN1,y + iny + dex + cpx #'L'-1 + bne __b1 + lda #'!' + sta SCREEN1,y + lda #'C' + ldy.z idx_nssa_g + sta SCREEN2,y + inc.z idx_nssa_g + lda #'M' + __b3: + ldy.z idx_nssa_g + sta SCREEN2,y + inc.z idx_nssa_g + sec + sbc #1 + cmp #'L'-1 + bne __b3 + lda #'!' + ldy.z idx_nssa_g + sta SCREEN2,y + inc.z idx_nssa_g + lda #'C' + sta SCREEN3 + ldy #1 + ldx #'M' + __b5: + txa + sta SCREEN3,y + iny + dex + cpx #'L'-1 + bne __b5 + lda #'!' + sta SCREEN3,y + lda #'C' + ldy.z idx_nssa_l + sta SCREEN4,y + inc.z idx_nssa_l + lda #'M' + __b7: + ldy.z idx_nssa_l + sta SCREEN4,y + inc.z idx_nssa_l + sec + sbc #1 + cmp #'L'-1 + bne __b7 + lda #'!' + ldy.z idx_nssa_l + sta SCREEN4,y + inc.z idx_nssa_l + rts +} diff --git a/src/test/ref/declared-ssa-var-0.cfg b/src/test/ref/declared-ssa-var-0.cfg new file mode 100644 index 000000000..cc1d7ff94 --- /dev/null +++ b/src/test/ref/declared-ssa-var-0.cfg @@ -0,0 +1,67 @@ +@begin: scope:[] from + [0] (byte) idx_nssa_g ← (byte) 0 + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() + +(void()) main() +main: scope:[main] from @1 + [4] (byte) main::idx_nssa_l ← (byte) 0 + [5] *((const byte*) SCREEN1) ← (byte) 'C' + to:main::@1 +main::@1: scope:[main] from main main::@1 + [6] (byte) idx_ssa_g#7 ← phi( main/(byte) 1 main::@1/(byte) idx_ssa_g#2 ) + [6] (byte) main::i#2 ← phi( main/(byte) 'M' main::@1/(byte) main::i#1 ) + [7] *((const byte*) SCREEN1 + (byte) idx_ssa_g#7) ← (byte) main::i#2 + [8] (byte) idx_ssa_g#2 ← ++ (byte) idx_ssa_g#7 + [9] (byte) main::i#1 ← -- (byte) main::i#2 + [10] if((byte) main::i#1!=(byte) 'L'-(byte) 1) goto main::@1 + to:main::@2 +main::@2: scope:[main] from main::@1 + [11] *((const byte*) SCREEN1 + (byte) idx_ssa_g#2) ← (byte) '!' + [12] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) 'C' + [13] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g + to:main::@3 +main::@3: scope:[main] from main::@2 main::@3 + [14] (byte) main::i1#2 ← phi( main::@2/(byte) 'M' main::@3/(byte) main::i1#1 ) + [15] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) main::i1#2 + [16] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g + [17] (byte) main::i1#1 ← -- (byte) main::i1#2 + [18] if((byte) main::i1#1!=(byte) 'L'-(byte) 1) goto main::@3 + to:main::@4 +main::@4: scope:[main] from main::@3 + [19] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) '!' + [20] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g + [21] *((const byte*) SCREEN3) ← (byte) 'C' + to:main::@5 +main::@5: scope:[main] from main::@4 main::@5 + [22] (byte) main::idx_ssa_l#5 ← phi( main::@4/(byte) 1 main::@5/(byte) main::idx_ssa_l#2 ) + [22] (byte) main::i2#2 ← phi( main::@4/(byte) 'M' main::@5/(byte) main::i2#1 ) + [23] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#5) ← (byte) main::i2#2 + [24] (byte) main::idx_ssa_l#2 ← ++ (byte) main::idx_ssa_l#5 + [25] (byte) main::i2#1 ← -- (byte) main::i2#2 + [26] if((byte) main::i2#1!=(byte) 'L'-(byte) 1) goto main::@5 + to:main::@6 +main::@6: scope:[main] from main::@5 + [27] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#2) ← (byte) '!' + [28] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) 'C' + [29] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l + to:main::@7 +main::@7: scope:[main] from main::@6 main::@7 + [30] (byte) main::i3#2 ← phi( main::@6/(byte) 'M' main::@7/(byte) main::i3#1 ) + [31] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) main::i3#2 + [32] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l + [33] (byte) main::i3#1 ← -- (byte) main::i3#2 + [34] if((byte) main::i3#1!=(byte) 'L'-(byte) 1) goto main::@7 + to:main::@8 +main::@8: scope:[main] from main::@7 + [35] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) '!' + [36] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l + to:main::@return +main::@return: scope:[main] from main::@8 + [37] return + to:@return diff --git a/src/test/ref/declared-ssa-var-0.log b/src/test/ref/declared-ssa-var-0.log new file mode 100644 index 000000000..a0ccf82fc --- /dev/null +++ b/src/test/ref/declared-ssa-var-0.log @@ -0,0 +1,1148 @@ + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte) idx_ssa_g#0 ← (byte) 0 + (byte) idx_nssa_g ← (byte) 0 + (byte*) SCREEN1 ← ((byte*)) (number) $400 + (byte*) SCREEN2 ← ((byte*)) (number) $400+(number) $28 + (byte*) SCREEN3 ← ((byte*)) (number) $400+(number) $50 + (byte*) SCREEN4 ← ((byte*)) (number) $400+(number) $78 + to:@1 + +(void()) main() +main: scope:[main] from @1 + (byte) idx_ssa_g#6 ← phi( @1/(byte) idx_ssa_g#11 ) + (byte) main::idx_ssa_l#0 ← (byte) 0 + (byte) main::idx_nssa_l ← (byte) 0 + *((byte*) SCREEN1 + (byte) idx_ssa_g#6) ← (byte) 'C' + (byte) idx_ssa_g#1 ← ++ (byte) idx_ssa_g#6 + (byte) main::i#0 ← (byte) 'M' + to:main::@1 +main::@1: scope:[main] from main main::@1 + (byte) main::idx_ssa_l#9 ← phi( main/(byte) main::idx_ssa_l#0 main::@1/(byte) main::idx_ssa_l#9 ) + (byte) idx_ssa_g#7 ← phi( main/(byte) idx_ssa_g#1 main::@1/(byte) idx_ssa_g#2 ) + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 ) + *((byte*) SCREEN1 + (byte) idx_ssa_g#7) ← (byte) main::i#2 + (byte) idx_ssa_g#2 ← ++ (byte) idx_ssa_g#7 + (byte) main::i#1 ← (byte) main::i#2 + rangenext('M','L') + (bool~) main::$0 ← (byte) main::i#1 != rangelast('M','L') + if((bool~) main::$0) goto main::@1 + to:main::@2 +main::@2: scope:[main] from main::@1 + (byte) main::idx_ssa_l#8 ← phi( main::@1/(byte) main::idx_ssa_l#9 ) + (byte) idx_ssa_g#8 ← phi( main::@1/(byte) idx_ssa_g#2 ) + *((byte*) SCREEN1 + (byte) idx_ssa_g#8) ← (byte) '!' + (byte) idx_ssa_g#3 ← ++ (byte) idx_ssa_g#8 + *((byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) 'C' + (byte) idx_nssa_g ← ++ (byte) idx_nssa_g + (byte) main::i1#0 ← (byte) 'M' + to:main::@3 +main::@3: scope:[main] from main::@2 main::@3 + (byte) idx_ssa_g#17 ← phi( main::@2/(byte) idx_ssa_g#3 main::@3/(byte) idx_ssa_g#17 ) + (byte) main::idx_ssa_l#7 ← phi( main::@2/(byte) main::idx_ssa_l#8 main::@3/(byte) main::idx_ssa_l#7 ) + (byte) main::i1#2 ← phi( main::@2/(byte) main::i1#0 main::@3/(byte) main::i1#1 ) + *((byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) main::i1#2 + (byte) idx_nssa_g ← ++ (byte) idx_nssa_g + (byte) main::i1#1 ← (byte) main::i1#2 + rangenext('M','L') + (bool~) main::$1 ← (byte) main::i1#1 != rangelast('M','L') + if((bool~) main::$1) goto main::@3 + to:main::@4 +main::@4: scope:[main] from main::@3 + (byte) idx_ssa_g#16 ← phi( main::@3/(byte) idx_ssa_g#17 ) + (byte) main::idx_ssa_l#4 ← phi( main::@3/(byte) main::idx_ssa_l#7 ) + *((byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) '!' + (byte) idx_nssa_g ← ++ (byte) idx_nssa_g + *((byte*) SCREEN3 + (byte) main::idx_ssa_l#4) ← (byte) 'C' + (byte) main::idx_ssa_l#1 ← ++ (byte) main::idx_ssa_l#4 + (byte) main::i2#0 ← (byte) 'M' + to:main::@5 +main::@5: scope:[main] from main::@4 main::@5 + (byte) idx_ssa_g#15 ← phi( main::@4/(byte) idx_ssa_g#16 main::@5/(byte) idx_ssa_g#15 ) + (byte) main::idx_ssa_l#5 ← phi( main::@4/(byte) main::idx_ssa_l#1 main::@5/(byte) main::idx_ssa_l#2 ) + (byte) main::i2#2 ← phi( main::@4/(byte) main::i2#0 main::@5/(byte) main::i2#1 ) + *((byte*) SCREEN3 + (byte) main::idx_ssa_l#5) ← (byte) main::i2#2 + (byte) main::idx_ssa_l#2 ← ++ (byte) main::idx_ssa_l#5 + (byte) main::i2#1 ← (byte) main::i2#2 + rangenext('M','L') + (bool~) main::$2 ← (byte) main::i2#1 != rangelast('M','L') + if((bool~) main::$2) goto main::@5 + to:main::@6 +main::@6: scope:[main] from main::@5 + (byte) idx_ssa_g#14 ← phi( main::@5/(byte) idx_ssa_g#15 ) + (byte) main::idx_ssa_l#6 ← phi( main::@5/(byte) main::idx_ssa_l#2 ) + *((byte*) SCREEN3 + (byte) main::idx_ssa_l#6) ← (byte) '!' + (byte) main::idx_ssa_l#3 ← ++ (byte) main::idx_ssa_l#6 + *((byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) 'C' + (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l + (byte) main::i3#0 ← (byte) 'M' + to:main::@7 +main::@7: scope:[main] from main::@6 main::@7 + (byte) idx_ssa_g#13 ← phi( main::@6/(byte) idx_ssa_g#14 main::@7/(byte) idx_ssa_g#13 ) + (byte) main::i3#2 ← phi( main::@6/(byte) main::i3#0 main::@7/(byte) main::i3#1 ) + *((byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) main::i3#2 + (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l + (byte) main::i3#1 ← (byte) main::i3#2 + rangenext('M','L') + (bool~) main::$3 ← (byte) main::i3#1 != rangelast('M','L') + if((bool~) main::$3) goto main::@7 + to:main::@8 +main::@8: scope:[main] from main::@7 + (byte) idx_ssa_g#12 ← phi( main::@7/(byte) idx_ssa_g#13 ) + *((byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) '!' + (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l + to:main::@return +main::@return: scope:[main] from main::@8 + (byte) idx_ssa_g#9 ← phi( main::@8/(byte) idx_ssa_g#12 ) + (byte) idx_ssa_g#4 ← (byte) idx_ssa_g#9 + return + to:@return +@1: scope:[] from @begin + (byte) idx_ssa_g#11 ← phi( @begin/(byte) idx_ssa_g#0 ) + call main + to:@2 +@2: scope:[] from @1 + (byte) idx_ssa_g#10 ← phi( @1/(byte) idx_ssa_g#4 ) + (byte) idx_ssa_g#5 ← (byte) idx_ssa_g#10 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(label) @1 +(label) @2 +(label) @begin +(label) @end +(byte*) SCREEN1 +(byte*) SCREEN2 +(byte*) SCREEN3 +(byte*) SCREEN4 +(byte) idx_nssa_g notregister +(byte) idx_ssa_g +(byte) idx_ssa_g#0 +(byte) idx_ssa_g#1 +(byte) idx_ssa_g#10 +(byte) idx_ssa_g#11 +(byte) idx_ssa_g#12 +(byte) idx_ssa_g#13 +(byte) idx_ssa_g#14 +(byte) idx_ssa_g#15 +(byte) idx_ssa_g#16 +(byte) idx_ssa_g#17 +(byte) idx_ssa_g#2 +(byte) idx_ssa_g#3 +(byte) idx_ssa_g#4 +(byte) idx_ssa_g#5 +(byte) idx_ssa_g#6 +(byte) idx_ssa_g#7 +(byte) idx_ssa_g#8 +(byte) idx_ssa_g#9 +(void()) main() +(bool~) main::$0 +(bool~) main::$1 +(bool~) main::$2 +(bool~) main::$3 +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@4 +(label) main::@5 +(label) main::@6 +(label) main::@7 +(label) main::@8 +(label) main::@return +(byte) main::i +(byte) main::i#0 +(byte) main::i#1 +(byte) main::i#2 +(byte) main::i1 +(byte) main::i1#0 +(byte) main::i1#1 +(byte) main::i1#2 +(byte) main::i2 +(byte) main::i2#0 +(byte) main::i2#1 +(byte) main::i2#2 +(byte) main::i3 +(byte) main::i3#0 +(byte) main::i3#1 +(byte) main::i3#2 +(byte) main::idx_nssa_l notregister +(byte) main::idx_ssa_l +(byte) main::idx_ssa_l#0 +(byte) main::idx_ssa_l#1 +(byte) main::idx_ssa_l#2 +(byte) main::idx_ssa_l#3 +(byte) main::idx_ssa_l#4 +(byte) main::idx_ssa_l#5 +(byte) main::idx_ssa_l#6 +(byte) main::idx_ssa_l#7 +(byte) main::idx_ssa_l#8 +(byte) main::idx_ssa_l#9 + +Inlining cast (byte*) SCREEN1 ← (byte*)(number) $400 +Inlining cast (byte*) SCREEN2 ← (byte*)(number) $400+(number) $28 +Inlining cast (byte*) SCREEN3 ← (byte*)(number) $400+(number) $50 +Inlining cast (byte*) SCREEN4 ← (byte*)(number) $400+(number) $78 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (byte*) 1024 +Successful SSA optimization PassNCastSimplification +Alias (byte) idx_ssa_g#2 = (byte) idx_ssa_g#8 +Alias (byte) main::idx_ssa_l#8 = (byte) main::idx_ssa_l#9 +Alias (byte) main::idx_ssa_l#4 = (byte) main::idx_ssa_l#7 +Alias (byte) idx_ssa_g#16 = (byte) idx_ssa_g#17 +Alias (byte) main::idx_ssa_l#2 = (byte) main::idx_ssa_l#6 +Alias (byte) idx_ssa_g#14 = (byte) idx_ssa_g#15 +Alias (byte) idx_ssa_g#12 = (byte) idx_ssa_g#13 (byte) idx_ssa_g#9 (byte) idx_ssa_g#4 +Alias (byte) idx_ssa_g#0 = (byte) idx_ssa_g#11 +Alias (byte) idx_ssa_g#10 = (byte) idx_ssa_g#5 +Successful SSA optimization Pass2AliasElimination +Identical Phi Values (byte) idx_ssa_g#6 (byte) idx_ssa_g#0 +Identical Phi Values (byte) main::idx_ssa_l#8 (byte) main::idx_ssa_l#0 +Identical Phi Values (byte) main::idx_ssa_l#4 (byte) main::idx_ssa_l#8 +Identical Phi Values (byte) idx_ssa_g#16 (byte) idx_ssa_g#3 +Identical Phi Values (byte) idx_ssa_g#14 (byte) idx_ssa_g#16 +Identical Phi Values (byte) idx_ssa_g#12 (byte) idx_ssa_g#14 +Identical Phi Values (byte) idx_ssa_g#10 (byte) idx_ssa_g#12 +Successful SSA optimization Pass2IdenticalPhiElimination +Simple Condition (bool~) main::$0 [17] if((byte) main::i#1!=rangelast('M','L')) goto main::@1 +Simple Condition (bool~) main::$1 [29] if((byte) main::i1#1!=rangelast('M','L')) goto main::@3 +Simple Condition (bool~) main::$2 [41] if((byte) main::i2#1!=rangelast('M','L')) goto main::@5 +Simple Condition (bool~) main::$3 [53] if((byte) main::i3#1!=rangelast('M','L')) goto main::@7 +Successful SSA optimization Pass2ConditionalJumpSimplification +Constant right-side identified [3] (byte*) SCREEN2 ← (byte*)(number) $400+(number) $28 +Constant right-side identified [4] (byte*) SCREEN3 ← (byte*)(number) $400+(number) $50 +Constant right-side identified [5] (byte*) SCREEN4 ← (byte*)(number) $400+(number) $78 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) idx_ssa_g#0 = 0 +Constant (const byte*) SCREEN1 = (byte*) 1024 +Constant (const byte*) SCREEN2 = (byte*)$400+$28 +Constant (const byte*) SCREEN3 = (byte*)$400+$50 +Constant (const byte*) SCREEN4 = (byte*)$400+$78 +Constant (const byte) main::idx_ssa_l#0 = 0 +Constant (const byte) main::i#0 = 'M' +Constant (const byte) main::i1#0 = 'M' +Constant (const byte) main::i2#0 = 'M' +Constant (const byte) main::i3#0 = 'M' +Successful SSA optimization Pass2ConstantIdentification +Resolved ranged next value [15] main::i#1 ← -- main::i#2 to -- +Resolved ranged comparison value [17] if(main::i#1!=rangelast('M','L')) goto main::@1 to (byte) 'L'-(number) 1 +Resolved ranged next value [27] main::i1#1 ← -- main::i1#2 to -- +Resolved ranged comparison value [29] if(main::i1#1!=rangelast('M','L')) goto main::@3 to (byte) 'L'-(number) 1 +Resolved ranged next value [39] main::i2#1 ← -- main::i2#2 to -- +Resolved ranged comparison value [41] if(main::i2#1!=rangelast('M','L')) goto main::@5 to (byte) 'L'-(number) 1 +Resolved ranged next value [51] main::i3#1 ← -- main::i3#2 to -- +Resolved ranged comparison value [53] if(main::i3#1!=rangelast('M','L')) goto main::@7 to (byte) 'L'-(number) 1 +Simplifying expression containing zero SCREEN1 in [9] *((const byte*) SCREEN1 + (const byte) idx_ssa_g#0) ← (byte) 'C' +Simplifying expression containing zero SCREEN3 in [33] *((const byte*) SCREEN3 + (const byte) main::idx_ssa_l#0) ← (byte) 'C' +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused variable (byte) idx_ssa_g#3 and assignment [10] (byte) idx_ssa_g#3 ← ++ (byte) idx_ssa_g#2 +Eliminating unused variable (byte) main::idx_ssa_l#3 and assignment [28] (byte) main::idx_ssa_l#3 ← ++ (byte) main::idx_ssa_l#2 +Successful SSA optimization PassNEliminateUnusedVars +Adding number conversion cast (unumber) 'L'-1 in if((byte) main::i#1!=(byte) 'L'-(number) 1) goto main::@1 +Adding number conversion cast (unumber) 1 in if((byte) main::i#1!=(unumber)(byte) 'L'-(number) 1) goto main::@1 +Adding number conversion cast (unumber) 'L'-1 in if((byte) main::i1#1!=(byte) 'L'-(number) 1) goto main::@3 +Adding number conversion cast (unumber) 1 in if((byte) main::i1#1!=(unumber)(byte) 'L'-(number) 1) goto main::@3 +Adding number conversion cast (unumber) 'L'-1 in if((byte) main::i2#1!=(byte) 'L'-(number) 1) goto main::@5 +Adding number conversion cast (unumber) 1 in if((byte) main::i2#1!=(unumber)(byte) 'L'-(number) 1) goto main::@5 +Adding number conversion cast (unumber) 'L'-1 in if((byte) main::i3#1!=(byte) 'L'-(number) 1) goto main::@7 +Adding number conversion cast (unumber) 1 in if((byte) main::i3#1!=(unumber)(byte) 'L'-(number) 1) goto main::@7 +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant integer cast (byte) 'L'-(unumber)(number) 1 +Simplifying constant integer cast 1 +Simplifying constant integer cast (byte) 'L'-(unumber)(number) 1 +Simplifying constant integer cast 1 +Simplifying constant integer cast (byte) 'L'-(unumber)(number) 1 +Simplifying constant integer cast 1 +Simplifying constant integer cast (byte) 'L'-(unumber)(number) 1 +Simplifying constant integer cast 1 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Constant right-side identified [3] (byte) idx_ssa_g#1 ← ++ (const byte) idx_ssa_g#0 +Constant right-side identified [20] (byte) main::idx_ssa_l#1 ← ++ (const byte) main::idx_ssa_l#0 +Successful SSA optimization Pass2ConstantRValueConsolidation +Constant (const byte) idx_ssa_g#1 = ++idx_ssa_g#0 +Constant (const byte) main::idx_ssa_l#1 = ++main::idx_ssa_l#0 +Successful SSA optimization Pass2ConstantIdentification +Inlining constant with var siblings (const byte) main::idx_ssa_l#0 +Inlining constant with var siblings (const byte) main::i#0 +Inlining constant with var siblings (const byte) main::i1#0 +Inlining constant with var siblings (const byte) main::i2#0 +Inlining constant with var siblings (const byte) main::i3#0 +Inlining constant with var siblings (const byte) main::idx_ssa_l#1 +Inlining constant with var siblings (const byte) idx_ssa_g#0 +Inlining constant with var siblings (const byte) idx_ssa_g#1 +Constant inlined main::idx_ssa_l#1 = ++(byte) 0 +Constant inlined main::idx_ssa_l#0 = (byte) 0 +Constant inlined main::i3#0 = (byte) 'M' +Constant inlined main::i#0 = (byte) 'M' +Constant inlined main::i1#0 = (byte) 'M' +Constant inlined main::i2#0 = (byte) 'M' +Constant inlined idx_ssa_g#0 = (byte) 0 +Constant inlined idx_ssa_g#1 = ++(byte) 0 +Successful SSA optimization Pass2ConstantInlining +Simplifying constant integer increment ++0 +Simplifying constant integer increment ++0 +Successful SSA optimization Pass2ConstantSimplification +Added new block during phi lifting main::@9(between main::@1 and main::@1) +Added new block during phi lifting main::@10(between main::@3 and main::@3) +Added new block during phi lifting main::@11(between main::@5 and main::@5) +Added new block during phi lifting main::@12(between main::@7 and main::@7) +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +CALL GRAPH +Calls in [] to main:2 + +Created 6 initial phi equivalence classes +Coalesced [39] main::i3#3 ← main::i3#1 +Coalesced [40] main::i2#3 ← main::i2#1 +Coalesced [41] main::idx_ssa_l#10 ← main::idx_ssa_l#2 +Coalesced [42] main::i1#3 ← main::i1#1 +Coalesced [43] main::i#3 ← main::i#1 +Coalesced [44] idx_ssa_g#18 ← idx_ssa_g#2 +Coalesced down to 6 phi equivalence classes +Culled Empty Block (label) @2 +Culled Empty Block (label) main::@12 +Culled Empty Block (label) main::@11 +Culled Empty Block (label) main::@10 +Culled Empty Block (label) main::@9 +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] (byte) idx_nssa_g ← (byte) 0 + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() + +(void()) main() +main: scope:[main] from @1 + [4] (byte) main::idx_nssa_l ← (byte) 0 + [5] *((const byte*) SCREEN1) ← (byte) 'C' + to:main::@1 +main::@1: scope:[main] from main main::@1 + [6] (byte) idx_ssa_g#7 ← phi( main/(byte) 1 main::@1/(byte) idx_ssa_g#2 ) + [6] (byte) main::i#2 ← phi( main/(byte) 'M' main::@1/(byte) main::i#1 ) + [7] *((const byte*) SCREEN1 + (byte) idx_ssa_g#7) ← (byte) main::i#2 + [8] (byte) idx_ssa_g#2 ← ++ (byte) idx_ssa_g#7 + [9] (byte) main::i#1 ← -- (byte) main::i#2 + [10] if((byte) main::i#1!=(byte) 'L'-(byte) 1) goto main::@1 + to:main::@2 +main::@2: scope:[main] from main::@1 + [11] *((const byte*) SCREEN1 + (byte) idx_ssa_g#2) ← (byte) '!' + [12] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) 'C' + [13] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g + to:main::@3 +main::@3: scope:[main] from main::@2 main::@3 + [14] (byte) main::i1#2 ← phi( main::@2/(byte) 'M' main::@3/(byte) main::i1#1 ) + [15] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) main::i1#2 + [16] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g + [17] (byte) main::i1#1 ← -- (byte) main::i1#2 + [18] if((byte) main::i1#1!=(byte) 'L'-(byte) 1) goto main::@3 + to:main::@4 +main::@4: scope:[main] from main::@3 + [19] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) '!' + [20] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g + [21] *((const byte*) SCREEN3) ← (byte) 'C' + to:main::@5 +main::@5: scope:[main] from main::@4 main::@5 + [22] (byte) main::idx_ssa_l#5 ← phi( main::@4/(byte) 1 main::@5/(byte) main::idx_ssa_l#2 ) + [22] (byte) main::i2#2 ← phi( main::@4/(byte) 'M' main::@5/(byte) main::i2#1 ) + [23] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#5) ← (byte) main::i2#2 + [24] (byte) main::idx_ssa_l#2 ← ++ (byte) main::idx_ssa_l#5 + [25] (byte) main::i2#1 ← -- (byte) main::i2#2 + [26] if((byte) main::i2#1!=(byte) 'L'-(byte) 1) goto main::@5 + to:main::@6 +main::@6: scope:[main] from main::@5 + [27] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#2) ← (byte) '!' + [28] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) 'C' + [29] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l + to:main::@7 +main::@7: scope:[main] from main::@6 main::@7 + [30] (byte) main::i3#2 ← phi( main::@6/(byte) 'M' main::@7/(byte) main::i3#1 ) + [31] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) main::i3#2 + [32] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l + [33] (byte) main::i3#1 ← -- (byte) main::i3#2 + [34] if((byte) main::i3#1!=(byte) 'L'-(byte) 1) goto main::@7 + to:main::@8 +main::@8: scope:[main] from main::@7 + [35] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) '!' + [36] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l + to:main::@return +main::@return: scope:[main] from main::@8 + [37] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(byte) idx_nssa_g notregister 3.1333333333333333 +(byte) idx_ssa_g +(byte) idx_ssa_g#2 8.0 +(byte) idx_ssa_g#7 16.5 +(void()) main() +(byte) main::i +(byte) main::i#1 16.5 +(byte) main::i#2 11.0 +(byte) main::i1 +(byte) main::i1#1 16.5 +(byte) main::i1#2 11.0 +(byte) main::i2 +(byte) main::i2#1 16.5 +(byte) main::i2#2 11.0 +(byte) main::i3 +(byte) main::i3#1 16.5 +(byte) main::i3#2 11.0 +(byte) main::idx_nssa_l notregister 1.6206896551724135 +(byte) main::idx_ssa_l +(byte) main::idx_ssa_l#2 8.0 +(byte) main::idx_ssa_l#5 16.5 + +Initial phi equivalence classes +[ main::i#2 main::i#1 ] +[ idx_ssa_g#7 idx_ssa_g#2 ] +[ main::i1#2 main::i1#1 ] +[ main::i2#2 main::i2#1 ] +[ main::idx_ssa_l#5 main::idx_ssa_l#2 ] +[ main::i3#2 main::i3#1 ] +Added variable idx_nssa_g to zero page equivalence class [ idx_nssa_g ] +Added variable main::idx_nssa_l to zero page equivalence class [ main::idx_nssa_l ] +Complete equivalence classes +[ main::i#2 main::i#1 ] +[ idx_ssa_g#7 idx_ssa_g#2 ] +[ main::i1#2 main::i1#1 ] +[ main::i2#2 main::i2#1 ] +[ main::idx_ssa_l#5 main::idx_ssa_l#2 ] +[ main::i3#2 main::i3#1 ] +[ idx_nssa_g ] +[ main::idx_nssa_l ] +Allocated zp[1]:2 [ main::i#2 main::i#1 ] +Allocated zp[1]:3 [ idx_ssa_g#7 idx_ssa_g#2 ] +Allocated zp[1]:4 [ main::i1#2 main::i1#1 ] +Allocated zp[1]:5 [ main::i2#2 main::i2#1 ] +Allocated zp[1]:6 [ main::idx_ssa_l#5 main::idx_ssa_l#2 ] +Allocated zp[1]:7 [ main::i3#2 main::i3#1 ] +Allocated zp[1]:8 [ idx_nssa_g ] +Allocated zp[1]:9 [ main::idx_nssa_l ] + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// Tests declaring variables as __ssa / __notssa + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN1 = $400 + .label SCREEN2 = $400+$28 + .label SCREEN3 = $400+$50 + .label SCREEN4 = $400+$78 + .label idx_nssa_g = 8 + .label idx_ssa_g = 3 + // @begin +__bbegin: + // [0] (byte) idx_nssa_g ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z idx_nssa_g + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + .label idx_nssa_l = 9 + .label i = 2 + .label i1 = 4 + .label idx_ssa_l = 6 + .label i2 = 5 + .label i3 = 7 + // [4] (byte) main::idx_nssa_l ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z idx_nssa_l + // [5] *((const byte*) SCREEN1) ← (byte) 'C' -- _deref_pbuc1=vbuc2 + lda #'C' + sta SCREEN1 + // [6] phi from main to main::@1 [phi:main->main::@1] + __b1_from_main: + // [6] phi (byte) idx_ssa_g#7 = (byte) 1 [phi:main->main::@1#0] -- vbuz1=vbuc1 + lda #1 + sta.z idx_ssa_g + // [6] phi (byte) main::i#2 = (byte) 'M' [phi:main->main::@1#1] -- vbuz1=vbuc1 + lda #'M' + sta.z i + jmp __b1 + // [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + __b1_from___b1: + // [6] phi (byte) idx_ssa_g#7 = (byte) idx_ssa_g#2 [phi:main::@1->main::@1#0] -- register_copy + // [6] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy + jmp __b1 + // main::@1 + __b1: + // [7] *((const byte*) SCREEN1 + (byte) idx_ssa_g#7) ← (byte) main::i#2 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z i + ldy.z idx_ssa_g + sta SCREEN1,y + // [8] (byte) idx_ssa_g#2 ← ++ (byte) idx_ssa_g#7 -- vbuz1=_inc_vbuz1 + inc.z idx_ssa_g + // [9] (byte) main::i#1 ← -- (byte) main::i#2 -- vbuz1=_dec_vbuz1 + dec.z i + // [10] if((byte) main::i#1!=(byte) 'L'-(byte) 1) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 + lda #'L'-1 + cmp.z i + bne __b1_from___b1 + jmp __b2 + // main::@2 + __b2: + // [11] *((const byte*) SCREEN1 + (byte) idx_ssa_g#2) ← (byte) '!' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'!' + ldy.z idx_ssa_g + sta SCREEN1,y + // [12] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) 'C' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'C' + ldy.z idx_nssa_g + sta SCREEN2,y + // [13] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_g + // [14] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + __b3_from___b2: + // [14] phi (byte) main::i1#2 = (byte) 'M' [phi:main::@2->main::@3#0] -- vbuz1=vbuc1 + lda #'M' + sta.z i1 + jmp __b3 + // [14] phi from main::@3 to main::@3 [phi:main::@3->main::@3] + __b3_from___b3: + // [14] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@3->main::@3#0] -- register_copy + jmp __b3 + // main::@3 + __b3: + // [15] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) main::i1#2 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z i1 + ldy.z idx_nssa_g + sta SCREEN2,y + // [16] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_g + // [17] (byte) main::i1#1 ← -- (byte) main::i1#2 -- vbuz1=_dec_vbuz1 + dec.z i1 + // [18] if((byte) main::i1#1!=(byte) 'L'-(byte) 1) goto main::@3 -- vbuz1_neq_vbuc1_then_la1 + lda #'L'-1 + cmp.z i1 + bne __b3_from___b3 + jmp __b4 + // main::@4 + __b4: + // [19] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) '!' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'!' + ldy.z idx_nssa_g + sta SCREEN2,y + // [20] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_g + // [21] *((const byte*) SCREEN3) ← (byte) 'C' -- _deref_pbuc1=vbuc2 + lda #'C' + sta SCREEN3 + // [22] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + __b5_from___b4: + // [22] phi (byte) main::idx_ssa_l#5 = (byte) 1 [phi:main::@4->main::@5#0] -- vbuz1=vbuc1 + lda #1 + sta.z idx_ssa_l + // [22] phi (byte) main::i2#2 = (byte) 'M' [phi:main::@4->main::@5#1] -- vbuz1=vbuc1 + lda #'M' + sta.z i2 + jmp __b5 + // [22] phi from main::@5 to main::@5 [phi:main::@5->main::@5] + __b5_from___b5: + // [22] phi (byte) main::idx_ssa_l#5 = (byte) main::idx_ssa_l#2 [phi:main::@5->main::@5#0] -- register_copy + // [22] phi (byte) main::i2#2 = (byte) main::i2#1 [phi:main::@5->main::@5#1] -- register_copy + jmp __b5 + // main::@5 + __b5: + // [23] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#5) ← (byte) main::i2#2 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z i2 + ldy.z idx_ssa_l + sta SCREEN3,y + // [24] (byte) main::idx_ssa_l#2 ← ++ (byte) main::idx_ssa_l#5 -- vbuz1=_inc_vbuz1 + inc.z idx_ssa_l + // [25] (byte) main::i2#1 ← -- (byte) main::i2#2 -- vbuz1=_dec_vbuz1 + dec.z i2 + // [26] if((byte) main::i2#1!=(byte) 'L'-(byte) 1) goto main::@5 -- vbuz1_neq_vbuc1_then_la1 + lda #'L'-1 + cmp.z i2 + bne __b5_from___b5 + jmp __b6 + // main::@6 + __b6: + // [27] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#2) ← (byte) '!' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'!' + ldy.z idx_ssa_l + sta SCREEN3,y + // [28] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) 'C' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'C' + ldy.z idx_nssa_l + sta SCREEN4,y + // [29] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_l + // [30] phi from main::@6 to main::@7 [phi:main::@6->main::@7] + __b7_from___b6: + // [30] phi (byte) main::i3#2 = (byte) 'M' [phi:main::@6->main::@7#0] -- vbuz1=vbuc1 + lda #'M' + sta.z i3 + jmp __b7 + // [30] phi from main::@7 to main::@7 [phi:main::@7->main::@7] + __b7_from___b7: + // [30] phi (byte) main::i3#2 = (byte) main::i3#1 [phi:main::@7->main::@7#0] -- register_copy + jmp __b7 + // main::@7 + __b7: + // [31] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) main::i3#2 -- pbuc1_derefidx_vbuz1=vbuz2 + lda.z i3 + ldy.z idx_nssa_l + sta SCREEN4,y + // [32] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_l + // [33] (byte) main::i3#1 ← -- (byte) main::i3#2 -- vbuz1=_dec_vbuz1 + dec.z i3 + // [34] if((byte) main::i3#1!=(byte) 'L'-(byte) 1) goto main::@7 -- vbuz1_neq_vbuc1_then_la1 + lda #'L'-1 + cmp.z i3 + bne __b7_from___b7 + jmp __b8 + // main::@8 + __b8: + // [35] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) '!' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'!' + ldy.z idx_nssa_l + sta SCREEN4,y + // [36] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_l + jmp __breturn + // main::@return + __breturn: + // [37] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [0] (byte) idx_nssa_g ← (byte) 0 [ idx_nssa_g ] ( [ idx_nssa_g ] ) always clobbers reg byte a +Statement [4] (byte) main::idx_nssa_l ← (byte) 0 [ idx_nssa_g main::idx_nssa_l ] ( main:2 [ idx_nssa_g main::idx_nssa_l ] ) always clobbers reg byte a +Statement [5] *((const byte*) SCREEN1) ← (byte) 'C' [ idx_nssa_g main::idx_nssa_l ] ( main:2 [ idx_nssa_g main::idx_nssa_l ] ) always clobbers reg byte a +Statement [11] *((const byte*) SCREEN1 + (byte) idx_ssa_g#2) ← (byte) '!' [ idx_nssa_g main::idx_nssa_l ] ( main:2 [ idx_nssa_g main::idx_nssa_l ] ) always clobbers reg byte a +Statement [12] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) 'C' [ main::idx_nssa_l ] ( main:2 [ main::idx_nssa_l ] ) always clobbers reg byte a reg byte y +Statement [15] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) main::i1#2 [ main::idx_nssa_l main::i1#2 ] ( main:2 [ main::idx_nssa_l main::i1#2 ] ) always clobbers reg byte y +Removing always clobbered register reg byte y as potential for zp[1]:4 [ main::i1#2 main::i1#1 ] +Statement [19] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) '!' [ main::idx_nssa_l ] ( main:2 [ main::idx_nssa_l ] ) always clobbers reg byte a reg byte y +Statement [21] *((const byte*) SCREEN3) ← (byte) 'C' [ main::idx_nssa_l ] ( main:2 [ main::idx_nssa_l ] ) always clobbers reg byte a +Statement [27] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#2) ← (byte) '!' [ main::idx_nssa_l ] ( main:2 [ main::idx_nssa_l ] ) always clobbers reg byte a +Statement [28] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) 'C' [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Statement [31] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) main::i3#2 [ main::i3#2 ] ( main:2 [ main::i3#2 ] ) always clobbers reg byte y +Removing always clobbered register reg byte y as potential for zp[1]:7 [ main::i3#2 main::i3#1 ] +Statement [35] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) '!' [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Statement [0] (byte) idx_nssa_g ← (byte) 0 [ idx_nssa_g ] ( [ idx_nssa_g ] ) always clobbers reg byte a +Statement [4] (byte) main::idx_nssa_l ← (byte) 0 [ idx_nssa_g main::idx_nssa_l ] ( main:2 [ idx_nssa_g main::idx_nssa_l ] ) always clobbers reg byte a +Statement [5] *((const byte*) SCREEN1) ← (byte) 'C' [ idx_nssa_g main::idx_nssa_l ] ( main:2 [ idx_nssa_g main::idx_nssa_l ] ) always clobbers reg byte a +Statement [11] *((const byte*) SCREEN1 + (byte) idx_ssa_g#2) ← (byte) '!' [ idx_nssa_g main::idx_nssa_l ] ( main:2 [ idx_nssa_g main::idx_nssa_l ] ) always clobbers reg byte a +Statement [12] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) 'C' [ main::idx_nssa_l ] ( main:2 [ main::idx_nssa_l ] ) always clobbers reg byte a reg byte y +Statement [15] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) main::i1#2 [ main::idx_nssa_l main::i1#2 ] ( main:2 [ main::idx_nssa_l main::i1#2 ] ) always clobbers reg byte y +Statement [19] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) '!' [ main::idx_nssa_l ] ( main:2 [ main::idx_nssa_l ] ) always clobbers reg byte a reg byte y +Statement [21] *((const byte*) SCREEN3) ← (byte) 'C' [ main::idx_nssa_l ] ( main:2 [ main::idx_nssa_l ] ) always clobbers reg byte a +Statement [27] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#2) ← (byte) '!' [ main::idx_nssa_l ] ( main:2 [ main::idx_nssa_l ] ) always clobbers reg byte a +Statement [28] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) 'C' [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Statement [31] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) main::i3#2 [ main::i3#2 ] ( main:2 [ main::i3#2 ] ) always clobbers reg byte y +Statement [35] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) '!' [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y +Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:3 [ idx_ssa_g#7 idx_ssa_g#2 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:4 [ main::i1#2 main::i1#1 ] : zp[1]:4 , reg byte a , reg byte x , +Potential registers zp[1]:5 [ main::i2#2 main::i2#1 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:6 [ main::idx_ssa_l#5 main::idx_ssa_l#2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:7 [ main::i3#2 main::i3#1 ] : zp[1]:7 , reg byte a , reg byte x , +Potential registers zp[1]:8 [ idx_nssa_g ] : zp[1]:8 , +Potential registers zp[1]:9 [ main::idx_nssa_l ] : zp[1]:9 , + +REGISTER UPLIFT SCOPES +Uplift Scope [main] 27.5: zp[1]:2 [ main::i#2 main::i#1 ] 27.5: zp[1]:4 [ main::i1#2 main::i1#1 ] 27.5: zp[1]:5 [ main::i2#2 main::i2#1 ] 27.5: zp[1]:7 [ main::i3#2 main::i3#1 ] 24.5: zp[1]:6 [ main::idx_ssa_l#5 main::idx_ssa_l#2 ] 1.62: zp[1]:9 [ main::idx_nssa_l ] +Uplift Scope [] 24.5: zp[1]:3 [ idx_ssa_g#7 idx_ssa_g#2 ] 3.13: zp[1]:8 [ idx_nssa_g ] + +Uplifting [main] best 1523 combination reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::i1#2 main::i1#1 ] reg byte x [ main::i2#2 main::i2#1 ] reg byte a [ main::i3#2 main::i3#1 ] zp[1]:6 [ main::idx_ssa_l#5 main::idx_ssa_l#2 ] zp[1]:9 [ main::idx_nssa_l ] +Limited combination testing to 100 combinations of 576 possible. +Uplifting [] best 1430 combination reg byte y [ idx_ssa_g#7 idx_ssa_g#2 ] zp[1]:8 [ idx_nssa_g ] +Attempting to uplift remaining variables inzp[1]:6 [ main::idx_ssa_l#5 main::idx_ssa_l#2 ] +Uplifting [main] best 1337 combination reg byte y [ main::idx_ssa_l#5 main::idx_ssa_l#2 ] +Attempting to uplift remaining variables inzp[1]:8 [ idx_nssa_g ] +Uplifting [] best 1337 combination zp[1]:8 [ idx_nssa_g ] +Attempting to uplift remaining variables inzp[1]:9 [ main::idx_nssa_l ] +Uplifting [main] best 1337 combination zp[1]:9 [ main::idx_nssa_l ] +Allocated (was zp[1]:8) zp[1]:2 [ idx_nssa_g ] +Allocated (was zp[1]:9) zp[1]:3 [ main::idx_nssa_l ] + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Tests declaring variables as __ssa / __notssa + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN1 = $400 + .label SCREEN2 = $400+$28 + .label SCREEN3 = $400+$50 + .label SCREEN4 = $400+$78 + .label idx_nssa_g = 2 + // @begin +__bbegin: + // [0] (byte) idx_nssa_g ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z idx_nssa_g + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + .label idx_nssa_l = 3 + // [4] (byte) main::idx_nssa_l ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z idx_nssa_l + // [5] *((const byte*) SCREEN1) ← (byte) 'C' -- _deref_pbuc1=vbuc2 + lda #'C' + sta SCREEN1 + // [6] phi from main to main::@1 [phi:main->main::@1] + __b1_from_main: + // [6] phi (byte) idx_ssa_g#7 = (byte) 1 [phi:main->main::@1#0] -- vbuyy=vbuc1 + ldy #1 + // [6] phi (byte) main::i#2 = (byte) 'M' [phi:main->main::@1#1] -- vbuxx=vbuc1 + ldx #'M' + jmp __b1 + // [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + __b1_from___b1: + // [6] phi (byte) idx_ssa_g#7 = (byte) idx_ssa_g#2 [phi:main::@1->main::@1#0] -- register_copy + // [6] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy + jmp __b1 + // main::@1 + __b1: + // [7] *((const byte*) SCREEN1 + (byte) idx_ssa_g#7) ← (byte) main::i#2 -- pbuc1_derefidx_vbuyy=vbuxx + txa + sta SCREEN1,y + // [8] (byte) idx_ssa_g#2 ← ++ (byte) idx_ssa_g#7 -- vbuyy=_inc_vbuyy + iny + // [9] (byte) main::i#1 ← -- (byte) main::i#2 -- vbuxx=_dec_vbuxx + dex + // [10] if((byte) main::i#1!=(byte) 'L'-(byte) 1) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 + cpx #'L'-1 + bne __b1_from___b1 + jmp __b2 + // main::@2 + __b2: + // [11] *((const byte*) SCREEN1 + (byte) idx_ssa_g#2) ← (byte) '!' -- pbuc1_derefidx_vbuyy=vbuc2 + lda #'!' + sta SCREEN1,y + // [12] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) 'C' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'C' + ldy.z idx_nssa_g + sta SCREEN2,y + // [13] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_g + // [14] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + __b3_from___b2: + // [14] phi (byte) main::i1#2 = (byte) 'M' [phi:main::@2->main::@3#0] -- vbuaa=vbuc1 + lda #'M' + jmp __b3 + // [14] phi from main::@3 to main::@3 [phi:main::@3->main::@3] + __b3_from___b3: + // [14] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@3->main::@3#0] -- register_copy + jmp __b3 + // main::@3 + __b3: + // [15] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) main::i1#2 -- pbuc1_derefidx_vbuz1=vbuaa + ldy.z idx_nssa_g + sta SCREEN2,y + // [16] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_g + // [17] (byte) main::i1#1 ← -- (byte) main::i1#2 -- vbuaa=_dec_vbuaa + sec + sbc #1 + // [18] if((byte) main::i1#1!=(byte) 'L'-(byte) 1) goto main::@3 -- vbuaa_neq_vbuc1_then_la1 + cmp #'L'-1 + bne __b3_from___b3 + jmp __b4 + // main::@4 + __b4: + // [19] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) '!' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'!' + ldy.z idx_nssa_g + sta SCREEN2,y + // [20] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_g + // [21] *((const byte*) SCREEN3) ← (byte) 'C' -- _deref_pbuc1=vbuc2 + lda #'C' + sta SCREEN3 + // [22] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + __b5_from___b4: + // [22] phi (byte) main::idx_ssa_l#5 = (byte) 1 [phi:main::@4->main::@5#0] -- vbuyy=vbuc1 + ldy #1 + // [22] phi (byte) main::i2#2 = (byte) 'M' [phi:main::@4->main::@5#1] -- vbuxx=vbuc1 + ldx #'M' + jmp __b5 + // [22] phi from main::@5 to main::@5 [phi:main::@5->main::@5] + __b5_from___b5: + // [22] phi (byte) main::idx_ssa_l#5 = (byte) main::idx_ssa_l#2 [phi:main::@5->main::@5#0] -- register_copy + // [22] phi (byte) main::i2#2 = (byte) main::i2#1 [phi:main::@5->main::@5#1] -- register_copy + jmp __b5 + // main::@5 + __b5: + // [23] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#5) ← (byte) main::i2#2 -- pbuc1_derefidx_vbuyy=vbuxx + txa + sta SCREEN3,y + // [24] (byte) main::idx_ssa_l#2 ← ++ (byte) main::idx_ssa_l#5 -- vbuyy=_inc_vbuyy + iny + // [25] (byte) main::i2#1 ← -- (byte) main::i2#2 -- vbuxx=_dec_vbuxx + dex + // [26] if((byte) main::i2#1!=(byte) 'L'-(byte) 1) goto main::@5 -- vbuxx_neq_vbuc1_then_la1 + cpx #'L'-1 + bne __b5_from___b5 + jmp __b6 + // main::@6 + __b6: + // [27] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#2) ← (byte) '!' -- pbuc1_derefidx_vbuyy=vbuc2 + lda #'!' + sta SCREEN3,y + // [28] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) 'C' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'C' + ldy.z idx_nssa_l + sta SCREEN4,y + // [29] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_l + // [30] phi from main::@6 to main::@7 [phi:main::@6->main::@7] + __b7_from___b6: + // [30] phi (byte) main::i3#2 = (byte) 'M' [phi:main::@6->main::@7#0] -- vbuaa=vbuc1 + lda #'M' + jmp __b7 + // [30] phi from main::@7 to main::@7 [phi:main::@7->main::@7] + __b7_from___b7: + // [30] phi (byte) main::i3#2 = (byte) main::i3#1 [phi:main::@7->main::@7#0] -- register_copy + jmp __b7 + // main::@7 + __b7: + // [31] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) main::i3#2 -- pbuc1_derefidx_vbuz1=vbuaa + ldy.z idx_nssa_l + sta SCREEN4,y + // [32] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_l + // [33] (byte) main::i3#1 ← -- (byte) main::i3#2 -- vbuaa=_dec_vbuaa + sec + sbc #1 + // [34] if((byte) main::i3#1!=(byte) 'L'-(byte) 1) goto main::@7 -- vbuaa_neq_vbuc1_then_la1 + cmp #'L'-1 + bne __b7_from___b7 + jmp __b8 + // main::@8 + __b8: + // [35] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) '!' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'!' + ldy.z idx_nssa_l + sta SCREEN4,y + // [36] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_l + jmp __breturn + // main::@return + __breturn: + // [37] return + rts +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __b1 +Removing instruction jmp __bend +Removing instruction jmp __b1 +Removing instruction jmp __b2 +Removing instruction jmp __b3 +Removing instruction jmp __b4 +Removing instruction jmp __b5 +Removing instruction jmp __b6 +Removing instruction jmp __b7 +Removing instruction jmp __b8 +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Replacing label __b1_from___b1 with __b1 +Replacing label __b3_from___b3 with __b3 +Replacing label __b5_from___b5 with __b5 +Replacing label __b7_from___b7 with __b7 +Removing instruction __b1_from___bbegin: +Removing instruction __bend_from___b1: +Removing instruction __b1_from___b1: +Removing instruction __b3_from___b3: +Removing instruction __b5_from___b5: +Removing instruction __b7_from___b7: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __b1: +Removing instruction __bend: +Removing instruction __b1_from_main: +Removing instruction __b2: +Removing instruction __b3_from___b2: +Removing instruction __b4: +Removing instruction __b5_from___b4: +Removing instruction __b6: +Removing instruction __b7_from___b6: +Removing instruction __b8: +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Adding RTS to root block +Succesful ASM optimization Pass5AddMainRts +Removing instruction jmp __b1 +Removing instruction jmp __b3 +Removing instruction jmp __b5 +Removing instruction jmp __b7 +Succesful ASM optimization Pass5NextJumpElimination + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(const byte*) SCREEN1 = (byte*) 1024 +(const byte*) SCREEN2 = (byte*)(number) $400+(number) $28 +(const byte*) SCREEN3 = (byte*)(number) $400+(number) $50 +(const byte*) SCREEN4 = (byte*)(number) $400+(number) $78 +(byte) idx_nssa_g notregister zp[1]:2 3.1333333333333333 +(byte) idx_ssa_g +(byte) idx_ssa_g#2 reg byte y 8.0 +(byte) idx_ssa_g#7 reg byte y 16.5 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@4 +(label) main::@5 +(label) main::@6 +(label) main::@7 +(label) main::@8 +(label) main::@return +(byte) main::i +(byte) main::i#1 reg byte x 16.5 +(byte) main::i#2 reg byte x 11.0 +(byte) main::i1 +(byte) main::i1#1 reg byte a 16.5 +(byte) main::i1#2 reg byte a 11.0 +(byte) main::i2 +(byte) main::i2#1 reg byte x 16.5 +(byte) main::i2#2 reg byte x 11.0 +(byte) main::i3 +(byte) main::i3#1 reg byte a 16.5 +(byte) main::i3#2 reg byte a 11.0 +(byte) main::idx_nssa_l notregister zp[1]:3 1.6206896551724135 +(byte) main::idx_ssa_l +(byte) main::idx_ssa_l#2 reg byte y 8.0 +(byte) main::idx_ssa_l#5 reg byte y 16.5 + +reg byte x [ main::i#2 main::i#1 ] +reg byte y [ idx_ssa_g#7 idx_ssa_g#2 ] +reg byte a [ main::i1#2 main::i1#1 ] +reg byte x [ main::i2#2 main::i2#1 ] +reg byte y [ main::idx_ssa_l#5 main::idx_ssa_l#2 ] +reg byte a [ main::i3#2 main::i3#1 ] +zp[1]:2 [ idx_nssa_g ] +zp[1]:3 [ main::idx_nssa_l ] + + +FINAL ASSEMBLER +Score: 974 + + // File Comments +// Tests declaring variables as __ssa / __notssa + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN1 = $400 + .label SCREEN2 = $400+$28 + .label SCREEN3 = $400+$50 + .label SCREEN4 = $400+$78 + .label idx_nssa_g = 2 + // @begin +__bbegin: + // idx_nssa_g + // [0] (byte) idx_nssa_g ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z idx_nssa_g + // [1] phi from @begin to @1 [phi:@begin->@1] + // @1 + // [2] call main + jsr main + rts + // [3] phi from @1 to @end [phi:@1->@end] + // @end + // main +main: { + .label idx_nssa_l = 3 + // idx_nssa_l + // [4] (byte) main::idx_nssa_l ← (byte) 0 -- vbuz1=vbuc1 + lda #0 + sta.z idx_nssa_l + // SCREEN1[idx_ssa_g++] = 'C' + // [5] *((const byte*) SCREEN1) ← (byte) 'C' -- _deref_pbuc1=vbuc2 + lda #'C' + sta SCREEN1 + // [6] phi from main to main::@1 [phi:main->main::@1] + // [6] phi (byte) idx_ssa_g#7 = (byte) 1 [phi:main->main::@1#0] -- vbuyy=vbuc1 + ldy #1 + // [6] phi (byte) main::i#2 = (byte) 'M' [phi:main->main::@1#1] -- vbuxx=vbuc1 + ldx #'M' + // [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1] + // [6] phi (byte) idx_ssa_g#7 = (byte) idx_ssa_g#2 [phi:main::@1->main::@1#0] -- register_copy + // [6] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#1] -- register_copy + // main::@1 + __b1: + // SCREEN1[idx_ssa_g++] = i + // [7] *((const byte*) SCREEN1 + (byte) idx_ssa_g#7) ← (byte) main::i#2 -- pbuc1_derefidx_vbuyy=vbuxx + txa + sta SCREEN1,y + // SCREEN1[idx_ssa_g++] = i; + // [8] (byte) idx_ssa_g#2 ← ++ (byte) idx_ssa_g#7 -- vbuyy=_inc_vbuyy + iny + // for( char i: 'M'..'L') + // [9] (byte) main::i#1 ← -- (byte) main::i#2 -- vbuxx=_dec_vbuxx + dex + // [10] if((byte) main::i#1!=(byte) 'L'-(byte) 1) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 + cpx #'L'-1 + bne __b1 + // main::@2 + // SCREEN1[idx_ssa_g++] = '!' + // [11] *((const byte*) SCREEN1 + (byte) idx_ssa_g#2) ← (byte) '!' -- pbuc1_derefidx_vbuyy=vbuc2 + lda #'!' + sta SCREEN1,y + // SCREEN2[idx_nssa_g++] = 'C' + // [12] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) 'C' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'C' + ldy.z idx_nssa_g + sta SCREEN2,y + // SCREEN2[idx_nssa_g++] = 'C'; + // [13] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_g + // [14] phi from main::@2 to main::@3 [phi:main::@2->main::@3] + // [14] phi (byte) main::i1#2 = (byte) 'M' [phi:main::@2->main::@3#0] -- vbuaa=vbuc1 + lda #'M' + // [14] phi from main::@3 to main::@3 [phi:main::@3->main::@3] + // [14] phi (byte) main::i1#2 = (byte) main::i1#1 [phi:main::@3->main::@3#0] -- register_copy + // main::@3 + __b3: + // SCREEN2[idx_nssa_g++] = i + // [15] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) main::i1#2 -- pbuc1_derefidx_vbuz1=vbuaa + ldy.z idx_nssa_g + sta SCREEN2,y + // SCREEN2[idx_nssa_g++] = i; + // [16] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_g + // for( char i: 'M'..'L') + // [17] (byte) main::i1#1 ← -- (byte) main::i1#2 -- vbuaa=_dec_vbuaa + sec + sbc #1 + // [18] if((byte) main::i1#1!=(byte) 'L'-(byte) 1) goto main::@3 -- vbuaa_neq_vbuc1_then_la1 + cmp #'L'-1 + bne __b3 + // main::@4 + // SCREEN2[idx_nssa_g++] = '!' + // [19] *((const byte*) SCREEN2 + (byte) idx_nssa_g) ← (byte) '!' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'!' + ldy.z idx_nssa_g + sta SCREEN2,y + // SCREEN2[idx_nssa_g++] = '!'; + // [20] (byte) idx_nssa_g ← ++ (byte) idx_nssa_g -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_g + // SCREEN3[idx_ssa_l++] = 'C' + // [21] *((const byte*) SCREEN3) ← (byte) 'C' -- _deref_pbuc1=vbuc2 + lda #'C' + sta SCREEN3 + // [22] phi from main::@4 to main::@5 [phi:main::@4->main::@5] + // [22] phi (byte) main::idx_ssa_l#5 = (byte) 1 [phi:main::@4->main::@5#0] -- vbuyy=vbuc1 + ldy #1 + // [22] phi (byte) main::i2#2 = (byte) 'M' [phi:main::@4->main::@5#1] -- vbuxx=vbuc1 + ldx #'M' + // [22] phi from main::@5 to main::@5 [phi:main::@5->main::@5] + // [22] phi (byte) main::idx_ssa_l#5 = (byte) main::idx_ssa_l#2 [phi:main::@5->main::@5#0] -- register_copy + // [22] phi (byte) main::i2#2 = (byte) main::i2#1 [phi:main::@5->main::@5#1] -- register_copy + // main::@5 + __b5: + // SCREEN3[idx_ssa_l++] = i + // [23] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#5) ← (byte) main::i2#2 -- pbuc1_derefidx_vbuyy=vbuxx + txa + sta SCREEN3,y + // SCREEN3[idx_ssa_l++] = i; + // [24] (byte) main::idx_ssa_l#2 ← ++ (byte) main::idx_ssa_l#5 -- vbuyy=_inc_vbuyy + iny + // for( char i: 'M'..'L') + // [25] (byte) main::i2#1 ← -- (byte) main::i2#2 -- vbuxx=_dec_vbuxx + dex + // [26] if((byte) main::i2#1!=(byte) 'L'-(byte) 1) goto main::@5 -- vbuxx_neq_vbuc1_then_la1 + cpx #'L'-1 + bne __b5 + // main::@6 + // SCREEN3[idx_ssa_l++] = '!' + // [27] *((const byte*) SCREEN3 + (byte) main::idx_ssa_l#2) ← (byte) '!' -- pbuc1_derefidx_vbuyy=vbuc2 + lda #'!' + sta SCREEN3,y + // SCREEN4[idx_nssa_l++] = 'C' + // [28] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) 'C' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'C' + ldy.z idx_nssa_l + sta SCREEN4,y + // SCREEN4[idx_nssa_l++] = 'C'; + // [29] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_l + // [30] phi from main::@6 to main::@7 [phi:main::@6->main::@7] + // [30] phi (byte) main::i3#2 = (byte) 'M' [phi:main::@6->main::@7#0] -- vbuaa=vbuc1 + lda #'M' + // [30] phi from main::@7 to main::@7 [phi:main::@7->main::@7] + // [30] phi (byte) main::i3#2 = (byte) main::i3#1 [phi:main::@7->main::@7#0] -- register_copy + // main::@7 + __b7: + // SCREEN4[idx_nssa_l++] = i + // [31] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) main::i3#2 -- pbuc1_derefidx_vbuz1=vbuaa + ldy.z idx_nssa_l + sta SCREEN4,y + // SCREEN4[idx_nssa_l++] = i; + // [32] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_l + // for( char i: 'M'..'L') + // [33] (byte) main::i3#1 ← -- (byte) main::i3#2 -- vbuaa=_dec_vbuaa + sec + sbc #1 + // [34] if((byte) main::i3#1!=(byte) 'L'-(byte) 1) goto main::@7 -- vbuaa_neq_vbuc1_then_la1 + cmp #'L'-1 + bne __b7 + // main::@8 + // SCREEN4[idx_nssa_l++] = '!' + // [35] *((const byte*) SCREEN4 + (byte) main::idx_nssa_l) ← (byte) '!' -- pbuc1_derefidx_vbuz1=vbuc2 + lda #'!' + ldy.z idx_nssa_l + sta SCREEN4,y + // SCREEN4[idx_nssa_l++] = '!'; + // [36] (byte) main::idx_nssa_l ← ++ (byte) main::idx_nssa_l -- vbuz1=_inc_vbuz1 + inc.z idx_nssa_l + // main::@return + // } + // [37] return + rts +} + // File Data + diff --git a/src/test/ref/declared-ssa-var-0.sym b/src/test/ref/declared-ssa-var-0.sym new file mode 100644 index 000000000..deff4b65c --- /dev/null +++ b/src/test/ref/declared-ssa-var-0.sym @@ -0,0 +1,46 @@ +(label) @1 +(label) @begin +(label) @end +(const byte*) SCREEN1 = (byte*) 1024 +(const byte*) SCREEN2 = (byte*)(number) $400+(number) $28 +(const byte*) SCREEN3 = (byte*)(number) $400+(number) $50 +(const byte*) SCREEN4 = (byte*)(number) $400+(number) $78 +(byte) idx_nssa_g notregister zp[1]:2 3.1333333333333333 +(byte) idx_ssa_g +(byte) idx_ssa_g#2 reg byte y 8.0 +(byte) idx_ssa_g#7 reg byte y 16.5 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@4 +(label) main::@5 +(label) main::@6 +(label) main::@7 +(label) main::@8 +(label) main::@return +(byte) main::i +(byte) main::i#1 reg byte x 16.5 +(byte) main::i#2 reg byte x 11.0 +(byte) main::i1 +(byte) main::i1#1 reg byte a 16.5 +(byte) main::i1#2 reg byte a 11.0 +(byte) main::i2 +(byte) main::i2#1 reg byte x 16.5 +(byte) main::i2#2 reg byte x 11.0 +(byte) main::i3 +(byte) main::i3#1 reg byte a 16.5 +(byte) main::i3#2 reg byte a 11.0 +(byte) main::idx_nssa_l notregister zp[1]:3 1.6206896551724135 +(byte) main::idx_ssa_l +(byte) main::idx_ssa_l#2 reg byte y 8.0 +(byte) main::idx_ssa_l#5 reg byte y 16.5 + +reg byte x [ main::i#2 main::i#1 ] +reg byte y [ idx_ssa_g#7 idx_ssa_g#2 ] +reg byte a [ main::i1#2 main::i1#1 ] +reg byte x [ main::i2#2 main::i2#1 ] +reg byte y [ main::idx_ssa_l#5 main::idx_ssa_l#2 ] +reg byte a [ main::i3#2 main::i3#1 ] +zp[1]:2 [ idx_nssa_g ] +zp[1]:3 [ main::idx_nssa_l ]