Inlined call call __init CONTROL FLOW GRAPH SSA void main() main: scope:[main] from __start::@1 to:main::@1 main::@1: scope:[main] from main main::@2 main::$0 = i < 7 if(main::$0) goto main::@2 to:main::@return main::@2: scope:[main] from main::@1 SCREEN[i] = i i = ++ i to:main::@1 main::@return: scope:[main] from main::@1 return to:@return void __start() __start: scope:[__start] from to:__start::__init1 __start::__init1: scope:[__start] from __start i = 3 to:__start::@1 __start::@1: scope:[__start] from __start::__init1 call main to:__start::@2 __start::@2: scope:[__start] from __start::@1 to:__start::@return __start::@return: scope:[__start] from __start::@2 return to:@return SYMBOL TABLE SSA __constant char * const SCREEN = (char *)$400 void __start() __loadstore volatile char i void main() bool main::$0 Adding number conversion cast (unumber) 7 in main::$0 = i < 7 Successful SSA optimization PassNAddNumberTypeConversions Simplifying constant pointer cast (char *) 1024 Simplifying constant integer cast 7 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (char) 7 Successful SSA optimization PassNFinalizeNumberTypeConversions Simple Condition main::$0 [1] if(i<7) goto main::@2 Successful SSA optimization Pass2ConditionalJumpSimplification Adding NOP phi() at start of __start Adding NOP phi() at start of __start::@1 Adding NOP phi() at start of __start::@2 Adding NOP phi() at start of main CALL GRAPH Calls in [__start] to main:3 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes Culled Empty Block label __start::@2 Adding NOP phi() at start of __start Adding NOP phi() at start of __start::@1 Adding NOP phi() at start of main FINAL CONTROL FLOW GRAPH void __start() __start: scope:[__start] from [0] phi() to:__start::__init1 __start::__init1: scope:[__start] from __start [1] i = 3 to:__start::@1 __start::@1: scope:[__start] from __start::__init1 [2] phi() [3] call main to:__start::@return __start::@return: scope:[__start] from __start::@1 [4] return to:@return void main() main: scope:[main] from __start::@1 [5] phi() to:main::@1 main::@1: scope:[main] from main main::@2 [6] if(i<7) goto main::@2 to:main::@return main::@return: scope:[main] from main::@1 [7] return to:@return main::@2: scope:[main] from main::@1 [8] SCREEN[i] = i [9] i = ++ i to:main::@1 VARIABLE REGISTER WEIGHTS void __start() __loadstore volatile char i // 84.49999999999999 void main() Initial phi equivalence classes Added variable i to live range equivalence class [ i ] Complete equivalence classes [ i ] Allocated zp[1]:2 [ i ] REGISTER UPLIFT POTENTIAL REGISTERS Statement [1] i = 3 [ i ] ( [ i ] { } ) always clobbers reg byte a Statement [6] if(i<7) goto main::@2 [ i ] ( main:3 [ i ] { } ) always clobbers reg byte a Statement [8] SCREEN[i] = i [ i ] ( main:3 [ i ] { } ) always clobbers reg byte a reg byte y Potential registers zp[1]:2 [ i ] : zp[1]:2 , REGISTER UPLIFT SCOPES Uplift Scope [] 84.5: zp[1]:2 [ i ] Uplift Scope [main] Uplift Scope [__start] Uplifting [] best 374 combination zp[1]:2 [ i ] Uplifting [main] best 374 combination Uplifting [__start] best 374 combination Attempting to uplift remaining variables inzp[1]:2 [ i ] Uplifting [] best 374 combination zp[1]:2 [ i ] ASSEMBLER BEFORE OPTIMIZATION // File Comments // Test that volatile vars are turned into load/store // Upstart // Commodore 64 PRG executable file .file [name="volatile-0.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(__start) // Global Constants & labels .label SCREEN = $400 .label i = 2 .segment Code // __start __start: { jmp __init1 // __start::__init1 __init1: // [1] i = 3 -- vbuz1=vbuc1 lda #3 sta.z i // [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] __b1_from___init1: jmp __b1 // __start::@1 __b1: // [3] call main // [5] phi from __start::@1 to main [phi:__start::@1->main] main_from___b1: jsr main jmp __breturn // __start::@return __breturn: // [4] return rts } // main main: { jmp __b1 // main::@1 __b1: // [6] if(i<7) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 lda.z i cmp #7 bcc __b2 jmp __breturn // main::@return __breturn: // [7] return rts // main::@2 __b2: // [8] SCREEN[i] = i -- pbuc1_derefidx_vbuz1=vbuz1 ldy.z i tya sta SCREEN,y // [9] i = ++ i -- vbuz1=_inc_vbuz1 inc.z i jmp __b1 } // File Data ASSEMBLER OPTIMIZATIONS Removing instruction jmp __init1 Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __b1 Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination Removing instruction __b1_from___init1: Removing instruction main_from___b1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __init1: Removing instruction __b1: Removing instruction __breturn: Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE __constant char * const SCREEN = (char *) 1024 void __start() __loadstore volatile char i // zp[1]:2 84.49999999999999 void main() zp[1]:2 [ i ] FINAL ASSEMBLER Score: 278 // File Comments // Test that volatile vars are turned into load/store // Upstart // Commodore 64 PRG executable file .file [name="volatile-0.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(__start) // Global Constants & labels .label SCREEN = $400 .label i = 2 .segment Code // __start __start: { // __start::__init1 // volatile char i = 3 // [1] i = 3 -- vbuz1=vbuc1 lda #3 sta.z i // [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] // __start::@1 // [3] call main // [5] phi from __start::@1 to main [phi:__start::@1->main] jsr main // __start::@return // [4] return rts } // main main: { // main::@1 __b1: // while(i<7) // [6] if(i<7) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 lda.z i cmp #7 bcc __b2 // main::@return // } // [7] return rts // main::@2 __b2: // SCREEN[i++] = i // [8] SCREEN[i] = i -- pbuc1_derefidx_vbuz1=vbuz1 ldy.z i tya sta SCREEN,y // SCREEN[i++] = i; // [9] i = ++ i -- vbuz1=_inc_vbuz1 inc.z i jmp __b1 } // File Data