Identified literal word (word) { main::b, 0 } in (word) main::w ← { (byte) main::b, (number) 0 } Adding pointer type conversion cast (byte*) main::sc in (byte*) main::sc ← (word) main::w2 Adding pointer type conversion cast (byte*) main::pos in (byte*) main::pos ← (number) $501 Adding pointer type conversion cast (byte*) main::bgcol in (byte*) main::bgcol ← (number) $d021 Identified constant variable (byte) main::b Identified constant variable (byte*) main::pos Identified constant variable (byte*) main::bgcol Culled Empty Block (label) main::@2 Culled Empty Block (label) main::@4 CONTROL FLOW GRAPH SSA @begin: scope:[] from to:@1 main: scope:[main] from @1 (byte[]) main::bs#0 ← { (byte) 'c', (byte) 'm' } (byte) main::b#0 ← (number) 4 (word) main::w#0 ← ((word)) { (byte) main::b#0, (number) 0 } (word~) main::$0 ← ((word)) { (number) 1, (number) 1 } (word~) main::$1 ← (word~) main::$0 + (word) main::w#0 (word~) main::$2 ← ((word)) { (number) 0, (number) 0 } (word~) main::$3 ← (word~) main::$1 + (word~) main::$2 (word) main::w2#0 ← (word~) main::$3 (byte*) main::sc#0 ← ((byte*)) (word) main::w2#0 *((byte*) main::sc#0) ← *((byte[]) main::bs#0 + (number) 1) (byte*) main::pos#0 ← ((byte*)) (number) $501 (byte*) main::bgcol#0 ← ((byte*)) (number) $d021 (bool~) main::$4 ← *((byte*) main::pos#0) == (byte) 'm' if((bool~) main::$4) goto main::@1 to:main::@3 main::@1: scope:[main] from main *((byte*) main::bgcol#0) ← (number) 5 to:main::@return main::@3: scope:[main] from main *((byte*) main::bgcol#0) ← (number) 2 to:main::@return main::@return: scope:[main] from main::@1 main::@3 return to:@return @1: scope:[] from @begin call main to:@2 @2: scope:[] from @1 to:@end @end: scope:[] from @2 SYMBOL TABLE SSA (label) @1 (label) @2 (label) @begin (label) @end (void()) main() (word~) main::$0 (word~) main::$1 (word~) main::$2 (word~) main::$3 (bool~) main::$4 (label) main::@1 (label) main::@3 (label) main::@return (byte) main::b (byte) main::b#0 (byte*) main::bgcol (byte*) main::bgcol#0 (byte[]) main::bs (byte[]) main::bs#0 (byte*) main::pos (byte*) main::pos#0 (byte*) main::sc (byte*) main::sc#0 (word) main::w (word) main::w#0 (word) main::w2 (word) main::w2#0 Fixing inline constructor with main::$5 ← (byte)main::b#0 w= (byte)0 Fixing inline constructor with main::$6 ← (byte)1 w= (byte)1 Fixing inline constructor with main::$7 ← (byte)0 w= (byte)0 Successful SSA optimization Pass2FixInlineConstructorsNew Adding number conversion cast (unumber) 4 in (byte) main::b#0 ← (number) 4 Adding number conversion cast (unumber) 1 in *((byte*) main::sc#0) ← *((byte[]) main::bs#0 + (number) 1) Adding number conversion cast (unumber) 5 in *((byte*) main::bgcol#0) ← (number) 5 Adding number conversion cast (unumber) 2 in *((byte*) main::bgcol#0) ← (number) 2 Successful SSA optimization PassNAddNumberTypeConversions Inlining cast (byte) main::b#0 ← (unumber)(number) 4 Inlining cast (byte*) main::sc#0 ← (byte*)(word) main::w2#0 Inlining cast (byte*) main::pos#0 ← (byte*)(number) $501 Inlining cast (byte*) main::bgcol#0 ← (byte*)(number) $d021 Inlining cast *((byte*) main::bgcol#0) ← (unumber)(number) 5 Inlining cast *((byte*) main::bgcol#0) ← (unumber)(number) 2 Successful SSA optimization Pass2InlineCast Simplifying constant integer cast 4 Simplifying constant integer cast (byte) main::b#0 Simplifying constant integer cast 0 Simplifying constant integer cast 1 Simplifying constant integer cast 1 Simplifying constant integer cast 0 Simplifying constant integer cast 0 Simplifying constant integer cast 1 Simplifying constant pointer cast (byte*) 1281 Simplifying constant pointer cast (byte*) 53281 Simplifying constant integer cast 5 Simplifying constant integer cast 2 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 4 Finalized unsigned number type (byte) 1 Finalized unsigned number type (byte) 5 Finalized unsigned number type (byte) 2 Successful SSA optimization PassNFinalizeNumberTypeConversions Alias (word) main::w#0 = (word~) main::$5 Alias (word~) main::$0 = (word~) main::$6 Alias (word~) main::$2 = (word~) main::$7 Alias (word) main::w2#0 = (word~) main::$3 Successful SSA optimization Pass2AliasElimination Simple Condition (bool~) main::$4 [16] if(*((byte*) main::pos#0)==(byte) 'm') goto main::@1 Successful SSA optimization Pass2ConditionalJumpSimplification Constant right-side identified [0] (byte[]) main::bs#0 ← { (byte) 'c', (byte) 'm' } Constant right-side identified [4] (word~) main::$0 ← (byte) 1 w= (byte) 1 Constant right-side identified [7] (word~) main::$2 ← (byte) 0 w= (byte) 0 Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const byte[]) main::bs#0 = { 'c', 'm' } Constant (const byte) main::b#0 = 4 Constant (const byte*) main::pos#0 = (byte*) 1281 Constant (const byte*) main::bgcol#0 = (byte*) 53281 Successful SSA optimization Pass2ConstantIdentification Simplifying constant evaluating to zero (byte) 0*(number) $100+(byte) 0 in [7] (word~) main::$2 ← (byte) 0*(number) $100+(byte) 0 Successful SSA optimization PassNSimplifyConstantZero Adding number conversion cast (unumber) 1*$100+1 in (word~) main::$0 ← (byte) 1*(number) $100+(byte) 1 Adding number conversion cast (unumber) 1*$100 in (word~) main::$0 ← ((unumber)) (byte) 1*(number) $100+(byte) 1 Adding number conversion cast (unumber) $100 in (word~) main::$0 ← ((unumber)) (unumber)(byte) 1*(number) $100+(byte) 1 Adding number conversion cast (unumber) 0 in (word~) main::$2 ← (number) 0 Successful SSA optimization PassNAddNumberTypeConversions Inlining cast (word~) main::$0 ← (unumber)(unumber)(byte) 1*(unumber)(number) $100+(byte) 1 Inlining cast (word~) main::$2 ← (unumber)(number) 0 Successful SSA optimization Pass2InlineCast Simplifying constant integer cast (unumber)(byte) 1*(unumber)(number) $100+(byte) 1 Simplifying constant integer cast (byte) 1*(unumber)(number) $100 Simplifying constant integer cast $100 Simplifying constant integer cast 0 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (word) $100 Finalized unsigned number type (byte) 0 Successful SSA optimization PassNFinalizeNumberTypeConversions Constant right-side identified [0] (word) main::w#0 ← (const byte) main::b#0 w= (byte) 0 Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const word) main::$0 = 1*$100+1 Constant (const word) main::$2 = 0 Successful SSA optimization Pass2ConstantIdentification Simplifying expression containing zero main::b#0*$100 in [0] (word) main::w#0 ← (const byte) main::b#0*(number) $100+(byte) 0 Simplifying expression containing zero main::$1 in [4] (word) main::w2#0 ← (word~) main::$1 + (const word) main::$2 Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused constant (const word) main::$2 Successful SSA optimization PassNEliminateUnusedVars Adding number conversion cast (unumber) main::b#0*$100 in (word) main::w#0 ← (const byte) main::b#0*(number) $100 Adding number conversion cast (unumber) $100 in (word) main::w#0 ← ((unumber)) (const byte) main::b#0*(number) $100 Successful SSA optimization PassNAddNumberTypeConversions Inlining cast (word) main::w#0 ← (unumber)(const byte) main::b#0*(unumber)(number) $100 Successful SSA optimization Pass2InlineCast Simplifying constant integer cast (const byte) main::b#0*(unumber)(number) $100 Simplifying constant integer cast $100 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (word) $100 Successful SSA optimization PassNFinalizeNumberTypeConversions Alias (word) main::w2#0 = (word~) main::$1 Successful SSA optimization Pass2AliasElimination Constant (const word) main::w#0 = main::b#0*$100 Successful SSA optimization Pass2ConstantIdentification Constant right-side identified [0] (word) main::w2#0 ← (const word) main::$0 + (const word) main::w#0 Successful SSA optimization Pass2ConstantRValueConsolidation Constant (const word) main::w2#0 = main::$0+main::w#0 Successful SSA optimization Pass2ConstantIdentification Constant value identified (byte*)main::w2#0 in [1] (byte*) main::sc#0 ← (byte*)(const word) main::w2#0 Successful SSA optimization Pass2ConstantValues Constant (const byte*) main::sc#0 = (byte*)main::w2#0 Successful SSA optimization Pass2ConstantIdentification Constant inlined main::$0 = (byte) 1*(word) $100+(byte) 1 Successful SSA optimization Pass2ConstantInlining Consolidated array index constant in *(main::bs#0+1) Successful SSA optimization Pass2ConstantAdditionElimination Adding NOP phi() at start of @begin Adding NOP phi() at start of @1 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 Culled Empty Block (label) @2 Renumbering block main::@3 to main::@2 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 [4] *((const byte*) main::sc#0) ← *((const byte[]) main::bs#0+(byte) 1) [5] if(*((const byte*) main::pos#0)==(byte) 'm') goto main::@1 to:main::@2 main::@2: scope:[main] from main [6] *((const byte*) main::bgcol#0) ← (byte) 2 to:main::@return main::@return: scope:[main] from main::@1 main::@2 [7] return to:@return main::@1: scope:[main] from main [8] *((const byte*) main::bgcol#0) ← (byte) 5 to:main::@return VARIABLE REGISTER WEIGHTS (void()) main() (byte) main::b (byte*) main::bgcol (byte[]) main::bs (byte*) main::pos (byte*) main::sc (word) main::w (word) main::w2 Initial phi equivalence classes Complete equivalence classes INITIAL ASM //SEG0 File Comments //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(bbegin) .pc = $80d "Program" //SEG2 Global Constants & labels //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 main: { // constant byte array .const b = 4 // Test the result .label pos = $501 .label bgcol = $d021 .const w = b*$100 .const w2 = 1*$100+1+w // constant inline words inside expression .label sc = w2 //SEG10 [4] *((const byte*) main::sc#0) ← *((const byte[]) main::bs#0+(byte) 1) -- _deref_pbuc1=_deref_pbuc2 // implicit cast to (byte*) lda bs+1 sta sc //SEG11 [5] if(*((const byte*) main::pos#0)==(byte) 'm') goto main::@1 -- _deref_pbuc1_eq_vbuc2_then_la1 lda #'m' cmp pos beq b1 jmp b2 //SEG12 main::@2 b2: //SEG13 [6] *((const byte*) main::bgcol#0) ← (byte) 2 -- _deref_pbuc1=vbuc2 lda #2 sta bgcol jmp breturn //SEG14 main::@return breturn: //SEG15 [7] return rts //SEG16 main::@1 b1: //SEG17 [8] *((const byte*) main::bgcol#0) ← (byte) 5 -- _deref_pbuc1=vbuc2 lda #5 sta bgcol jmp breturn bs: .byte 'c', 'm' } REGISTER UPLIFT POTENTIAL REGISTERS Statement [4] *((const byte*) main::sc#0) ← *((const byte[]) main::bs#0+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [5] if(*((const byte*) main::pos#0)==(byte) 'm') goto main::@1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [6] *((const byte*) main::bgcol#0) ← (byte) 2 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [8] *((const byte*) main::bgcol#0) ← (byte) 5 [ ] ( main:2 [ ] ) always clobbers reg byte a REGISTER UPLIFT SCOPES Uplift Scope [main] Uplift Scope [] Uplifting [main] best 55 combination Uplifting [] best 55 combination ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(bbegin) .pc = $80d "Program" //SEG2 Global Constants & labels //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 main: { // constant byte array .const b = 4 // Test the result .label pos = $501 .label bgcol = $d021 .const w = b*$100 .const w2 = 1*$100+1+w // constant inline words inside expression .label sc = w2 //SEG10 [4] *((const byte*) main::sc#0) ← *((const byte[]) main::bs#0+(byte) 1) -- _deref_pbuc1=_deref_pbuc2 // implicit cast to (byte*) lda bs+1 sta sc //SEG11 [5] if(*((const byte*) main::pos#0)==(byte) 'm') goto main::@1 -- _deref_pbuc1_eq_vbuc2_then_la1 lda #'m' cmp pos beq b1 jmp b2 //SEG12 main::@2 b2: //SEG13 [6] *((const byte*) main::bgcol#0) ← (byte) 2 -- _deref_pbuc1=vbuc2 lda #2 sta bgcol jmp breturn //SEG14 main::@return breturn: //SEG15 [7] return rts //SEG16 main::@1 b1: //SEG17 [8] *((const byte*) main::bgcol#0) ← (byte) 5 -- _deref_pbuc1=vbuc2 lda #5 sta bgcol jmp breturn bs: .byte 'c', 'm' } ASSEMBLER OPTIMIZATIONS Removing instruction jmp b1 Removing instruction jmp bend Removing instruction jmp b2 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 b2: Succesful ASM optimization Pass5UnusedLabelElimination Updating BasicUpstart to call main directly Removing instruction jsr main Succesful ASM optimization Pass5SkipBegin Replacing jump to rts with rts in jmp breturn Succesful ASM optimization Pass5DoubleJumpElimination Removing instruction bbegin: Removing instruction breturn: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE (label) @1 (label) @begin (label) @end (void()) main() (label) main::@1 (label) main::@2 (label) main::@return (byte) main::b (const byte) main::b#0 b = (byte) 4 (byte*) main::bgcol (const byte*) main::bgcol#0 bgcol = (byte*) 53281 (byte[]) main::bs (const byte[]) main::bs#0 bs = { (byte) 'c', (byte) 'm' } (byte*) main::pos (const byte*) main::pos#0 pos = (byte*) 1281 (byte*) main::sc (const byte*) main::sc#0 sc = (byte*)(const word) main::w2#0 (word) main::w (const word) main::w#0 w = (const byte) main::b#0*(word) $100 (word) main::w2 (const word) main::w2#0 w2 = (byte) 1*(word) $100+(byte) 1+(const word) main::w#0 FINAL ASSEMBLER Score: 40 //SEG0 File Comments //SEG1 Basic Upstart .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" //SEG2 Global Constants & labels //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 main: { // constant byte array .const b = 4 // Test the result .label pos = $501 .label bgcol = $d021 .const w = b*$100 .const w2 = 1*$100+1+w // constant inline words inside expression .label sc = w2 //SEG10 [4] *((const byte*) main::sc#0) ← *((const byte[]) main::bs#0+(byte) 1) -- _deref_pbuc1=_deref_pbuc2 // implicit cast to (byte*) lda bs+1 sta sc //SEG11 [5] if(*((const byte*) main::pos#0)==(byte) 'm') goto main::@1 -- _deref_pbuc1_eq_vbuc2_then_la1 lda #'m' cmp pos beq b1 //SEG12 main::@2 //SEG13 [6] *((const byte*) main::bgcol#0) ← (byte) 2 -- _deref_pbuc1=vbuc2 lda #2 sta bgcol //SEG14 main::@return //SEG15 [7] return rts //SEG16 main::@1 b1: //SEG17 [8] *((const byte*) main::bgcol#0) ← (byte) 5 -- _deref_pbuc1=vbuc2 lda #5 sta bgcol rts bs: .byte 'c', 'm' }