From b0e6ae0b67836f4dd1e1b3b1cb7bf0e9190e3ec6 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Fri, 10 Nov 2017 00:27:56 +0100 Subject: [PATCH] Added a test with two levels of methods to test live ranges / call-paths and allocation of a minimal number of registers. --- .../dk/camelot64/kickc/test/TestPrograms.java | 4 + .../kickc/test/overlap-allocation-2.kc | 20 + .../kickc/test/ref/overlap-allocation-2.asm | 35 + .../kickc/test/ref/overlap-allocation-2.cfg | 50 + .../kickc/test/ref/overlap-allocation-2.log | 2172 +++++++++++++++++ .../kickc/test/ref/overlap-allocation-2.sym | 37 + 6 files changed, 2318 insertions(+) create mode 100644 src/main/java/dk/camelot64/kickc/test/overlap-allocation-2.kc create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.asm create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.cfg create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.log create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.sym diff --git a/src/main/java/dk/camelot64/kickc/test/TestPrograms.java b/src/main/java/dk/camelot64/kickc/test/TestPrograms.java index fee4ae35f..fb2c74755 100644 --- a/src/main/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/main/java/dk/camelot64/kickc/test/TestPrograms.java @@ -24,6 +24,10 @@ public class TestPrograms extends TestCase { helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/"); } + public void testOverlapAllocation2() throws IOException, URISyntaxException { + compileAndCompare("overlap-allocation-2"); + } + public void testOverlapAllocation() throws IOException, URISyntaxException { compileAndCompare("overlap-allocation"); } diff --git a/src/main/java/dk/camelot64/kickc/test/overlap-allocation-2.kc b/src/main/java/dk/camelot64/kickc/test/overlap-allocation-2.kc new file mode 100644 index 000000000..b9d4b0de8 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/overlap-allocation-2.kc @@ -0,0 +1,20 @@ +// Two levels of functions to test that register allocation handles live ranges and call-ranges optimally to allocate the fewest possible ZP-variables +byte* SCREEN = $0400; + +void main() { + for(byte i : 0..8) { + line(i); + } + for(byte j : 10..18) { + line(j); + } +} + +void line(byte l) { + plot(l); + plot(l+20); +} + +void plot(byte x) { + SCREEN[x] = '*'; +} diff --git a/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.asm b/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.asm new file mode 100644 index 000000000..a27954736 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.asm @@ -0,0 +1,35 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .const SCREEN = $400 + jsr main +main: { + ldy #0 + b1: + jsr line + iny + cpy #9 + bne b1 + ldy #$a + b2: + jsr line + iny + cpy #$13 + bne b2 + rts +} +line: { + tya + jsr plot + tya + clc + adc #$14 + jsr plot + rts +} +plot: { + tax + lda #'*' + sta SCREEN,x + rts +} diff --git a/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.cfg b/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.cfg new file mode 100644 index 000000000..d9803c385 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.cfg @@ -0,0 +1,50 @@ +@begin: scope:[] from + to:@3 +@3: scope:[] from @begin + [0] call main param-assignment [ ] ( ) + to:@end +@end: scope:[] from @3 +main: scope:[main] from @3 + [1] phi() [ ] ( main:0 [ ] ) + to:main::@1 +main::@1: scope:[main] from main main::@5 + [2] (byte) main::i#2 ← phi( main/(byte) 0 main::@5/(byte) main::i#1 ) [ main::i#2 ] ( main:0 [ main::i#2 ] ) + [3] (byte) line::l#0 ← (byte) main::i#2 [ main::i#2 line::l#0 ] ( main:0 [ main::i#2 line::l#0 ] ) + [4] call line param-assignment [ main::i#2 ] ( main:0 [ main::i#2 ] ) + to:main::@5 +main::@5: scope:[main] from main::@1 + [5] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:0 [ main::i#1 ] ) + [6] if((byte) main::i#1!=(byte) 9) goto main::@1 [ main::i#1 ] ( main:0 [ main::i#1 ] ) + to:main::@2 +main::@2: scope:[main] from main::@5 main::@6 + [7] (byte) main::j#2 ← phi( main::@5/(byte) 10 main::@6/(byte) main::j#1 ) [ main::j#2 ] ( main:0 [ main::j#2 ] ) + [8] (byte) line::l#1 ← (byte) main::j#2 [ main::j#2 line::l#1 ] ( main:0 [ main::j#2 line::l#1 ] ) + [9] call line param-assignment [ main::j#2 ] ( main:0 [ main::j#2 ] ) + to:main::@6 +main::@6: scope:[main] from main::@2 + [10] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) + [11] if((byte) main::j#1!=(byte) 19) goto main::@2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) + to:main::@return +main::@return: scope:[main] from main::@6 + [12] return [ ] ( main:0 [ ] ) + to:@return +line: scope:[line] from main::@1 main::@2 + [13] (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) [ line::l#2 ] ( main:0::line:4 [ main::i#2 line::l#2 ] main:0::line:9 [ main::j#2 line::l#2 ] ) + [14] (byte) plot::x#0 ← (byte) line::l#2 [ line::l#2 plot::x#0 ] ( main:0::line:4 [ main::i#2 line::l#2 plot::x#0 ] main:0::line:9 [ main::j#2 line::l#2 plot::x#0 ] ) + [15] call plot param-assignment [ line::l#2 ] ( main:0::line:4 [ main::i#2 line::l#2 ] main:0::line:9 [ main::j#2 line::l#2 ] ) + to:line::@1 +line::@1: scope:[line] from line + [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] ( main:0::line:4 [ main::i#2 line::$1 ] main:0::line:9 [ main::j#2 line::$1 ] ) + [17] (byte) plot::x#1 ← (byte~) line::$1 [ plot::x#1 ] ( main:0::line:4 [ main::i#2 plot::x#1 ] main:0::line:9 [ main::j#2 plot::x#1 ] ) + [18] call plot param-assignment [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + to:line::@return +line::@return: scope:[line] from line::@1 + [19] return [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + to:@return +plot: scope:[plot] from line line::@1 + [20] (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) [ plot::x#2 ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 plot::x#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 plot::x#2 ] main:0::line:4::plot:18 [ main::i#2 plot::x#2 ] main:0::line:9::plot:18 [ main::j#2 plot::x#2 ] ) + [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) + to:plot::@return +plot::@return: scope:[plot] from plot + [22] return [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) + to:@return diff --git a/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.log b/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.log new file mode 100644 index 000000000..39100e1ce --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.log @@ -0,0 +1,2172 @@ +// Two levels of functions to test that register allocation handles live ranges and call-ranges optimally to allocate the fewest possible ZP-variables +byte* SCREEN = $0400; + +void main() { + for(byte i : 0..8) { + line(i); + } + for(byte j : 10..18) { + line(j); + } +} + +void line(byte l) { + plot(l); + plot(l+20); +} + +void plot(byte x) { + SCREEN[x] = '*'; +} + +PROGRAM + (byte*) SCREEN ← (word) 1024 +proc (void()) main() + (byte) main::i ← (byte) 0 +main::@1: + (void~) main::$0 ← call line (byte) main::i + (byte) main::i ← ++ (byte) main::i + (boolean~) main::$1 ← (byte) main::i != (byte) 9 + if((boolean~) main::$1) goto main::@1 + (byte) main::j ← (byte) 10 +main::@2: + (void~) main::$2 ← call line (byte) main::j + (byte) main::j ← ++ (byte) main::j + (boolean~) main::$3 ← (byte) main::j != (byte) 19 + if((boolean~) main::$3) goto main::@2 +main::@return: + return +endproc // main() +proc (void()) line((byte) line::l) + (void~) line::$0 ← call plot (byte) line::l + (byte~) line::$1 ← (byte) line::l + (byte) 20 + (void~) line::$2 ← call plot (byte~) line::$1 +line::@return: + return +endproc // line() +proc (void()) plot((byte) plot::x) + *((byte*) SCREEN + (byte) plot::x) ← (byte) '*' +plot::@return: + return +endproc // plot() + call main + +SYMBOLS +(byte*) SCREEN +(void()) line((byte) line::l) +(void~) line::$0 +(byte~) line::$1 +(void~) line::$2 +(label) line::@return +(byte) line::l +(void()) main() +(void~) main::$0 +(boolean~) main::$1 +(void~) main::$2 +(boolean~) main::$3 +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte) main::i +(byte) main::j +(void()) plot((byte) plot::x) +(label) plot::@return +(byte) plot::x + +INITIAL CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN ← (word) 1024 + to:@1 +main: scope:[main] from + (byte) main::i ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@1 + (void~) main::$0 ← call line (byte) main::i + (byte) main::i ← ++ (byte) main::i + (boolean~) main::$1 ← (byte) main::i != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@1 + (byte) main::j ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@2 main::@3 + (void~) main::$2 ← call line (byte) main::j + (byte) main::j ← ++ (byte) main::j + (boolean~) main::$3 ← (byte) main::j != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@4 +main::@4: scope:[main] from main::@2 + to:main::@return +main::@return: scope:[main] from main::@4 + return + to:@return +@1: scope:[] from @begin + to:@2 +line: scope:[line] from + (void~) line::$0 ← call plot (byte) line::l + (byte~) line::$1 ← (byte) line::l + (byte) 20 + (void~) line::$2 ← call plot (byte~) line::$1 + to:line::@return +line::@return: scope:[line] from line + return + to:@return +@2: scope:[] from @1 + to:@3 +plot: scope:[plot] from + *((byte*) SCREEN + (byte) plot::x) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @2 + call main + to:@end +@end: scope:[] from @3 + +Removing empty block main::@4 +Removing empty block @1 +Removing empty block @2 +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN ← (word) 1024 + to:@3 +main: scope:[main] from + (byte) main::i ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@1 + (void~) main::$0 ← call line (byte) main::i + (byte) main::i ← ++ (byte) main::i + (boolean~) main::$1 ← (byte) main::i != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@1 + (byte) main::j ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@2 main::@3 + (void~) main::$2 ← call line (byte) main::j + (byte) main::j ← ++ (byte) main::j + (boolean~) main::$3 ← (byte) main::j != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@2 + return + to:@return +line: scope:[line] from + (void~) line::$0 ← call plot (byte) line::l + (byte~) line::$1 ← (byte) line::l + (byte) 20 + (void~) line::$2 ← call plot (byte~) line::$1 + to:line::@return +line::@return: scope:[line] from line + return + to:@return +plot: scope:[plot] from + *((byte*) SCREEN + (byte) plot::x) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main + to:@end +@end: scope:[] from @3 + +PROCEDURE MODIFY VARIABLE ANALYSIS + +CONTROL FLOW GRAPH WITH ASSIGNMENT CALL +@begin: scope:[] from + (byte*) SCREEN ← (word) 1024 + to:@3 +main: scope:[main] from @3 + (byte) main::i ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) line::l ← (byte) main::i + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i ← ++ (byte) main::i + (boolean~) main::$1 ← (byte) main::i != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + (byte) main::j ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte) line::l ← (byte) main::j + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j ← ++ (byte) main::j + (boolean~) main::$3 ← (byte) main::j != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte) plot::x ← (byte) line::l + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l + (byte) 20 + (byte) plot::x ← (byte~) line::$1 + call plot param-assignment + to:line::@2 +line::@2: scope:[line] from line::@1 + to:line::@return +line::@return: scope:[line] from line::@2 + return + to:@return +plot: scope:[plot] from line line::@1 + *((byte*) SCREEN + (byte) plot::x) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main param-assignment + to:@4 +@4: scope:[] from @3 + to:@end +@end: scope:[] from @4 + +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@3 +main: scope:[main] from @3 + (byte*) SCREEN#6 ← phi( @3/(byte*) SCREEN#10 ) + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte*) SCREEN#4 ← phi( main/(byte*) SCREEN#6 main::@5/(byte*) SCREEN#7 ) + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte*) SCREEN#7 ← phi( main::@1/(byte*) SCREEN#4 ) + (byte) main::i#3 ← phi( main::@1/(byte) main::i#2 ) + (byte) main::i#1 ← ++ (byte) main::i#3 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + (byte*) SCREEN#8 ← phi( main::@5/(byte*) SCREEN#7 ) + (byte) main::j#0 ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte*) SCREEN#5 ← phi( main::@3/(byte*) SCREEN#8 main::@6/(byte*) SCREEN#9 ) + (byte) main::j#2 ← phi( main::@3/(byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte*) SCREEN#9 ← phi( main::@2/(byte*) SCREEN#5 ) + (byte) main::j#3 ← phi( main::@2/(byte) main::j#2 ) + (byte) main::j#1 ← ++ (byte) main::j#3 + (boolean~) main::$3 ← (byte) main::j#1 != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte*) SCREEN#2 ← phi( main::@1/(byte*) SCREEN#4 main::@2/(byte*) SCREEN#5 ) + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte*) SCREEN#3 ← phi( line/(byte*) SCREEN#2 ) + (byte) line::l#3 ← phi( line/(byte) line::l#2 ) + (byte~) line::$1 ← (byte) line::l#3 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@2 +line::@2: scope:[line] from line::@1 + to:line::@return +line::@return: scope:[line] from line::@2 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + (byte*) SCREEN#1 ← phi( line/(byte*) SCREEN#2 line::@1/(byte*) SCREEN#3 ) + *((byte*) SCREEN#1 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + (byte*) SCREEN#10 ← phi( @begin/(byte*) SCREEN#0 ) + call main param-assignment + to:@4 +@4: scope:[] from @3 + to:@end +@end: scope:[] from @4 + +CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@3 +main: scope:[main] from @3 + (byte*) SCREEN#6 ← phi( @3/(byte*) SCREEN#10 ) + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte*) SCREEN#4 ← phi( main/(byte*) SCREEN#6 main::@5/(byte*) SCREEN#7 ) + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte*) SCREEN#7 ← phi( main::@1/(byte*) SCREEN#4 ) + (byte) main::i#3 ← phi( main::@1/(byte) main::i#2 ) + (byte) main::i#1 ← ++ (byte) main::i#3 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + (byte*) SCREEN#8 ← phi( main::@5/(byte*) SCREEN#7 ) + (byte) main::j#0 ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte*) SCREEN#5 ← phi( main::@3/(byte*) SCREEN#8 main::@6/(byte*) SCREEN#9 ) + (byte) main::j#2 ← phi( main::@3/(byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte*) SCREEN#9 ← phi( main::@2/(byte*) SCREEN#5 ) + (byte) main::j#3 ← phi( main::@2/(byte) main::j#2 ) + (byte) main::j#1 ← ++ (byte) main::j#3 + (boolean~) main::$3 ← (byte) main::j#1 != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte*) SCREEN#2 ← phi( main::@1/(byte*) SCREEN#4 main::@2/(byte*) SCREEN#5 ) + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte*) SCREEN#3 ← phi( line/(byte*) SCREEN#2 ) + (byte) line::l#3 ← phi( line/(byte) line::l#2 ) + (byte~) line::$1 ← (byte) line::l#3 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@2 +line::@2: scope:[line] from line::@1 + to:line::@return +line::@return: scope:[line] from line::@2 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + (byte*) SCREEN#1 ← phi( line/(byte*) SCREEN#2 line::@1/(byte*) SCREEN#3 ) + *((byte*) SCREEN#1 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + (byte*) SCREEN#10 ← phi( @begin/(byte*) SCREEN#0 ) + call main param-assignment + to:@4 +@4: scope:[] from @3 + to:@end +@end: scope:[] from @4 + +INITIAL SSA SYMBOL TABLE +(label) @3 +(label) @4 +(label) @begin +(label) @end +(byte*) SCREEN +(byte*) SCREEN#0 +(byte*) SCREEN#1 +(byte*) SCREEN#10 +(byte*) SCREEN#2 +(byte*) SCREEN#3 +(byte*) SCREEN#4 +(byte*) SCREEN#5 +(byte*) SCREEN#6 +(byte*) SCREEN#7 +(byte*) SCREEN#8 +(byte*) SCREEN#9 +(void()) line((byte) line::l) +(byte~) line::$1 +(label) line::@1 +(label) line::@2 +(label) line::@return +(byte) line::l +(byte) line::l#0 +(byte) line::l#1 +(byte) line::l#2 +(byte) line::l#3 +(void()) main() +(boolean~) main::$1 +(boolean~) main::$3 +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@5 +(label) main::@6 +(label) main::@return +(byte) main::i +(byte) main::i#0 +(byte) main::i#1 +(byte) main::i#2 +(byte) main::i#3 +(byte) main::j +(byte) main::j#0 +(byte) main::j#1 +(byte) main::j#2 +(byte) main::j#3 +(void()) plot((byte) plot::x) +(label) plot::@return +(byte) plot::x +(byte) plot::x#0 +(byte) plot::x#1 +(byte) plot::x#2 + +Culled Empty Block (label) line::@2 +Culled Empty Block (label) @4 +Succesful SSA optimization Pass2CullEmptyBlocks +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@3 +main: scope:[main] from @3 + (byte*) SCREEN#6 ← phi( @3/(byte*) SCREEN#10 ) + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte*) SCREEN#4 ← phi( main/(byte*) SCREEN#6 main::@5/(byte*) SCREEN#7 ) + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte*) SCREEN#7 ← phi( main::@1/(byte*) SCREEN#4 ) + (byte) main::i#3 ← phi( main::@1/(byte) main::i#2 ) + (byte) main::i#1 ← ++ (byte) main::i#3 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + (byte*) SCREEN#8 ← phi( main::@5/(byte*) SCREEN#7 ) + (byte) main::j#0 ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte*) SCREEN#5 ← phi( main::@3/(byte*) SCREEN#8 main::@6/(byte*) SCREEN#9 ) + (byte) main::j#2 ← phi( main::@3/(byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte*) SCREEN#9 ← phi( main::@2/(byte*) SCREEN#5 ) + (byte) main::j#3 ← phi( main::@2/(byte) main::j#2 ) + (byte) main::j#1 ← ++ (byte) main::j#3 + (boolean~) main::$3 ← (byte) main::j#1 != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte*) SCREEN#2 ← phi( main::@1/(byte*) SCREEN#4 main::@2/(byte*) SCREEN#5 ) + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte*) SCREEN#3 ← phi( line/(byte*) SCREEN#2 ) + (byte) line::l#3 ← phi( line/(byte) line::l#2 ) + (byte~) line::$1 ← (byte) line::l#3 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + (byte*) SCREEN#1 ← phi( line/(byte*) SCREEN#2 line::@1/(byte*) SCREEN#3 ) + *((byte*) SCREEN#1 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + (byte*) SCREEN#10 ← phi( @begin/(byte*) SCREEN#0 ) + call main param-assignment + to:@end +@end: scope:[] from @3 + +Not aliassing across scopes: line::l#0 main::i#2 +Not aliassing across scopes: line::l#1 main::j#2 +Not aliassing across scopes: plot::x#0 line::l#2 +Not aliassing across scopes: plot::x#1 line::$1 +Alias (byte*) SCREEN#0 = (byte*) SCREEN#6 (byte*) SCREEN#10 +Alias (byte) main::i#2 = (byte) main::i#3 +Alias (byte*) SCREEN#4 = (byte*) SCREEN#7 (byte*) SCREEN#8 +Alias (byte) main::j#2 = (byte) main::j#3 +Alias (byte*) SCREEN#5 = (byte*) SCREEN#9 +Alias (byte) line::l#2 = (byte) line::l#3 +Alias (byte*) SCREEN#2 = (byte*) SCREEN#3 +Succesful SSA optimization Pass2AliasElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@3 +main: scope:[main] from @3 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte*) SCREEN#4 ← phi( main/(byte*) SCREEN#0 main::@5/(byte*) SCREEN#4 ) + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i#1 ← ++ (byte) main::i#2 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + (byte) main::j#0 ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte*) SCREEN#5 ← phi( main::@3/(byte*) SCREEN#4 main::@6/(byte*) SCREEN#5 ) + (byte) main::j#2 ← phi( main::@3/(byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$3 ← (byte) main::j#1 != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte*) SCREEN#2 ← phi( main::@1/(byte*) SCREEN#4 main::@2/(byte*) SCREEN#5 ) + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + (byte*) SCREEN#1 ← phi( line/(byte*) SCREEN#2 line::@1/(byte*) SCREEN#2 ) + *((byte*) SCREEN#1 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @3 + +Not aliassing across scopes: line::l#0 main::i#2 +Not aliassing across scopes: line::l#1 main::j#2 +Not aliassing across scopes: plot::x#0 line::l#2 +Not aliassing across scopes: plot::x#1 line::$1 +Alias (byte*) SCREEN#1 = (byte*) SCREEN#2 +Succesful SSA optimization Pass2AliasElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@3 +main: scope:[main] from @3 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte*) SCREEN#4 ← phi( main/(byte*) SCREEN#0 main::@5/(byte*) SCREEN#4 ) + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i#1 ← ++ (byte) main::i#2 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + (byte) main::j#0 ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte*) SCREEN#5 ← phi( main::@3/(byte*) SCREEN#4 main::@6/(byte*) SCREEN#5 ) + (byte) main::j#2 ← phi( main::@3/(byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$3 ← (byte) main::j#1 != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte*) SCREEN#1 ← phi( main::@1/(byte*) SCREEN#4 main::@2/(byte*) SCREEN#5 ) + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + *((byte*) SCREEN#1 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @3 + +Not aliassing across scopes: line::l#0 main::i#2 +Not aliassing across scopes: line::l#1 main::j#2 +Not aliassing across scopes: plot::x#0 line::l#2 +Not aliassing across scopes: plot::x#1 line::$1 +Self Phi Eliminated (byte*) SCREEN#4 +Self Phi Eliminated (byte*) SCREEN#5 +Succesful SSA optimization Pass2SelfPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@3 +main: scope:[main] from @3 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte*) SCREEN#4 ← phi( main/(byte*) SCREEN#0 ) + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i#1 ← ++ (byte) main::i#2 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + (byte) main::j#0 ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte*) SCREEN#5 ← phi( main::@3/(byte*) SCREEN#4 ) + (byte) main::j#2 ← phi( main::@3/(byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$3 ← (byte) main::j#1 != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte*) SCREEN#1 ← phi( main::@1/(byte*) SCREEN#4 main::@2/(byte*) SCREEN#5 ) + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + *((byte*) SCREEN#1 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @3 + +Redundant Phi (byte*) SCREEN#4 (byte*) SCREEN#0 +Redundant Phi (byte*) SCREEN#5 (byte*) SCREEN#4 +Succesful SSA optimization Pass2RedundantPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@3 +main: scope:[main] from @3 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i#1 ← ++ (byte) main::i#2 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + (byte) main::j#0 ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte) main::j#2 ← phi( main::@3/(byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$3 ← (byte) main::j#1 != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte*) SCREEN#1 ← phi( main::@1/(byte*) SCREEN#0 main::@2/(byte*) SCREEN#0 ) + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + *((byte*) SCREEN#1 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @3 + +Redundant Phi (byte*) SCREEN#1 (byte*) SCREEN#0 +Succesful SSA optimization Pass2RedundantPhiElimination +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@3 +main: scope:[main] from @3 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i#1 ← ++ (byte) main::i#2 + (boolean~) main::$1 ← (byte) main::i#1 != (byte) 9 + if((boolean~) main::$1) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + (byte) main::j#0 ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte) main::j#2 ← phi( main::@3/(byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j#1 ← ++ (byte) main::j#2 + (boolean~) main::$3 ← (byte) main::j#1 != (byte) 19 + if((boolean~) main::$3) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + *((byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @3 + +Simple Condition (boolean~) main::$1 if((byte) main::i#1!=(byte) 9) goto main::@1 +Simple Condition (boolean~) main::$3 if((byte) main::j#1!=(byte) 19) goto main::@2 +Succesful SSA optimization Pass2ConditionalJumpSimplification +CONTROL FLOW GRAPH +@begin: scope:[] from + (byte*) SCREEN#0 ← (word) 1024 + to:@3 +main: scope:[main] from @3 + (byte) main::i#0 ← (byte) 0 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i#1 ← ++ (byte) main::i#2 + if((byte) main::i#1!=(byte) 9) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + (byte) main::j#0 ← (byte) 10 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte) main::j#2 ← phi( main::@3/(byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 19) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + *((byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @3 + +Constant (const byte*) SCREEN#0 = 1024 +Constant (const byte) main::i#0 = 0 +Constant (const byte) main::j#0 = 10 +Succesful SSA optimization Pass2ConstantIdentification +CONTROL FLOW GRAPH +@begin: scope:[] from + to:@3 +main: scope:[main] from @3 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#2 ← phi( main/(const byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i#1 ← ++ (byte) main::i#2 + if((byte) main::i#1!=(byte) 9) goto main::@1 + to:main::@3 +main::@3: scope:[main] from main::@5 + to:main::@2 +main::@2: scope:[main] from main::@3 main::@6 + (byte) main::j#2 ← phi( main::@3/(const byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 19) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @3 + +Multiple usages for variable. Not optimizing sub-constant (byte) line::l#2 +Culled Empty Block (label) main::@3 +Succesful SSA optimization Pass2CullEmptyBlocks +CONTROL FLOW GRAPH +@begin: scope:[] from + to:@3 +main: scope:[main] from @3 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#2 ← phi( main/(const byte) main::i#0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i#1 ← ++ (byte) main::i#2 + if((byte) main::i#1!=(byte) 9) goto main::@1 + to:main::@2 +main::@2: scope:[main] from main::@5 main::@6 + (byte) main::j#2 ← phi( main::@5/(const byte) main::j#0 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 19) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @3 + +Not aliassing across scopes: line::l#0 main::i#2 +Not aliassing across scopes: line::l#1 main::j#2 +Not aliassing across scopes: plot::x#0 line::l#2 +Not aliassing across scopes: plot::x#1 line::$1 +Multiple usages for variable. Not optimizing sub-constant (byte) line::l#2 +Not aliassing across scopes: line::l#0 main::i#2 +Not aliassing across scopes: line::l#1 main::j#2 +Not aliassing across scopes: plot::x#0 line::l#2 +Not aliassing across scopes: plot::x#1 line::$1 +Multiple usages for variable. Not optimizing sub-constant (byte) line::l#2 +Inlining constant with var siblings (const byte) main::i#0 +Inlining constant with var siblings (const byte) main::i#0 +Inlining constant with var siblings (const byte) main::j#0 +Inlining constant with var siblings (const byte) main::j#0 +Constant inlined main::j#0 = (byte) 10 +Constant inlined main::i#0 = (byte) 0 +Succesful SSA optimization Pass2ConstantInlining +CONTROL FLOW GRAPH +@begin: scope:[] from + to:@3 +main: scope:[main] from @3 + to:main::@1 +main::@1: scope:[main] from main main::@5 + (byte) main::i#2 ← phi( main/(byte) 0 main::@5/(byte) main::i#1 ) + (byte) line::l#0 ← (byte) main::i#2 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i#1 ← ++ (byte) main::i#2 + if((byte) main::i#1!=(byte) 9) goto main::@1 + to:main::@2 +main::@2: scope:[main] from main::@5 main::@6 + (byte) main::j#2 ← phi( main::@5/(byte) 10 main::@6/(byte) main::j#1 ) + (byte) line::l#1 ← (byte) main::j#2 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 19) goto main::@2 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +line: scope:[line] from main::@1 main::@2 + (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) + (byte) plot::x#0 ← (byte) line::l#2 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) + *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return +@3: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @3 + +FINAL SYMBOL TABLE +(label) @3 +(label) @begin +(label) @end +(byte*) SCREEN +(const byte*) SCREEN#0 = (word) 1024 +(void()) line((byte) line::l) +(byte~) line::$1 +(label) line::@1 +(label) line::@return +(byte) line::l +(byte) line::l#0 +(byte) line::l#1 +(byte) line::l#2 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@5 +(label) main::@6 +(label) main::@return +(byte) main::i +(byte) main::i#1 +(byte) main::i#2 +(byte) main::j +(byte) main::j#1 +(byte) main::j#2 +(void()) plot((byte) plot::x) +(label) plot::@return +(byte) plot::x +(byte) plot::x#0 +(byte) plot::x#1 +(byte) plot::x#2 + +Block Sequence Planned @begin @3 @end main main::@1 main::@5 main::@2 main::@6 main::@return line line::@1 line::@return plot plot::@return +Added new block during phi lifting main::@7(between main::@5 and main::@1) +Added new block during phi lifting main::@8(between main::@6 and main::@2) +Block Sequence Planned @begin @3 @end main main::@1 main::@5 main::@2 main::@6 main::@return main::@8 main::@7 line line::@1 line::@return plot plot::@return +CONTROL FLOW GRAPH - PHI LIFTED +@begin: scope:[] from + to:@3 +@3: scope:[] from @begin + call main param-assignment + to:@end +@end: scope:[] from @3 +main: scope:[main] from @3 + to:main::@1 +main::@1: scope:[main] from main main::@7 + (byte) main::i#2 ← phi( main/(byte) 0 main::@7/(byte~) main::i#4 ) + (byte) line::l#0 ← (byte) main::i#2 + (byte~) line::l#4 ← (byte) line::l#0 + call line param-assignment + to:main::@5 +main::@5: scope:[main] from main::@1 + (byte) main::i#1 ← ++ (byte) main::i#2 + if((byte) main::i#1!=(byte) 9) goto main::@7 + to:main::@2 +main::@2: scope:[main] from main::@5 main::@8 + (byte) main::j#2 ← phi( main::@5/(byte) 10 main::@8/(byte~) main::j#4 ) + (byte) line::l#1 ← (byte) main::j#2 + (byte~) line::l#5 ← (byte) line::l#1 + call line param-assignment + to:main::@6 +main::@6: scope:[main] from main::@2 + (byte) main::j#1 ← ++ (byte) main::j#2 + if((byte) main::j#1!=(byte) 19) goto main::@8 + to:main::@return +main::@return: scope:[main] from main::@6 + return + to:@return +main::@8: scope:[main] from main::@6 + (byte~) main::j#4 ← (byte) main::j#1 + to:main::@2 +main::@7: scope:[main] from main::@5 + (byte~) main::i#4 ← (byte) main::i#1 + to:main::@1 +line: scope:[line] from main::@1 main::@2 + (byte) line::l#2 ← phi( main::@1/(byte~) line::l#4 main::@2/(byte~) line::l#5 ) + (byte) plot::x#0 ← (byte) line::l#2 + (byte~) plot::x#3 ← (byte) plot::x#0 + call plot param-assignment + to:line::@1 +line::@1: scope:[line] from line + (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 + (byte) plot::x#1 ← (byte~) line::$1 + (byte~) plot::x#4 ← (byte) plot::x#1 + call plot param-assignment + to:line::@return +line::@return: scope:[line] from line::@1 + return + to:@return +plot: scope:[plot] from line line::@1 + (byte) plot::x#2 ← phi( line/(byte~) plot::x#3 line::@1/(byte~) plot::x#4 ) + *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' + to:plot::@return +plot::@return: scope:[plot] from plot + return + to:@return + +Adding NOP phi() at start of main +CALL GRAPH +Calls in [] to main:0 +Calls in [main] to line:5 line:11 +Calls in [line] to plot:20 plot:24 + +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +CONTROL FLOW GRAPH - LIVE RANGES FOUND +@begin: scope:[] from + to:@3 +@3: scope:[] from @begin + [0] call main param-assignment [ ] + to:@end +@end: scope:[] from @3 +main: scope:[main] from @3 + [1] phi() [ ] + to:main::@1 +main::@1: scope:[main] from main main::@7 + [2] (byte) main::i#2 ← phi( main/(byte) 0 main::@7/(byte~) main::i#4 ) [ main::i#2 ] + [3] (byte) line::l#0 ← (byte) main::i#2 [ main::i#2 line::l#0 ] + [4] (byte~) line::l#4 ← (byte) line::l#0 [ main::i#2 line::l#4 ] + [5] call line param-assignment [ main::i#2 ] + to:main::@5 +main::@5: scope:[main] from main::@1 + [6] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] + [7] if((byte) main::i#1!=(byte) 9) goto main::@7 [ main::i#1 ] + to:main::@2 +main::@2: scope:[main] from main::@5 main::@8 + [8] (byte) main::j#2 ← phi( main::@5/(byte) 10 main::@8/(byte~) main::j#4 ) [ main::j#2 ] + [9] (byte) line::l#1 ← (byte) main::j#2 [ main::j#2 line::l#1 ] + [10] (byte~) line::l#5 ← (byte) line::l#1 [ main::j#2 line::l#5 ] + [11] call line param-assignment [ main::j#2 ] + to:main::@6 +main::@6: scope:[main] from main::@2 + [12] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::j#1 ] + [13] if((byte) main::j#1!=(byte) 19) goto main::@8 [ main::j#1 ] + to:main::@return +main::@return: scope:[main] from main::@6 + [14] return [ ] + to:@return +main::@8: scope:[main] from main::@6 + [15] (byte~) main::j#4 ← (byte) main::j#1 [ main::j#4 ] + to:main::@2 +main::@7: scope:[main] from main::@5 + [16] (byte~) main::i#4 ← (byte) main::i#1 [ main::i#4 ] + to:main::@1 +line: scope:[line] from main::@1 main::@2 + [17] (byte) line::l#2 ← phi( main::@1/(byte~) line::l#4 main::@2/(byte~) line::l#5 ) [ line::l#2 ] + [18] (byte) plot::x#0 ← (byte) line::l#2 [ line::l#2 plot::x#0 ] + [19] (byte~) plot::x#3 ← (byte) plot::x#0 [ line::l#2 plot::x#3 ] + [20] call plot param-assignment [ line::l#2 ] + to:line::@1 +line::@1: scope:[line] from line + [21] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] + [22] (byte) plot::x#1 ← (byte~) line::$1 [ plot::x#1 ] + [23] (byte~) plot::x#4 ← (byte) plot::x#1 [ plot::x#4 ] + [24] call plot param-assignment [ ] + to:line::@return +line::@return: scope:[line] from line::@1 + [25] return [ ] + to:@return +plot: scope:[plot] from line line::@1 + [26] (byte) plot::x#2 ← phi( line/(byte~) plot::x#3 line::@1/(byte~) plot::x#4 ) [ plot::x#2 ] + [27] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] + to:plot::@return +plot::@return: scope:[plot] from plot + [28] return [ ] + to:@return + +Created 4 initial phi equivalence classes +Coalesced [4] line::l#4 ← line::l#0 +Coalesced [10] line::l#5 ← line::l#1 +Coalesced [15] main::j#4 ← main::j#1 +Coalesced [16] main::i#4 ← main::i#1 +Coalesced [19] plot::x#3 ← plot::x#0 +Coalesced [23] plot::x#4 ← plot::x#1 +Coalesced down to 4 phi equivalence classes +Culled Empty Block (label) main::@8 +Culled Empty Block (label) main::@7 +Block Sequence Planned @begin @3 @end main main::@1 main::@5 main::@2 main::@6 main::@return line line::@1 line::@return plot plot::@return +Adding NOP phi() at start of main +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +CONTROL FLOW GRAPH - BEFORE EFFECTIVE LIVE RANGES +@begin: scope:[] from + to:@3 +@3: scope:[] from @begin + [0] call main param-assignment [ ] + to:@end +@end: scope:[] from @3 +main: scope:[main] from @3 + [1] phi() [ ] + to:main::@1 +main::@1: scope:[main] from main main::@5 + [2] (byte) main::i#2 ← phi( main/(byte) 0 main::@5/(byte) main::i#1 ) [ main::i#2 ] + [3] (byte) line::l#0 ← (byte) main::i#2 [ main::i#2 line::l#0 ] + [4] call line param-assignment [ main::i#2 ] + to:main::@5 +main::@5: scope:[main] from main::@1 + [5] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] + [6] if((byte) main::i#1!=(byte) 9) goto main::@1 [ main::i#1 ] + to:main::@2 +main::@2: scope:[main] from main::@5 main::@6 + [7] (byte) main::j#2 ← phi( main::@5/(byte) 10 main::@6/(byte) main::j#1 ) [ main::j#2 ] + [8] (byte) line::l#1 ← (byte) main::j#2 [ main::j#2 line::l#1 ] + [9] call line param-assignment [ main::j#2 ] + to:main::@6 +main::@6: scope:[main] from main::@2 + [10] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::j#1 ] + [11] if((byte) main::j#1!=(byte) 19) goto main::@2 [ main::j#1 ] + to:main::@return +main::@return: scope:[main] from main::@6 + [12] return [ ] + to:@return +line: scope:[line] from main::@1 main::@2 + [13] (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) [ line::l#2 ] + [14] (byte) plot::x#0 ← (byte) line::l#2 [ line::l#2 plot::x#0 ] + [15] call plot param-assignment [ line::l#2 ] + to:line::@1 +line::@1: scope:[line] from line + [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] + [17] (byte) plot::x#1 ← (byte~) line::$1 [ plot::x#1 ] + [18] call plot param-assignment [ ] + to:line::@return +line::@return: scope:[line] from line::@1 + [19] return [ ] + to:@return +plot: scope:[plot] from line line::@1 + [20] (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) [ plot::x#2 ] + [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] + to:plot::@return +plot::@return: scope:[plot] from plot + [22] return [ ] + to:@return + +CONTROL FLOW GRAPH - PHI MEM COALESCED +@begin: scope:[] from + to:@3 +@3: scope:[] from @begin + [0] call main param-assignment [ ] ( ) + to:@end +@end: scope:[] from @3 +main: scope:[main] from @3 + [1] phi() [ ] ( main:0 [ ] ) + to:main::@1 +main::@1: scope:[main] from main main::@5 + [2] (byte) main::i#2 ← phi( main/(byte) 0 main::@5/(byte) main::i#1 ) [ main::i#2 ] ( main:0 [ main::i#2 ] ) + [3] (byte) line::l#0 ← (byte) main::i#2 [ main::i#2 line::l#0 ] ( main:0 [ main::i#2 line::l#0 ] ) + [4] call line param-assignment [ main::i#2 ] ( main:0 [ main::i#2 ] ) + to:main::@5 +main::@5: scope:[main] from main::@1 + [5] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:0 [ main::i#1 ] ) + [6] if((byte) main::i#1!=(byte) 9) goto main::@1 [ main::i#1 ] ( main:0 [ main::i#1 ] ) + to:main::@2 +main::@2: scope:[main] from main::@5 main::@6 + [7] (byte) main::j#2 ← phi( main::@5/(byte) 10 main::@6/(byte) main::j#1 ) [ main::j#2 ] ( main:0 [ main::j#2 ] ) + [8] (byte) line::l#1 ← (byte) main::j#2 [ main::j#2 line::l#1 ] ( main:0 [ main::j#2 line::l#1 ] ) + [9] call line param-assignment [ main::j#2 ] ( main:0 [ main::j#2 ] ) + to:main::@6 +main::@6: scope:[main] from main::@2 + [10] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) + [11] if((byte) main::j#1!=(byte) 19) goto main::@2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) + to:main::@return +main::@return: scope:[main] from main::@6 + [12] return [ ] ( main:0 [ ] ) + to:@return +line: scope:[line] from main::@1 main::@2 + [13] (byte) line::l#2 ← phi( main::@1/(byte) line::l#0 main::@2/(byte) line::l#1 ) [ line::l#2 ] ( main:0::line:4 [ main::i#2 line::l#2 ] main:0::line:9 [ main::j#2 line::l#2 ] ) + [14] (byte) plot::x#0 ← (byte) line::l#2 [ line::l#2 plot::x#0 ] ( main:0::line:4 [ main::i#2 line::l#2 plot::x#0 ] main:0::line:9 [ main::j#2 line::l#2 plot::x#0 ] ) + [15] call plot param-assignment [ line::l#2 ] ( main:0::line:4 [ main::i#2 line::l#2 ] main:0::line:9 [ main::j#2 line::l#2 ] ) + to:line::@1 +line::@1: scope:[line] from line + [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] ( main:0::line:4 [ main::i#2 line::$1 ] main:0::line:9 [ main::j#2 line::$1 ] ) + [17] (byte) plot::x#1 ← (byte~) line::$1 [ plot::x#1 ] ( main:0::line:4 [ main::i#2 plot::x#1 ] main:0::line:9 [ main::j#2 plot::x#1 ] ) + [18] call plot param-assignment [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + to:line::@return +line::@return: scope:[line] from line::@1 + [19] return [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + to:@return +plot: scope:[plot] from line line::@1 + [20] (byte) plot::x#2 ← phi( line/(byte) plot::x#0 line::@1/(byte) plot::x#1 ) [ plot::x#2 ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 plot::x#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 plot::x#2 ] main:0::line:4::plot:18 [ main::i#2 plot::x#2 ] main:0::line:9::plot:18 [ main::j#2 plot::x#2 ] ) + [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) + to:plot::@return +plot::@return: scope:[plot] from plot + [22] return [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) + to:@return + +DOMINATORS +@begin dominated by @begin +@3 dominated by @3 @begin +@end dominated by @3 @end @begin +main dominated by @3 @begin main +main::@1 dominated by @3 @begin main::@1 main +main::@5 dominated by @3 @begin main::@1 main::@5 main +main::@2 dominated by @3 @begin main::@2 main::@1 main main::@5 +main::@6 dominated by @3 @begin main::@2 main::@1 main::@6 main main::@5 +main::@return dominated by @3 @begin main::@2 main::@1 main::@6 main main::@5 main::@return +line dominated by @3 @begin line main::@1 main +line::@1 dominated by @3 @begin line::@1 line main::@1 main +line::@return dominated by @3 @begin line::@1 line main::@1 line::@return main +plot dominated by @3 @begin line main::@1 plot main +plot::@return dominated by @3 @begin line main::@1 plot::@return plot main + +Found back edge: Loop head: main::@1 tails: main::@5 blocks: null +Found back edge: Loop head: main::@2 tails: main::@6 blocks: null +Populated: Loop head: main::@1 tails: main::@5 blocks: main::@5 main::@1 +Populated: Loop head: main::@2 tails: main::@6 blocks: main::@6 main::@2 +NATURAL LOOPS +Loop head: main::@1 tails: main::@5 blocks: main::@5 main::@1 +Loop head: main::@2 tails: main::@6 blocks: main::@6 main::@2 + +Found 0 loops in scope [] +Found 2 loops in scope [main] + Loop head: main::@1 tails: main::@5 blocks: main::@5 main::@1 + Loop head: main::@2 tails: main::@6 blocks: main::@6 main::@2 +Found 0 loops in scope [line] +Found 0 loops in scope [plot] +NATURAL LOOPS WITH DEPTH +Loop head: main::@1 tails: main::@5 blocks: main::@5 main::@1 depth: 1 +Loop head: main::@2 tails: main::@6 blocks: main::@6 main::@2 depth: 1 + + +VARIABLE REGISTER WEIGHTS +(byte*) SCREEN +(void()) line((byte) line::l) +(byte~) line::$1 4.0 +(byte) line::l +(byte) line::l#0 22.0 +(byte) line::l#1 22.0 +(byte) line::l#2 8.666666666666666 +(void()) main() +(byte) main::i +(byte) main::i#1 16.5 +(byte) main::i#2 11.0 +(byte) main::j +(byte) main::j#1 16.5 +(byte) main::j#2 11.0 +(void()) plot((byte) plot::x) +(byte) plot::x +(byte) plot::x#0 4.0 +(byte) plot::x#1 4.0 +(byte) plot::x#2 6.0 + +Initial phi equivalence classes +[ main::i#2 main::i#1 ] +[ main::j#2 main::j#1 ] +[ line::l#2 line::l#0 line::l#1 ] +[ plot::x#2 plot::x#0 plot::x#1 ] +Added variable line::$1 to zero page equivalence class [ line::$1 ] +Complete equivalence classes +[ main::i#2 main::i#1 ] +[ main::j#2 main::j#1 ] +[ line::l#2 line::l#0 line::l#1 ] +[ plot::x#2 plot::x#0 plot::x#1 ] +[ line::$1 ] +Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ] +Allocated zp ZP_BYTE:3 [ main::j#2 main::j#1 ] +Allocated zp ZP_BYTE:4 [ line::l#2 line::l#0 line::l#1 ] +Allocated zp ZP_BYTE:5 [ plot::x#2 plot::x#0 plot::x#1 ] +Allocated zp ZP_BYTE:6 [ line::$1 ] +INITIAL ASM +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +bbegin: + jmp b3 +//SEG3 @3 +b3: +//SEG4 [0] call main param-assignment [ ] ( ) +//SEG5 [1] phi from @3 to main [phi:@3->main] +main_from_b3: + jsr main + jmp bend +//SEG6 @end +bend: +//SEG7 main +main: { + .label i = 2 + .label j = 3 + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG9 [2] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- zpby1=coby1 + lda #0 + sta i + jmp b1 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + b1_from_b5: + //SEG11 [2] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + jmp b1 + //SEG12 main::@1 + b1: + //SEG13 [3] (byte) line::l#0 ← (byte) main::i#2 [ main::i#2 line::l#0 ] ( main:0 [ main::i#2 line::l#0 ] ) -- zpby1=zpby2 + lda i + sta line.l + //SEG14 [4] call line param-assignment [ main::i#2 ] ( main:0 [ main::i#2 ] ) + //SEG15 [13] phi from main::@1 to line [phi:main::@1->line] + line_from_b1: + //SEG16 [13] phi (byte) line::l#2 = (byte) line::l#0 [phi:main::@1->line#0] -- register_copy + jsr line + jmp b5 + //SEG17 main::@5 + b5: + //SEG18 [5] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- zpby1=_inc_zpby1 + inc i + //SEG19 [6] if((byte) main::i#1!=(byte) 9) goto main::@1 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- zpby1_neq_coby1_then_la1 + lda i + cmp #9 + bne b1_from_b5 + //SEG20 [7] phi from main::@5 to main::@2 [phi:main::@5->main::@2] + b2_from_b5: + //SEG21 [7] phi (byte) main::j#2 = (byte) 10 [phi:main::@5->main::@2#0] -- zpby1=coby1 + lda #$a + sta j + jmp b2 + //SEG22 [7] phi from main::@6 to main::@2 [phi:main::@6->main::@2] + b2_from_b6: + //SEG23 [7] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@6->main::@2#0] -- register_copy + jmp b2 + //SEG24 main::@2 + b2: + //SEG25 [8] (byte) line::l#1 ← (byte) main::j#2 [ main::j#2 line::l#1 ] ( main:0 [ main::j#2 line::l#1 ] ) -- zpby1=zpby2 + lda j + sta line.l + //SEG26 [9] call line param-assignment [ main::j#2 ] ( main:0 [ main::j#2 ] ) + //SEG27 [13] phi from main::@2 to line [phi:main::@2->line] + line_from_b2: + //SEG28 [13] phi (byte) line::l#2 = (byte) line::l#1 [phi:main::@2->line#0] -- register_copy + jsr line + jmp b6 + //SEG29 main::@6 + b6: + //SEG30 [10] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- zpby1=_inc_zpby1 + inc j + //SEG31 [11] if((byte) main::j#1!=(byte) 19) goto main::@2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- zpby1_neq_coby1_then_la1 + lda j + cmp #$13 + bne b2_from_b6 + jmp breturn + //SEG32 main::@return + breturn: + //SEG33 [12] return [ ] ( main:0 [ ] ) + rts +} +//SEG34 line +line: { + .label _1 = 6 + .label l = 4 + //SEG35 [14] (byte) plot::x#0 ← (byte) line::l#2 [ line::l#2 plot::x#0 ] ( main:0::line:4 [ main::i#2 line::l#2 plot::x#0 ] main:0::line:9 [ main::j#2 line::l#2 plot::x#0 ] ) -- zpby1=zpby2 + lda l + sta plot.x + //SEG36 [15] call plot param-assignment [ line::l#2 ] ( main:0::line:4 [ main::i#2 line::l#2 ] main:0::line:9 [ main::j#2 line::l#2 ] ) + //SEG37 [20] phi from line to plot [phi:line->plot] + plot_from_line: + //SEG38 [20] phi (byte) plot::x#2 = (byte) plot::x#0 [phi:line->plot#0] -- register_copy + jsr plot + jmp b1 + //SEG39 line::@1 + b1: + //SEG40 [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] ( main:0::line:4 [ main::i#2 line::$1 ] main:0::line:9 [ main::j#2 line::$1 ] ) -- zpby1=zpby2_plus_coby1 + lda l + clc + adc #$14 + sta _1 + //SEG41 [17] (byte) plot::x#1 ← (byte~) line::$1 [ plot::x#1 ] ( main:0::line:4 [ main::i#2 plot::x#1 ] main:0::line:9 [ main::j#2 plot::x#1 ] ) -- zpby1=zpby2 + lda _1 + sta plot.x + //SEG42 [18] call plot param-assignment [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + //SEG43 [20] phi from line::@1 to plot [phi:line::@1->plot] + plot_from_b1: + //SEG44 [20] phi (byte) plot::x#2 = (byte) plot::x#1 [phi:line::@1->plot#0] -- register_copy + jsr plot + jmp breturn + //SEG45 line::@return + breturn: + //SEG46 [19] return [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + rts +} +//SEG47 plot +plot: { + .label x = 5 + //SEG48 [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) -- cowo1_staridx_zpby1=coby2 + lda #'*' + ldx x + sta SCREEN,x + jmp breturn + //SEG49 plot::@return + breturn: + //SEG50 [22] return [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) + rts +} + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] ( main:0::line:4 [ main::i#2 line::$1 ] main:0::line:9 [ main::j#2 line::$1 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ] +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::j#2 main::j#1 ] +Statement [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) always clobbers reg byte a +Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ line::l#2 line::l#0 line::l#1 ] +Statement [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] ( main:0::line:4 [ main::i#2 line::$1 ] main:0::line:9 [ main::j#2 line::$1 ] ) always clobbers reg byte a +Statement [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) always clobbers reg byte a +Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:3 [ main::j#2 main::j#1 ] : zp ZP_BYTE:3 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:4 [ line::l#2 line::l#0 line::l#1 ] : zp ZP_BYTE:4 , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:5 [ plot::x#2 plot::x#0 plot::x#1 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:6 [ line::$1 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [line] 52.67: zp ZP_BYTE:4 [ line::l#2 line::l#0 line::l#1 ] 4: zp ZP_BYTE:6 [ line::$1 ] +Uplift Scope [main] 27.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 27.5: zp ZP_BYTE:3 [ main::j#2 main::j#1 ] +Uplift Scope [plot] 14: zp ZP_BYTE:5 [ plot::x#2 plot::x#0 plot::x#1 ] +Uplift Scope [] + +Uplifting [line] best 678 combination reg byte y [ line::l#2 line::l#0 line::l#1 ] reg byte a [ line::$1 ] +Uplifting [main] best 438 combination reg byte y [ main::i#2 main::i#1 ] reg byte y [ main::j#2 main::j#1 ] +Uplifting [plot] best 433 combination reg byte a [ plot::x#2 plot::x#0 plot::x#1 ] +Uplifting [] best 433 combination +Removing instruction jmp b3 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp b5 +Removing instruction jmp b2 +Removing instruction jmp b6 +Removing instruction jmp breturn +Removing instruction jmp b1 +Removing instruction jmp breturn +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +bbegin: +//SEG3 @3 +b3: +//SEG4 [0] call main param-assignment [ ] ( ) +//SEG5 [1] phi from @3 to main [phi:@3->main] +main_from_b3: + jsr main +//SEG6 @end +bend: +//SEG7 main +main: { + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG9 [2] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- yby=coby1 + ldy #0 + jmp b1 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + b1_from_b5: + //SEG11 [2] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + //SEG12 main::@1 + b1: + //SEG13 [3] (byte) line::l#0 ← (byte) main::i#2 [ main::i#2 line::l#0 ] ( main:0 [ main::i#2 line::l#0 ] ) + // (byte) line::l#0 = (byte) main::i#2 // register copy reg byte y + //SEG14 [4] call line param-assignment [ main::i#2 ] ( main:0 [ main::i#2 ] ) + //SEG15 [13] phi from main::@1 to line [phi:main::@1->line] + line_from_b1: + //SEG16 [13] phi (byte) line::l#2 = (byte) line::l#0 [phi:main::@1->line#0] -- register_copy + jsr line + //SEG17 main::@5 + b5: + //SEG18 [5] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- yby=_inc_yby + iny + //SEG19 [6] if((byte) main::i#1!=(byte) 9) goto main::@1 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- yby_neq_coby1_then_la1 + cpy #9 + bne b1_from_b5 + //SEG20 [7] phi from main::@5 to main::@2 [phi:main::@5->main::@2] + b2_from_b5: + //SEG21 [7] phi (byte) main::j#2 = (byte) 10 [phi:main::@5->main::@2#0] -- yby=coby1 + ldy #$a + jmp b2 + //SEG22 [7] phi from main::@6 to main::@2 [phi:main::@6->main::@2] + b2_from_b6: + //SEG23 [7] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@6->main::@2#0] -- register_copy + //SEG24 main::@2 + b2: + //SEG25 [8] (byte) line::l#1 ← (byte) main::j#2 [ main::j#2 line::l#1 ] ( main:0 [ main::j#2 line::l#1 ] ) + // (byte) line::l#1 = (byte) main::j#2 // register copy reg byte y + //SEG26 [9] call line param-assignment [ main::j#2 ] ( main:0 [ main::j#2 ] ) + //SEG27 [13] phi from main::@2 to line [phi:main::@2->line] + line_from_b2: + //SEG28 [13] phi (byte) line::l#2 = (byte) line::l#1 [phi:main::@2->line#0] -- register_copy + jsr line + //SEG29 main::@6 + b6: + //SEG30 [10] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- yby=_inc_yby + iny + //SEG31 [11] if((byte) main::j#1!=(byte) 19) goto main::@2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- yby_neq_coby1_then_la1 + cpy #$13 + bne b2_from_b6 + //SEG32 main::@return + breturn: + //SEG33 [12] return [ ] ( main:0 [ ] ) + rts +} +//SEG34 line +line: { + //SEG35 [14] (byte) plot::x#0 ← (byte) line::l#2 [ line::l#2 plot::x#0 ] ( main:0::line:4 [ main::i#2 line::l#2 plot::x#0 ] main:0::line:9 [ main::j#2 line::l#2 plot::x#0 ] ) -- aby=yby + tya + //SEG36 [15] call plot param-assignment [ line::l#2 ] ( main:0::line:4 [ main::i#2 line::l#2 ] main:0::line:9 [ main::j#2 line::l#2 ] ) + //SEG37 [20] phi from line to plot [phi:line->plot] + plot_from_line: + //SEG38 [20] phi (byte) plot::x#2 = (byte) plot::x#0 [phi:line->plot#0] -- register_copy + jsr plot + //SEG39 line::@1 + b1: + //SEG40 [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] ( main:0::line:4 [ main::i#2 line::$1 ] main:0::line:9 [ main::j#2 line::$1 ] ) -- aby=yby_plus_coby1 + tya + clc + adc #$14 + //SEG41 [17] (byte) plot::x#1 ← (byte~) line::$1 [ plot::x#1 ] ( main:0::line:4 [ main::i#2 plot::x#1 ] main:0::line:9 [ main::j#2 plot::x#1 ] ) + // (byte) plot::x#1 = (byte~) line::$1 // register copy reg byte a + //SEG42 [18] call plot param-assignment [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + //SEG43 [20] phi from line::@1 to plot [phi:line::@1->plot] + plot_from_b1: + //SEG44 [20] phi (byte) plot::x#2 = (byte) plot::x#1 [phi:line::@1->plot#0] -- register_copy + jsr plot + //SEG45 line::@return + breturn: + //SEG46 [19] return [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + rts +} +//SEG47 plot +plot: { + //SEG48 [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) -- cowo1_staridx_aby=coby2 + tax + lda #'*' + sta SCREEN,x + //SEG49 plot::@return + breturn: + //SEG50 [22] return [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) + rts +} + +Replacing label b1_from_b5 with b1 +Replacing label b2_from_b6 with b2 +Removing instruction bbegin: +Removing instruction main_from_b3: +Removing instruction b1_from_b5: +Removing instruction b2_from_b6: +Succesful ASM optimization Pass5RedundantLabelElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +//SEG3 @3 +b3: +//SEG4 [0] call main param-assignment [ ] ( ) +//SEG5 [1] phi from @3 to main [phi:@3->main] + jsr main +//SEG6 @end +bend: +//SEG7 main +main: { + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + b1_from_main: + //SEG9 [2] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- yby=coby1 + ldy #0 + jmp b1 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + //SEG11 [2] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + //SEG12 main::@1 + b1: + //SEG13 [3] (byte) line::l#0 ← (byte) main::i#2 [ main::i#2 line::l#0 ] ( main:0 [ main::i#2 line::l#0 ] ) + // (byte) line::l#0 = (byte) main::i#2 // register copy reg byte y + //SEG14 [4] call line param-assignment [ main::i#2 ] ( main:0 [ main::i#2 ] ) + //SEG15 [13] phi from main::@1 to line [phi:main::@1->line] + line_from_b1: + //SEG16 [13] phi (byte) line::l#2 = (byte) line::l#0 [phi:main::@1->line#0] -- register_copy + jsr line + //SEG17 main::@5 + b5: + //SEG18 [5] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- yby=_inc_yby + iny + //SEG19 [6] if((byte) main::i#1!=(byte) 9) goto main::@1 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- yby_neq_coby1_then_la1 + cpy #9 + bne b1 + //SEG20 [7] phi from main::@5 to main::@2 [phi:main::@5->main::@2] + b2_from_b5: + //SEG21 [7] phi (byte) main::j#2 = (byte) 10 [phi:main::@5->main::@2#0] -- yby=coby1 + ldy #$a + jmp b2 + //SEG22 [7] phi from main::@6 to main::@2 [phi:main::@6->main::@2] + //SEG23 [7] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@6->main::@2#0] -- register_copy + //SEG24 main::@2 + b2: + //SEG25 [8] (byte) line::l#1 ← (byte) main::j#2 [ main::j#2 line::l#1 ] ( main:0 [ main::j#2 line::l#1 ] ) + // (byte) line::l#1 = (byte) main::j#2 // register copy reg byte y + //SEG26 [9] call line param-assignment [ main::j#2 ] ( main:0 [ main::j#2 ] ) + //SEG27 [13] phi from main::@2 to line [phi:main::@2->line] + line_from_b2: + //SEG28 [13] phi (byte) line::l#2 = (byte) line::l#1 [phi:main::@2->line#0] -- register_copy + jsr line + //SEG29 main::@6 + b6: + //SEG30 [10] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- yby=_inc_yby + iny + //SEG31 [11] if((byte) main::j#1!=(byte) 19) goto main::@2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- yby_neq_coby1_then_la1 + cpy #$13 + bne b2 + //SEG32 main::@return + breturn: + //SEG33 [12] return [ ] ( main:0 [ ] ) + rts +} +//SEG34 line +line: { + //SEG35 [14] (byte) plot::x#0 ← (byte) line::l#2 [ line::l#2 plot::x#0 ] ( main:0::line:4 [ main::i#2 line::l#2 plot::x#0 ] main:0::line:9 [ main::j#2 line::l#2 plot::x#0 ] ) -- aby=yby + tya + //SEG36 [15] call plot param-assignment [ line::l#2 ] ( main:0::line:4 [ main::i#2 line::l#2 ] main:0::line:9 [ main::j#2 line::l#2 ] ) + //SEG37 [20] phi from line to plot [phi:line->plot] + plot_from_line: + //SEG38 [20] phi (byte) plot::x#2 = (byte) plot::x#0 [phi:line->plot#0] -- register_copy + jsr plot + //SEG39 line::@1 + b1: + //SEG40 [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] ( main:0::line:4 [ main::i#2 line::$1 ] main:0::line:9 [ main::j#2 line::$1 ] ) -- aby=yby_plus_coby1 + tya + clc + adc #$14 + //SEG41 [17] (byte) plot::x#1 ← (byte~) line::$1 [ plot::x#1 ] ( main:0::line:4 [ main::i#2 plot::x#1 ] main:0::line:9 [ main::j#2 plot::x#1 ] ) + // (byte) plot::x#1 = (byte~) line::$1 // register copy reg byte a + //SEG42 [18] call plot param-assignment [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + //SEG43 [20] phi from line::@1 to plot [phi:line::@1->plot] + plot_from_b1: + //SEG44 [20] phi (byte) plot::x#2 = (byte) plot::x#1 [phi:line::@1->plot#0] -- register_copy + jsr plot + //SEG45 line::@return + breturn: + //SEG46 [19] return [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + rts +} +//SEG47 plot +plot: { + //SEG48 [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) -- cowo1_staridx_aby=coby2 + tax + lda #'*' + sta SCREEN,x + //SEG49 plot::@return + breturn: + //SEG50 [22] return [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) + rts +} + +Removing instruction b3: +Removing instruction bend: +Removing instruction b1_from_main: +Removing instruction line_from_b1: +Removing instruction b5: +Removing instruction b2_from_b5: +Removing instruction line_from_b2: +Removing instruction b6: +Removing instruction breturn: +Removing instruction plot_from_line: +Removing instruction b1: +Removing instruction plot_from_b1: +Removing instruction breturn: +Removing instruction breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +//SEG3 @3 +//SEG4 [0] call main param-assignment [ ] ( ) +//SEG5 [1] phi from @3 to main [phi:@3->main] + jsr main +//SEG6 @end +//SEG7 main +main: { + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + //SEG9 [2] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- yby=coby1 + ldy #0 + jmp b1 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + //SEG11 [2] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + //SEG12 main::@1 + b1: + //SEG13 [3] (byte) line::l#0 ← (byte) main::i#2 [ main::i#2 line::l#0 ] ( main:0 [ main::i#2 line::l#0 ] ) + // (byte) line::l#0 = (byte) main::i#2 // register copy reg byte y + //SEG14 [4] call line param-assignment [ main::i#2 ] ( main:0 [ main::i#2 ] ) + //SEG15 [13] phi from main::@1 to line [phi:main::@1->line] + //SEG16 [13] phi (byte) line::l#2 = (byte) line::l#0 [phi:main::@1->line#0] -- register_copy + jsr line + //SEG17 main::@5 + //SEG18 [5] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- yby=_inc_yby + iny + //SEG19 [6] if((byte) main::i#1!=(byte) 9) goto main::@1 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- yby_neq_coby1_then_la1 + cpy #9 + bne b1 + //SEG20 [7] phi from main::@5 to main::@2 [phi:main::@5->main::@2] + //SEG21 [7] phi (byte) main::j#2 = (byte) 10 [phi:main::@5->main::@2#0] -- yby=coby1 + ldy #$a + jmp b2 + //SEG22 [7] phi from main::@6 to main::@2 [phi:main::@6->main::@2] + //SEG23 [7] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@6->main::@2#0] -- register_copy + //SEG24 main::@2 + b2: + //SEG25 [8] (byte) line::l#1 ← (byte) main::j#2 [ main::j#2 line::l#1 ] ( main:0 [ main::j#2 line::l#1 ] ) + // (byte) line::l#1 = (byte) main::j#2 // register copy reg byte y + //SEG26 [9] call line param-assignment [ main::j#2 ] ( main:0 [ main::j#2 ] ) + //SEG27 [13] phi from main::@2 to line [phi:main::@2->line] + //SEG28 [13] phi (byte) line::l#2 = (byte) line::l#1 [phi:main::@2->line#0] -- register_copy + jsr line + //SEG29 main::@6 + //SEG30 [10] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- yby=_inc_yby + iny + //SEG31 [11] if((byte) main::j#1!=(byte) 19) goto main::@2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- yby_neq_coby1_then_la1 + cpy #$13 + bne b2 + //SEG32 main::@return + //SEG33 [12] return [ ] ( main:0 [ ] ) + rts +} +//SEG34 line +line: { + //SEG35 [14] (byte) plot::x#0 ← (byte) line::l#2 [ line::l#2 plot::x#0 ] ( main:0::line:4 [ main::i#2 line::l#2 plot::x#0 ] main:0::line:9 [ main::j#2 line::l#2 plot::x#0 ] ) -- aby=yby + tya + //SEG36 [15] call plot param-assignment [ line::l#2 ] ( main:0::line:4 [ main::i#2 line::l#2 ] main:0::line:9 [ main::j#2 line::l#2 ] ) + //SEG37 [20] phi from line to plot [phi:line->plot] + //SEG38 [20] phi (byte) plot::x#2 = (byte) plot::x#0 [phi:line->plot#0] -- register_copy + jsr plot + //SEG39 line::@1 + //SEG40 [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] ( main:0::line:4 [ main::i#2 line::$1 ] main:0::line:9 [ main::j#2 line::$1 ] ) -- aby=yby_plus_coby1 + tya + clc + adc #$14 + //SEG41 [17] (byte) plot::x#1 ← (byte~) line::$1 [ plot::x#1 ] ( main:0::line:4 [ main::i#2 plot::x#1 ] main:0::line:9 [ main::j#2 plot::x#1 ] ) + // (byte) plot::x#1 = (byte~) line::$1 // register copy reg byte a + //SEG42 [18] call plot param-assignment [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + //SEG43 [20] phi from line::@1 to plot [phi:line::@1->plot] + //SEG44 [20] phi (byte) plot::x#2 = (byte) plot::x#1 [phi:line::@1->plot#0] -- register_copy + jsr plot + //SEG45 line::@return + //SEG46 [19] return [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + rts +} +//SEG47 plot +plot: { + //SEG48 [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) -- cowo1_staridx_aby=coby2 + tax + lda #'*' + sta SCREEN,x + //SEG49 plot::@return + //SEG50 [22] return [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) + rts +} + +Removing instruction jmp b1 +Removing instruction jmp b2 +Succesful ASM optimization Pass5NextJumpElimination +ASSEMBLER +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +//SEG3 @3 +//SEG4 [0] call main param-assignment [ ] ( ) +//SEG5 [1] phi from @3 to main [phi:@3->main] + jsr main +//SEG6 @end +//SEG7 main +main: { + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + //SEG9 [2] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- yby=coby1 + ldy #0 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + //SEG11 [2] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + //SEG12 main::@1 + b1: + //SEG13 [3] (byte) line::l#0 ← (byte) main::i#2 [ main::i#2 line::l#0 ] ( main:0 [ main::i#2 line::l#0 ] ) + // (byte) line::l#0 = (byte) main::i#2 // register copy reg byte y + //SEG14 [4] call line param-assignment [ main::i#2 ] ( main:0 [ main::i#2 ] ) + //SEG15 [13] phi from main::@1 to line [phi:main::@1->line] + //SEG16 [13] phi (byte) line::l#2 = (byte) line::l#0 [phi:main::@1->line#0] -- register_copy + jsr line + //SEG17 main::@5 + //SEG18 [5] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- yby=_inc_yby + iny + //SEG19 [6] if((byte) main::i#1!=(byte) 9) goto main::@1 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- yby_neq_coby1_then_la1 + cpy #9 + bne b1 + //SEG20 [7] phi from main::@5 to main::@2 [phi:main::@5->main::@2] + //SEG21 [7] phi (byte) main::j#2 = (byte) 10 [phi:main::@5->main::@2#0] -- yby=coby1 + ldy #$a + //SEG22 [7] phi from main::@6 to main::@2 [phi:main::@6->main::@2] + //SEG23 [7] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@6->main::@2#0] -- register_copy + //SEG24 main::@2 + b2: + //SEG25 [8] (byte) line::l#1 ← (byte) main::j#2 [ main::j#2 line::l#1 ] ( main:0 [ main::j#2 line::l#1 ] ) + // (byte) line::l#1 = (byte) main::j#2 // register copy reg byte y + //SEG26 [9] call line param-assignment [ main::j#2 ] ( main:0 [ main::j#2 ] ) + //SEG27 [13] phi from main::@2 to line [phi:main::@2->line] + //SEG28 [13] phi (byte) line::l#2 = (byte) line::l#1 [phi:main::@2->line#0] -- register_copy + jsr line + //SEG29 main::@6 + //SEG30 [10] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- yby=_inc_yby + iny + //SEG31 [11] if((byte) main::j#1!=(byte) 19) goto main::@2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- yby_neq_coby1_then_la1 + cpy #$13 + bne b2 + //SEG32 main::@return + //SEG33 [12] return [ ] ( main:0 [ ] ) + rts +} +//SEG34 line +line: { + //SEG35 [14] (byte) plot::x#0 ← (byte) line::l#2 [ line::l#2 plot::x#0 ] ( main:0::line:4 [ main::i#2 line::l#2 plot::x#0 ] main:0::line:9 [ main::j#2 line::l#2 plot::x#0 ] ) -- aby=yby + tya + //SEG36 [15] call plot param-assignment [ line::l#2 ] ( main:0::line:4 [ main::i#2 line::l#2 ] main:0::line:9 [ main::j#2 line::l#2 ] ) + //SEG37 [20] phi from line to plot [phi:line->plot] + //SEG38 [20] phi (byte) plot::x#2 = (byte) plot::x#0 [phi:line->plot#0] -- register_copy + jsr plot + //SEG39 line::@1 + //SEG40 [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] ( main:0::line:4 [ main::i#2 line::$1 ] main:0::line:9 [ main::j#2 line::$1 ] ) -- aby=yby_plus_coby1 + tya + clc + adc #$14 + //SEG41 [17] (byte) plot::x#1 ← (byte~) line::$1 [ plot::x#1 ] ( main:0::line:4 [ main::i#2 plot::x#1 ] main:0::line:9 [ main::j#2 plot::x#1 ] ) + // (byte) plot::x#1 = (byte~) line::$1 // register copy reg byte a + //SEG42 [18] call plot param-assignment [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + //SEG43 [20] phi from line::@1 to plot [phi:line::@1->plot] + //SEG44 [20] phi (byte) plot::x#2 = (byte) plot::x#1 [phi:line::@1->plot#0] -- register_copy + jsr plot + //SEG45 line::@return + //SEG46 [19] return [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + rts +} +//SEG47 plot +plot: { + //SEG48 [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) -- cowo1_staridx_aby=coby2 + tax + lda #'*' + sta SCREEN,x + //SEG49 plot::@return + //SEG50 [22] return [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) + rts +} + +FINAL SYMBOL TABLE +(label) @3 +(label) @begin +(label) @end +(byte*) SCREEN +(const byte*) SCREEN#0 SCREEN = (word) 1024 +(void()) line((byte) line::l) +(byte~) line::$1 reg byte a 4.0 +(label) line::@1 +(label) line::@return +(byte) line::l +(byte) line::l#0 reg byte y 22.0 +(byte) line::l#1 reg byte y 22.0 +(byte) line::l#2 reg byte y 8.666666666666666 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@5 +(label) main::@6 +(label) main::@return +(byte) main::i +(byte) main::i#1 reg byte y 16.5 +(byte) main::i#2 reg byte y 11.0 +(byte) main::j +(byte) main::j#1 reg byte y 16.5 +(byte) main::j#2 reg byte y 11.0 +(void()) plot((byte) plot::x) +(label) plot::@return +(byte) plot::x +(byte) plot::x#0 reg byte a 4.0 +(byte) plot::x#1 reg byte a 4.0 +(byte) plot::x#2 reg byte a 6.0 + +reg byte y [ main::i#2 main::i#1 ] +reg byte y [ main::j#2 main::j#1 ] +reg byte y [ line::l#2 line::l#0 line::l#1 ] +reg byte a [ plot::x#2 plot::x#0 plot::x#1 ] +reg byte a [ line::$1 ] + +FINAL CODE +//SEG0 Basic Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +//SEG1 Global Constants & labels + .const SCREEN = $400 +//SEG2 @begin +//SEG3 @3 +//SEG4 [0] call main param-assignment [ ] ( ) +//SEG5 [1] phi from @3 to main [phi:@3->main] + jsr main +//SEG6 @end +//SEG7 main +main: { + //SEG8 [2] phi from main to main::@1 [phi:main->main::@1] + //SEG9 [2] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- yby=coby1 + ldy #0 + //SEG10 [2] phi from main::@5 to main::@1 [phi:main::@5->main::@1] + //SEG11 [2] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@5->main::@1#0] -- register_copy + //SEG12 main::@1 + b1: + //SEG13 [3] (byte) line::l#0 ← (byte) main::i#2 [ main::i#2 line::l#0 ] ( main:0 [ main::i#2 line::l#0 ] ) + // (byte) line::l#0 = (byte) main::i#2 // register copy reg byte y + //SEG14 [4] call line param-assignment [ main::i#2 ] ( main:0 [ main::i#2 ] ) + //SEG15 [13] phi from main::@1 to line [phi:main::@1->line] + //SEG16 [13] phi (byte) line::l#2 = (byte) line::l#0 [phi:main::@1->line#0] -- register_copy + jsr line + //SEG17 main::@5 + //SEG18 [5] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- yby=_inc_yby + iny + //SEG19 [6] if((byte) main::i#1!=(byte) 9) goto main::@1 [ main::i#1 ] ( main:0 [ main::i#1 ] ) -- yby_neq_coby1_then_la1 + cpy #9 + bne b1 + //SEG20 [7] phi from main::@5 to main::@2 [phi:main::@5->main::@2] + //SEG21 [7] phi (byte) main::j#2 = (byte) 10 [phi:main::@5->main::@2#0] -- yby=coby1 + ldy #$a + //SEG22 [7] phi from main::@6 to main::@2 [phi:main::@6->main::@2] + //SEG23 [7] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@6->main::@2#0] -- register_copy + //SEG24 main::@2 + b2: + //SEG25 [8] (byte) line::l#1 ← (byte) main::j#2 [ main::j#2 line::l#1 ] ( main:0 [ main::j#2 line::l#1 ] ) + // (byte) line::l#1 = (byte) main::j#2 // register copy reg byte y + //SEG26 [9] call line param-assignment [ main::j#2 ] ( main:0 [ main::j#2 ] ) + //SEG27 [13] phi from main::@2 to line [phi:main::@2->line] + //SEG28 [13] phi (byte) line::l#2 = (byte) line::l#1 [phi:main::@2->line#0] -- register_copy + jsr line + //SEG29 main::@6 + //SEG30 [10] (byte) main::j#1 ← ++ (byte) main::j#2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- yby=_inc_yby + iny + //SEG31 [11] if((byte) main::j#1!=(byte) 19) goto main::@2 [ main::j#1 ] ( main:0 [ main::j#1 ] ) -- yby_neq_coby1_then_la1 + cpy #$13 + bne b2 + //SEG32 main::@return + //SEG33 [12] return [ ] ( main:0 [ ] ) + rts +} +//SEG34 line +line: { + //SEG35 [14] (byte) plot::x#0 ← (byte) line::l#2 [ line::l#2 plot::x#0 ] ( main:0::line:4 [ main::i#2 line::l#2 plot::x#0 ] main:0::line:9 [ main::j#2 line::l#2 plot::x#0 ] ) -- aby=yby + tya + //SEG36 [15] call plot param-assignment [ line::l#2 ] ( main:0::line:4 [ main::i#2 line::l#2 ] main:0::line:9 [ main::j#2 line::l#2 ] ) + //SEG37 [20] phi from line to plot [phi:line->plot] + //SEG38 [20] phi (byte) plot::x#2 = (byte) plot::x#0 [phi:line->plot#0] -- register_copy + jsr plot + //SEG39 line::@1 + //SEG40 [16] (byte~) line::$1 ← (byte) line::l#2 + (byte) 20 [ line::$1 ] ( main:0::line:4 [ main::i#2 line::$1 ] main:0::line:9 [ main::j#2 line::$1 ] ) -- aby=yby_plus_coby1 + tya + clc + adc #$14 + //SEG41 [17] (byte) plot::x#1 ← (byte~) line::$1 [ plot::x#1 ] ( main:0::line:4 [ main::i#2 plot::x#1 ] main:0::line:9 [ main::j#2 plot::x#1 ] ) + // (byte) plot::x#1 = (byte~) line::$1 // register copy reg byte a + //SEG42 [18] call plot param-assignment [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + //SEG43 [20] phi from line::@1 to plot [phi:line::@1->plot] + //SEG44 [20] phi (byte) plot::x#2 = (byte) plot::x#1 [phi:line::@1->plot#0] -- register_copy + jsr plot + //SEG45 line::@return + //SEG46 [19] return [ ] ( main:0::line:4 [ main::i#2 ] main:0::line:9 [ main::j#2 ] ) + rts +} +//SEG47 plot +plot: { + //SEG48 [21] *((const byte*) SCREEN#0 + (byte) plot::x#2) ← (byte) '*' [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) -- cowo1_staridx_aby=coby2 + tax + lda #'*' + sta SCREEN,x + //SEG49 plot::@return + //SEG50 [22] return [ ] ( main:0::line:4::plot:15 [ main::i#2 line::l#2 ] main:0::line:9::plot:15 [ main::j#2 line::l#2 ] main:0::line:4::plot:18 [ main::i#2 ] main:0::line:9::plot:18 [ main::j#2 ] ) + rts +} + diff --git a/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.sym b/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.sym new file mode 100644 index 000000000..072189008 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/overlap-allocation-2.sym @@ -0,0 +1,37 @@ +(label) @3 +(label) @begin +(label) @end +(byte*) SCREEN +(const byte*) SCREEN#0 SCREEN = (word) 1024 +(void()) line((byte) line::l) +(byte~) line::$1 reg byte a 4.0 +(label) line::@1 +(label) line::@return +(byte) line::l +(byte) line::l#0 reg byte y 22.0 +(byte) line::l#1 reg byte y 22.0 +(byte) line::l#2 reg byte y 8.666666666666666 +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@5 +(label) main::@6 +(label) main::@return +(byte) main::i +(byte) main::i#1 reg byte y 16.5 +(byte) main::i#2 reg byte y 11.0 +(byte) main::j +(byte) main::j#1 reg byte y 16.5 +(byte) main::j#2 reg byte y 11.0 +(void()) plot((byte) plot::x) +(label) plot::@return +(byte) plot::x +(byte) plot::x#0 reg byte a 4.0 +(byte) plot::x#1 reg byte a 4.0 +(byte) plot::x#2 reg byte a 6.0 + +reg byte y [ main::i#2 main::i#1 ] +reg byte y [ main::j#2 main::j#1 ] +reg byte y [ line::l#2 line::l#0 line::l#1 ] +reg byte a [ plot::x#2 plot::x#0 plot::x#1 ] +reg byte a [ line::$1 ]