diff --git a/src/dk/camelot64/kickc/test/TestCompilationOutput.java b/src/dk/camelot64/kickc/test/TestCompilationOutput.java index f6ad635fc..f34818383 100644 --- a/src/dk/camelot64/kickc/test/TestCompilationOutput.java +++ b/src/dk/camelot64/kickc/test/TestCompilationOutput.java @@ -53,6 +53,12 @@ public class TestCompilationOutput extends TestCase { tester.testFile("loopsplit"); } + public void testLoopNest() throws IOException, URISyntaxException { + TestCompilationOutput tester = new TestCompilationOutput(); + tester.testFile("loopnest"); + } + + private void testFile(String fileName) throws IOException, URISyntaxException { String inputPath = testPath + fileName + ".kc"; System.out.println("Testing output for " + inputPath); diff --git a/src/dk/camelot64/kickc/test/loopnest.kc b/src/dk/camelot64/kickc/test/loopnest.kc new file mode 100644 index 000000000..5147847b3 --- /dev/null +++ b/src/dk/camelot64/kickc/test/loopnest.kc @@ -0,0 +1,33 @@ +byte* SCREEN = $0400; + +main(); + +void main() { + byte i=100; + do { + byte j=100; + do { + nest1(); + } while (--j>0) + } while (--i>0) +} + +void nest1() { + byte i=100; + do { + byte j=100; + do { + nest2(); + } while (--j>0) + } while (--i>0) +} + +void nest2() { + byte i=100; + do { + byte j=100; + do { + *SCREEN = j; + } while (--j>0) + } while (--i>0) +} diff --git a/src/dk/camelot64/kickc/test/ref/loopnest.asm b/src/dk/camelot64/kickc/test/ref/loopnest.asm new file mode 100644 index 000000000..3dd0d9ec0 --- /dev/null +++ b/src/dk/camelot64/kickc/test/ref/loopnest.asm @@ -0,0 +1,69 @@ +BBEGIN: + jsr main +BEND: +main: +main__B1_from_main: + lda #100 + sta 2 +main__B1_from_B3: +main__B1: +main__B2_from_B1: + lda #100 + sta 3 +main__B2_from_B5: +main__B2: + jsr nest1 +main__B5: + dec 3 + lda 3 + bne main__B2_from_B5 +main__B3: + dec 2 + lda 2 + bne main__B1_from_B3 +main__Breturn: + rts +nest1: +nest1__B1_from_nest1: + lda #100 + sta 4 +nest1__B1_from_B3: +nest1__B1: +nest1__B2_from_B1: + lda #100 + sta 5 +nest1__B2_from_B5: +nest1__B2: + jsr nest2 +nest1__B5: + dec 5 + lda 5 + bne nest1__B2_from_B5 +nest1__B3: + dec 4 + lda 4 + bne nest1__B1_from_B3 +nest1__Breturn: + rts +nest2: +nest2__B1_from_nest2: + lda #100 + sta 6 +nest2__B1_from_B3: +nest2__B1: +nest2__B2_from_B1: + lda #100 + sta 7 +nest2__B2_from_B2: +nest2__B2: + lda 7 + sta 1024 + dec 7 + lda 7 + bne nest2__B2_from_B2 +nest2__B3: + dec 6 + lda 6 + bne nest2__B1_from_B3 +nest2__Breturn: + rts diff --git a/src/dk/camelot64/kickc/test/ref/loopnest.cfg b/src/dk/camelot64/kickc/test/ref/loopnest.cfg new file mode 100644 index 000000000..26c9576f1 --- /dev/null +++ b/src/dk/camelot64/kickc/test/ref/loopnest.cfg @@ -0,0 +1,62 @@ +@BEGIN: from + [0] call main param-assignment [ ] + to:@END +@END: from @BEGIN +main: from @BEGIN + to:main::@1 +main::@1: from main main::@3 + [1] (byte) main::i#2 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) [ ] + to:main::@2 +main::@2: from main::@1 main::@5 + [2] (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) [ ] + [3] call nest1 param-assignment [ main::j#2 main::i#2 ] + to:main::@5 +main::@5: from main::@2 + [4] (byte) main::j#1 ← -- (byte) main::j#2 [ main::j#1 main::i#2 ] + [5] if((byte) main::j#1>(byte) 0) goto main::@2 [ main::j#1 main::i#2 ] + to:main::@3 +main::@3: from main::@5 + [6] (byte) main::i#1 ← -- (byte) main::i#2 [ main::i#1 ] + [7] if((byte) main::i#1>(byte) 0) goto main::@1 [ main::i#1 ] + to:main::@return +main::@return: from main::@3 + [8] return [ ] + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + [9] (byte) nest1::i#2 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) [ ] + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + [10] (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) [ ] + [11] call nest2 param-assignment [ nest1::j#2 nest1::i#2 ] + to:nest1::@5 +nest1::@5: from nest1::@2 + [12] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] + [13] if((byte) nest1::j#1>(byte) 0) goto nest1::@2 [ nest1::j#1 nest1::i#2 ] + to:nest1::@3 +nest1::@3: from nest1::@5 + [14] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] + [15] if((byte) nest1::i#1>(byte) 0) goto nest1::@1 [ nest1::i#1 ] + to:nest1::@return +nest1::@return: from nest1::@3 + [16] return [ ] + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + [17] (byte) nest2::i#2 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) [ nest2::i#2 ] + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + [18] (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) [ nest2::j#2 nest2::i#2 ] + [19] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] + [20] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] + [21] if((byte) nest2::j#1>(byte) 0) goto nest2::@2 [ nest2::j#1 nest2::i#2 ] + to:nest2::@3 +nest2::@3: from nest2::@2 + [22] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] + [23] if((byte) nest2::i#1>(byte) 0) goto nest2::@1 [ nest2::i#1 ] + to:nest2::@return +nest2::@return: from nest2::@3 + [24] return [ ] + to:@RETURN diff --git a/src/dk/camelot64/kickc/test/ref/loopnest.log b/src/dk/camelot64/kickc/test/ref/loopnest.log new file mode 100644 index 000000000..cfdbc2784 --- /dev/null +++ b/src/dk/camelot64/kickc/test/ref/loopnest.log @@ -0,0 +1,2278 @@ +byte* SCREEN = $0400; + +main(); + +void main() { + byte i=100; + do { + byte j=100; + do { + nest1(); + } while (--j>0) + } while (--i>0) +} + +void nest1() { + byte i=100; + do { + byte j=100; + do { + nest2(); + } while (--j>0) + } while (--i>0) +} + +void nest2() { + byte i=100; + do { + byte j=100; + do { + *SCREEN = j; + } while (--j>0) + } while (--i>0) +} + +Adding pre/post-modifier (byte) main::j ← -- (byte) main::j +Adding pre/post-modifier (byte) main::i ← -- (byte) main::i +Adding pre/post-modifier (byte) nest1::j ← -- (byte) nest1::j +Adding pre/post-modifier (byte) nest1::i ← -- (byte) nest1::i +Adding pre/post-modifier (byte) nest2::j ← -- (byte) nest2::j +Adding pre/post-modifier (byte) nest2::i ← -- (byte) nest2::i +PROGRAM + (byte*) SCREEN ← (word) 1024 + (void~) $0 ← call main + proc (void()) main() + (byte) main::i ← (byte) 100 +main::@1: + (byte) main::j ← (byte) 100 +main::@2: + (void~) main::$0 ← call nest1 + (byte) main::j ← -- (byte) main::j + (boolean~) main::$1 ← (byte) main::j > (byte) 0 + if((boolean~) main::$1) goto main::@2 + (byte) main::i ← -- (byte) main::i + (boolean~) main::$2 ← (byte) main::i > (byte) 0 + if((boolean~) main::$2) goto main::@1 +main::@return: + return + endproc // main() + proc (void()) nest1() + (byte) nest1::i ← (byte) 100 +nest1::@1: + (byte) nest1::j ← (byte) 100 +nest1::@2: + (void~) nest1::$0 ← call nest2 + (byte) nest1::j ← -- (byte) nest1::j + (boolean~) nest1::$1 ← (byte) nest1::j > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + (byte) nest1::i ← -- (byte) nest1::i + (boolean~) nest1::$2 ← (byte) nest1::i > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 +nest1::@return: + return + endproc // nest1() + proc (void()) nest2() + (byte) nest2::i ← (byte) 100 +nest2::@1: + (byte) nest2::j ← (byte) 100 +nest2::@2: + *((byte*) SCREEN) ← (byte) nest2::j + (byte) nest2::j ← -- (byte) nest2::j + (boolean~) nest2::$0 ← (byte) nest2::j > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + (byte) nest2::i ← -- (byte) nest2::i + (boolean~) nest2::$1 ← (byte) nest2::i > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 +nest2::@return: + return + endproc // nest2() + +SYMBOLS +(void~) $0 +(byte*) SCREEN +(void()) main() +(void~) main::$0 +(boolean~) main::$1 +(boolean~) main::$2 +(label) main::@1 +(label) main::@2 +(label) main::@return +(byte) main::i +(byte) main::j + +(void()) nest1() +(void~) nest1::$0 +(boolean~) nest1::$1 +(boolean~) nest1::$2 +(label) nest1::@1 +(label) nest1::@2 +(label) nest1::@return +(byte) nest1::i +(byte) nest1::j + +(void()) nest2() +(boolean~) nest2::$0 +(boolean~) nest2::$1 +(label) nest2::@1 +(label) nest2::@2 +(label) nest2::@return +(byte) nest2::i +(byte) nest2::j + + +INITIAL CONTROL FLOW GRAPH +@BEGIN: from + (byte*) SCREEN ← (word) 1024 + (void~) $0 ← call main + to:@1 +main: from + (byte) main::i ← (byte) 100 + to:main::@1 +main::@1: from main main::@3 + (byte) main::j ← (byte) 100 + to:main::@2 +main::@2: from main::@1 main::@2 + (void~) main::$0 ← call nest1 + (byte) main::j ← -- (byte) main::j + (boolean~) main::$1 ← (byte) main::j > (byte) 0 + if((boolean~) main::$1) goto main::@2 + to:main::@3 +main::@3: from main::@2 + (byte) main::i ← -- (byte) main::i + (boolean~) main::$2 ← (byte) main::i > (byte) 0 + if((boolean~) main::$2) goto main::@1 + to:main::@4 +main::@4: from main::@3 + to:main::@return +main::@return: from main::@4 + return + to:@RETURN +@1: from @BEGIN + to:@2 +nest1: from + (byte) nest1::i ← (byte) 100 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte) nest1::j ← (byte) 100 + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@2 + (void~) nest1::$0 ← call nest2 + (byte) nest1::j ← -- (byte) nest1::j + (boolean~) nest1::$1 ← (byte) nest1::j > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@2 + (byte) nest1::i ← -- (byte) nest1::i + (boolean~) nest1::$2 ← (byte) nest1::i > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 + to:nest1::@4 +nest1::@4: from nest1::@3 + to:nest1::@return +nest1::@return: from nest1::@4 + return + to:@RETURN +@2: from @1 + to:@3 +nest2: from + (byte) nest2::i ← (byte) 100 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::j ← (byte) 100 + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + *((byte*) SCREEN) ← (byte) nest2::j + (byte) nest2::j ← -- (byte) nest2::j + (boolean~) nest2::$0 ← (byte) nest2::j > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i ← -- (byte) nest2::i + (boolean~) nest2::$1 ← (byte) nest2::i > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 + to:nest2::@4 +nest2::@4: from nest2::@3 + to:nest2::@return +nest2::@return: from nest2::@4 + return + to:@RETURN +@3: from @2 + to:@END +@END: from @3 + +Removing empty block main::@4 +Removing empty block @1 +Removing empty block nest1::@4 +Removing empty block @2 +Removing empty block nest2::@4 +Removing empty block @3 +CONTROL FLOW GRAPH +@BEGIN: from + (byte*) SCREEN ← (word) 1024 + (void~) $0 ← call main + to:@END +main: from + (byte) main::i ← (byte) 100 + to:main::@1 +main::@1: from main main::@3 + (byte) main::j ← (byte) 100 + to:main::@2 +main::@2: from main::@1 main::@2 + (void~) main::$0 ← call nest1 + (byte) main::j ← -- (byte) main::j + (boolean~) main::$1 ← (byte) main::j > (byte) 0 + if((boolean~) main::$1) goto main::@2 + to:main::@3 +main::@3: from main::@2 + (byte) main::i ← -- (byte) main::i + (boolean~) main::$2 ← (byte) main::i > (byte) 0 + if((boolean~) main::$2) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from + (byte) nest1::i ← (byte) 100 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte) nest1::j ← (byte) 100 + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@2 + (void~) nest1::$0 ← call nest2 + (byte) nest1::j ← -- (byte) nest1::j + (boolean~) nest1::$1 ← (byte) nest1::j > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@2 + (byte) nest1::i ← -- (byte) nest1::i + (boolean~) nest1::$2 ← (byte) nest1::i > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from + (byte) nest2::i ← (byte) 100 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::j ← (byte) 100 + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + *((byte*) SCREEN) ← (byte) nest2::j + (byte) nest2::j ← -- (byte) nest2::j + (boolean~) nest2::$0 ← (byte) nest2::j > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i ← -- (byte) nest2::i + (boolean~) nest2::$1 ← (byte) nest2::i > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +CONTROL FLOW GRAPH WITH ASSIGNMENT CALL +@BEGIN: from + (byte*) SCREEN ← (word) 1024 + call main param-assignment + to:@4 +@4: from @BEGIN + to:@END +main: from @BEGIN + (byte) main::i ← (byte) 100 + to:main::@1 +main::@1: from main main::@3 + (byte) main::j ← (byte) 100 + to:main::@2 +main::@2: from main::@1 main::@5 + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j ← -- (byte) main::j + (boolean~) main::$1 ← (byte) main::j > (byte) 0 + if((boolean~) main::$1) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte) main::i ← -- (byte) main::i + (boolean~) main::$2 ← (byte) main::i > (byte) 0 + if((boolean~) main::$2) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + (byte) nest1::i ← (byte) 100 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte) nest1::j ← (byte) 100 + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j ← -- (byte) nest1::j + (boolean~) nest1::$1 ← (byte) nest1::j > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i ← -- (byte) nest1::i + (boolean~) nest1::$2 ← (byte) nest1::i > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + (byte) nest2::i ← (byte) 100 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::j ← (byte) 100 + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + *((byte*) SCREEN) ← (byte) nest2::j + (byte) nest2::j ← -- (byte) nest2::j + (boolean~) nest2::$0 ← (byte) nest2::j > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i ← -- (byte) nest2::i + (boolean~) nest2::$1 ← (byte) nest2::i > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @4 + +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +Completing Phi functions... +CONTROL FLOW GRAPH SSA +@BEGIN: from + (byte*) SCREEN#0 ← (word) 1024 + call main param-assignment + to:@4 +@4: from @BEGIN + to:@END +main: from @BEGIN + (byte*) SCREEN#13 ← phi( @BEGIN/(byte*) SCREEN#0 ) + (byte) main::i#0 ← (byte) 100 + to:main::@1 +main::@1: from main main::@3 + (byte*) SCREEN#11 ← phi( main/(byte*) SCREEN#13 main::@3/(byte*) SCREEN#14 ) + (byte) main::i#5 ← phi( main/(byte) main::i#0 main::@3/(byte) main::i#1 ) + (byte) main::j#0 ← (byte) 100 + to:main::@2 +main::@2: from main::@1 main::@5 + (byte*) SCREEN#10 ← phi( main::@1/(byte*) SCREEN#11 main::@5/(byte*) SCREEN#12 ) + (byte) main::i#4 ← phi( main::@1/(byte) main::i#5 main::@5/(byte) main::i#3 ) + (byte) main::j#3 ← phi( main::@1/(byte) main::j#0 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte*) SCREEN#12 ← phi( main::@2/(byte*) SCREEN#10 ) + (byte) main::i#3 ← phi( main::@2/(byte) main::i#4 ) + (byte) main::j#2 ← phi( main::@2/(byte) main::j#3 ) + (byte) main::j#1 ← -- (byte) main::j#2 + (boolean~) main::$1 ← (byte) main::j#1 > (byte) 0 + if((boolean~) main::$1) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte*) SCREEN#14 ← phi( main::@5/(byte*) SCREEN#12 ) + (byte) main::i#2 ← phi( main::@5/(byte) main::i#3 ) + (byte) main::i#1 ← -- (byte) main::i#2 + (boolean~) main::$2 ← (byte) main::i#1 > (byte) 0 + if((boolean~) main::$2) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + (byte*) SCREEN#8 ← phi( main::@2/(byte*) SCREEN#10 ) + (byte) nest1::i#0 ← (byte) 100 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#6 ← phi( nest1/(byte*) SCREEN#8 nest1::@3/(byte*) SCREEN#9 ) + (byte) nest1::i#5 ← phi( nest1/(byte) nest1::i#0 nest1::@3/(byte) nest1::i#1 ) + (byte) nest1::j#0 ← (byte) 100 + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte*) SCREEN#5 ← phi( nest1::@1/(byte*) SCREEN#6 nest1::@5/(byte*) SCREEN#7 ) + (byte) nest1::i#4 ← phi( nest1::@1/(byte) nest1::i#5 nest1::@5/(byte) nest1::i#3 ) + (byte) nest1::j#3 ← phi( nest1::@1/(byte) nest1::j#0 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte*) SCREEN#7 ← phi( nest1::@2/(byte*) SCREEN#5 ) + (byte) nest1::i#3 ← phi( nest1::@2/(byte) nest1::i#4 ) + (byte) nest1::j#2 ← phi( nest1::@2/(byte) nest1::j#3 ) + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + (boolean~) nest1::$1 ← (byte) nest1::j#1 > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte*) SCREEN#9 ← phi( nest1::@5/(byte*) SCREEN#7 ) + (byte) nest1::i#2 ← phi( nest1::@5/(byte) nest1::i#3 ) + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + (boolean~) nest1::$2 ← (byte) nest1::i#1 > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + (byte*) SCREEN#3 ← phi( nest1::@2/(byte*) SCREEN#5 ) + (byte) nest2::i#0 ← (byte) 100 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#4 ← phi( nest2/(byte) nest2::i#0 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#2 ← phi( nest2/(byte*) SCREEN#3 nest2::@3/(byte*) SCREEN#4 ) + (byte) nest2::j#0 ← (byte) 100 + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::i#3 ← phi( nest2::@1/(byte) nest2::i#4 nest2::@2/(byte) nest2::i#3 ) + (byte*) SCREEN#1 ← phi( nest2::@1/(byte*) SCREEN#2 nest2::@2/(byte*) SCREEN#1 ) + (byte) nest2::j#2 ← phi( nest2::@1/(byte) nest2::j#0 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + (boolean~) nest2::$0 ← (byte) nest2::j#1 > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte*) SCREEN#4 ← phi( nest2::@2/(byte*) SCREEN#1 ) + (byte) nest2::i#2 ← phi( nest2::@2/(byte) nest2::i#3 ) + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + (boolean~) nest2::$1 ← (byte) nest2::i#1 > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @4 + +CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN +@BEGIN: from + (byte*) SCREEN#0 ← (word) 1024 + call main param-assignment + to:@4 +@4: from @BEGIN + to:@END +main: from @BEGIN + (byte*) SCREEN#13 ← phi( @BEGIN/(byte*) SCREEN#0 ) + (byte) main::i#0 ← (byte) 100 + to:main::@1 +main::@1: from main main::@3 + (byte*) SCREEN#11 ← phi( main/(byte*) SCREEN#13 main::@3/(byte*) SCREEN#14 ) + (byte) main::i#5 ← phi( main/(byte) main::i#0 main::@3/(byte) main::i#1 ) + (byte) main::j#0 ← (byte) 100 + to:main::@2 +main::@2: from main::@1 main::@5 + (byte*) SCREEN#10 ← phi( main::@1/(byte*) SCREEN#11 main::@5/(byte*) SCREEN#12 ) + (byte) main::i#4 ← phi( main::@1/(byte) main::i#5 main::@5/(byte) main::i#3 ) + (byte) main::j#3 ← phi( main::@1/(byte) main::j#0 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte*) SCREEN#12 ← phi( main::@2/(byte*) SCREEN#10 ) + (byte) main::i#3 ← phi( main::@2/(byte) main::i#4 ) + (byte) main::j#2 ← phi( main::@2/(byte) main::j#3 ) + (byte) main::j#1 ← -- (byte) main::j#2 + (boolean~) main::$1 ← (byte) main::j#1 > (byte) 0 + if((boolean~) main::$1) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte*) SCREEN#14 ← phi( main::@5/(byte*) SCREEN#12 ) + (byte) main::i#2 ← phi( main::@5/(byte) main::i#3 ) + (byte) main::i#1 ← -- (byte) main::i#2 + (boolean~) main::$2 ← (byte) main::i#1 > (byte) 0 + if((boolean~) main::$2) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + (byte*) SCREEN#8 ← phi( main::@2/(byte*) SCREEN#10 ) + (byte) nest1::i#0 ← (byte) 100 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#6 ← phi( nest1/(byte*) SCREEN#8 nest1::@3/(byte*) SCREEN#9 ) + (byte) nest1::i#5 ← phi( nest1/(byte) nest1::i#0 nest1::@3/(byte) nest1::i#1 ) + (byte) nest1::j#0 ← (byte) 100 + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte*) SCREEN#5 ← phi( nest1::@1/(byte*) SCREEN#6 nest1::@5/(byte*) SCREEN#7 ) + (byte) nest1::i#4 ← phi( nest1::@1/(byte) nest1::i#5 nest1::@5/(byte) nest1::i#3 ) + (byte) nest1::j#3 ← phi( nest1::@1/(byte) nest1::j#0 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte*) SCREEN#7 ← phi( nest1::@2/(byte*) SCREEN#5 ) + (byte) nest1::i#3 ← phi( nest1::@2/(byte) nest1::i#4 ) + (byte) nest1::j#2 ← phi( nest1::@2/(byte) nest1::j#3 ) + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + (boolean~) nest1::$1 ← (byte) nest1::j#1 > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte*) SCREEN#9 ← phi( nest1::@5/(byte*) SCREEN#7 ) + (byte) nest1::i#2 ← phi( nest1::@5/(byte) nest1::i#3 ) + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + (boolean~) nest1::$2 ← (byte) nest1::i#1 > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + (byte*) SCREEN#3 ← phi( nest1::@2/(byte*) SCREEN#5 ) + (byte) nest2::i#0 ← (byte) 100 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#4 ← phi( nest2/(byte) nest2::i#0 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#2 ← phi( nest2/(byte*) SCREEN#3 nest2::@3/(byte*) SCREEN#4 ) + (byte) nest2::j#0 ← (byte) 100 + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::i#3 ← phi( nest2::@1/(byte) nest2::i#4 nest2::@2/(byte) nest2::i#3 ) + (byte*) SCREEN#1 ← phi( nest2::@1/(byte*) SCREEN#2 nest2::@2/(byte*) SCREEN#1 ) + (byte) nest2::j#2 ← phi( nest2::@1/(byte) nest2::j#0 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + (boolean~) nest2::$0 ← (byte) nest2::j#1 > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte*) SCREEN#4 ← phi( nest2::@2/(byte*) SCREEN#1 ) + (byte) nest2::i#2 ← phi( nest2::@2/(byte) nest2::i#3 ) + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + (boolean~) nest2::$1 ← (byte) nest2::i#1 > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @4 + +Culled Empty Block (label) @4 +Succesful SSA optimization Pass2CullEmptyBlocks +CONTROL FLOW GRAPH +@BEGIN: from + (byte*) SCREEN#0 ← (word) 1024 + call main param-assignment + to:@END +main: from @BEGIN + (byte*) SCREEN#13 ← phi( @BEGIN/(byte*) SCREEN#0 ) + (byte) main::i#0 ← (byte) 100 + to:main::@1 +main::@1: from main main::@3 + (byte*) SCREEN#11 ← phi( main/(byte*) SCREEN#13 main::@3/(byte*) SCREEN#14 ) + (byte) main::i#5 ← phi( main/(byte) main::i#0 main::@3/(byte) main::i#1 ) + (byte) main::j#0 ← (byte) 100 + to:main::@2 +main::@2: from main::@1 main::@5 + (byte*) SCREEN#10 ← phi( main::@1/(byte*) SCREEN#11 main::@5/(byte*) SCREEN#12 ) + (byte) main::i#4 ← phi( main::@1/(byte) main::i#5 main::@5/(byte) main::i#3 ) + (byte) main::j#3 ← phi( main::@1/(byte) main::j#0 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte*) SCREEN#12 ← phi( main::@2/(byte*) SCREEN#10 ) + (byte) main::i#3 ← phi( main::@2/(byte) main::i#4 ) + (byte) main::j#2 ← phi( main::@2/(byte) main::j#3 ) + (byte) main::j#1 ← -- (byte) main::j#2 + (boolean~) main::$1 ← (byte) main::j#1 > (byte) 0 + if((boolean~) main::$1) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte*) SCREEN#14 ← phi( main::@5/(byte*) SCREEN#12 ) + (byte) main::i#2 ← phi( main::@5/(byte) main::i#3 ) + (byte) main::i#1 ← -- (byte) main::i#2 + (boolean~) main::$2 ← (byte) main::i#1 > (byte) 0 + if((boolean~) main::$2) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + (byte*) SCREEN#8 ← phi( main::@2/(byte*) SCREEN#10 ) + (byte) nest1::i#0 ← (byte) 100 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#6 ← phi( nest1/(byte*) SCREEN#8 nest1::@3/(byte*) SCREEN#9 ) + (byte) nest1::i#5 ← phi( nest1/(byte) nest1::i#0 nest1::@3/(byte) nest1::i#1 ) + (byte) nest1::j#0 ← (byte) 100 + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte*) SCREEN#5 ← phi( nest1::@1/(byte*) SCREEN#6 nest1::@5/(byte*) SCREEN#7 ) + (byte) nest1::i#4 ← phi( nest1::@1/(byte) nest1::i#5 nest1::@5/(byte) nest1::i#3 ) + (byte) nest1::j#3 ← phi( nest1::@1/(byte) nest1::j#0 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte*) SCREEN#7 ← phi( nest1::@2/(byte*) SCREEN#5 ) + (byte) nest1::i#3 ← phi( nest1::@2/(byte) nest1::i#4 ) + (byte) nest1::j#2 ← phi( nest1::@2/(byte) nest1::j#3 ) + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + (boolean~) nest1::$1 ← (byte) nest1::j#1 > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte*) SCREEN#9 ← phi( nest1::@5/(byte*) SCREEN#7 ) + (byte) nest1::i#2 ← phi( nest1::@5/(byte) nest1::i#3 ) + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + (boolean~) nest1::$2 ← (byte) nest1::i#1 > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + (byte*) SCREEN#3 ← phi( nest1::@2/(byte*) SCREEN#5 ) + (byte) nest2::i#0 ← (byte) 100 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#4 ← phi( nest2/(byte) nest2::i#0 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#2 ← phi( nest2/(byte*) SCREEN#3 nest2::@3/(byte*) SCREEN#4 ) + (byte) nest2::j#0 ← (byte) 100 + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::i#3 ← phi( nest2::@1/(byte) nest2::i#4 nest2::@2/(byte) nest2::i#3 ) + (byte*) SCREEN#1 ← phi( nest2::@1/(byte*) SCREEN#2 nest2::@2/(byte*) SCREEN#1 ) + (byte) nest2::j#2 ← phi( nest2::@1/(byte) nest2::j#0 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + (boolean~) nest2::$0 ← (byte) nest2::j#1 > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte*) SCREEN#4 ← phi( nest2::@2/(byte*) SCREEN#1 ) + (byte) nest2::i#2 ← phi( nest2::@2/(byte) nest2::i#3 ) + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + (boolean~) nest2::$1 ← (byte) nest2::i#1 > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Constant (byte*) SCREEN#0 (word) 1024 +Constant (byte) main::i#0 (byte) 100 +Constant (byte) main::j#0 (byte) 100 +Constant (byte) nest1::i#0 (byte) 100 +Constant (byte) nest1::j#0 (byte) 100 +Constant (byte) nest2::i#0 (byte) 100 +Constant (byte) nest2::j#0 (byte) 100 +Succesful SSA optimization Pass2ConstantPropagation +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + (byte*) SCREEN#13 ← phi( @BEGIN/(word) 1024 ) + to:main::@1 +main::@1: from main main::@3 + (byte*) SCREEN#11 ← phi( main/(byte*) SCREEN#13 main::@3/(byte*) SCREEN#14 ) + (byte) main::i#5 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) + to:main::@2 +main::@2: from main::@1 main::@5 + (byte*) SCREEN#10 ← phi( main::@1/(byte*) SCREEN#11 main::@5/(byte*) SCREEN#12 ) + (byte) main::i#4 ← phi( main::@1/(byte) main::i#5 main::@5/(byte) main::i#3 ) + (byte) main::j#3 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte*) SCREEN#12 ← phi( main::@2/(byte*) SCREEN#10 ) + (byte) main::i#3 ← phi( main::@2/(byte) main::i#4 ) + (byte) main::j#2 ← phi( main::@2/(byte) main::j#3 ) + (byte) main::j#1 ← -- (byte) main::j#2 + (boolean~) main::$1 ← (byte) main::j#1 > (byte) 0 + if((boolean~) main::$1) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte*) SCREEN#14 ← phi( main::@5/(byte*) SCREEN#12 ) + (byte) main::i#2 ← phi( main::@5/(byte) main::i#3 ) + (byte) main::i#1 ← -- (byte) main::i#2 + (boolean~) main::$2 ← (byte) main::i#1 > (byte) 0 + if((boolean~) main::$2) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + (byte*) SCREEN#8 ← phi( main::@2/(byte*) SCREEN#10 ) + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#6 ← phi( nest1/(byte*) SCREEN#8 nest1::@3/(byte*) SCREEN#9 ) + (byte) nest1::i#5 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte*) SCREEN#5 ← phi( nest1::@1/(byte*) SCREEN#6 nest1::@5/(byte*) SCREEN#7 ) + (byte) nest1::i#4 ← phi( nest1::@1/(byte) nest1::i#5 nest1::@5/(byte) nest1::i#3 ) + (byte) nest1::j#3 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte*) SCREEN#7 ← phi( nest1::@2/(byte*) SCREEN#5 ) + (byte) nest1::i#3 ← phi( nest1::@2/(byte) nest1::i#4 ) + (byte) nest1::j#2 ← phi( nest1::@2/(byte) nest1::j#3 ) + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + (boolean~) nest1::$1 ← (byte) nest1::j#1 > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte*) SCREEN#9 ← phi( nest1::@5/(byte*) SCREEN#7 ) + (byte) nest1::i#2 ← phi( nest1::@5/(byte) nest1::i#3 ) + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + (boolean~) nest1::$2 ← (byte) nest1::i#1 > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + (byte*) SCREEN#3 ← phi( nest1::@2/(byte*) SCREEN#5 ) + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#4 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#2 ← phi( nest2/(byte*) SCREEN#3 nest2::@3/(byte*) SCREEN#4 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::i#3 ← phi( nest2::@1/(byte) nest2::i#4 nest2::@2/(byte) nest2::i#3 ) + (byte*) SCREEN#1 ← phi( nest2::@1/(byte*) SCREEN#2 nest2::@2/(byte*) SCREEN#1 ) + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + (boolean~) nest2::$0 ← (byte) nest2::j#1 > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte*) SCREEN#4 ← phi( nest2::@2/(byte*) SCREEN#1 ) + (byte) nest2::i#2 ← phi( nest2::@2/(byte) nest2::i#3 ) + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + (boolean~) nest2::$1 ← (byte) nest2::i#1 > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Alias (byte) main::j#2 = (byte) main::j#3 +Alias (byte) main::i#2 = (byte) main::i#3 (byte) main::i#4 +Alias (byte*) SCREEN#10 = (byte*) SCREEN#12 (byte*) SCREEN#14 (byte*) SCREEN#8 +Alias (byte) nest1::j#2 = (byte) nest1::j#3 +Alias (byte) nest1::i#2 = (byte) nest1::i#3 (byte) nest1::i#4 +Alias (byte*) SCREEN#3 = (byte*) SCREEN#7 (byte*) SCREEN#5 (byte*) SCREEN#9 +Alias (byte) nest2::i#2 = (byte) nest2::i#3 +Alias (byte*) SCREEN#1 = (byte*) SCREEN#4 +Succesful SSA optimization Pass2AliasElimination +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + (byte*) SCREEN#13 ← phi( @BEGIN/(word) 1024 ) + to:main::@1 +main::@1: from main main::@3 + (byte*) SCREEN#11 ← phi( main/(byte*) SCREEN#13 main::@3/(byte*) SCREEN#10 ) + (byte) main::i#5 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) + to:main::@2 +main::@2: from main::@1 main::@5 + (byte*) SCREEN#10 ← phi( main::@1/(byte*) SCREEN#11 main::@5/(byte*) SCREEN#10 ) + (byte) main::i#2 ← phi( main::@1/(byte) main::i#5 main::@5/(byte) main::i#2 ) + (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j#1 ← -- (byte) main::j#2 + (boolean~) main::$1 ← (byte) main::j#1 > (byte) 0 + if((boolean~) main::$1) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte) main::i#1 ← -- (byte) main::i#2 + (boolean~) main::$2 ← (byte) main::i#1 > (byte) 0 + if((boolean~) main::$2) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#6 ← phi( nest1/(byte*) SCREEN#10 nest1::@3/(byte*) SCREEN#3 ) + (byte) nest1::i#5 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte*) SCREEN#3 ← phi( nest1::@1/(byte*) SCREEN#6 nest1::@5/(byte*) SCREEN#3 ) + (byte) nest1::i#2 ← phi( nest1::@1/(byte) nest1::i#5 nest1::@5/(byte) nest1::i#2 ) + (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + (boolean~) nest1::$1 ← (byte) nest1::j#1 > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + (boolean~) nest1::$2 ← (byte) nest1::i#1 > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#4 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#2 ← phi( nest2/(byte*) SCREEN#3 nest2::@3/(byte*) SCREEN#1 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::i#2 ← phi( nest2::@1/(byte) nest2::i#4 nest2::@2/(byte) nest2::i#2 ) + (byte*) SCREEN#1 ← phi( nest2::@1/(byte*) SCREEN#2 nest2::@2/(byte*) SCREEN#1 ) + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + (boolean~) nest2::$0 ← (byte) nest2::j#1 > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + (boolean~) nest2::$1 ← (byte) nest2::i#1 > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Redundant Phi (byte*) SCREEN#13 (word) 1024 +Succesful SSA optimization Pass2RedundantPhiElimination +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + to:main::@1 +main::@1: from main main::@3 + (byte*) SCREEN#11 ← phi( main/(word) 1024 main::@3/(byte*) SCREEN#10 ) + (byte) main::i#5 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) + to:main::@2 +main::@2: from main::@1 main::@5 + (byte*) SCREEN#10 ← phi( main::@1/(byte*) SCREEN#11 main::@5/(byte*) SCREEN#10 ) + (byte) main::i#2 ← phi( main::@1/(byte) main::i#5 main::@5/(byte) main::i#2 ) + (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j#1 ← -- (byte) main::j#2 + (boolean~) main::$1 ← (byte) main::j#1 > (byte) 0 + if((boolean~) main::$1) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte) main::i#1 ← -- (byte) main::i#2 + (boolean~) main::$2 ← (byte) main::i#1 > (byte) 0 + if((boolean~) main::$2) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#6 ← phi( nest1/(byte*) SCREEN#10 nest1::@3/(byte*) SCREEN#3 ) + (byte) nest1::i#5 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte*) SCREEN#3 ← phi( nest1::@1/(byte*) SCREEN#6 nest1::@5/(byte*) SCREEN#3 ) + (byte) nest1::i#2 ← phi( nest1::@1/(byte) nest1::i#5 nest1::@5/(byte) nest1::i#2 ) + (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + (boolean~) nest1::$1 ← (byte) nest1::j#1 > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + (boolean~) nest1::$2 ← (byte) nest1::i#1 > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#4 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#2 ← phi( nest2/(byte*) SCREEN#3 nest2::@3/(byte*) SCREEN#1 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::i#2 ← phi( nest2::@1/(byte) nest2::i#4 nest2::@2/(byte) nest2::i#2 ) + (byte*) SCREEN#1 ← phi( nest2::@1/(byte*) SCREEN#2 nest2::@2/(byte*) SCREEN#1 ) + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + (boolean~) nest2::$0 ← (byte) nest2::j#1 > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + (boolean~) nest2::$1 ← (byte) nest2::i#1 > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Self Phi Eliminated (byte) main::i#2 +Self Phi Eliminated (byte*) SCREEN#10 +Self Phi Eliminated (byte) nest1::i#2 +Self Phi Eliminated (byte*) SCREEN#3 +Self Phi Eliminated (byte*) SCREEN#1 +Self Phi Eliminated (byte) nest2::i#2 +Succesful SSA optimization Pass2SelfPhiElimination +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + to:main::@1 +main::@1: from main main::@3 + (byte*) SCREEN#11 ← phi( main/(word) 1024 main::@3/(byte*) SCREEN#10 ) + (byte) main::i#5 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) + to:main::@2 +main::@2: from main::@1 main::@5 + (byte*) SCREEN#10 ← phi( main::@1/(byte*) SCREEN#11 ) + (byte) main::i#2 ← phi( main::@1/(byte) main::i#5 ) + (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j#1 ← -- (byte) main::j#2 + (boolean~) main::$1 ← (byte) main::j#1 > (byte) 0 + if((boolean~) main::$1) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte) main::i#1 ← -- (byte) main::i#2 + (boolean~) main::$2 ← (byte) main::i#1 > (byte) 0 + if((boolean~) main::$2) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#6 ← phi( nest1/(byte*) SCREEN#10 nest1::@3/(byte*) SCREEN#3 ) + (byte) nest1::i#5 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte*) SCREEN#3 ← phi( nest1::@1/(byte*) SCREEN#6 ) + (byte) nest1::i#2 ← phi( nest1::@1/(byte) nest1::i#5 ) + (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + (boolean~) nest1::$1 ← (byte) nest1::j#1 > (byte) 0 + if((boolean~) nest1::$1) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + (boolean~) nest1::$2 ← (byte) nest1::i#1 > (byte) 0 + if((boolean~) nest1::$2) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#4 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#2 ← phi( nest2/(byte*) SCREEN#3 nest2::@3/(byte*) SCREEN#1 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::i#2 ← phi( nest2::@1/(byte) nest2::i#4 ) + (byte*) SCREEN#1 ← phi( nest2::@1/(byte*) SCREEN#2 ) + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + (boolean~) nest2::$0 ← (byte) nest2::j#1 > (byte) 0 + if((boolean~) nest2::$0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + (boolean~) nest2::$1 ← (byte) nest2::i#1 > (byte) 0 + if((boolean~) nest2::$1) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Simple Condition (boolean~) main::$1 if((byte) main::j#1>(byte) 0) goto main::@2 +Simple Condition (boolean~) main::$2 if((byte) main::i#1>(byte) 0) goto main::@1 +Simple Condition (boolean~) nest1::$1 if((byte) nest1::j#1>(byte) 0) goto nest1::@2 +Simple Condition (boolean~) nest1::$2 if((byte) nest1::i#1>(byte) 0) goto nest1::@1 +Simple Condition (boolean~) nest2::$0 if((byte) nest2::j#1>(byte) 0) goto nest2::@2 +Simple Condition (boolean~) nest2::$1 if((byte) nest2::i#1>(byte) 0) goto nest2::@1 +Succesful SSA optimization Pass2ConditionalJumpSimplification +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + to:main::@1 +main::@1: from main main::@3 + (byte*) SCREEN#11 ← phi( main/(word) 1024 main::@3/(byte*) SCREEN#10 ) + (byte) main::i#5 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) + to:main::@2 +main::@2: from main::@1 main::@5 + (byte*) SCREEN#10 ← phi( main::@1/(byte*) SCREEN#11 ) + (byte) main::i#2 ← phi( main::@1/(byte) main::i#5 ) + (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j#1 ← -- (byte) main::j#2 + if((byte) main::j#1>(byte) 0) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte) main::i#1 ← -- (byte) main::i#2 + if((byte) main::i#1>(byte) 0) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#6 ← phi( nest1/(byte*) SCREEN#10 nest1::@3/(byte*) SCREEN#3 ) + (byte) nest1::i#5 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte*) SCREEN#3 ← phi( nest1::@1/(byte*) SCREEN#6 ) + (byte) nest1::i#2 ← phi( nest1::@1/(byte) nest1::i#5 ) + (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + if((byte) nest1::j#1>(byte) 0) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + if((byte) nest1::i#1>(byte) 0) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#4 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#2 ← phi( nest2/(byte*) SCREEN#3 nest2::@3/(byte*) SCREEN#1 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::i#2 ← phi( nest2::@1/(byte) nest2::i#4 ) + (byte*) SCREEN#1 ← phi( nest2::@1/(byte*) SCREEN#2 ) + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + if((byte) nest2::j#1>(byte) 0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + if((byte) nest2::i#1>(byte) 0) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Alias (byte) main::i#2 = (byte) main::i#5 +Alias (byte*) SCREEN#10 = (byte*) SCREEN#11 +Alias (byte) nest1::i#2 = (byte) nest1::i#5 +Alias (byte*) SCREEN#3 = (byte*) SCREEN#6 +Alias (byte*) SCREEN#1 = (byte*) SCREEN#2 +Alias (byte) nest2::i#2 = (byte) nest2::i#4 +Succesful SSA optimization Pass2AliasElimination +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + to:main::@1 +main::@1: from main main::@3 + (byte*) SCREEN#10 ← phi( main/(word) 1024 main::@3/(byte*) SCREEN#10 ) + (byte) main::i#2 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) + to:main::@2 +main::@2: from main::@1 main::@5 + (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j#1 ← -- (byte) main::j#2 + if((byte) main::j#1>(byte) 0) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte) main::i#1 ← -- (byte) main::i#2 + if((byte) main::i#1>(byte) 0) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#3 ← phi( nest1/(byte*) SCREEN#10 nest1::@3/(byte*) SCREEN#3 ) + (byte) nest1::i#2 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + if((byte) nest1::j#1>(byte) 0) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + if((byte) nest1::i#1>(byte) 0) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#2 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#1 ← phi( nest2/(byte*) SCREEN#3 nest2::@3/(byte*) SCREEN#1 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + if((byte) nest2::j#1>(byte) 0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + if((byte) nest2::i#1>(byte) 0) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Self Phi Eliminated (byte*) SCREEN#10 +Self Phi Eliminated (byte*) SCREEN#3 +Self Phi Eliminated (byte*) SCREEN#1 +Succesful SSA optimization Pass2SelfPhiElimination +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + to:main::@1 +main::@1: from main main::@3 + (byte*) SCREEN#10 ← phi( main/(word) 1024 ) + (byte) main::i#2 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) + to:main::@2 +main::@2: from main::@1 main::@5 + (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j#1 ← -- (byte) main::j#2 + if((byte) main::j#1>(byte) 0) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte) main::i#1 ← -- (byte) main::i#2 + if((byte) main::i#1>(byte) 0) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#3 ← phi( nest1/(byte*) SCREEN#10 ) + (byte) nest1::i#2 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + if((byte) nest1::j#1>(byte) 0) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + if((byte) nest1::i#1>(byte) 0) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#2 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#1 ← phi( nest2/(byte*) SCREEN#3 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + if((byte) nest2::j#1>(byte) 0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + if((byte) nest2::i#1>(byte) 0) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Constant (byte*) SCREEN#10 (word) 1024 +Succesful SSA optimization Pass2ConstantPropagation +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + to:main::@1 +main::@1: from main main::@3 + (byte) main::i#2 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) + to:main::@2 +main::@2: from main::@1 main::@5 + (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j#1 ← -- (byte) main::j#2 + if((byte) main::j#1>(byte) 0) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte) main::i#1 ← -- (byte) main::i#2 + if((byte) main::i#1>(byte) 0) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#3 ← phi( nest1/(word) 1024 ) + (byte) nest1::i#2 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + if((byte) nest1::j#1>(byte) 0) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + if((byte) nest1::i#1>(byte) 0) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#2 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) + (byte*) SCREEN#1 ← phi( nest2/(byte*) SCREEN#3 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + if((byte) nest2::j#1>(byte) 0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + if((byte) nest2::i#1>(byte) 0) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Alias (byte*) SCREEN#1 = (byte*) SCREEN#3 +Succesful SSA optimization Pass2AliasElimination +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + to:main::@1 +main::@1: from main main::@3 + (byte) main::i#2 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) + to:main::@2 +main::@2: from main::@1 main::@5 + (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j#1 ← -- (byte) main::j#2 + if((byte) main::j#1>(byte) 0) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte) main::i#1 ← -- (byte) main::i#2 + if((byte) main::i#1>(byte) 0) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte*) SCREEN#1 ← phi( nest1/(word) 1024 ) + (byte) nest1::i#2 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + if((byte) nest1::j#1>(byte) 0) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + if((byte) nest1::i#1>(byte) 0) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#2 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) + *((byte*) SCREEN#1) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + if((byte) nest2::j#1>(byte) 0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + if((byte) nest2::i#1>(byte) 0) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Redundant Phi (byte*) SCREEN#1 (word) 1024 +Succesful SSA optimization Pass2RedundantPhiElimination +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + to:main::@1 +main::@1: from main main::@3 + (byte) main::i#2 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) + to:main::@2 +main::@2: from main::@1 main::@5 + (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j#1 ← -- (byte) main::j#2 + if((byte) main::j#1>(byte) 0) goto main::@2 + to:main::@3 +main::@3: from main::@5 + (byte) main::i#1 ← -- (byte) main::i#2 + if((byte) main::i#1>(byte) 0) goto main::@1 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + (byte) nest1::i#2 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + if((byte) nest1::j#1>(byte) 0) goto nest1::@2 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + if((byte) nest1::i#1>(byte) 0) goto nest1::@1 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + (byte) nest2::i#2 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) + *((word) 1024) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + if((byte) nest2::j#1>(byte) 0) goto nest2::@2 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + if((byte) nest2::i#1>(byte) 0) goto nest2::@1 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +@END: from @BEGIN + +Block Sequence Planned @BEGIN @END main main::@1 main::@2 main::@5 main::@3 main::@return nest1 nest1::@1 nest1::@2 nest1::@5 nest1::@3 nest1::@return nest2 nest2::@1 nest2::@2 nest2::@3 nest2::@return +Added new block during phi lifting main::@6(between main::@3 and main::@1) +Added new block during phi lifting main::@7(between main::@5 and main::@2) +Added new block during phi lifting nest1::@6(between nest1::@3 and nest1::@1) +Added new block during phi lifting nest1::@7(between nest1::@5 and nest1::@2) +Added new block during phi lifting nest2::@5(between nest2::@3 and nest2::@1) +Added new block during phi lifting nest2::@6(between nest2::@2 and nest2::@2) +Block Sequence Planned @BEGIN @END main main::@1 main::@2 main::@5 main::@3 main::@return main::@6 main::@7 nest1 nest1::@1 nest1::@2 nest1::@5 nest1::@3 nest1::@return nest1::@6 nest1::@7 nest2 nest2::@1 nest2::@2 nest2::@3 nest2::@return nest2::@5 nest2::@6 +CONTROL FLOW GRAPH - PHI LIFTED +@BEGIN: from + call main param-assignment + to:@END +@END: from @BEGIN +main: from @BEGIN + to:main::@1 +main::@1: from main main::@6 + (byte) main::i#2 ← phi( main/(byte) 100 main::@6/(byte~) main::i#6 ) + to:main::@2 +main::@2: from main::@1 main::@7 + (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@7/(byte~) main::j#4 ) + call nest1 param-assignment + to:main::@5 +main::@5: from main::@2 + (byte) main::j#1 ← -- (byte) main::j#2 + if((byte) main::j#1>(byte) 0) goto main::@7 + to:main::@3 +main::@3: from main::@5 + (byte) main::i#1 ← -- (byte) main::i#2 + if((byte) main::i#1>(byte) 0) goto main::@6 + to:main::@return +main::@return: from main::@3 + return + to:@RETURN +main::@6: from main::@3 + (byte~) main::i#6 ← (byte) main::i#1 + to:main::@1 +main::@7: from main::@5 + (byte~) main::j#4 ← (byte) main::j#1 + to:main::@2 +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@6 + (byte) nest1::i#2 ← phi( nest1/(byte) 100 nest1::@6/(byte~) nest1::i#6 ) + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@7 + (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@7/(byte~) nest1::j#4 ) + call nest2 param-assignment + to:nest1::@5 +nest1::@5: from nest1::@2 + (byte) nest1::j#1 ← -- (byte) nest1::j#2 + if((byte) nest1::j#1>(byte) 0) goto nest1::@7 + to:nest1::@3 +nest1::@3: from nest1::@5 + (byte) nest1::i#1 ← -- (byte) nest1::i#2 + if((byte) nest1::i#1>(byte) 0) goto nest1::@6 + to:nest1::@return +nest1::@return: from nest1::@3 + return + to:@RETURN +nest1::@6: from nest1::@3 + (byte~) nest1::i#6 ← (byte) nest1::i#1 + to:nest1::@1 +nest1::@7: from nest1::@5 + (byte~) nest1::j#4 ← (byte) nest1::j#1 + to:nest1::@2 +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@5 + (byte) nest2::i#2 ← phi( nest2/(byte) 100 nest2::@5/(byte~) nest2::i#5 ) + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@6 + (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@6/(byte~) nest2::j#3 ) + *((word) 1024) ← (byte) nest2::j#2 + (byte) nest2::j#1 ← -- (byte) nest2::j#2 + if((byte) nest2::j#1>(byte) 0) goto nest2::@6 + to:nest2::@3 +nest2::@3: from nest2::@2 + (byte) nest2::i#1 ← -- (byte) nest2::i#2 + if((byte) nest2::i#1>(byte) 0) goto nest2::@5 + to:nest2::@return +nest2::@return: from nest2::@3 + return + to:@RETURN +nest2::@5: from nest2::@3 + (byte~) nest2::i#5 ← (byte) nest2::i#1 + to:nest2::@1 +nest2::@6: from nest2::@2 + (byte~) nest2::j#3 ← (byte) nest2::j#1 + to:nest2::@2 + +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +CONTROL FLOW GRAPH - LIVE RANGES +@BEGIN: from + [0] call main param-assignment [ ] + to:@END +@END: from @BEGIN +main: from @BEGIN + to:main::@1 +main::@1: from main main::@6 + [1] (byte) main::i#2 ← phi( main/(byte) 100 main::@6/(byte~) main::i#6 ) [ ] + to:main::@2 +main::@2: from main::@1 main::@7 + [2] (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@7/(byte~) main::j#4 ) [ ] + [3] call nest1 param-assignment [ main::j#2 main::i#2 ] + to:main::@5 +main::@5: from main::@2 + [4] (byte) main::j#1 ← -- (byte) main::j#2 [ main::j#1 main::i#2 ] + [5] if((byte) main::j#1>(byte) 0) goto main::@7 [ main::j#1 main::i#2 ] + to:main::@3 +main::@3: from main::@5 + [6] (byte) main::i#1 ← -- (byte) main::i#2 [ main::i#1 ] + [7] if((byte) main::i#1>(byte) 0) goto main::@6 [ main::i#1 ] + to:main::@return +main::@return: from main::@3 + [8] return [ ] + to:@RETURN +main::@6: from main::@3 + [9] (byte~) main::i#6 ← (byte) main::i#1 [ main::i#6 ] + to:main::@1 +main::@7: from main::@5 + [10] (byte~) main::j#4 ← (byte) main::j#1 [ main::j#4 ] + to:main::@2 +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@6 + [11] (byte) nest1::i#2 ← phi( nest1/(byte) 100 nest1::@6/(byte~) nest1::i#6 ) [ ] + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@7 + [12] (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@7/(byte~) nest1::j#4 ) [ ] + [13] call nest2 param-assignment [ nest1::j#2 nest1::i#2 ] + to:nest1::@5 +nest1::@5: from nest1::@2 + [14] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] + [15] if((byte) nest1::j#1>(byte) 0) goto nest1::@7 [ nest1::j#1 nest1::i#2 ] + to:nest1::@3 +nest1::@3: from nest1::@5 + [16] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] + [17] if((byte) nest1::i#1>(byte) 0) goto nest1::@6 [ nest1::i#1 ] + to:nest1::@return +nest1::@return: from nest1::@3 + [18] return [ ] + to:@RETURN +nest1::@6: from nest1::@3 + [19] (byte~) nest1::i#6 ← (byte) nest1::i#1 [ nest1::i#6 ] + to:nest1::@1 +nest1::@7: from nest1::@5 + [20] (byte~) nest1::j#4 ← (byte) nest1::j#1 [ nest1::j#4 ] + to:nest1::@2 +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@5 + [21] (byte) nest2::i#2 ← phi( nest2/(byte) 100 nest2::@5/(byte~) nest2::i#5 ) [ nest2::i#2 ] + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@6 + [22] (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@6/(byte~) nest2::j#3 ) [ nest2::j#2 nest2::i#2 ] + [23] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] + [24] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] + [25] if((byte) nest2::j#1>(byte) 0) goto nest2::@6 [ nest2::j#1 nest2::i#2 ] + to:nest2::@3 +nest2::@3: from nest2::@2 + [26] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] + [27] if((byte) nest2::i#1>(byte) 0) goto nest2::@5 [ nest2::i#1 ] + to:nest2::@return +nest2::@return: from nest2::@3 + [28] return [ ] + to:@RETURN +nest2::@5: from nest2::@3 + [29] (byte~) nest2::i#5 ← (byte) nest2::i#1 [ nest2::i#5 ] + to:nest2::@1 +nest2::@6: from nest2::@2 + [30] (byte~) nest2::j#3 ← (byte) nest2::j#1 [ nest2::j#3 nest2::i#2 ] + to:nest2::@2 + +Created 6 initial phi equivalence classes +Coalesced [9] main::i#6 ← main::i#1 +Coalesced [10] main::j#4 ← main::j#1 +Coalesced [19] nest1::i#6 ← nest1::i#1 +Coalesced [20] nest1::j#4 ← nest1::j#1 +Coalesced [29] nest2::i#5 ← nest2::i#1 +Coalesced [30] nest2::j#3 ← nest2::j#1 +Coalesced down to 6 phi equivalence classes +Culled Empty Block (label) main::@6 +Culled Empty Block (label) main::@7 +Culled Empty Block (label) nest1::@6 +Culled Empty Block (label) nest1::@7 +Culled Empty Block (label) nest2::@5 +Culled Empty Block (label) nest2::@6 +Block Sequence Planned @BEGIN @END main main::@1 main::@2 main::@5 main::@3 main::@return nest1 nest1::@1 nest1::@2 nest1::@5 nest1::@3 nest1::@return nest2 nest2::@1 nest2::@2 nest2::@3 nest2::@return +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +Propagating live ranges... +CONTROL FLOW GRAPH - PHI MEM COALESCED +@BEGIN: from + [0] call main param-assignment [ ] + to:@END +@END: from @BEGIN +main: from @BEGIN + to:main::@1 +main::@1: from main main::@3 + [1] (byte) main::i#2 ← phi( main/(byte) 100 main::@3/(byte) main::i#1 ) [ ] + to:main::@2 +main::@2: from main::@1 main::@5 + [2] (byte) main::j#2 ← phi( main::@1/(byte) 100 main::@5/(byte) main::j#1 ) [ ] + [3] call nest1 param-assignment [ main::j#2 main::i#2 ] + to:main::@5 +main::@5: from main::@2 + [4] (byte) main::j#1 ← -- (byte) main::j#2 [ main::j#1 main::i#2 ] + [5] if((byte) main::j#1>(byte) 0) goto main::@2 [ main::j#1 main::i#2 ] + to:main::@3 +main::@3: from main::@5 + [6] (byte) main::i#1 ← -- (byte) main::i#2 [ main::i#1 ] + [7] if((byte) main::i#1>(byte) 0) goto main::@1 [ main::i#1 ] + to:main::@return +main::@return: from main::@3 + [8] return [ ] + to:@RETURN +nest1: from main::@2 + to:nest1::@1 +nest1::@1: from nest1 nest1::@3 + [9] (byte) nest1::i#2 ← phi( nest1/(byte) 100 nest1::@3/(byte) nest1::i#1 ) [ ] + to:nest1::@2 +nest1::@2: from nest1::@1 nest1::@5 + [10] (byte) nest1::j#2 ← phi( nest1::@1/(byte) 100 nest1::@5/(byte) nest1::j#1 ) [ ] + [11] call nest2 param-assignment [ nest1::j#2 nest1::i#2 ] + to:nest1::@5 +nest1::@5: from nest1::@2 + [12] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] + [13] if((byte) nest1::j#1>(byte) 0) goto nest1::@2 [ nest1::j#1 nest1::i#2 ] + to:nest1::@3 +nest1::@3: from nest1::@5 + [14] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] + [15] if((byte) nest1::i#1>(byte) 0) goto nest1::@1 [ nest1::i#1 ] + to:nest1::@return +nest1::@return: from nest1::@3 + [16] return [ ] + to:@RETURN +nest2: from nest1::@2 + to:nest2::@1 +nest2::@1: from nest2 nest2::@3 + [17] (byte) nest2::i#2 ← phi( nest2/(byte) 100 nest2::@3/(byte) nest2::i#1 ) [ nest2::i#2 ] + to:nest2::@2 +nest2::@2: from nest2::@1 nest2::@2 + [18] (byte) nest2::j#2 ← phi( nest2::@1/(byte) 100 nest2::@2/(byte) nest2::j#1 ) [ nest2::j#2 nest2::i#2 ] + [19] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] + [20] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] + [21] if((byte) nest2::j#1>(byte) 0) goto nest2::@2 [ nest2::j#1 nest2::i#2 ] + to:nest2::@3 +nest2::@3: from nest2::@2 + [22] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] + [23] if((byte) nest2::i#1>(byte) 0) goto nest2::@1 [ nest2::i#1 ] + to:nest2::@return +nest2::@return: from nest2::@3 + [24] return [ ] + to:@RETURN + +CALL GRAPH +Calls in [] to 0:main +Calls in [main] to 3:nest1 +Calls in [nest1] to 11:nest2 + +DOMINATORS +@BEGIN dominated by @BEGIN +@END dominated by @BEGIN @END +main dominated by @BEGIN main +main::@1 dominated by @BEGIN main::@1 main +main::@2 dominated by @BEGIN main::@2 main::@1 main +main::@5 dominated by @BEGIN main::@2 main::@1 main::@5 main +main::@3 dominated by @BEGIN main::@2 main::@1 main::@3 main main::@5 +main::@return dominated by @BEGIN main::@2 main::@1 main::@3 main main::@5 main::@return +nest1 dominated by @BEGIN main::@2 main::@1 main nest1 +nest1::@1 dominated by nest1::@1 @BEGIN main::@2 main::@1 main nest1 +nest1::@2 dominated by nest1::@1 nest1::@2 @BEGIN main::@2 main::@1 main nest1 +nest1::@5 dominated by nest1::@1 @BEGIN nest1::@2 nest1::@5 main::@2 main::@1 main nest1 +nest1::@3 dominated by nest1::@1 @BEGIN nest1::@2 nest1::@5 nest1::@3 main::@2 main::@1 main nest1 +nest1::@return dominated by nest1::@1 @BEGIN nest1::@2 nest1::@5 nest1::@3 nest1::@return main::@2 main::@1 main nest1 +nest2 dominated by nest1::@1 @BEGIN nest1::@2 main::@2 main::@1 main nest2 nest1 +nest2::@1 dominated by nest1::@1 @BEGIN nest1::@2 main::@2 main::@1 main nest2 nest2::@1 nest1 +nest2::@2 dominated by nest1::@1 @BEGIN nest1::@2 main::@2 main::@1 main nest2::@2 nest2 nest2::@1 nest1 +nest2::@3 dominated by nest1::@1 @BEGIN nest1::@2 main::@2 main::@1 main nest2::@3 nest2::@2 nest2 nest2::@1 nest1 +nest2::@return dominated by nest1::@1 @BEGIN nest1::@2 nest2::@return main::@2 main::@1 main nest2::@3 nest2::@2 nest2 nest2::@1 nest1 + +Found back edge: Loop head: main::@2 tails: main::@5 blocks: null +Found back edge: Loop head: main::@1 tails: main::@3 blocks: null +Found back edge: Loop head: nest1::@2 tails: nest1::@5 blocks: null +Found back edge: Loop head: nest1::@1 tails: nest1::@3 blocks: null +Found back edge: Loop head: nest2::@2 tails: nest2::@2 blocks: null +Found back edge: Loop head: nest2::@1 tails: nest2::@3 blocks: null +Populated: Loop head: main::@2 tails: main::@5 blocks: main::@5 main::@2 +Populated: Loop head: main::@1 tails: main::@3 blocks: main::@3 main::@5 main::@2 main::@1 +Populated: Loop head: nest1::@2 tails: nest1::@5 blocks: nest1::@5 nest1::@2 +Populated: Loop head: nest1::@1 tails: nest1::@3 blocks: nest1::@3 nest1::@5 nest1::@2 nest1::@1 +Populated: Loop head: nest2::@2 tails: nest2::@2 blocks: nest2::@2 +Populated: Loop head: nest2::@1 tails: nest2::@3 blocks: nest2::@3 nest2::@2 nest2::@1 +NATURAL LOOPS +Loop head: main::@2 tails: main::@5 blocks: main::@5 main::@2 +Loop head: main::@1 tails: main::@3 blocks: main::@3 main::@5 main::@2 main::@1 +Loop head: nest1::@2 tails: nest1::@5 blocks: nest1::@5 nest1::@2 +Loop head: nest1::@1 tails: nest1::@3 blocks: nest1::@3 nest1::@5 nest1::@2 nest1::@1 +Loop head: nest2::@2 tails: nest2::@2 blocks: nest2::@2 +Loop head: nest2::@1 tails: nest2::@3 blocks: nest2::@3 nest2::@2 nest2::@1 + +Found 0 loops in scope [] +Found 2 loops in scope [main] + Loop head: main::@2 tails: main::@5 blocks: main::@5 main::@2 + Loop head: main::@1 tails: main::@3 blocks: main::@3 main::@5 main::@2 main::@1 +Found 2 loops in scope [nest1] + Loop head: nest1::@2 tails: nest1::@5 blocks: nest1::@5 nest1::@2 + Loop head: nest1::@1 tails: nest1::@3 blocks: nest1::@3 nest1::@5 nest1::@2 nest1::@1 +Found 2 loops in scope [nest2] + Loop head: nest2::@2 tails: nest2::@2 blocks: nest2::@2 + Loop head: nest2::@1 tails: nest2::@3 blocks: nest2::@3 nest2::@2 nest2::@1 +NATURAL LOOPS WITH DEPTH +Loop head: main::@2 tails: main::@5 blocks: main::@5 main::@2 depth: 2 +Loop head: main::@1 tails: main::@3 blocks: main::@3 main::@5 main::@2 main::@1 depth: 1 +Loop head: nest1::@2 tails: nest1::@5 blocks: nest1::@5 nest1::@2 depth: 4 +Loop head: nest1::@1 tails: nest1::@3 blocks: nest1::@3 nest1::@5 nest1::@2 nest1::@1 depth: 3 +Loop head: nest2::@2 tails: nest2::@2 blocks: nest2::@2 depth: 6 +Loop head: nest2::@1 tails: nest2::@3 blocks: nest2::@3 nest2::@2 nest2::@1 depth: 5 + +Initial phi equivalence classes +[ main::i#2 main::i#1 ] +[ main::j#2 main::j#1 ] +[ nest1::i#2 nest1::i#1 ] +[ nest1::j#2 nest1::j#1 ] +[ nest2::i#2 nest2::i#1 ] +[ nest2::j#2 nest2::j#1 ] +Copy Coalesced equivalence classes +[ main::i#2 main::i#1 ] +[ main::j#2 main::j#1 ] +[ nest1::i#2 nest1::i#1 ] +[ nest1::j#2 nest1::j#1 ] +[ nest2::i#2 nest2::i#1 ] +[ nest2::j#2 nest2::j#1 ] +Complete equivalence classes +[ main::i#2 main::i#1 ] +[ main::j#2 main::j#1 ] +[ nest1::i#2 nest1::i#1 ] +[ nest1::j#2 nest1::j#1 ] +[ nest2::i#2 nest2::i#1 ] +[ nest2::j#2 nest2::j#1 ] +Allocated zp byte:2 to [ main::i#2 main::i#1 ] +Allocated zp byte:3 to [ main::j#2 main::j#1 ] +Allocated zp byte:4 to [ nest1::i#2 nest1::i#1 ] +Allocated zp byte:5 to [ nest1::j#2 nest1::j#1 ] +Allocated zp byte:6 to [ nest2::i#2 nest2::i#1 ] +Allocated zp byte:7 to [ nest2::j#2 nest2::j#1 ] +INITIAL ASM +BBEGIN: + jsr main + jmp BEND +BEND: +main: +main__B1_from_main: + // (byte) main::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 2 + jmp main__B1 +main__B1_from_B3: + // (byte) main::i#2 = (byte) main::i#1 // register copy + jmp main__B1 +main__B1: +main__B2_from_B1: + // (byte) main::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 3 + jmp main__B2 +main__B2_from_B5: + // (byte) main::j#2 = (byte) main::j#1 // register copy + jmp main__B2 +main__B2: + jsr nest1 + jmp main__B5 +main__B5: + // [4] (byte) main::j#1 ← -- (byte) main::j#2 [ main::j#1 main::i#2 ] // zpby1=_dec_zpby1 + dec 3 + // [5] if((byte) main::j#1>(byte) 0) goto main::@2 [ main::j#1 main::i#2 ] // zpby1_gt_0_then_la1 + lda 3 + bne main__B2_from_B5 + jmp main__B3 +main__B3: + // [6] (byte) main::i#1 ← -- (byte) main::i#2 [ main::i#1 ] // zpby1=_dec_zpby1 + dec 2 + // [7] if((byte) main::i#1>(byte) 0) goto main::@1 [ main::i#1 ] // zpby1_gt_0_then_la1 + lda 2 + bne main__B1_from_B3 + jmp main__Breturn +main__Breturn: + rts +nest1: +nest1__B1_from_nest1: + // (byte) nest1::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 4 + jmp nest1__B1 +nest1__B1_from_B3: + // (byte) nest1::i#2 = (byte) nest1::i#1 // register copy + jmp nest1__B1 +nest1__B1: +nest1__B2_from_B1: + // (byte) nest1::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 5 + jmp nest1__B2 +nest1__B2_from_B5: + // (byte) nest1::j#2 = (byte) nest1::j#1 // register copy + jmp nest1__B2 +nest1__B2: + jsr nest2 + jmp nest1__B5 +nest1__B5: + // [12] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] // zpby1=_dec_zpby1 + dec 5 + // [13] if((byte) nest1::j#1>(byte) 0) goto nest1::@2 [ nest1::j#1 nest1::i#2 ] // zpby1_gt_0_then_la1 + lda 5 + bne nest1__B2_from_B5 + jmp nest1__B3 +nest1__B3: + // [14] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] // zpby1=_dec_zpby1 + dec 4 + // [15] if((byte) nest1::i#1>(byte) 0) goto nest1::@1 [ nest1::i#1 ] // zpby1_gt_0_then_la1 + lda 4 + bne nest1__B1_from_B3 + jmp nest1__Breturn +nest1__Breturn: + rts +nest2: +nest2__B1_from_nest2: + // (byte) nest2::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 6 + jmp nest2__B1 +nest2__B1_from_B3: + // (byte) nest2::i#2 = (byte) nest2::i#1 // register copy + jmp nest2__B1 +nest2__B1: +nest2__B2_from_B1: + // (byte) nest2::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 7 + jmp nest2__B2 +nest2__B2_from_B2: + // (byte) nest2::j#2 = (byte) nest2::j#1 // register copy + jmp nest2__B2 +nest2__B2: + // [19] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] // coptr1=zpby1 + lda 7 + sta 1024 + // [20] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] // zpby1=_dec_zpby1 + dec 7 + // [21] if((byte) nest2::j#1>(byte) 0) goto nest2::@2 [ nest2::j#1 nest2::i#2 ] // zpby1_gt_0_then_la1 + lda 7 + bne nest2__B2_from_B2 + jmp nest2__B3 +nest2__B3: + // [22] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] // zpby1=_dec_zpby1 + dec 6 + // [23] if((byte) nest2::i#1>(byte) 0) goto nest2::@1 [ nest2::i#1 ] // zpby1_gt_0_then_la1 + lda 6 + bne nest2__B1_from_B3 + jmp nest2__Breturn +nest2__Breturn: + rts + +Removing instruction jmp BEND +Removing instruction jmp main__B1 +Removing instruction jmp main__B2 +Removing instruction jmp main__B5 +Removing instruction jmp main__B3 +Removing instruction jmp main__Breturn +Removing instruction jmp nest1__B1 +Removing instruction jmp nest1__B2 +Removing instruction jmp nest1__B5 +Removing instruction jmp nest1__B3 +Removing instruction jmp nest1__Breturn +Removing instruction jmp nest2__B1 +Removing instruction jmp nest2__B2 +Removing instruction jmp nest2__B3 +Removing instruction jmp nest2__Breturn +Succesful ASM optimization Pass5NextJumpElimination +ASSEMBLER +BBEGIN: + jsr main +BEND: +main: +main__B1_from_main: + // (byte) main::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 2 + jmp main__B1 +main__B1_from_B3: + // (byte) main::i#2 = (byte) main::i#1 // register copy +main__B1: +main__B2_from_B1: + // (byte) main::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 3 + jmp main__B2 +main__B2_from_B5: + // (byte) main::j#2 = (byte) main::j#1 // register copy +main__B2: + jsr nest1 +main__B5: + // [4] (byte) main::j#1 ← -- (byte) main::j#2 [ main::j#1 main::i#2 ] // zpby1=_dec_zpby1 + dec 3 + // [5] if((byte) main::j#1>(byte) 0) goto main::@2 [ main::j#1 main::i#2 ] // zpby1_gt_0_then_la1 + lda 3 + bne main__B2_from_B5 +main__B3: + // [6] (byte) main::i#1 ← -- (byte) main::i#2 [ main::i#1 ] // zpby1=_dec_zpby1 + dec 2 + // [7] if((byte) main::i#1>(byte) 0) goto main::@1 [ main::i#1 ] // zpby1_gt_0_then_la1 + lda 2 + bne main__B1_from_B3 +main__Breturn: + rts +nest1: +nest1__B1_from_nest1: + // (byte) nest1::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 4 + jmp nest1__B1 +nest1__B1_from_B3: + // (byte) nest1::i#2 = (byte) nest1::i#1 // register copy +nest1__B1: +nest1__B2_from_B1: + // (byte) nest1::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 5 + jmp nest1__B2 +nest1__B2_from_B5: + // (byte) nest1::j#2 = (byte) nest1::j#1 // register copy +nest1__B2: + jsr nest2 +nest1__B5: + // [12] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] // zpby1=_dec_zpby1 + dec 5 + // [13] if((byte) nest1::j#1>(byte) 0) goto nest1::@2 [ nest1::j#1 nest1::i#2 ] // zpby1_gt_0_then_la1 + lda 5 + bne nest1__B2_from_B5 +nest1__B3: + // [14] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] // zpby1=_dec_zpby1 + dec 4 + // [15] if((byte) nest1::i#1>(byte) 0) goto nest1::@1 [ nest1::i#1 ] // zpby1_gt_0_then_la1 + lda 4 + bne nest1__B1_from_B3 +nest1__Breturn: + rts +nest2: +nest2__B1_from_nest2: + // (byte) nest2::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 6 + jmp nest2__B1 +nest2__B1_from_B3: + // (byte) nest2::i#2 = (byte) nest2::i#1 // register copy +nest2__B1: +nest2__B2_from_B1: + // (byte) nest2::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 7 + jmp nest2__B2 +nest2__B2_from_B2: + // (byte) nest2::j#2 = (byte) nest2::j#1 // register copy +nest2__B2: + // [19] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] // coptr1=zpby1 + lda 7 + sta 1024 + // [20] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] // zpby1=_dec_zpby1 + dec 7 + // [21] if((byte) nest2::j#1>(byte) 0) goto nest2::@2 [ nest2::j#1 nest2::i#2 ] // zpby1_gt_0_then_la1 + lda 7 + bne nest2__B2_from_B2 +nest2__B3: + // [22] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] // zpby1=_dec_zpby1 + dec 6 + // [23] if((byte) nest2::i#1>(byte) 0) goto nest2::@1 [ nest2::i#1 ] // zpby1_gt_0_then_la1 + lda 6 + bne nest2__B1_from_B3 +nest2__Breturn: + rts + +Removing instruction jmp main__B1 +Removing instruction jmp main__B2 +Removing instruction jmp nest1__B1 +Removing instruction jmp nest1__B2 +Removing instruction jmp nest2__B1 +Removing instruction jmp nest2__B2 +Succesful ASM optimization Pass5NextJumpElimination +ASSEMBLER +BBEGIN: + jsr main +BEND: +main: +main__B1_from_main: + // (byte) main::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 2 +main__B1_from_B3: + // (byte) main::i#2 = (byte) main::i#1 // register copy +main__B1: +main__B2_from_B1: + // (byte) main::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 3 +main__B2_from_B5: + // (byte) main::j#2 = (byte) main::j#1 // register copy +main__B2: + jsr nest1 +main__B5: + // [4] (byte) main::j#1 ← -- (byte) main::j#2 [ main::j#1 main::i#2 ] // zpby1=_dec_zpby1 + dec 3 + // [5] if((byte) main::j#1>(byte) 0) goto main::@2 [ main::j#1 main::i#2 ] // zpby1_gt_0_then_la1 + lda 3 + bne main__B2_from_B5 +main__B3: + // [6] (byte) main::i#1 ← -- (byte) main::i#2 [ main::i#1 ] // zpby1=_dec_zpby1 + dec 2 + // [7] if((byte) main::i#1>(byte) 0) goto main::@1 [ main::i#1 ] // zpby1_gt_0_then_la1 + lda 2 + bne main__B1_from_B3 +main__Breturn: + rts +nest1: +nest1__B1_from_nest1: + // (byte) nest1::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 4 +nest1__B1_from_B3: + // (byte) nest1::i#2 = (byte) nest1::i#1 // register copy +nest1__B1: +nest1__B2_from_B1: + // (byte) nest1::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 5 +nest1__B2_from_B5: + // (byte) nest1::j#2 = (byte) nest1::j#1 // register copy +nest1__B2: + jsr nest2 +nest1__B5: + // [12] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] // zpby1=_dec_zpby1 + dec 5 + // [13] if((byte) nest1::j#1>(byte) 0) goto nest1::@2 [ nest1::j#1 nest1::i#2 ] // zpby1_gt_0_then_la1 + lda 5 + bne nest1__B2_from_B5 +nest1__B3: + // [14] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] // zpby1=_dec_zpby1 + dec 4 + // [15] if((byte) nest1::i#1>(byte) 0) goto nest1::@1 [ nest1::i#1 ] // zpby1_gt_0_then_la1 + lda 4 + bne nest1__B1_from_B3 +nest1__Breturn: + rts +nest2: +nest2__B1_from_nest2: + // (byte) nest2::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 6 +nest2__B1_from_B3: + // (byte) nest2::i#2 = (byte) nest2::i#1 // register copy +nest2__B1: +nest2__B2_from_B1: + // (byte) nest2::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 7 +nest2__B2_from_B2: + // (byte) nest2::j#2 = (byte) nest2::j#1 // register copy +nest2__B2: + // [19] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] // coptr1=zpby1 + lda 7 + sta 1024 + // [20] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] // zpby1=_dec_zpby1 + dec 7 + // [21] if((byte) nest2::j#1>(byte) 0) goto nest2::@2 [ nest2::j#1 nest2::i#2 ] // zpby1_gt_0_then_la1 + lda 7 + bne nest2__B2_from_B2 +nest2__B3: + // [22] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] // zpby1=_dec_zpby1 + dec 6 + // [23] if((byte) nest2::i#1>(byte) 0) goto nest2::@1 [ nest2::i#1 ] // zpby1_gt_0_then_la1 + lda 6 + bne nest2__B1_from_B3 +nest2__Breturn: + rts + +FINAL SYMBOL TABLE +(label) @BEGIN +(label) @END +(byte*) SCREEN +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@5 +(label) main::@return +(byte) main::i +(byte) main::i#1 zp byte:2 +(byte) main::i#2 zp byte:2 +(byte) main::j +(byte) main::j#1 zp byte:3 +(byte) main::j#2 zp byte:3 + +(void()) nest1() +(label) nest1::@1 +(label) nest1::@2 +(label) nest1::@3 +(label) nest1::@5 +(label) nest1::@return +(byte) nest1::i +(byte) nest1::i#1 zp byte:4 +(byte) nest1::i#2 zp byte:4 +(byte) nest1::j +(byte) nest1::j#1 zp byte:5 +(byte) nest1::j#2 zp byte:5 + +(void()) nest2() +(label) nest2::@1 +(label) nest2::@2 +(label) nest2::@3 +(label) nest2::@return +(byte) nest2::i +(byte) nest2::i#1 zp byte:6 +(byte) nest2::i#2 zp byte:6 +(byte) nest2::j +(byte) nest2::j#1 zp byte:7 +(byte) nest2::j#2 zp byte:7 + + +FINAL CODE +BBEGIN: + jsr main +BEND: +main: +main__B1_from_main: + // (byte) main::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 2 +main__B1_from_B3: + // (byte) main::i#2 = (byte) main::i#1 // register copy +main__B1: +main__B2_from_B1: + // (byte) main::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 3 +main__B2_from_B5: + // (byte) main::j#2 = (byte) main::j#1 // register copy +main__B2: + jsr nest1 +main__B5: + // [4] (byte) main::j#1 ← -- (byte) main::j#2 [ main::j#1 main::i#2 ] // zpby1=_dec_zpby1 + dec 3 + // [5] if((byte) main::j#1>(byte) 0) goto main::@2 [ main::j#1 main::i#2 ] // zpby1_gt_0_then_la1 + lda 3 + bne main__B2_from_B5 +main__B3: + // [6] (byte) main::i#1 ← -- (byte) main::i#2 [ main::i#1 ] // zpby1=_dec_zpby1 + dec 2 + // [7] if((byte) main::i#1>(byte) 0) goto main::@1 [ main::i#1 ] // zpby1_gt_0_then_la1 + lda 2 + bne main__B1_from_B3 +main__Breturn: + rts +nest1: +nest1__B1_from_nest1: + // (byte) nest1::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 4 +nest1__B1_from_B3: + // (byte) nest1::i#2 = (byte) nest1::i#1 // register copy +nest1__B1: +nest1__B2_from_B1: + // (byte) nest1::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 5 +nest1__B2_from_B5: + // (byte) nest1::j#2 = (byte) nest1::j#1 // register copy +nest1__B2: + jsr nest2 +nest1__B5: + // [12] (byte) nest1::j#1 ← -- (byte) nest1::j#2 [ nest1::j#1 nest1::i#2 ] // zpby1=_dec_zpby1 + dec 5 + // [13] if((byte) nest1::j#1>(byte) 0) goto nest1::@2 [ nest1::j#1 nest1::i#2 ] // zpby1_gt_0_then_la1 + lda 5 + bne nest1__B2_from_B5 +nest1__B3: + // [14] (byte) nest1::i#1 ← -- (byte) nest1::i#2 [ nest1::i#1 ] // zpby1=_dec_zpby1 + dec 4 + // [15] if((byte) nest1::i#1>(byte) 0) goto nest1::@1 [ nest1::i#1 ] // zpby1_gt_0_then_la1 + lda 4 + bne nest1__B1_from_B3 +nest1__Breturn: + rts +nest2: +nest2__B1_from_nest2: + // (byte) nest2::i#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 6 +nest2__B1_from_B3: + // (byte) nest2::i#2 = (byte) nest2::i#1 // register copy +nest2__B1: +nest2__B2_from_B1: + // (byte) nest2::j#2 = (byte) 100 // zpby1=coby1 + lda #100 + sta 7 +nest2__B2_from_B2: + // (byte) nest2::j#2 = (byte) nest2::j#1 // register copy +nest2__B2: + // [19] *((word) 1024) ← (byte) nest2::j#2 [ nest2::j#2 nest2::i#2 ] // coptr1=zpby1 + lda 7 + sta 1024 + // [20] (byte) nest2::j#1 ← -- (byte) nest2::j#2 [ nest2::j#1 nest2::i#2 ] // zpby1=_dec_zpby1 + dec 7 + // [21] if((byte) nest2::j#1>(byte) 0) goto nest2::@2 [ nest2::j#1 nest2::i#2 ] // zpby1_gt_0_then_la1 + lda 7 + bne nest2__B2_from_B2 +nest2__B3: + // [22] (byte) nest2::i#1 ← -- (byte) nest2::i#2 [ nest2::i#1 ] // zpby1=_dec_zpby1 + dec 6 + // [23] if((byte) nest2::i#1>(byte) 0) goto nest2::@1 [ nest2::i#1 ] // zpby1_gt_0_then_la1 + lda 6 + bne nest2__B1_from_B3 +nest2__Breturn: + rts + diff --git a/src/dk/camelot64/kickc/test/ref/loopnest.sym b/src/dk/camelot64/kickc/test/ref/loopnest.sym new file mode 100644 index 000000000..32cd22334 --- /dev/null +++ b/src/dk/camelot64/kickc/test/ref/loopnest.sym @@ -0,0 +1,41 @@ +(label) @BEGIN +(label) @END +(byte*) SCREEN +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@3 +(label) main::@5 +(label) main::@return +(byte) main::i +(byte) main::i#1 zp byte:2 +(byte) main::i#2 zp byte:2 +(byte) main::j +(byte) main::j#1 zp byte:3 +(byte) main::j#2 zp byte:3 + +(void()) nest1() +(label) nest1::@1 +(label) nest1::@2 +(label) nest1::@3 +(label) nest1::@5 +(label) nest1::@return +(byte) nest1::i +(byte) nest1::i#1 zp byte:4 +(byte) nest1::i#2 zp byte:4 +(byte) nest1::j +(byte) nest1::j#1 zp byte:5 +(byte) nest1::j#2 zp byte:5 + +(void()) nest2() +(label) nest2::@1 +(label) nest2::@2 +(label) nest2::@3 +(label) nest2::@return +(byte) nest2::i +(byte) nest2::i#1 zp byte:6 +(byte) nest2::i#2 zp byte:6 +(byte) nest2::j +(byte) nest2::j#1 zp byte:7 +(byte) nest2::j#2 zp byte:7 +