CONTROL FLOW GRAPH SSA void main() main: scope:[main] from __start main::i#0 = 0 to:main::@1 main::@1: scope:[main] from main main::@1 main::i#2 = phi( main/main::i#0, main::@1/main::i#1 ) plots[main::i#2] = main::i#2 SCREEN[main::i#2] = 0 main::i#1 = main::i#2 + rangenext(0,$27) main::$0 = main::i#1 != rangelast(0,$27) if(main::$0) goto main::@1 to:main::@2 main::@2: scope:[main] from main::@1 main::@3 line::x0#0 = 0 line::x1#0 = $a call line to:main::@3 main::@3: scope:[main] from main::@2 if(true) goto main::@2 to:main::@return main::@return: scope:[main] from main::@3 return to:@return void line(char x0 , char x1) line: scope:[line] from main::@2 line::x1#1 = phi( main::@2/line::x1#0 ) line::x0#1 = phi( main::@2/line::x0#0 ) line::$0 = line::x0#1 < line::x1#1 if(line::$0) goto line::@1 to:line::@2 line::@1: scope:[line] from line line::x1#3 = phi( line/line::x1#1 ) line::x0#2 = phi( line/line::x0#1 ) line::x#0 = line::x0#2 to:line::@3 line::@2: scope:[line] from line line::x0#3 = phi( line/line::x0#1 ) plot::x#0 = line::x0#3 call plot to:line::@5 line::@5: scope:[line] from line::@2 to:line::@return line::@3: scope:[line] from line::@1 line::@6 line::x1#2 = phi( line::@1/line::x1#3, line::@6/line::x1#4 ) line::x#2 = phi( line::@1/line::x#0, line::@6/line::x#1 ) line::$2 = line::x#2 <= line::x1#2 if(line::$2) goto line::@4 to:line::@return line::@4: scope:[line] from line::@3 line::x1#5 = phi( line::@3/line::x1#2 ) line::x#3 = phi( line::@3/line::x#2 ) plot::x#1 = line::x#3 call plot to:line::@6 line::@6: scope:[line] from line::@4 line::x1#4 = phi( line::@4/line::x1#5 ) line::x#4 = phi( line::@4/line::x#3 ) line::x#1 = ++ line::x#4 to:line::@3 line::@return: scope:[line] from line::@3 line::@5 return to:@return void plot(char x) plot: scope:[plot] from line::@2 line::@4 plot::x#2 = phi( line::@2/plot::x#0, line::@4/plot::x#1 ) plot::idx#0 = plots[plot::x#2] plot::$0 = SCREEN[plot::idx#0] + 1 SCREEN[plot::idx#0] = plot::$0 to:plot::@return plot::@return: scope:[plot] from plot return to:@return void __start() __start: scope:[__start] from call main to:__start::@1 __start::@1: scope:[__start] from __start to:__start::@return __start::@return: scope:[__start] from __start::@1 return to:@return SYMBOL TABLE SSA __constant char * const SCREEN = (char *)$400 void __start() void line(char x0 , char x1) bool line::$0 bool line::$2 char line::x char line::x#0 char line::x#1 char line::x#2 char line::x#3 char line::x#4 char line::x0 char line::x0#0 char line::x0#1 char line::x0#2 char line::x0#3 char line::x1 char line::x1#0 char line::x1#1 char line::x1#2 char line::x1#3 char line::x1#4 char line::x1#5 void main() bool main::$0 char main::i char main::i#0 char main::i#1 char main::i#2 void plot(char x) number plot::$0 char plot::idx char plot::idx#0 char plot::x char plot::x#0 char plot::x#1 char plot::x#2 __constant char * const plots = (char *)$1000 Adding number conversion cast (unumber) 0 in SCREEN[main::i#2] = 0 Adding number conversion cast (unumber) 0 in line::x0#0 = 0 Adding number conversion cast (unumber) $a in line::x1#0 = $a Adding number conversion cast (unumber) 1 in plot::$0 = SCREEN[plot::idx#0] + 1 Adding number conversion cast (unumber) plot::$0 in plot::$0 = SCREEN[plot::idx#0] + (unumber)1 Successful SSA optimization PassNAddNumberTypeConversions Inlining cast SCREEN[main::i#2] = (unumber)0 Inlining cast line::x0#0 = (unumber)0 Inlining cast line::x1#0 = (unumber)$a Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (char *) 4096 Simplifying constant pointer cast (char *) 1024 Simplifying constant integer cast 0 Simplifying constant integer cast 0 Simplifying constant integer cast $a Simplifying constant integer cast 1 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0 Finalized unsigned number type (char) $a Finalized unsigned number type (char) 1 Successful SSA optimization PassNFinalizeNumberTypeConversions Inferred type updated to char in plot::$0 = SCREEN[plot::idx#0] + 1 Alias line::x0#1 = line::x0#2 line::x#0 line::x0#3 Alias line::x1#1 = line::x1#3 Alias line::x#2 = line::x#3 line::x#4 Alias line::x1#2 = line::x1#5 line::x1#4 Successful SSA optimization Pass2AliasElimination Identical Phi Values line::x0#1 line::x0#0 Identical Phi Values line::x1#1 line::x1#0 Identical Phi Values line::x1#2 line::x1#1 Successful SSA optimization Pass2IdenticalPhiElimination Simple Condition main::$0 [6] if(main::i#1!=rangelast(0,$27)) goto main::@1 Simple Condition line::$0 [14] if(line::x0#0main::@1] __b1_from_main: // [1] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 ldx #0 jmp __b1 // [1] phi from main::@1 to main::@1 [phi:main::@1->main::@1] __b1_from___b1: // [1] phi main::i#2 = main::i#1 [phi:main::@1->main::@1#0] -- register_copy jmp __b1 // main::@1 __b1: // [2] plots[main::i#2] = main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx txa sta plots,x // [3] SCREEN[main::i#2] = 0 -- pbuc1_derefidx_vbuxx=vbuc2 lda #0 sta SCREEN,x // [4] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx inx // [5] if(main::i#1!=$28) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 cpx #$28 bne __b1_from___b1 // [6] phi from main::@1 main::@2 to main::@2 [phi:main::@1/main::@2->main::@2] __b2_from___b1: __b2_from___b2: jmp __b2 // main::@2 __b2: // [7] call line // [8] phi from main::@2 to line [phi:main::@2->line] line_from___b2: jsr line jmp __b2_from___b2 } // line // void line(char x0, char x1) line: { .const x0 = 0 .const x1 = $a // [9] phi from line to line::@1 [phi:line->line::@1] __b1_from_line: // [9] phi line::x#2 = line::x0#0 [phi:line->line::@1#0] -- vbuxx=vbuc1 ldx #x0 jmp __b1 // line::@1 __b1: // [10] if(line::x#2line::@1] __b1_from___b3: // [9] phi line::x#2 = line::x#1 [phi:line::@3->line::@1#0] -- register_copy jmp __b1 } // plot // void plot(__register(X) char x) plot: { // [15] plot::idx#0 = plots[plot::x#1] -- vbuyy=pbuc1_derefidx_vbuxx ldy plots,x // [16] plot::$0 = SCREEN[plot::idx#0] + 1 -- vbuaa=pbuc1_derefidx_vbuyy_plus_1 lda SCREEN,y clc adc #1 // [17] SCREEN[plot::idx#0] = plot::$0 -- pbuc1_derefidx_vbuyy=vbuaa sta SCREEN,y jmp __breturn // plot::@return __breturn: // [18] return rts } // File Data ASSEMBLER OPTIMIZATIONS Removing instruction jmp __b1 Removing instruction jmp __b2 Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __b3 Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination Replacing label __b1_from___b1 with __b1 Replacing label __b2_from___b2 with __b2 Removing instruction __b1_from___b1: Removing instruction __b2_from___b1: Removing instruction __b2_from___b2: Removing instruction line_from___b2: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __b1_from_main: Removing instruction __b1_from_line: Removing instruction __breturn: Removing instruction __b3: Removing instruction __b1_from___b3: Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination Removing instruction jmp __b1 Succesful ASM optimization Pass5NextJumpElimination FINAL SYMBOL TABLE __constant char * const SCREEN = (char *) 1024 void line(char x0 , char x1) char line::x char line::x#1 // reg byte x 20002.0 char line::x#2 // reg byte x 10001.0 char line::x0 __constant char line::x0#0 = 0 // x0 char line::x1 __constant char line::x1#0 = $a // x1 void main() char main::i char main::i#1 // reg byte x 16.5 char main::i#2 // reg byte x 18.333333333333332 void plot(char x) char plot::$0 // reg byte a 200002.0 char plot::idx char plot::idx#0 // reg byte y 150001.5 char plot::x char plot::x#1 // reg byte x 110002.0 __constant char * const plots = (char *) 4096 reg byte x [ main::i#2 main::i#1 ] reg byte x [ line::x#2 line::x#1 ] reg byte x [ plot::x#1 ] reg byte y [ plot::idx#0 ] reg byte a [ plot::$0 ] FINAL ASSEMBLER Score: 2013 // File Comments // Upstart // Commodore 64 PRG executable file .file [name="const-identification.prg", type="prg", segments="Program"] .segmentdef Program [segments="Basic, Code, Data"] .segmentdef Basic [start=$0801] .segmentdef Code [start=$80d] .segmentdef Data [startAfter="Code"] .segment Basic :BasicUpstart(main) // Global Constants & labels .label plots = $1000 .label SCREEN = $400 .segment Code // main main: { // [1] phi from main to main::@1 [phi:main->main::@1] // [1] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 ldx #0 // [1] phi from main::@1 to main::@1 [phi:main::@1->main::@1] // [1] phi main::i#2 = main::i#1 [phi:main::@1->main::@1#0] -- register_copy // main::@1 __b1: // plots[i] = i // [2] plots[main::i#2] = main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx txa sta plots,x // SCREEN[i] = 0 // [3] SCREEN[main::i#2] = 0 -- pbuc1_derefidx_vbuxx=vbuc2 lda #0 sta SCREEN,x // for(byte i : 0..39) // [4] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx inx // [5] if(main::i#1!=$28) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 cpx #$28 bne __b1 // [6] phi from main::@1 main::@2 to main::@2 [phi:main::@1/main::@2->main::@2] // main::@2 __b2: // line(0, 10) // [7] call line // [8] phi from main::@2 to line [phi:main::@2->line] jsr line jmp __b2 } // line // void line(char x0, char x1) line: { .const x0 = 0 .const x1 = $a // [9] phi from line to line::@1 [phi:line->line::@1] // [9] phi line::x#2 = line::x0#0 [phi:line->line::@1#0] -- vbuxx=vbuc1 ldx #x0 // line::@1 __b1: // for(byte x = x0; x<=x1; x++) // [10] if(line::x#2line::@1] // [9] phi line::x#2 = line::x#1 [phi:line::@3->line::@1#0] -- register_copy jmp __b1 } // plot // void plot(__register(X) char x) plot: { // byte idx = plots[x] // [15] plot::idx#0 = plots[plot::x#1] -- vbuyy=pbuc1_derefidx_vbuxx ldy plots,x // SCREEN[idx]+1 // [16] plot::$0 = SCREEN[plot::idx#0] + 1 -- vbuaa=pbuc1_derefidx_vbuyy_plus_1 lda SCREEN,y clc adc #1 // SCREEN[idx] = SCREEN[idx]+1 // [17] SCREEN[plot::idx#0] = plot::$0 -- pbuc1_derefidx_vbuyy=vbuaa sta SCREEN,y // plot::@return // } // [18] return rts } // File Data