Setting inferred volatile on symbol affected by address-of: print::ch in asm { ldxidx ldach staSCREEN,x incidx } Inlined call call __init CONTROL FLOW GRAPH SSA void main() main: scope:[main] from __start::@1 print::ch = 'c' call print to:main::@1 main::@1: scope:[main] from main print::ch = 'm' call print to:main::@2 main::@2: scope:[main] from main::@1 print::ch = 'l' call print to:main::@3 main::@3: scope:[main] from main::@2 to:main::@return main::@return: scope:[main] from main::@3 return to:@return void print(volatile byte print::ch) print: scope:[print] from main main::@1 main::@2 asm { ldxidx ldach staSCREEN,x incidx } to:print::@return print::@return: scope:[print] from print return to:@return void __start() __start: scope:[__start] from to:__start::__init1 __start::__init1: scope:[__start] from __start idx = 0 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 const nomodify byte* SCREEN = (byte*)$400 void __start() volatile byte idx loadstore !zp[-1]:3 void main() void print(volatile byte print::ch) volatile byte print::ch loadstore !zp[-1]:2 Simplifying constant pointer cast (byte*) 1024 Successful SSA optimization PassNCastSimplification 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::@3 CALL GRAPH Calls in [__start] to main:3 Calls in [main] to print:7 print:9 print:11 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes Culled Empty Block label __start::@2 Culled Empty Block label main::@3 Adding NOP phi() at start of __start Adding NOP phi() at start of __start::@1 FINAL CONTROL FLOW GRAPH void __start() __start: scope:[__start] from [0] phi() to:__start::__init1 __start::__init1: scope:[__start] from __start [1] idx = 0 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] print::ch = 'c' [6] call print to:main::@1 main::@1: scope:[main] from main [7] print::ch = 'm' [8] call print to:main::@2 main::@2: scope:[main] from main::@1 [9] print::ch = 'l' [10] call print to:main::@return main::@return: scope:[main] from main::@2 [11] return to:@return void print(volatile byte print::ch) print: scope:[print] from main main::@1 main::@2 asm { ldxidx ldach staSCREEN,x incidx } to:print::@return print::@return: scope:[print] from print [13] return to:@return VARIABLE REGISTER WEIGHTS void __start() volatile byte idx loadstore !zp[-1]:3 0.2222222222222222 void main() void print(volatile byte print::ch) volatile byte print::ch loadstore !zp[-1]:2 11.0 Initial phi equivalence classes Added variable idx to live range equivalence class [ idx ] Added variable print::ch to live range equivalence class [ print::ch ] Complete equivalence classes [ idx ] [ print::ch ] REGISTER UPLIFT POTENTIAL REGISTERS Statement [1] idx = 0 [ idx ] ( [ idx ] { } ) always clobbers reg byte a Statement [5] print::ch = 'c' [ idx print::ch ] ( main:3 [ idx print::ch ] { } ) always clobbers reg byte a Statement [7] print::ch = 'm' [ idx print::ch ] ( main:3 [ idx print::ch ] { } ) always clobbers reg byte a Statement [9] print::ch = 'l' [ idx print::ch ] ( main:3 [ idx print::ch ] { } ) always clobbers reg byte a Statement asm { ldxidx ldach staSCREEN,x incidx } always clobbers reg byte a reg byte x Potential registers zp[1]:3 [ idx ] : zp[1]:3 , Potential registers zp[1]:2 [ print::ch ] : zp[1]:2 , REGISTER UPLIFT SCOPES Uplift Scope [print] 11: zp[1]:2 [ print::ch ] Uplift Scope [] 0.22: zp[1]:3 [ idx ] Uplift Scope [main] Uplift Scope [__start] Uplifting [print] best 129 combination zp[1]:2 [ print::ch ] Uplifting [] best 129 combination zp[1]:3 [ idx ] Uplifting [main] best 129 combination Uplifting [__start] best 129 combination Attempting to uplift remaining variables inzp[1]:2 [ print::ch ] Uplifting [print] best 129 combination zp[1]:2 [ print::ch ] Attempting to uplift remaining variables inzp[1]:3 [ idx ] Uplifting [] best 129 combination zp[1]:3 [ idx ] ASSEMBLER BEFORE OPTIMIZATION // File Comments // Test declaring a variable as at a hard-coded address // zero-page hard-coded address parameter // Upstart .pc = $801 "Basic" :BasicUpstart(__start) .pc = $80d "Program" // Global Constants & labels .label SCREEN = $400 .label idx = 3 // __start __start: { jmp __init1 // __start::__init1 __init1: // [1] idx = 0 -- vbuz1=vbuc1 lda #0 sta.z idx // [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] __b1_from___init1: jmp __b1 // __start::@1 __b1: // [3] call main jsr main jmp __breturn // __start::@return __breturn: // [4] return rts } // main main: { // [5] print::ch = 'c' -- vbuz1=vbuc1 lda #'c' sta.z print.ch // [6] call print jsr print jmp __b1 // main::@1 __b1: // [7] print::ch = 'm' -- vbuz1=vbuc1 lda #'m' sta.z print.ch // [8] call print jsr print jmp __b2 // main::@2 __b2: // [9] print::ch = 'l' -- vbuz1=vbuc1 lda #'l' sta.z print.ch // [10] call print jsr print jmp __breturn // main::@return __breturn: // [11] return rts } // print // print(byte zp(2) ch) print: { .label ch = 2 // asm { ldxidx ldach staSCREEN,x incidx } ldx idx lda ch sta SCREEN,x inc idx jmp __breturn // print::@return __breturn: // [13] return rts } // File Data ASSEMBLER OPTIMIZATIONS Removing instruction jmp __init1 Removing instruction jmp __b1 Removing instruction jmp __breturn Removing instruction jmp __b1 Removing instruction jmp __b2 Removing instruction jmp __breturn Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination Removing instruction __b1_from___init1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction __init1: Removing instruction __b1: Removing instruction __breturn: Removing instruction __b1: Removing instruction __b2: Removing instruction __breturn: Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE const nomodify byte* SCREEN = (byte*) 1024 void __start() volatile byte idx loadstore !zp[-1]:3 zp[1]:3 0.2222222222222222 void main() void print(volatile byte print::ch) volatile byte print::ch loadstore !zp[-1]:2 zp[1]:2 11.0 zp[1]:3 [ idx ] zp[1]:2 [ print::ch ] FINAL ASSEMBLER Score: 81 // File Comments // Test declaring a variable as at a hard-coded address // zero-page hard-coded address parameter // Upstart .pc = $801 "Basic" :BasicUpstart(__start) .pc = $80d "Program" // Global Constants & labels .label SCREEN = $400 .label idx = 3 // __start __start: { // __start::__init1 // idx // [1] idx = 0 -- vbuz1=vbuc1 lda #0 sta.z idx // [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1] // __start::@1 // [3] call main jsr main // __start::@return // [4] return rts } // main main: { // print('c') // [5] print::ch = 'c' -- vbuz1=vbuc1 lda #'c' sta.z print.ch // [6] call print jsr print // main::@1 // print('m') // [7] print::ch = 'm' -- vbuz1=vbuc1 lda #'m' sta.z print.ch // [8] call print jsr print // main::@2 // print('l') // [9] print::ch = 'l' -- vbuz1=vbuc1 lda #'l' sta.z print.ch // [10] call print jsr print // main::@return // } // [11] return rts } // print // print(byte zp(2) ch) print: { .label ch = 2 // asm // asm { ldxidx ldach staSCREEN,x incidx } ldx idx lda ch sta SCREEN,x inc idx // print::@return // } // [13] return rts } // File Data