CONTROL FLOW GRAPH SSA void main() main: scope:[main] from __start main::$0 = 0 * SIZEOF_STRUCT_POINT main::$8 = (char *)points + main::$0 main::$8[OFFSET_STRUCT_POINT_X] = 2 main::$1 = 0 * SIZEOF_STRUCT_POINT main::$9 = (char *)points + main::$1 main::$9[OFFSET_STRUCT_POINT_Y] = 3 main::$2 = 1 * SIZEOF_STRUCT_POINT main::$10 = (char *)points + main::$2 main::$10[OFFSET_STRUCT_POINT_X] = 5 main::$3 = 1 * SIZEOF_STRUCT_POINT main::$11 = (char *)points + main::$3 main::$11[OFFSET_STRUCT_POINT_Y] = 6 main::$4 = 0 * SIZEOF_STRUCT_POINT main::$12 = (char *)points + main::$4 main::SCREEN[0] = main::$12[OFFSET_STRUCT_POINT_X] main::$5 = 0 * SIZEOF_STRUCT_POINT main::$13 = (char *)points + main::$5 main::SCREEN[1] = main::$13[OFFSET_STRUCT_POINT_Y] main::$6 = 1 * SIZEOF_STRUCT_POINT main::$14 = (char *)points + main::$6 main::SCREEN[3] = main::$14[OFFSET_STRUCT_POINT_X] main::$7 = 1 * SIZEOF_STRUCT_POINT main::$15 = (char *)points + main::$7 main::SCREEN[4] = main::$15[OFFSET_STRUCT_POINT_Y] to:main::@return main::@return: scope:[main] from main 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 __constant char OFFSET_STRUCT_POINT_X = 0 __constant char OFFSET_STRUCT_POINT_Y = 1 __constant char SIZEOF_STRUCT_POINT = 2 void __start() void main() number main::$0 number main::$1 char *main::$10 char *main::$11 char *main::$12 char *main::$13 char *main::$14 char *main::$15 number main::$2 number main::$3 number main::$4 number main::$5 number main::$6 number main::$7 char *main::$8 char *main::$9 __constant char * const main::SCREEN = (char *)$400 __constant struct Point points[2] = { fill( 2, 0) } Adding number conversion cast (unumber) 0 in main::$0 = 0 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) main::$0 in main::$0 = (unumber)0 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) 2 in main::$8[OFFSET_STRUCT_POINT_X] = 2 Adding number conversion cast (unumber) 0 in main::$1 = 0 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) main::$1 in main::$1 = (unumber)0 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) 3 in main::$9[OFFSET_STRUCT_POINT_Y] = 3 Adding number conversion cast (unumber) 1 in main::$2 = 1 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) main::$2 in main::$2 = (unumber)1 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) 5 in main::$10[OFFSET_STRUCT_POINT_X] = 5 Adding number conversion cast (unumber) 1 in main::$3 = 1 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) main::$3 in main::$3 = (unumber)1 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) 6 in main::$11[OFFSET_STRUCT_POINT_Y] = 6 Adding number conversion cast (unumber) 0 in main::$4 = 0 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) main::$4 in main::$4 = (unumber)0 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) 0 in main::SCREEN[0] = main::$12[OFFSET_STRUCT_POINT_X] Adding number conversion cast (unumber) 0 in main::$5 = 0 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) main::$5 in main::$5 = (unumber)0 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) 1 in main::SCREEN[1] = main::$13[OFFSET_STRUCT_POINT_Y] Adding number conversion cast (unumber) 1 in main::$6 = 1 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) main::$6 in main::$6 = (unumber)1 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) 3 in main::SCREEN[3] = main::$14[OFFSET_STRUCT_POINT_X] Adding number conversion cast (unumber) 1 in main::$7 = 1 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) main::$7 in main::$7 = (unumber)1 * SIZEOF_STRUCT_POINT Adding number conversion cast (unumber) 4 in main::SCREEN[4] = main::$15[OFFSET_STRUCT_POINT_Y] Successful SSA optimization PassNAddNumberTypeConversions Inlining cast main::$8[OFFSET_STRUCT_POINT_X] = (unumber)2 Inlining cast main::$9[OFFSET_STRUCT_POINT_Y] = (unumber)3 Inlining cast main::$10[OFFSET_STRUCT_POINT_X] = (unumber)5 Inlining cast main::$11[OFFSET_STRUCT_POINT_Y] = (unumber)6 Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (char *) 1024 Simplifying constant integer cast 0 Simplifying constant integer cast 2 Simplifying constant integer cast 0 Simplifying constant integer cast 3 Simplifying constant integer cast 1 Simplifying constant integer cast 5 Simplifying constant integer cast 1 Simplifying constant integer cast 6 Simplifying constant integer cast 0 Simplifying constant integer cast 0 Simplifying constant integer cast 0 Simplifying constant integer cast 1 Simplifying constant integer cast 1 Simplifying constant integer cast 3 Simplifying constant integer cast 1 Simplifying constant integer cast 4 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 2 Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 3 Finalized unsigned number type (char) 1 Finalized unsigned number type (char) 5 Finalized unsigned number type (char) 1 Finalized unsigned number type (char) 6 Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 1 Finalized unsigned number type (char) 1 Finalized unsigned number type (char) 3 Finalized unsigned number type (char) 1 Finalized unsigned number type (char) 4 Successful SSA optimization PassNFinalizeNumberTypeConversions Inferred type updated to char in main::$0 = 0 * SIZEOF_STRUCT_POINT Inferred type updated to char in main::$1 = 0 * SIZEOF_STRUCT_POINT Inferred type updated to char in main::$2 = 1 * SIZEOF_STRUCT_POINT Inferred type updated to char in main::$3 = 1 * SIZEOF_STRUCT_POINT Inferred type updated to char in main::$4 = 0 * SIZEOF_STRUCT_POINT Inferred type updated to char in main::$5 = 0 * SIZEOF_STRUCT_POINT Inferred type updated to char in main::$6 = 1 * SIZEOF_STRUCT_POINT Inferred type updated to char in main::$7 = 1 * SIZEOF_STRUCT_POINT Constant right-side identified [0] main::$0 = 0 * SIZEOF_STRUCT_POINT Constant right-side identified [3] main::$1 = 0 * SIZEOF_STRUCT_POINT Constant right-side identified [6] main::$2 = 1 * SIZEOF_STRUCT_POINT Constant right-side identified [9] main::$3 = 1 * SIZEOF_STRUCT_POINT Constant right-side identified [12] main::$4 = 0 * SIZEOF_STRUCT_POINT Constant right-side identified [15] main::$5 = 0 * SIZEOF_STRUCT_POINT Constant right-side identified [18] main::$6 = 1 * SIZEOF_STRUCT_POINT Constant right-side identified [21] main::$7 = 1 * SIZEOF_STRUCT_POINT Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::$0 = 0*SIZEOF_STRUCT_POINT Constant main::$1 = 0*SIZEOF_STRUCT_POINT Constant main::$2 = 1*SIZEOF_STRUCT_POINT Constant main::$3 = 1*SIZEOF_STRUCT_POINT Constant main::$4 = 0*SIZEOF_STRUCT_POINT Constant main::$5 = 0*SIZEOF_STRUCT_POINT Constant main::$6 = 1*SIZEOF_STRUCT_POINT Constant main::$7 = 1*SIZEOF_STRUCT_POINT Successful SSA optimization Pass2ConstantIdentification Simplifying constant evaluating to zero 0*SIZEOF_STRUCT_POINT in Simplifying constant evaluating to zero 0*SIZEOF_STRUCT_POINT in Simplifying constant evaluating to zero 0*SIZEOF_STRUCT_POINT in Simplifying constant evaluating to zero 0*SIZEOF_STRUCT_POINT in Successful SSA optimization PassNSimplifyConstantZero Simplifying expression containing zero (char *)points in [1] main::$8 = (char *)points + main::$0 Simplifying expression containing zero main::$8 in [2] main::$8[OFFSET_STRUCT_POINT_X] = 2 Simplifying expression containing zero (char *)points in [4] main::$9 = (char *)points + main::$1 Simplifying expression containing zero main::$10 in [8] main::$10[OFFSET_STRUCT_POINT_X] = 5 Simplifying expression containing zero (char *)points in [13] main::$12 = (char *)points + main::$4 Simplifying expression containing zero main::$12 in [14] main::SCREEN[0] = main::$12[OFFSET_STRUCT_POINT_X] Simplifying expression containing zero main::SCREEN in [14] main::SCREEN[0] = *main::$12 Simplifying expression containing zero (char *)points in [16] main::$13 = (char *)points + main::$5 Simplifying expression containing zero main::$14 in [20] main::SCREEN[3] = main::$14[OFFSET_STRUCT_POINT_X] Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused constant main::$0 Eliminating unused constant main::$1 Eliminating unused constant main::$4 Eliminating unused constant main::$5 Eliminating unused constant OFFSET_STRUCT_POINT_X Successful SSA optimization PassNEliminateUnusedVars 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 Constant right-side identified [4] main::$10 = (char *)points + main::$2 Constant right-side identified [6] main::$11 = (char *)points + main::$3 Constant right-side identified [12] main::$14 = (char *)points + main::$6 Constant right-side identified [14] main::$15 = (char *)points + main::$7 Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::$8 = (char *)points Constant main::$9 = (char *)points Constant main::$10 = (char *)points+main::$2 Constant main::$11 = (char *)points+main::$3 Constant main::$12 = (char *)points Constant main::$13 = (char *)points Constant main::$14 = (char *)points+main::$6 Constant main::$15 = (char *)points+main::$7 Successful SSA optimization Pass2ConstantIdentification Constant inlined main::$2 = 1*SIZEOF_STRUCT_POINT Constant inlined main::$12 = (char *)points Constant inlined main::$6 = 1*SIZEOF_STRUCT_POINT Constant inlined main::$13 = (char *)points Constant inlined main::$3 = 1*SIZEOF_STRUCT_POINT Constant inlined main::$14 = (char *)points+1*SIZEOF_STRUCT_POINT Constant inlined main::$15 = (char *)points+1*SIZEOF_STRUCT_POINT Constant inlined main::$9 = (char *)points Constant inlined main::$7 = 1*SIZEOF_STRUCT_POINT Constant inlined main::$10 = (char *)points+1*SIZEOF_STRUCT_POINT Constant inlined main::$8 = (char *)points Constant inlined main::$11 = (char *)points+1*SIZEOF_STRUCT_POINT Successful SSA optimization Pass2ConstantInlining Consolidated array index constant in *((char *)points+OFFSET_STRUCT_POINT_Y) Consolidated array index constant in *((char *)points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) Consolidated array index constant in *((char *)points+OFFSET_STRUCT_POINT_Y) Consolidated array index constant in *(main::SCREEN+1) Consolidated array index constant in *(main::SCREEN+3) Consolidated array index constant in *((char *)points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) Consolidated array index constant in *(main::SCREEN+4) Successful SSA optimization Pass2ConstantAdditionElimination Finalized unsigned number type (char) 2 Finalized unsigned number type (char) 2 Successful SSA optimization PassNFinalizeNumberTypeConversions CALL GRAPH Created 0 initial phi equivalence classes Coalesced down to 0 phi equivalence classes FINAL CONTROL FLOW GRAPH void main() main: scope:[main] from [0] *((char *)points) = 2 [1] *((char *)points+OFFSET_STRUCT_POINT_Y) = 3 [2] *((char *)points+1*SIZEOF_STRUCT_POINT) = 5 [3] *((char *)points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = 6 [4] *main::SCREEN = *((char *)points) [5] *(main::SCREEN+1) = *((char *)points+OFFSET_STRUCT_POINT_Y) [6] *(main::SCREEN+3) = *((char *)points+1*SIZEOF_STRUCT_POINT) [7] *(main::SCREEN+4) = *((char *)points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) to:main::@return main::@return: scope:[main] from main [8] return to:@return VARIABLE REGISTER WEIGHTS void main() Initial phi equivalence classes Complete equivalence classes REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] *((char *)points) = 2 [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] *((char *)points+OFFSET_STRUCT_POINT_Y) = 3 [ ] ( [ ] { } ) always clobbers reg byte a Statement [2] *((char *)points+1*SIZEOF_STRUCT_POINT) = 5 [ ] ( [ ] { } ) always clobbers reg byte a Statement [3] *((char *)points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = 6 [ ] ( [ ] { } ) always clobbers reg byte a Statement [4] *main::SCREEN = *((char *)points) [ ] ( [ ] { } ) always clobbers reg byte a Statement [5] *(main::SCREEN+1) = *((char *)points+OFFSET_STRUCT_POINT_Y) [ ] ( [ ] { } ) always clobbers reg byte a Statement [6] *(main::SCREEN+3) = *((char *)points+1*SIZEOF_STRUCT_POINT) [ ] ( [ ] { } ) always clobbers reg byte a Statement [7] *(main::SCREEN+4) = *((char *)points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) [ ] ( [ ] { } ) always clobbers reg byte a REGISTER UPLIFT SCOPES Uplift Scope [Point] Uplift Scope [main] Uplift Scope [] Uplifting [Point] best 65 combination Uplifting [main] best 65 combination Uplifting [] best 65 combination ASSEMBLER BEFORE OPTIMIZATION // File Comments // Minimal struct - direct (constant) array access // Upstart // Commodore 64 PRG executable file .file [name="struct-ptr-7.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 .const SIZEOF_STRUCT_POINT = 2 .const OFFSET_STRUCT_POINT_Y = 1 .segment Code // main main: { .label SCREEN = $400 // [0] *((char *)points) = 2 -- _deref_pbuc1=vbuc2 lda #2 sta points // [1] *((char *)points+OFFSET_STRUCT_POINT_Y) = 3 -- _deref_pbuc1=vbuc2 lda #3 sta points+OFFSET_STRUCT_POINT_Y // [2] *((char *)points+1*SIZEOF_STRUCT_POINT) = 5 -- _deref_pbuc1=vbuc2 lda #5 sta points+1*SIZEOF_STRUCT_POINT // [3] *((char *)points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = 6 -- _deref_pbuc1=vbuc2 lda #6 sta points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y // [4] *main::SCREEN = *((char *)points) -- _deref_pbuc1=_deref_pbuc2 lda points sta SCREEN // [5] *(main::SCREEN+1) = *((char *)points+OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2 lda points+OFFSET_STRUCT_POINT_Y sta SCREEN+1 // [6] *(main::SCREEN+3) = *((char *)points+1*SIZEOF_STRUCT_POINT) -- _deref_pbuc1=_deref_pbuc2 lda points+1*SIZEOF_STRUCT_POINT sta SCREEN+3 // [7] *(main::SCREEN+4) = *((char *)points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2 lda points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y sta SCREEN+4 jmp __breturn // main::@return __breturn: // [8] return rts } // File Data .segment Data points: .fill 2*2, 0 ASSEMBLER OPTIMIZATIONS Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE __constant char OFFSET_STRUCT_POINT_Y = 1 __constant char SIZEOF_STRUCT_POINT = 2 void main() __constant char * const main::SCREEN = (char *) 1024 __constant struct Point points[2] = { fill( 2, 0) } FINAL ASSEMBLER Score: 62 // File Comments // Minimal struct - direct (constant) array access // Upstart // Commodore 64 PRG executable file .file [name="struct-ptr-7.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 .const SIZEOF_STRUCT_POINT = 2 .const OFFSET_STRUCT_POINT_Y = 1 .segment Code // main main: { .label SCREEN = $400 // points[0].x = 2 // [0] *((char *)points) = 2 -- _deref_pbuc1=vbuc2 lda #2 sta points // points[0].y = 3 // [1] *((char *)points+OFFSET_STRUCT_POINT_Y) = 3 -- _deref_pbuc1=vbuc2 lda #3 sta points+OFFSET_STRUCT_POINT_Y // points[1].x = 5 // [2] *((char *)points+1*SIZEOF_STRUCT_POINT) = 5 -- _deref_pbuc1=vbuc2 lda #5 sta points+1*SIZEOF_STRUCT_POINT // points[1].y = 6 // [3] *((char *)points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) = 6 -- _deref_pbuc1=vbuc2 lda #6 sta points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y // SCREEN[0] = points[0].x // [4] *main::SCREEN = *((char *)points) -- _deref_pbuc1=_deref_pbuc2 lda points sta SCREEN // SCREEN[1] = points[0].y // [5] *(main::SCREEN+1) = *((char *)points+OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2 lda points+OFFSET_STRUCT_POINT_Y sta SCREEN+1 // SCREEN[3] = points[1].x // [6] *(main::SCREEN+3) = *((char *)points+1*SIZEOF_STRUCT_POINT) -- _deref_pbuc1=_deref_pbuc2 lda points+1*SIZEOF_STRUCT_POINT sta SCREEN+3 // SCREEN[4] = points[1].y // [7] *(main::SCREEN+4) = *((char *)points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2 lda points+1*SIZEOF_STRUCT_POINT+OFFSET_STRUCT_POINT_Y sta SCREEN+4 // main::@return // } // [8] return rts } // File Data .segment Data points: .fill 2*2, 0