Resolved forward reference irq to interrupt(KERNEL_MIN)(void()) irq() CONTROL FLOW GRAPH SSA @begin: scope:[] from (void()**) KERNEL_IRQ#0 ← ((void()**)) (word/signed word/dword/signed dword) 788 (byte*) RASTER#0 ← ((byte*)) (word/dword/signed dword) 53266 (byte*) VIC_CONTROL#0 ← ((byte*)) (word/dword/signed dword) 53265 (byte*) IRQ_STATUS#0 ← ((byte*)) (word/dword/signed dword) 53273 (byte*) IRQ_ENABLE#0 ← ((byte*)) (word/dword/signed dword) 53274 (byte) IRQ_RASTER#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1 (byte) IRQ_COLLISION_BG#0 ← (byte/signed byte/word/signed word/dword/signed dword) 2 (byte) IRQ_COLLISION_SPRITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 4 (byte) IRQ_LIGHTPEN#0 ← (byte/signed byte/word/signed word/dword/signed dword) 8 (byte*) BGCOL#0 ← ((byte*)) (word/dword/signed dword) 53280 (byte) WHITE#0 ← (byte/signed byte/word/signed word/dword/signed dword) 1 (byte) BLACK#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 (byte*) CIA1_INTERRUPT#0 ← ((byte*)) (word/dword/signed dword) 56333 (byte) CIA_INTERRUPT_CLEAR#0 ← (byte/signed byte/word/signed word/dword/signed dword) 127 to:@2 main: scope:[main] from @2 asm { sei } *((byte*) CIA1_INTERRUPT#0) ← (byte) CIA_INTERRUPT_CLEAR#0 *((byte*) VIC_CONTROL#0) ← *((byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 *((byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 *((byte*) IRQ_ENABLE#0) ← (byte) IRQ_RASTER#0 (void()*~) main::$0 ← & interrupt(KERNEL_MIN)(void()) irq() *((void()**) KERNEL_IRQ#0) ← (void()*~) main::$0 asm { cli } to:main::@return main::@return: scope:[main] from main return to:@return irq: scope:[irq] from *((byte*) BGCOL#0) ← (byte) WHITE#0 *((byte*) BGCOL#0) ← (byte) BLACK#0 *((byte*) IRQ_STATUS#0) ← (byte) IRQ_RASTER#0 to:irq::@return irq::@return: scope:[irq] from irq return to:@return @2: scope:[] from @begin call main to:@3 @3: scope:[] from @2 to:@end @end: scope:[] from @3 SYMBOL TABLE SSA (label) @2 (label) @3 (label) @begin (label) @end (byte*) BGCOL (byte*) BGCOL#0 (byte) BLACK (byte) BLACK#0 (byte*) CIA1_INTERRUPT (byte*) CIA1_INTERRUPT#0 (byte) CIA_INTERRUPT_CLEAR (byte) CIA_INTERRUPT_CLEAR#0 (byte) IRQ_COLLISION_BG (byte) IRQ_COLLISION_BG#0 (byte) IRQ_COLLISION_SPRITE (byte) IRQ_COLLISION_SPRITE#0 (byte*) IRQ_ENABLE (byte*) IRQ_ENABLE#0 (byte) IRQ_LIGHTPEN (byte) IRQ_LIGHTPEN#0 (byte) IRQ_RASTER (byte) IRQ_RASTER#0 (byte*) IRQ_STATUS (byte*) IRQ_STATUS#0 (void()**) KERNEL_IRQ (void()**) KERNEL_IRQ#0 (byte*) RASTER (byte*) RASTER#0 (byte*) VIC_CONTROL (byte*) VIC_CONTROL#0 (byte) WHITE (byte) WHITE#0 interrupt(KERNEL_MIN)(void()) irq() (label) irq::@return (void()) main() (void()*~) main::$0 (label) main::@return Culled Empty Block (label) @3 Successful SSA optimization Pass2CullEmptyBlocks Constant (const void()**) KERNEL_IRQ#0 = ((void()**))788 Constant (const byte*) RASTER#0 = ((byte*))53266 Constant (const byte*) VIC_CONTROL#0 = ((byte*))53265 Constant (const byte*) IRQ_STATUS#0 = ((byte*))53273 Constant (const byte*) IRQ_ENABLE#0 = ((byte*))53274 Constant (const byte) IRQ_RASTER#0 = 1 Constant (const byte) IRQ_COLLISION_BG#0 = 2 Constant (const byte) IRQ_COLLISION_SPRITE#0 = 4 Constant (const byte) IRQ_LIGHTPEN#0 = 8 Constant (const byte*) BGCOL#0 = ((byte*))53280 Constant (const byte) WHITE#0 = 1 Constant (const byte) BLACK#0 = 0 Constant (const byte*) CIA1_INTERRUPT#0 = ((byte*))56333 Constant (const byte) CIA_INTERRUPT_CLEAR#0 = 127 Constant (const void()*) main::$0 = &irq Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization PassNEliminateUnusedVars Constant inlined main::$0 = &interrupt(KERNEL_MIN)(void()) irq() Successful SSA optimization Pass2ConstantInlining Adding NOP phi() at start of @begin Adding NOP phi() at start of @2 Adding NOP phi() at start of @end CALL GRAPH Calls in [] to main:2 Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes Adding NOP phi() at start of @begin Adding NOP phi() at start of @2 Adding NOP phi() at start of @end FINAL CONTROL FLOW GRAPH @begin: scope:[] from [0] phi() to:@2 @2: scope:[] from @begin [1] phi() [2] call main to:@end @end: scope:[] from @2 [3] phi() main: scope:[main] from @2 asm { sei } [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() asm { cli } to:main::@return main::@return: scope:[main] from main [11] return to:@return irq: scope:[irq] from [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 to:irq::@return irq::@return: scope:[irq] from irq [15] return to:@return VARIABLE REGISTER WEIGHTS (byte*) BGCOL (byte) BLACK (byte*) CIA1_INTERRUPT (byte) CIA_INTERRUPT_CLEAR (byte) IRQ_COLLISION_BG (byte) IRQ_COLLISION_SPRITE (byte*) IRQ_ENABLE (byte) IRQ_LIGHTPEN (byte) IRQ_RASTER (byte*) IRQ_STATUS (void()**) KERNEL_IRQ (byte*) RASTER (byte*) VIC_CONTROL (byte) WHITE interrupt(KERNEL_MIN)(void()) irq() (void()) main() Initial phi equivalence classes Complete equivalence classes INITIAL ASM //SEG0 File Comments // A minimal working raster IRQ //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(bbegin) .pc = $80d "Program" //SEG2 Global Constants & labels .label KERNEL_IRQ = $314 .label RASTER = $d012 .label VIC_CONTROL = $d011 .label IRQ_STATUS = $d019 .label IRQ_ENABLE = $d01a .const IRQ_RASTER = 1 .label BGCOL = $d020 .const WHITE = 1 .const BLACK = 0 .label CIA1_INTERRUPT = $dc0d .const CIA_INTERRUPT_CLEAR = $7f //SEG3 @begin bbegin: //SEG4 [1] phi from @begin to @2 [phi:@begin->@2] b2_from_bbegin: jmp b2 //SEG5 @2 b2: //SEG6 [2] call main jsr main //SEG7 [3] phi from @2 to @end [phi:@2->@end] bend_from_b2: jmp bend //SEG8 @end bend: //SEG9 main main: { //SEG10 asm { sei } sei //SEG11 [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2 // Disable CIA 1 Timer IRQ lda #CIA_INTERRUPT_CLEAR sta CIA1_INTERRUPT //SEG12 [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 // Set raster line to $100 lda VIC_CONTROL ora #$80 sta VIC_CONTROL //SEG13 [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 lda #0 sta RASTER //SEG14 [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 // Enable Raster Interrupt lda #IRQ_RASTER sta IRQ_ENABLE //SEG15 [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2 // Set the IRQ routine lda #irq sta KERNEL_IRQ+1 //SEG16 asm { cli } cli jmp breturn //SEG17 main::@return breturn: //SEG18 [11] return rts } //SEG19 irq // Interrupt Routine irq: { //SEG20 entry interrupt(KERNEL_MIN) //SEG21 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 lda #WHITE sta BGCOL //SEG22 [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 lda #BLACK sta BGCOL //SEG23 [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 // Acknowledge the IRQ lda #IRQ_RASTER sta IRQ_STATUS jmp breturn //SEG24 irq::@return breturn: //SEG25 [15] return - exit interrupt(KERNEL_MIN) jmp $ea81 } REGISTER UPLIFT POTENTIAL REGISTERS Statement [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( [ ] ) always clobbers reg byte a Statement [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( [ ] ) always clobbers reg byte a Statement [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 [ ] ( [ ] ) always clobbers reg byte a REGISTER UPLIFT SCOPES Uplift Scope [main] Uplift Scope [irq] Uplift Scope [] Uplifting [main] best 89 combination Uplifting [irq] best 89 combination Uplifting [] best 89 combination ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments // A minimal working raster IRQ //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(bbegin) .pc = $80d "Program" //SEG2 Global Constants & labels .label KERNEL_IRQ = $314 .label RASTER = $d012 .label VIC_CONTROL = $d011 .label IRQ_STATUS = $d019 .label IRQ_ENABLE = $d01a .const IRQ_RASTER = 1 .label BGCOL = $d020 .const WHITE = 1 .const BLACK = 0 .label CIA1_INTERRUPT = $dc0d .const CIA_INTERRUPT_CLEAR = $7f //SEG3 @begin bbegin: //SEG4 [1] phi from @begin to @2 [phi:@begin->@2] b2_from_bbegin: jmp b2 //SEG5 @2 b2: //SEG6 [2] call main jsr main //SEG7 [3] phi from @2 to @end [phi:@2->@end] bend_from_b2: jmp bend //SEG8 @end bend: //SEG9 main main: { //SEG10 asm { sei } sei //SEG11 [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2 // Disable CIA 1 Timer IRQ lda #CIA_INTERRUPT_CLEAR sta CIA1_INTERRUPT //SEG12 [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 // Set raster line to $100 lda VIC_CONTROL ora #$80 sta VIC_CONTROL //SEG13 [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 lda #0 sta RASTER //SEG14 [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 // Enable Raster Interrupt lda #IRQ_RASTER sta IRQ_ENABLE //SEG15 [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2 // Set the IRQ routine lda #irq sta KERNEL_IRQ+1 //SEG16 asm { cli } cli jmp breturn //SEG17 main::@return breturn: //SEG18 [11] return rts } //SEG19 irq // Interrupt Routine irq: { //SEG20 entry interrupt(KERNEL_MIN) //SEG21 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 lda #WHITE sta BGCOL //SEG22 [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 lda #BLACK sta BGCOL //SEG23 [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 // Acknowledge the IRQ lda #IRQ_RASTER sta IRQ_STATUS jmp breturn //SEG24 irq::@return breturn: //SEG25 [15] return - exit interrupt(KERNEL_MIN) jmp $ea81 } ASSEMBLER OPTIMIZATIONS Removing instruction jmp b2 Removing instruction jmp bend Removing instruction jmp breturn Removing instruction jmp breturn Succesful ASM optimization Pass5NextJumpElimination Removing instruction b2_from_bbegin: Removing instruction b2: Removing instruction bend_from_b2: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction bend: Removing instruction breturn: Removing instruction breturn: Succesful ASM optimization Pass5UnusedLabelElimination Updating BasicUpstart to call main directly Removing instruction jsr main Succesful ASM optimization Pass5SkipBegin Removing instruction bbegin: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE (label) @2 (label) @begin (label) @end (byte*) BGCOL (const byte*) BGCOL#0 BGCOL = ((byte*))(word/dword/signed dword) 53280 (byte) BLACK (const byte) BLACK#0 BLACK = (byte/signed byte/word/signed word/dword/signed dword) 0 (byte*) CIA1_INTERRUPT (const byte*) CIA1_INTERRUPT#0 CIA1_INTERRUPT = ((byte*))(word/dword/signed dword) 56333 (byte) CIA_INTERRUPT_CLEAR (const byte) CIA_INTERRUPT_CLEAR#0 CIA_INTERRUPT_CLEAR = (byte/signed byte/word/signed word/dword/signed dword) 127 (byte) IRQ_COLLISION_BG (byte) IRQ_COLLISION_SPRITE (byte*) IRQ_ENABLE (const byte*) IRQ_ENABLE#0 IRQ_ENABLE = ((byte*))(word/dword/signed dword) 53274 (byte) IRQ_LIGHTPEN (byte) IRQ_RASTER (const byte) IRQ_RASTER#0 IRQ_RASTER = (byte/signed byte/word/signed word/dword/signed dword) 1 (byte*) IRQ_STATUS (const byte*) IRQ_STATUS#0 IRQ_STATUS = ((byte*))(word/dword/signed dword) 53273 (void()**) KERNEL_IRQ (const void()**) KERNEL_IRQ#0 KERNEL_IRQ = ((void()**))(word/signed word/dword/signed dword) 788 (byte*) RASTER (const byte*) RASTER#0 RASTER = ((byte*))(word/dword/signed dword) 53266 (byte*) VIC_CONTROL (const byte*) VIC_CONTROL#0 VIC_CONTROL = ((byte*))(word/dword/signed dword) 53265 (byte) WHITE (const byte) WHITE#0 WHITE = (byte/signed byte/word/signed word/dword/signed dword) 1 interrupt(KERNEL_MIN)(void()) irq() (label) irq::@return (void()) main() (label) main::@return FINAL ASSEMBLER Score: 71 //SEG0 File Comments // A minimal working raster IRQ //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" //SEG2 Global Constants & labels .label KERNEL_IRQ = $314 .label RASTER = $d012 .label VIC_CONTROL = $d011 .label IRQ_STATUS = $d019 .label IRQ_ENABLE = $d01a .const IRQ_RASTER = 1 .label BGCOL = $d020 .const WHITE = 1 .const BLACK = 0 .label CIA1_INTERRUPT = $dc0d .const CIA_INTERRUPT_CLEAR = $7f //SEG3 @begin //SEG4 [1] phi from @begin to @2 [phi:@begin->@2] //SEG5 @2 //SEG6 [2] call main //SEG7 [3] phi from @2 to @end [phi:@2->@end] //SEG8 @end //SEG9 main main: { //SEG10 asm { sei } sei //SEG11 [5] *((const byte*) CIA1_INTERRUPT#0) ← (const byte) CIA_INTERRUPT_CLEAR#0 -- _deref_pbuc1=vbuc2 // Disable CIA 1 Timer IRQ lda #CIA_INTERRUPT_CLEAR sta CIA1_INTERRUPT //SEG12 [6] *((const byte*) VIC_CONTROL#0) ← *((const byte*) VIC_CONTROL#0) | (byte/word/signed word/dword/signed dword) 128 -- _deref_pbuc1=_deref_pbuc1_bor_vbuc2 // Set raster line to $100 lda VIC_CONTROL ora #$80 sta VIC_CONTROL //SEG13 [7] *((const byte*) RASTER#0) ← (byte/signed byte/word/signed word/dword/signed dword) 0 -- _deref_pbuc1=vbuc2 lda #0 sta RASTER //SEG14 [8] *((const byte*) IRQ_ENABLE#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 // Enable Raster Interrupt lda #IRQ_RASTER sta IRQ_ENABLE //SEG15 [9] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_MIN)(void()) irq() -- _deref_pptc1=pprc2 // Set the IRQ routine lda #irq sta KERNEL_IRQ+1 //SEG16 asm { cli } cli //SEG17 main::@return //SEG18 [11] return rts } //SEG19 irq // Interrupt Routine irq: { //SEG20 entry interrupt(KERNEL_MIN) //SEG21 [12] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 lda #WHITE sta BGCOL //SEG22 [13] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 lda #BLACK sta BGCOL //SEG23 [14] *((const byte*) IRQ_STATUS#0) ← (const byte) IRQ_RASTER#0 -- _deref_pbuc1=vbuc2 // Acknowledge the IRQ lda #IRQ_RASTER sta IRQ_STATUS //SEG24 irq::@return //SEG25 [15] return - exit interrupt(KERNEL_MIN) jmp $ea81 }