Fixing struct type size struct Point to 4 Fixing struct type size struct Point to 4 Fixing struct type SIZE_OF struct Point to 4 Fixing struct type SIZE_OF struct Point to 4 CONTROL FLOW GRAPH SSA void main() main: scope:[main] from __start *main::point1_initials = memcpy(*(&$0), char, 3) SCREEN[0] = main::point1_x SCREEN[1] = main::point1_initials[0] SCREEN[2] = main::point1_initials[1] 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 $0[3] = "jg" __constant char * const SCREEN = (char *)$400 void __start() void main() __constant char main::point1_initials[3] = { fill( 3, 0) } __constant char main::point1_x = 2 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::point1_x Adding number conversion cast (unumber) 0 in SCREEN[1] = main::point1_initials[0] Adding number conversion cast (unumber) 1 in SCREEN[1] = main::point1_initials[(unumber)0] Adding number conversion cast (unumber) 1 in SCREEN[2] = main::point1_initials[1] Adding number conversion cast (unumber) 2 in SCREEN[2] = main::point1_initials[(unumber)1] Successful SSA optimization PassNAddNumberTypeConversions Simplifying constant pointer cast (char *) 1024 Simplifying constant integer cast 0 Simplifying constant integer cast 0 Simplifying constant integer cast 1 Simplifying constant integer cast 1 Simplifying constant integer cast 2 Successful SSA optimization PassNCastSimplification 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) 2 Successful SSA optimization PassNFinalizeNumberTypeConversions Simplifying expression containing zero SCREEN in [1] SCREEN[0] = main::point1_x Simplifying expression containing zero main::point1_initials in [2] SCREEN[1] = main::point1_initials[0] Successful SSA optimization PassNSimplifyExpressionWithZero 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 Consolidated array index constant in *(SCREEN+1) Consolidated array index constant in *(main::point1_initials+1) Consolidated array index constant in *(SCREEN+2) Successful SSA optimization Pass2ConstantAdditionElimination Finalized unsigned number type (char) 3 Finalized unsigned number type (char) 3 Finalized unsigned number type (char) 3 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] *main::point1_initials = memcpy(*(&$0), char, 3) [1] *SCREEN = main::point1_x [2] *(SCREEN+1) = *main::point1_initials [3] *(SCREEN+2) = *(main::point1_initials+1) to:main::@return main::@return: scope:[main] from main [4] return to:@return VARIABLE REGISTER WEIGHTS void main() Initial phi equivalence classes Complete equivalence classes REGISTER UPLIFT POTENTIAL REGISTERS Statement [0] *main::point1_initials = memcpy(*(&$0), char, 3) [ ] ( [ ] { } ) always clobbers reg byte a reg byte y Statement [1] *SCREEN = main::point1_x [ ] ( [ ] { } ) always clobbers reg byte a Statement [2] *(SCREEN+1) = *main::point1_initials [ ] ( [ ] { } ) always clobbers reg byte a Statement [3] *(SCREEN+2) = *(main::point1_initials+1) [ ] ( [ ] { } ) always clobbers reg byte a REGISTER UPLIFT SCOPES Uplift Scope [Point] Uplift Scope [main] Uplift Scope [] Uplifting [Point] best 47 combination Uplifting [main] best 47 combination Uplifting [] best 47 combination ASSEMBLER BEFORE OPTIMIZATION // File Comments // Minimal struct with MemberUnwind behavior - array member and local initializer // Upstart // Commodore 64 PRG executable file .file [name="struct-30.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 .label SCREEN = $400 .segment Code // main main: { .const point1_x = 2 // [0] *main::point1_initials = memcpy(*(&$0), char, 3) -- _deref_pbuc1=_deref_qbuc2_memcpy_vbuc3 ldy #3 !: lda __0-1,y sta point1_initials-1,y dey bne !- // [1] *SCREEN = main::point1_x -- _deref_pbuc1=vbuc2 lda #point1_x sta SCREEN // [2] *(SCREEN+1) = *main::point1_initials -- _deref_pbuc1=_deref_pbuc2 lda point1_initials sta SCREEN+1 // [3] *(SCREEN+2) = *(main::point1_initials+1) -- _deref_pbuc1=_deref_pbuc2 lda point1_initials+1 sta SCREEN+2 jmp __breturn // main::@return __breturn: // [4] return rts .segment Data point1_initials: .fill 3, 0 } // File Data __0: .text "jg" .byte 0 ASSEMBLER OPTIMIZATIONS Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination Removing instruction __breturn: Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE __constant char $0[3] = "jg" __constant char * const SCREEN = (char *) 1024 void main() __constant char main::point1_initials[3] = { fill( 3, 0) } __constant char main::point1_x = 2 FINAL ASSEMBLER Score: 44 // File Comments // Minimal struct with MemberUnwind behavior - array member and local initializer // Upstart // Commodore 64 PRG executable file .file [name="struct-30.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 .label SCREEN = $400 .segment Code // main main: { .const point1_x = 2 // struct Point point1 = { 2, "jg" } // [0] *main::point1_initials = memcpy(*(&$0), char, 3) -- _deref_pbuc1=_deref_qbuc2_memcpy_vbuc3 ldy #3 !: lda __0-1,y sta point1_initials-1,y dey bne !- // SCREEN[0] = point1.x // [1] *SCREEN = main::point1_x -- _deref_pbuc1=vbuc2 lda #point1_x sta SCREEN // SCREEN[1] = point1.initials[0] // [2] *(SCREEN+1) = *main::point1_initials -- _deref_pbuc1=_deref_pbuc2 lda point1_initials sta SCREEN+1 // SCREEN[2] = point1.initials[1] // [3] *(SCREEN+2) = *(main::point1_initials+1) -- _deref_pbuc1=_deref_pbuc2 lda point1_initials+1 sta SCREEN+2 // main::@return // } // [4] return rts .segment Data point1_initials: .fill 3, 0 } // File Data __0: .text "jg" .byte 0