Resolved forward reference irq to interrupt(KERNEL_KEYBOARD)(void()) irq() Adding pointer type conversion cast (byte*) PROCPORT_DDR in (byte*) PROCPORT_DDR ← (number) 0 Adding pointer type conversion cast (byte*) PROCPORT in (byte*) PROCPORT ← (number) 1 Adding pointer type conversion cast (byte*) CHARGEN in (byte*) CHARGEN ← (number) $d000 Adding pointer type conversion cast (byte*) SPRITES_XPOS in (byte*) SPRITES_XPOS ← (number) $d000 Adding pointer type conversion cast (byte*) SPRITES_YPOS in (byte*) SPRITES_YPOS ← (number) $d001 Adding pointer type conversion cast (byte*) SPRITES_XMSB in (byte*) SPRITES_XMSB ← (number) $d010 Adding pointer type conversion cast (byte*) RASTER in (byte*) RASTER ← (number) $d012 Adding pointer type conversion cast (byte*) SPRITES_ENABLE in (byte*) SPRITES_ENABLE ← (number) $d015 Adding pointer type conversion cast (byte*) SPRITES_EXPAND_Y in (byte*) SPRITES_EXPAND_Y ← (number) $d017 Adding pointer type conversion cast (byte*) SPRITES_PRIORITY in (byte*) SPRITES_PRIORITY ← (number) $d01b Adding pointer type conversion cast (byte*) SPRITES_MC in (byte*) SPRITES_MC ← (number) $d01c Adding pointer type conversion cast (byte*) SPRITES_EXPAND_X in (byte*) SPRITES_EXPAND_X ← (number) $d01d Adding pointer type conversion cast (byte*) BORDERCOL in (byte*) BORDERCOL ← (number) $d020 Adding pointer type conversion cast (byte*) BGCOL in (byte*) BGCOL ← (number) $d021 Adding pointer type conversion cast (byte*) BGCOL1 in (byte*) BGCOL1 ← (number) $d021 Adding pointer type conversion cast (byte*) BGCOL2 in (byte*) BGCOL2 ← (number) $d022 Adding pointer type conversion cast (byte*) BGCOL3 in (byte*) BGCOL3 ← (number) $d023 Adding pointer type conversion cast (byte*) BGCOL4 in (byte*) BGCOL4 ← (number) $d024 Adding pointer type conversion cast (byte*) SPRITES_MC1 in (byte*) SPRITES_MC1 ← (number) $d025 Adding pointer type conversion cast (byte*) SPRITES_MC2 in (byte*) SPRITES_MC2 ← (number) $d026 Adding pointer type conversion cast (byte*) SPRITES_COLS in (byte*) SPRITES_COLS ← (number) $d027 Adding pointer type conversion cast (byte*) VIC_CONTROL in (byte*) VIC_CONTROL ← (number) $d011 Adding pointer type conversion cast (byte*) D011 in (byte*) D011 ← (number) $d011 Adding pointer type conversion cast (byte*) VIC_CONTROL2 in (byte*) VIC_CONTROL2 ← (number) $d016 Adding pointer type conversion cast (byte*) D016 in (byte*) D016 ← (number) $d016 Adding pointer type conversion cast (byte*) D018 in (byte*) D018 ← (number) $d018 Adding pointer type conversion cast (byte*) VIC_MEMORY in (byte*) VIC_MEMORY ← (number) $d018 Adding pointer type conversion cast (byte*) LIGHTPEN_X in (byte*) LIGHTPEN_X ← (number) $d013 Adding pointer type conversion cast (byte*) LIGHTPEN_Y in (byte*) LIGHTPEN_Y ← (number) $d014 Adding pointer type conversion cast (byte*) IRQ_STATUS in (byte*) IRQ_STATUS ← (number) $d019 Adding pointer type conversion cast (byte*) IRQ_ENABLE in (byte*) IRQ_ENABLE ← (number) $d01a Adding pointer type conversion cast (byte*) COLS in (byte*) COLS ← (number) $d800 Adding pointer type conversion cast (byte*) CIA1_PORT_A in (byte*) CIA1_PORT_A ← (number) $dc00 Adding pointer type conversion cast (byte*) CIA1_PORT_B in (byte*) CIA1_PORT_B ← (number) $dc01 Adding pointer type conversion cast (byte*) CIA1_PORT_A_DDR in (byte*) CIA1_PORT_A_DDR ← (number) $dc02 Adding pointer type conversion cast (byte*) CIA1_PORT_B_DDR in (byte*) CIA1_PORT_B_DDR ← (number) $dc03 Adding pointer type conversion cast (byte*) CIA1_INTERRUPT in (byte*) CIA1_INTERRUPT ← (number) $dc0d Adding pointer type conversion cast (byte*) CIA2_PORT_A in (byte*) CIA2_PORT_A ← (number) $dd00 Adding pointer type conversion cast (byte*) CIA2_PORT_B in (byte*) CIA2_PORT_B ← (number) $dd01 Adding pointer type conversion cast (byte*) CIA2_PORT_A_DDR in (byte*) CIA2_PORT_A_DDR ← (number) $dd02 Adding pointer type conversion cast (byte*) CIA2_PORT_B_DDR in (byte*) CIA2_PORT_B_DDR ← (number) $dd03 Adding pointer type conversion cast (byte*) CIA2_INTERRUPT in (byte*) CIA2_INTERRUPT ← (number) $dd0d Adding pointer type conversion cast (void()**) KERNEL_IRQ in (void()**) KERNEL_IRQ ← (number) $314 Adding pointer type conversion cast (void()**) HARDWARE_IRQ in (void()**) HARDWARE_IRQ ← (number) $fffe Inlined call [105] (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx Culled Empty Block (label) @1 Culled Empty Block (label) @2 Culled Empty Block (label) @3 Culled Empty Block (label) @4 Culled Empty Block (label) @5 CONTROL FLOW GRAPH SSA @begin: scope:[] from (byte*) BGCOL#0 ← ((byte*)) (number) $d021 (void()**) KERNEL_IRQ#0 ← ((void()**)) (number) $314 (byte) BLACK#0 ← (number) 0 (byte) WHITE#0 ← (number) 1 to:@6 main: scope:[main] from @6 asm { sei } (void()*~) main::$0 ← & interrupt(KERNEL_KEYBOARD)(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 to:irq::@return irq::@return: scope:[irq] from irq return to:@return @6: scope:[] from @begin call main to:@7 @7: scope:[] from @6 to:@end @end: scope:[] from @7 SYMBOL TABLE SSA (label) @6 (label) @7 (label) @begin (label) @end (byte*) BGCOL (byte*) BGCOL#0 (byte) BLACK (byte) BLACK#0 (void()**) KERNEL_IRQ (void()**) KERNEL_IRQ#0 (byte) WHITE (byte) WHITE#0 interrupt(KERNEL_KEYBOARD)(void()) irq() (label) irq::@return (void()) main() (void()*~) main::$0 (label) main::@return Adding number conversion cast (unumber) 0 in (byte) BLACK#0 ← (number) 0 Adding number conversion cast (unumber) 1 in (byte) WHITE#0 ← (number) 1 Successful SSA optimization PassNAddNumberTypeConversions Inlining cast (byte*) BGCOL#0 ← (byte*)(number) $d021 Inlining cast (void()**) KERNEL_IRQ#0 ← (void()**)(number) $314 Inlining cast (byte) BLACK#0 ← (unumber)(number) 0 Inlining cast (byte) WHITE#0 ← (unumber)(number) 1 Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 53281 Simplifying constant pointer cast (void()**) 788 Simplifying constant integer cast 0 Simplifying constant integer cast 1 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 1 Successful SSA optimization PassNFinalizeNumberTypeConversions Constant right-side identified [5] (void()*~) main::$0 ← & interrupt(KERNEL_KEYBOARD)(void()) irq() Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte*) BGCOL#0 = (byte*) 53281 Constant (const void()**) KERNEL_IRQ#0 = (void()**) 788 Constant (const byte) BLACK#0 = 0 Constant (const byte) WHITE#0 = 1 Constant (const void()*) main::$0 = &irq Successful SSA optimization Pass2ConstantIdentification Constant inlined main::$0 = &interrupt(KERNEL_KEYBOARD)(void()) irq() Successful SSA optimization Pass2ConstantInlining Adding NOP phi() at start of @begin Adding NOP phi() at start of @6 Adding NOP phi() at start of @7 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 Culled Empty Block (label) @7 Renumbering block @6 to @1 Adding NOP phi() at start of @begin Adding NOP phi() at start of @1 Adding NOP phi() at start of @end FINAL CONTROL FLOW GRAPH @begin: scope:[] from [0] phi() to:@1 @1: scope:[] from @begin [1] phi() [2] call main to:@end @end: scope:[] from @1 [3] phi() main: scope:[main] from @1 asm { sei } [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() asm { cli } to:main::@return main::@return: scope:[main] from main [7] return to:@return irq: scope:[irq] from [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 to:irq::@return irq::@return: scope:[irq] from irq [10] return to:@return VARIABLE REGISTER WEIGHTS (byte*) BGCOL (byte) BLACK (void()**) KERNEL_IRQ (byte) WHITE interrupt(KERNEL_KEYBOARD)(void()) irq() (void()) main() Initial phi equivalence classes Complete equivalence classes INITIAL ASM //SEG0 File Comments // A minimal working IRQ //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(bbegin) .pc = $80d "Program" //SEG2 Global Constants & labels .label BGCOL = $d021 // The vector used when the KERNAL serves IRQ interrupts .label KERNEL_IRQ = $314 // The colors of the C64 .const BLACK = 0 .const WHITE = 1 //SEG3 @begin bbegin: //SEG4 [1] phi from @begin to @1 [phi:@begin->@1] b1_from_bbegin: jmp b1 //SEG5 @1 b1: //SEG6 [2] call main jsr main //SEG7 [3] phi from @1 to @end [phi:@1->@end] bend_from_b1: jmp bend //SEG8 @end bend: //SEG9 main // Setup the IRQ routine main: { //SEG10 asm { sei } sei //SEG11 [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() -- _deref_pptc1=pprc2 lda #irq sta KERNEL_IRQ+1 //SEG12 asm { cli } cli jmp breturn //SEG13 main::@return breturn: //SEG14 [7] return rts } //SEG15 irq // The Interrupt Handler irq: { //SEG16 entry interrupt(KERNEL_KEYBOARD) //SEG17 [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 lda #WHITE sta BGCOL //SEG18 [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 lda #BLACK sta BGCOL jmp breturn //SEG19 irq::@return breturn: //SEG20 [10] return - exit interrupt(KERNEL_KEYBOARD) jmp $ea31 } REGISTER UPLIFT POTENTIAL REGISTERS Statement [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 [ ] ( [ ] ) always clobbers reg byte a Statement [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( [ ] ) always clobbers reg byte a REGISTER UPLIFT SCOPES Uplift Scope [main] Uplift Scope [irq] Uplift Scope [] Uplifting [main] best 55 combination Uplifting [irq] best 55 combination Uplifting [] best 55 combination ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments // A minimal working IRQ //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(bbegin) .pc = $80d "Program" //SEG2 Global Constants & labels .label BGCOL = $d021 // The vector used when the KERNAL serves IRQ interrupts .label KERNEL_IRQ = $314 // The colors of the C64 .const BLACK = 0 .const WHITE = 1 //SEG3 @begin bbegin: //SEG4 [1] phi from @begin to @1 [phi:@begin->@1] b1_from_bbegin: jmp b1 //SEG5 @1 b1: //SEG6 [2] call main jsr main //SEG7 [3] phi from @1 to @end [phi:@1->@end] bend_from_b1: jmp bend //SEG8 @end bend: //SEG9 main // Setup the IRQ routine main: { //SEG10 asm { sei } sei //SEG11 [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() -- _deref_pptc1=pprc2 lda #irq sta KERNEL_IRQ+1 //SEG12 asm { cli } cli jmp breturn //SEG13 main::@return breturn: //SEG14 [7] return rts } //SEG15 irq // The Interrupt Handler irq: { //SEG16 entry interrupt(KERNEL_KEYBOARD) //SEG17 [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 lda #WHITE sta BGCOL //SEG18 [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 lda #BLACK sta BGCOL jmp breturn //SEG19 irq::@return breturn: //SEG20 [10] return - exit interrupt(KERNEL_KEYBOARD) jmp $ea31 } ASSEMBLER OPTIMIZATIONS Removing instruction jmp b1 Removing instruction jmp bend Removing instruction jmp breturn Removing instruction jmp breturn Succesful ASM optimization Pass5NextJumpElimination Removing instruction b1_from_bbegin: Removing instruction b1: Removing instruction bend_from_b1: 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) @1 (label) @begin (label) @end (byte*) BGCOL (const byte*) BGCOL#0 BGCOL = (byte*) 53281 (byte) BLACK (const byte) BLACK#0 BLACK = (byte) 0 (void()**) KERNEL_IRQ (const void()**) KERNEL_IRQ#0 KERNEL_IRQ = (void()**) 788 (byte) WHITE (const byte) WHITE#0 WHITE = (byte) 1 interrupt(KERNEL_KEYBOARD)(void()) irq() (label) irq::@return (void()) main() (label) main::@return FINAL ASSEMBLER Score: 37 //SEG0 File Comments // A minimal working IRQ //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" //SEG2 Global Constants & labels .label BGCOL = $d021 // The vector used when the KERNAL serves IRQ interrupts .label KERNEL_IRQ = $314 // The colors of the C64 .const BLACK = 0 .const WHITE = 1 //SEG3 @begin //SEG4 [1] phi from @begin to @1 [phi:@begin->@1] //SEG5 @1 //SEG6 [2] call main //SEG7 [3] phi from @1 to @end [phi:@1->@end] //SEG8 @end //SEG9 main // Setup the IRQ routine main: { //SEG10 asm { sei } sei //SEG11 [5] *((const void()**) KERNEL_IRQ#0) ← &interrupt(KERNEL_KEYBOARD)(void()) irq() -- _deref_pptc1=pprc2 lda #irq sta KERNEL_IRQ+1 //SEG12 asm { cli } cli //SEG13 main::@return //SEG14 [7] return rts } //SEG15 irq // The Interrupt Handler irq: { //SEG16 entry interrupt(KERNEL_KEYBOARD) //SEG17 [8] *((const byte*) BGCOL#0) ← (const byte) WHITE#0 -- _deref_pbuc1=vbuc2 lda #WHITE sta BGCOL //SEG18 [9] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 lda #BLACK sta BGCOL //SEG19 irq::@return //SEG20 [10] return - exit interrupt(KERNEL_KEYBOARD) jmp $ea31 }