CONTROL FLOW GRAPH SSA void main() main: scope:[main] from __start main::b#0 = main::BITMAP+$1fff to:main::@1 main::@1: scope:[main] from main main::@1 main::b#2 = phi( main/main::b#0, main::@1/main::b#1 ) *main::b#2 = $5a main::b#1 = main::b#2 + rangenext(main::BITMAP+$1fff,main::BITMAP) main::$0 = main::b#1 != rangelast(main::BITMAP+$1fff,main::BITMAP) if(main::$0) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 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 void __start() void main() bool~ main::$0 const nomodify byte* main::BITMAP = (byte*)$2000 byte* main::b byte* main::b#0 byte* main::b#1 byte* main::b#2 Adding number conversion cast (unumber) $1fff in main::b#0 = main::BITMAP+$1fff Adding number conversion cast (unumber) $5a in *main::b#2 = $5a Successful SSA optimization PassNAddNumberTypeConversions Inlining cast *main::b#2 = (unumber)$5a Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 8192 Simplifying constant integer cast $1fff Simplifying constant integer cast $5a Successful SSA optimization PassNCastSimplification Finalized unsigned number type (word) $1fff Finalized unsigned number type (byte) $5a Successful SSA optimization PassNFinalizeNumberTypeConversions Simple Condition main::$0 [5] if(main::b#1!=rangelast(main::BITMAP+$1fff,main::BITMAP)) goto main::@1 Successful SSA optimization Pass2ConditionalJumpSimplification Constant main::b#0 = main::BITMAP+$1fff Successful SSA optimization Pass2ConstantIdentification Resolved ranged next value [3] main::b#1 = -- main::b#2 to -- Resolved ranged comparison value [5] if(main::b#1!=rangelast(main::BITMAP+$1fff,main::BITMAP)) goto main::@1 to (byte*)main::BITMAP-1 Removing unused procedure __start Removing unused procedure block __start Removing unused procedure block __start::@1 Removing unused procedure block __start::@return Successful SSA optimization PassNEliminateEmptyStart Adding number conversion cast (unumber) 1 in [3] if(main::b#1!=(byte*)main::BITMAP-1) goto main::@1 Successful SSA optimization PassNAddNumberTypeConversions Simplifying constant integer cast main::BITMAP-(unumber)1 Simplifying constant integer cast 1 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 1 Successful SSA optimization PassNFinalizeNumberTypeConversions Inlining constant with var siblings main::b#0 Constant inlined main::b#0 = main::BITMAP+$1fff Successful SSA optimization Pass2ConstantInlining Added new block during phi lifting main::@2(between main::@1 and main::@1) Adding NOP phi() at start of main CALL GRAPH Created 1 initial phi equivalence classes Coalesced [6] main::b#3 = main::b#1 Coalesced down to 1 phi equivalence classes Culled Empty Block label main::@2 Adding NOP phi() at start of main FINAL CONTROL FLOW GRAPH void main() main: scope:[main] from [0] phi() to:main::@1 main::@1: scope:[main] from main main::@1 [1] main::b#2 = phi( main/main::BITMAP+$1fff, main::@1/main::b#1 ) [2] *main::b#2 = $5a [3] main::b#1 = -- main::b#2 [4] if(main::b#1!=main::BITMAP-1) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 [5] return to:@return VARIABLE REGISTER WEIGHTS void main() byte* main::b byte* main::b#1 16.5 byte* main::b#2 16.5 Initial phi equivalence classes [ main::b#2 main::b#1 ] Complete equivalence classes [ main::b#2 main::b#1 ] Allocated zp[2]:2 [ main::b#2 main::b#1 ] REGISTER UPLIFT POTENTIAL REGISTERS Statement [2] *main::b#2 = $5a [ main::b#2 ] ( [ main::b#2 ] { } ) always clobbers reg byte a reg byte y Statement [3] main::b#1 = -- main::b#2 [ main::b#1 ] ( [ main::b#1 ] { } ) always clobbers reg byte a Statement [4] if(main::b#1!=main::BITMAP-1) goto main::@1 [ main::b#1 ] ( [ main::b#1 ] { } ) always clobbers reg byte a Potential registers zp[2]:2 [ main::b#2 main::b#1 ] : zp[2]:2 , REGISTER UPLIFT SCOPES Uplift Scope [main] 33: zp[2]:2 [ main::b#2 main::b#1 ] Uplift Scope [] Uplifting [main] best 601 combination zp[2]:2 [ main::b#2 main::b#1 ] Uplifting [] best 601 combination ASSEMBLER BEFORE OPTIMIZATION // File Comments // Range-based for does not recognize symbolic constants. // The following should work but gives a not-constant exception // Upstart // Commodore 64 PRG executable file .file [name="forrangesymbolic.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 .segment Code // main main: { .label BITMAP = $2000 .label b = 2 // [1] phi from main to main::@1 [phi:main->main::@1] __b1_from_main: // [1] phi main::b#2 = main::BITMAP+$1fff [phi:main->main::@1#0] -- pbuz1=pbuc1 lda #BITMAP+$1fff sta.z b+1 jmp __b1 // [1] phi from main::@1 to main::@1 [phi:main::@1->main::@1] __b1_from___b1: // [1] phi main::b#2 = main::b#1 [phi:main::@1->main::@1#0] -- register_copy jmp __b1 // main::@1 __b1: // [2] *main::b#2 = $5a -- _deref_pbuz1=vbuc1 lda #$5a ldy #0 sta (b),y // [3] main::b#1 = -- main::b#2 -- pbuz1=_dec_pbuz1 lda.z b bne !+ dec.z b+1 !: dec.z b // [4] if(main::b#1!=main::BITMAP-1) goto main::@1 -- pbuz1_neq_pbuc1_then_la1 lda.z b+1 cmp #>BITMAP-1 bne __b1_from___b1 lda.z b cmp #main::@1] // [1] phi main::b#2 = main::BITMAP+$1fff [phi:main->main::@1#0] -- pbuz1=pbuc1 lda #BITMAP+$1fff sta.z b+1 // [1] phi from main::@1 to main::@1 [phi:main::@1->main::@1] // [1] phi main::b#2 = main::b#1 [phi:main::@1->main::@1#0] -- register_copy // main::@1 __b1: // *b = $5a // [2] *main::b#2 = $5a -- _deref_pbuz1=vbuc1 lda #$5a ldy #0 sta (b),y // for(byte* b : BITMAP+$1fff..BITMAP) // [3] main::b#1 = -- main::b#2 -- pbuz1=_dec_pbuz1 lda.z b bne !+ dec.z b+1 !: dec.z b // [4] if(main::b#1!=main::BITMAP-1) goto main::@1 -- pbuz1_neq_pbuc1_then_la1 lda.z b+1 cmp #>BITMAP-1 bne __b1 lda.z b cmp #