Resolving sizeof() main::$0 = sizeof main::p Resolving sizeof() main::$2 = sizeof main::c CONTROL FLOW GRAPH SSA void main() main: scope:[main] from __start main::idx#0 = 0 SCREEN[main::idx#0] = '0'+(byte)SIZEOF_STRUCT_POINT main::idx#1 = ++ main::idx#0 SCREEN[main::idx#1] = '0'+(byte)SIZEOF_STRUCT_CIRCLE main::idx#2 = ++ main::idx#1 main::idx#3 = ++ main::idx#2 main::$0 = SIZEOF_STRUCT_POINT main::$14 = (byte)main::$0 main::$1 = '0' + main::$14 SCREEN[main::idx#3] = main::$1 main::idx#4 = ++ main::idx#3 main::$2 = SIZEOF_STRUCT_CIRCLE main::$15 = (byte)main::$2 main::$3 = '0' + main::$15 SCREEN[main::idx#4] = main::$3 main::idx#5 = ++ main::idx#4 main::idx#6 = ++ main::idx#5 main::$4 = sizeof main::points main::$16 = (byte)main::$4 main::$5 = '0' + main::$16 SCREEN[main::idx#6] = main::$5 main::idx#7 = ++ main::idx#6 main::$6 = sizeof main::points main::$7 = main::$6 / SIZEOF_STRUCT_POINT main::$17 = (byte)main::$7 main::$8 = '0' + main::$17 SCREEN[main::idx#7] = main::$8 main::idx#8 = ++ main::idx#7 main::$9 = sizeof main::circles main::$18 = (byte)main::$9 main::$10 = '0' + main::$18 SCREEN[main::idx#8] = main::$10 main::idx#9 = ++ main::idx#8 main::$11 = sizeof main::circles main::$12 = main::$11 / SIZEOF_STRUCT_CIRCLE main::$19 = (byte)main::$12 main::$13 = '0' + main::$19 SCREEN[main::idx#9] = main::$13 main::idx#10 = ++ main::idx#9 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 byte* const SCREEN = (byte*)$400 constant byte SIZEOF_STRUCT_CIRCLE = 3 constant byte SIZEOF_STRUCT_POINT = 2 void __start() void main() word~ main::$0 byte~ main::$1 byte~ main::$10 word~ main::$11 word~ main::$12 byte~ main::$13 byte~ main::$14 byte~ main::$15 byte~ main::$16 byte~ main::$17 byte~ main::$18 byte~ main::$19 word~ main::$2 byte~ main::$3 word~ main::$4 byte~ main::$5 word~ main::$6 word~ main::$7 byte~ main::$8 word~ main::$9 constant const byte main::NUM_CIRCLES = (byte)main::NUM_POINTS-1 constant const byte main::NUM_POINTS = 4 struct Point main::c_center constant struct Circle* main::circles[main::NUM_CIRCLES] = { fill( main::NUM_CIRCLES, 0) } byte main::idx byte main::idx#0 byte main::idx#1 byte main::idx#10 byte main::idx#2 byte main::idx#3 byte main::idx#4 byte main::idx#5 byte main::idx#6 byte main::idx#7 byte main::idx#8 byte main::idx#9 constant struct Point* main::points[main::NUM_POINTS] = { fill( main::NUM_POINTS, 0) } Adding number conversion cast (unumber) 1 in Successful SSA optimization PassNAddNumberTypeConversions Simplifying constant pointer cast (byte*) 1024 Simplifying constant integer cast 1 Simplifying constant integer cast SIZEOF_STRUCT_POINT Simplifying constant integer cast SIZEOF_STRUCT_CIRCLE Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 1 Successful SSA optimization PassNFinalizeNumberTypeConversions Constant right-side identified [17] main::$4 = sizeof main::points Constant right-side identified [22] main::$6 = sizeof main::points Constant right-side identified [28] main::$9 = sizeof main::circles Constant right-side identified [33] main::$11 = sizeof main::circles Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::idx#0 = 0 Constant main::$0 = SIZEOF_STRUCT_POINT Constant main::$2 = SIZEOF_STRUCT_CIRCLE Constant main::$4 = sizeof main::points Constant main::$6 = sizeof main::points Constant main::$9 = sizeof main::circles Constant main::$11 = sizeof main::circles Successful SSA optimization Pass2ConstantIdentification Constant main::$14 = (byte)main::$0 Constant main::$15 = (byte)main::$2 Constant main::$16 = (byte)main::$4 Constant main::$18 = (byte)main::$9 Successful SSA optimization Pass2ConstantIdentification Simplifying expression containing zero SCREEN in [1] SCREEN[main::idx#0] = '0'+SIZEOF_STRUCT_POINT Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused variable main::idx#10 and assignment [27] main::idx#10 = ++ main::idx#9 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 Simplifying constant integer cast main::NUM_POINTS-1 Successful SSA optimization PassNCastSimplification Resolving array sizeof() sizeof main::points Resolving array sizeof() sizeof main::points Resolving array sizeof() sizeof main::circles Resolving array sizeof() sizeof main::circles Successful SSA optimization PassNSizeOfSimplification Constant right-side identified [1] main::idx#1 = ++ main::idx#0 Constant right-side identified [5] main::$1 = '0' + main::$14 Constant right-side identified [8] main::$3 = '0' + main::$15 Constant right-side identified [12] main::$5 = '0' + main::$16 Constant right-side identified [15] main::$7 = main::$6 / SIZEOF_STRUCT_POINT Constant right-side identified [20] main::$10 = '0' + main::$18 Constant right-side identified [23] main::$12 = main::$11 / SIZEOF_STRUCT_CIRCLE Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::idx#1 = ++main::idx#0 Constant main::$1 = '0'+main::$14 Constant main::$3 = '0'+main::$15 Constant main::$5 = '0'+main::$16 Constant main::$7 = main::$6/SIZEOF_STRUCT_POINT Constant main::$10 = '0'+main::$18 Constant main::$12 = main::$11/SIZEOF_STRUCT_CIRCLE Successful SSA optimization Pass2ConstantIdentification Constant main::$17 = (byte)main::$7 Constant main::$19 = (byte)main::$12 Successful SSA optimization Pass2ConstantIdentification Eliminating unused constant main::points Eliminating unused constant main::circles Successful SSA optimization PassNEliminateUnusedVars Constant right-side identified [2] main::idx#2 = ++ main::idx#1 Constant right-side identified [11] main::$8 = '0' + main::$17 Constant right-side identified [16] main::$13 = '0' + main::$19 Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::idx#2 = ++main::idx#1 Constant main::$8 = '0'+main::$17 Constant main::$13 = '0'+main::$19 Successful SSA optimization Pass2ConstantIdentification Constant right-side identified [2] main::idx#3 = ++ main::idx#2 Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::idx#3 = ++main::idx#2 Successful SSA optimization Pass2ConstantIdentification Constant right-side identified [3] main::idx#4 = ++ main::idx#3 Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::idx#4 = ++main::idx#3 Successful SSA optimization Pass2ConstantIdentification Constant right-side identified [4] main::idx#5 = ++ main::idx#4 Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::idx#5 = ++main::idx#4 Successful SSA optimization Pass2ConstantIdentification Constant right-side identified [4] main::idx#6 = ++ main::idx#5 Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::idx#6 = ++main::idx#5 Successful SSA optimization Pass2ConstantIdentification Constant right-side identified [5] main::idx#7 = ++ main::idx#6 Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::idx#7 = ++main::idx#6 Successful SSA optimization Pass2ConstantIdentification Constant right-side identified [6] main::idx#8 = ++ main::idx#7 Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::idx#8 = ++main::idx#7 Successful SSA optimization Pass2ConstantIdentification Constant right-side identified [7] main::idx#9 = ++ main::idx#8 Successful SSA optimization Pass2ConstantRValueConsolidation Constant main::idx#9 = ++main::idx#8 Successful SSA optimization Pass2ConstantIdentification Inlining constant with different constant siblings main::idx#0 Inlining constant with different constant siblings main::idx#1 Inlining constant with different constant siblings main::idx#2 Inlining constant with different constant siblings main::idx#3 Inlining constant with different constant siblings main::idx#4 Inlining constant with different constant siblings main::idx#5 Inlining constant with different constant siblings main::idx#6 Inlining constant with different constant siblings main::idx#7 Inlining constant with different constant siblings main::idx#8 Inlining constant with different constant siblings main::idx#9 Constant inlined main::$12 = main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE/SIZEOF_STRUCT_CIRCLE Constant inlined main::$13 = '0'+(byte)main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE/SIZEOF_STRUCT_CIRCLE Constant inlined main::$14 = (byte)SIZEOF_STRUCT_POINT Constant inlined main::$15 = (byte)SIZEOF_STRUCT_CIRCLE Constant inlined main::$10 = '0'+(byte)main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE Constant inlined main::$11 = main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE Constant inlined main::$16 = (byte)main::NUM_POINTS*SIZEOF_STRUCT_POINT Constant inlined main::$17 = (byte)main::NUM_POINTS*SIZEOF_STRUCT_POINT/SIZEOF_STRUCT_POINT Constant inlined main::$18 = (byte)main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE Constant inlined main::$19 = (byte)main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE/SIZEOF_STRUCT_CIRCLE Constant inlined main::idx#0 = 0 Constant inlined main::idx#1 = ++0 Constant inlined main::idx#2 = ++++0 Constant inlined main::$1 = '0'+(byte)SIZEOF_STRUCT_POINT Constant inlined main::idx#3 = ++++++0 Constant inlined main::$2 = SIZEOF_STRUCT_CIRCLE Constant inlined main::idx#4 = ++++++++0 Constant inlined main::idx#5 = ++++++++++0 Constant inlined main::$0 = SIZEOF_STRUCT_POINT Constant inlined main::idx#6 = ++++++++++++0 Constant inlined main::$5 = '0'+(byte)main::NUM_POINTS*SIZEOF_STRUCT_POINT Constant inlined main::idx#7 = ++++++++++++++0 Constant inlined main::$6 = main::NUM_POINTS*SIZEOF_STRUCT_POINT Constant inlined main::idx#8 = ++++++++++++++++0 Constant inlined main::$3 = '0'+(byte)SIZEOF_STRUCT_CIRCLE Constant inlined main::idx#9 = ++++++++++++++++++0 Constant inlined main::$4 = main::NUM_POINTS*SIZEOF_STRUCT_POINT Constant inlined main::$9 = main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE Constant inlined main::$7 = main::NUM_POINTS*SIZEOF_STRUCT_POINT/SIZEOF_STRUCT_POINT Constant inlined main::$8 = '0'+(byte)main::NUM_POINTS*SIZEOF_STRUCT_POINT/SIZEOF_STRUCT_POINT Successful SSA optimization Pass2ConstantInlining Consolidated array index constant in *(SCREEN+++0) Consolidated array index constant in *(SCREEN+++++++0) Consolidated array index constant in *(SCREEN+++++++++0) Consolidated array index constant in *(SCREEN+++++++++++++0) Consolidated array index constant in *(SCREEN+++++++++++++++0) Consolidated array index constant in *(SCREEN+++++++++++++++++0) Consolidated array index constant in *(SCREEN+++++++++++++++++++0) Successful SSA optimization Pass2ConstantAdditionElimination Simplifying constant integer increment ++0 Simplifying constant integer increment ++0 Simplifying constant integer increment ++1 Simplifying constant integer increment ++2 Simplifying constant integer increment ++3 Simplifying constant integer increment ++4 Simplifying constant integer increment ++5 Successful SSA optimization Pass2ConstantSimplification Simplifying constant integer increment ++2 Simplifying constant integer increment ++3 Simplifying constant integer increment ++5 Simplifying constant integer increment ++6 Simplifying constant integer increment ++6 Simplifying constant integer increment ++7 Successful SSA optimization Pass2ConstantSimplification Simplifying constant integer increment ++7 Simplifying constant integer increment ++8 Successful SSA optimization Pass2ConstantSimplification Simplifying constant integer cast SIZEOF_STRUCT_POINT Simplifying constant integer cast SIZEOF_STRUCT_CIRCLE Simplifying constant integer cast main::NUM_POINTS*SIZEOF_STRUCT_POINT Simplifying constant integer cast main::NUM_POINTS*SIZEOF_STRUCT_POINT/SIZEOF_STRUCT_POINT Simplifying constant integer cast main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE Simplifying constant integer cast main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE/SIZEOF_STRUCT_CIRCLE Successful SSA optimization PassNCastSimplification 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] *SCREEN = '0'+SIZEOF_STRUCT_POINT [1] *(SCREEN+1) = '0'+SIZEOF_STRUCT_CIRCLE [2] *(SCREEN+3) = '0'+SIZEOF_STRUCT_POINT [3] *(SCREEN+4) = '0'+SIZEOF_STRUCT_CIRCLE [4] *(SCREEN+6) = '0'+main::NUM_POINTS*SIZEOF_STRUCT_POINT [5] *(SCREEN+7) = '0'+main::NUM_POINTS*SIZEOF_STRUCT_POINT/SIZEOF_STRUCT_POINT [6] *(SCREEN+8) = '0'+main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE [7] *(SCREEN+9) = '0'+main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE/SIZEOF_STRUCT_CIRCLE to:main::@return main::@return: scope:[main] from main [8] return to:@return VARIABLE REGISTER WEIGHTS void main() struct Point main::c_center byte main::idx Initial phi equivalence classes Complete equivalence classes REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] *SCREEN = '0'+SIZEOF_STRUCT_POINT [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] *(SCREEN+1) = '0'+SIZEOF_STRUCT_CIRCLE [ ] ( [ ] { } ) always clobbers reg byte a Statement [2] *(SCREEN+3) = '0'+SIZEOF_STRUCT_POINT [ ] ( [ ] { } ) always clobbers reg byte a Statement [3] *(SCREEN+4) = '0'+SIZEOF_STRUCT_CIRCLE [ ] ( [ ] { } ) always clobbers reg byte a Statement [4] *(SCREEN+6) = '0'+main::NUM_POINTS*SIZEOF_STRUCT_POINT [ ] ( [ ] { } ) always clobbers reg byte a Statement [5] *(SCREEN+7) = '0'+main::NUM_POINTS*SIZEOF_STRUCT_POINT/SIZEOF_STRUCT_POINT [ ] ( [ ] { } ) always clobbers reg byte a Statement [6] *(SCREEN+8) = '0'+main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE [ ] ( [ ] { } ) always clobbers reg byte a Statement [7] *(SCREEN+9) = '0'+main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE/SIZEOF_STRUCT_CIRCLE [ ] ( [ ] { } ) always clobbers reg byte a REGISTER UPLIFT SCOPES Uplift Scope [Point] Uplift Scope [Circle] Uplift Scope [main] Uplift Scope [] Uplifting [Point] best 57 combination Uplifting [Circle] best 57 combination Uplifting [main] best 57 combination Uplifting [] best 57 combination ASSEMBLER BEFORE OPTIMIZATION // File Comments // Tests the sizeof() operator on structs // Upstart // Commodore 64 PRG executable file .file [name="sizeof-struct.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 SIZEOF_STRUCT_CIRCLE = 3 .label SCREEN = $400 .segment Code // main main: { // Struct Arrays .const NUM_POINTS = 4 .const NUM_CIRCLES = NUM_POINTS-1 // [0] *SCREEN = '0'+SIZEOF_STRUCT_POINT -- _deref_pbuc1=vbuc2 // Struct Types lda #'0'+SIZEOF_STRUCT_POINT sta SCREEN // [1] *(SCREEN+1) = '0'+SIZEOF_STRUCT_CIRCLE -- _deref_pbuc1=vbuc2 lda #'0'+SIZEOF_STRUCT_CIRCLE sta SCREEN+1 // [2] *(SCREEN+3) = '0'+SIZEOF_STRUCT_POINT -- _deref_pbuc1=vbuc2 lda #'0'+SIZEOF_STRUCT_POINT sta SCREEN+3 // [3] *(SCREEN+4) = '0'+SIZEOF_STRUCT_CIRCLE -- _deref_pbuc1=vbuc2 lda #'0'+SIZEOF_STRUCT_CIRCLE sta SCREEN+4 // [4] *(SCREEN+6) = '0'+main::NUM_POINTS*SIZEOF_STRUCT_POINT -- _deref_pbuc1=vbuc2 lda #'0'+NUM_POINTS*SIZEOF_STRUCT_POINT sta SCREEN+6 // [5] *(SCREEN+7) = '0'+main::NUM_POINTS*SIZEOF_STRUCT_POINT/SIZEOF_STRUCT_POINT -- _deref_pbuc1=vbuc2 lda #'0'+NUM_POINTS*SIZEOF_STRUCT_POINT/SIZEOF_STRUCT_POINT sta SCREEN+7 // [6] *(SCREEN+8) = '0'+main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE -- _deref_pbuc1=vbuc2 lda #'0'+NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE sta SCREEN+8 // [7] *(SCREEN+9) = '0'+main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE/SIZEOF_STRUCT_CIRCLE -- _deref_pbuc1=vbuc2 lda #'0'+NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE/SIZEOF_STRUCT_CIRCLE sta SCREEN+9 jmp __breturn // main::@return __breturn: // [8] return rts } // File Data ASSEMBLER OPTIMIZATIONS Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE constant byte* const SCREEN = (byte*) 1024 constant byte SIZEOF_STRUCT_CIRCLE = 3 constant byte SIZEOF_STRUCT_POINT = 2 void main() constant const byte main::NUM_CIRCLES = main::NUM_POINTS-1 constant const byte main::NUM_POINTS = 4 struct Point main::c_center byte main::idx FINAL ASSEMBLER Score: 54 // File Comments // Tests the sizeof() operator on structs // Upstart // Commodore 64 PRG executable file .file [name="sizeof-struct.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 SIZEOF_STRUCT_CIRCLE = 3 .label SCREEN = $400 .segment Code // main main: { // Struct Arrays .const NUM_POINTS = 4 .const NUM_CIRCLES = NUM_POINTS-1 // SCREEN[idx++] = '0'+(char)sizeof(struct Point) // [0] *SCREEN = '0'+SIZEOF_STRUCT_POINT -- _deref_pbuc1=vbuc2 // Struct Types lda #'0'+SIZEOF_STRUCT_POINT sta SCREEN // SCREEN[idx++] = '0'+(char)sizeof(struct Circle) // [1] *(SCREEN+1) = '0'+SIZEOF_STRUCT_CIRCLE -- _deref_pbuc1=vbuc2 lda #'0'+SIZEOF_STRUCT_CIRCLE sta SCREEN+1 // SCREEN[idx++] = '0'+(char)sizeof(p) // [2] *(SCREEN+3) = '0'+SIZEOF_STRUCT_POINT -- _deref_pbuc1=vbuc2 lda #'0'+SIZEOF_STRUCT_POINT sta SCREEN+3 // SCREEN[idx++] = '0'+(char)sizeof(c) // [3] *(SCREEN+4) = '0'+SIZEOF_STRUCT_CIRCLE -- _deref_pbuc1=vbuc2 lda #'0'+SIZEOF_STRUCT_CIRCLE sta SCREEN+4 // SCREEN[idx++] = '0'+(char)sizeof(points) // [4] *(SCREEN+6) = '0'+main::NUM_POINTS*SIZEOF_STRUCT_POINT -- _deref_pbuc1=vbuc2 lda #'0'+NUM_POINTS*SIZEOF_STRUCT_POINT sta SCREEN+6 // SCREEN[idx++] = '0'+(char)(sizeof(points)/sizeof(struct Point)) // [5] *(SCREEN+7) = '0'+main::NUM_POINTS*SIZEOF_STRUCT_POINT/SIZEOF_STRUCT_POINT -- _deref_pbuc1=vbuc2 lda #'0'+NUM_POINTS*SIZEOF_STRUCT_POINT/SIZEOF_STRUCT_POINT sta SCREEN+7 // SCREEN[idx++] = '0'+(char)(sizeof(circles)) // [6] *(SCREEN+8) = '0'+main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE -- _deref_pbuc1=vbuc2 lda #'0'+NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE sta SCREEN+8 // SCREEN[idx++] = '0'+(char)(sizeof(circles)/sizeof(struct Circle)) // [7] *(SCREEN+9) = '0'+main::NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE/SIZEOF_STRUCT_CIRCLE -- _deref_pbuc1=vbuc2 lda #'0'+NUM_CIRCLES*SIZEOF_STRUCT_CIRCLE/SIZEOF_STRUCT_CIRCLE sta SCREEN+9 // main::@return // } // [8] return rts } // File Data