Fixing struct type size struct Person to 17
Fixing struct type size struct Person to 17
Fixing struct type size struct Person to 17
Fixing struct type size struct Person to 17
Fixing struct type SIZE_OF struct Person to 17
Fixing struct type SIZE_OF struct Person to 17
Fixing constant pointer addition persons+1
Inlined call call __init

CONTROL FLOW GRAPH SSA

void main()
main: scope:[main]  from __start::@1
  idx#20 = phi( __start::@1/idx#22 )
  print_person::person#0 = persons
  call print_person
  to:main::@1
main::@1: scope:[main]  from main
  idx#11 = phi( main/idx#7 )
  idx#0 = idx#11
  print_person::person#1 = persons+1*SIZEOF_STRUCT_PERSON
  call print_person
  to:main::@2
main::@2: scope:[main]  from main::@1
  idx#12 = phi( main::@1/idx#7 )
  idx#1 = idx#12
  to:main::@return
main::@return: scope:[main]  from main::@2
  idx#13 = phi( main::@2/idx#1 )
  idx#2 = idx#13
  return 
  to:@return

void print_person(struct Person *person)
print_person: scope:[print_person]  from main main::@1
  idx#14 = phi( main/idx#20, main::@1/idx#0 )
  print_person::person#2 = phi( main/print_person::person#0, main::@1/print_person::person#1 )
  print_person::$3 = (char *)print_person::person#2
  print_person::$0 = print_person::$3 + OFFSET_STRUCT_PERSON_ID
  SCREEN[idx#14] = DIGIT[*print_person::$0]
  idx#3 = ++ idx#14
  SCREEN[idx#3] = ' '
  idx#4 = ++ idx#3
  print_person::i#0 = 0
  to:print_person::@1
print_person::@1: scope:[print_person]  from print_person print_person::@2
  idx#21 = phi( print_person/idx#4, print_person::@2/idx#5 )
  print_person::i#2 = phi( print_person/print_person::i#0, print_person::@2/print_person::i#1 )
  print_person::person#3 = phi( print_person/print_person::person#2, print_person::@2/print_person::person#4 )
  print_person::$4 = (char *)print_person::person#3
  print_person::$1 = print_person::$4 + OFFSET_STRUCT_PERSON_NAME
  print_person::$6 = 0 != print_person::$1[print_person::i#2]
  if(print_person::$6) goto print_person::@2
  to:print_person::@3
print_person::@2: scope:[print_person]  from print_person::@1
  idx#15 = phi( print_person::@1/idx#21 )
  print_person::i#3 = phi( print_person::@1/print_person::i#2 )
  print_person::person#4 = phi( print_person::@1/print_person::person#3 )
  print_person::$5 = (char *)print_person::person#4
  print_person::$2 = print_person::$5 + OFFSET_STRUCT_PERSON_NAME
  SCREEN[idx#15] = print_person::$2[print_person::i#3]
  idx#5 = ++ idx#15
  print_person::i#1 = ++ print_person::i#3
  to:print_person::@1
print_person::@3: scope:[print_person]  from print_person::@1
  idx#16 = phi( print_person::@1/idx#21 )
  SCREEN[idx#16] = ' '
  idx#6 = ++ idx#16
  to:print_person::@return
print_person::@return: scope:[print_person]  from print_person::@3
  idx#17 = phi( print_person::@3/idx#6 )
  idx#7 = idx#17
  return 
  to:@return

void __start()
__start: scope:[__start]  from
  to:__start::__init1
__start::__init1: scope:[__start]  from __start
  idx#8 = 0
  to:__start::@1
__start::@1: scope:[__start]  from __start::__init1
  idx#22 = phi( __start::__init1/idx#8 )
  call main
  to:__start::@2
__start::@2: scope:[__start]  from __start::@1
  idx#18 = phi( __start::@1/idx#2 )
  idx#9 = idx#18
  to:__start::@return
__start::@return: scope:[__start]  from __start::@2
  idx#19 = phi( __start::@2/idx#9 )
  idx#10 = idx#19
  return 
  to:@return

SYMBOL TABLE SSA
__constant char DIGIT[] = "0123456789"
__constant char OFFSET_STRUCT_PERSON_ID = 0
__constant char OFFSET_STRUCT_PERSON_NAME = 1
__constant char * const SCREEN = (char *)$400
__constant char SIZEOF_STRUCT_PERSON = $11
void __start()
char idx
char idx#0
char idx#1
char idx#10
char idx#11
char idx#12
char idx#13
char idx#14
char idx#15
char idx#16
char idx#17
char idx#18
char idx#19
char idx#2
char idx#20
char idx#21
char idx#22
char idx#3
char idx#4
char idx#5
char idx#6
char idx#7
char idx#8
char idx#9
void main()
__constant struct Person persons[] = { { id: 4, name: "jesper" }, { id: 7, name: "henriette" } }
void print_person(struct Person *person)
char *print_person::$0
char *print_person::$1
char *print_person::$2
char *print_person::$3
char *print_person::$4
char *print_person::$5
bool print_person::$6
char print_person::i
char print_person::i#0
char print_person::i#1
char print_person::i#2
char print_person::i#3
struct Person *print_person::person
struct Person *print_person::person#0
struct Person *print_person::person#1
struct Person *print_person::person#2
struct Person *print_person::person#3
struct Person *print_person::person#4

Adding number conversion cast (unumber) 1*SIZEOF_STRUCT_PERSON in print_person::person#1 = persons+1*SIZEOF_STRUCT_PERSON
Adding number conversion cast (unumber) 1 in print_person::person#1 = persons+(unumber)1*SIZEOF_STRUCT_PERSON
Adding number conversion cast (unumber) 0 in print_person::$6 = 0 != print_person::$1[print_person::i#2]
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast (unumber)1*SIZEOF_STRUCT_PERSON
Simplifying constant integer cast 1
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 1
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias idx#0 = idx#11 
Alias idx#1 = idx#12 idx#13 idx#2 
Alias print_person::person#3 = print_person::person#4 
Alias print_person::i#2 = print_person::i#3 
Alias idx#15 = idx#21 idx#16 
Alias idx#17 = idx#6 idx#7 
Alias idx#22 = idx#8 
Alias idx#10 = idx#9 idx#18 idx#19 
Successful SSA optimization Pass2AliasElimination
Identical Phi Values idx#20 idx#22
Identical Phi Values idx#0 idx#17
Identical Phi Values idx#1 idx#17
Identical Phi Values print_person::person#3 print_person::person#2
Identical Phi Values idx#10 idx#1
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition print_person::$6 [20] if(0!=print_person::$1[print_person::i#2]) goto print_person::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant print_person::person#0 = persons
Constant print_person::person#1 = persons+1*SIZEOF_STRUCT_PERSON
Constant print_person::i#0 = 0
Constant idx#22 = 0
Successful SSA optimization Pass2ConstantIdentification
Converting *(pointer+n) to pointer[n] [11] SCREEN[idx#14] = DIGIT[*print_person::$0]  -- print_person::$3[OFFSET_STRUCT_PERSON_ID]
Successful SSA optimization Pass2InlineDerefIdx
Simplifying expression containing zero print_person::$3 in [10] print_person::$0 = print_person::$3 + OFFSET_STRUCT_PERSON_ID
Simplifying expression containing zero print_person::$3 in [11] SCREEN[idx#14] = DIGIT[print_person::$3[OFFSET_STRUCT_PERSON_ID]]
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable print_person::$0 and assignment [5] print_person::$0 = print_person::$3
Eliminating unused constant OFFSET_STRUCT_PERSON_ID
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::__init1
Removing unused procedure block __start::@1
Removing unused procedure block __start::@2
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Inlining Noop Cast [4] print_person::$3 = (char *)print_person::person#2 keeping print_person::person#2
Inlining Noop Cast [10] print_person::$4 = (char *)print_person::person#2 keeping print_person::person#2
Inlining Noop Cast [13] print_person::$5 = (char *)print_person::person#2 keeping print_person::person#2
Successful SSA optimization Pass2NopCastInlining
Inlining constant with var siblings print_person::person#0
Inlining constant with var siblings print_person::person#1
Inlining constant with var siblings print_person::i#0
Inlining constant with var siblings idx#22
Constant inlined idx#22 = 0
Constant inlined print_person::person#0 = persons
Constant inlined print_person::i#0 = 0
Constant inlined print_person::person#1 = persons+1*SIZEOF_STRUCT_PERSON
Successful SSA optimization Pass2ConstantInlining
Finalized unsigned number type (char) $10
Finalized unsigned number type (char) $10
Successful SSA optimization PassNFinalizeNumberTypeConversions
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@2
CALL GRAPH
Calls in [main] to print_person:1 print_person:3 

Created 4 initial phi equivalence classes
Coalesced [2] idx#23 = idx#17
Coalesced [11] idx#24 = idx#4
Coalesced [22] print_person::i#4 = print_person::i#1
Coalesced [23] idx#25 = idx#5
Coalesced down to 4 phi equivalence classes
Culled Empty Block label main::@2
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1

FINAL CONTROL FLOW GRAPH

void main()
main: scope:[main]  from
  [0] phi()
  [1] call print_person
  to:main::@1
main::@1: scope:[main]  from main
  [2] phi()
  [3] call print_person
  to:main::@return
main::@return: scope:[main]  from main::@1
  [4] return 
  to:@return

void print_person(struct Person *person)
print_person: scope:[print_person]  from main main::@1
  [5] idx#14 = phi( main/0, main::@1/idx#17 )
  [5] print_person::person#2 = phi( main/persons, main::@1/persons+1*SIZEOF_STRUCT_PERSON )
  [6] SCREEN[idx#14] = DIGIT[*((char *)print_person::person#2)]
  [7] idx#3 = ++ idx#14
  [8] SCREEN[idx#3] = ' '
  [9] idx#4 = ++ idx#3
  to:print_person::@1
print_person::@1: scope:[print_person]  from print_person print_person::@2
  [10] idx#15 = phi( print_person/idx#4, print_person::@2/idx#5 )
  [10] print_person::i#2 = phi( print_person/0, print_person::@2/print_person::i#1 )
  [11] print_person::$1 = (char *)print_person::person#2 + OFFSET_STRUCT_PERSON_NAME
  [12] if(0!=print_person::$1[print_person::i#2]) goto print_person::@2
  to:print_person::@3
print_person::@3: scope:[print_person]  from print_person::@1
  [13] SCREEN[idx#15] = ' '
  [14] idx#17 = ++ idx#15
  to:print_person::@return
print_person::@return: scope:[print_person]  from print_person::@3
  [15] return 
  to:@return
print_person::@2: scope:[print_person]  from print_person::@1
  [16] print_person::$2 = (char *)print_person::person#2 + OFFSET_STRUCT_PERSON_NAME
  [17] SCREEN[idx#15] = print_person::$2[print_person::i#2]
  [18] idx#5 = ++ idx#15
  [19] print_person::i#1 = ++ print_person::i#2
  to:print_person::@1


VARIABLE REGISTER WEIGHTS
char idx
char idx#14 // 12.0
char idx#15 // 55.999999999999986
char idx#17 // 3.25
char idx#3 // 16.5
char idx#4 // 22.0
char idx#5 // 101.0
void main()
void print_person(struct Person *person)
char *print_person::$1 // 202.0
char *print_person::$2 // 202.0
char print_person::i
char print_person::i#1 // 202.0
char print_person::i#2 // 67.33333333333333
struct Person *print_person::person
struct Person *print_person::person#2

Initial phi equivalence classes
[ print_person::person#2 ]
[ idx#14 idx#17 ]
[ print_person::i#2 print_person::i#1 ]
[ idx#15 idx#4 idx#5 ]
Added variable idx#3 to live range equivalence class [ idx#3 ]
Added variable print_person::$1 to live range equivalence class [ print_person::$1 ]
Added variable print_person::$2 to live range equivalence class [ print_person::$2 ]
Complete equivalence classes
[ print_person::person#2 ]
[ idx#14 idx#17 ]
[ print_person::i#2 print_person::i#1 ]
[ idx#15 idx#4 idx#5 ]
[ idx#3 ]
[ print_person::$1 ]
[ print_person::$2 ]
Allocated zp[1]:2 [ print_person::i#2 print_person::i#1 ]
Allocated zp[2]:3 [ print_person::$1 ]
Allocated zp[2]:5 [ print_person::$2 ]
Allocated zp[1]:7 [ idx#15 idx#4 idx#5 ]
Allocated zp[1]:8 [ idx#3 ]
Allocated zp[1]:9 [ idx#14 idx#17 ]
Allocated zp[2]:10 [ print_person::person#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [6] SCREEN[idx#14] = DIGIT[*((char *)print_person::person#2)] [ print_person::person#2 idx#14 ] ( print_person:1 [ print_person::person#2 idx#14 ] { }  print_person:3 [ print_person::person#2 idx#14 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a reg byte y 
Removing always clobbered register reg byte a as potential for zp[1]:9 [ idx#14 idx#17 ]
Removing always clobbered register reg byte y as potential for zp[1]:9 [ idx#14 idx#17 ]
Statement [8] SCREEN[idx#3] = ' ' [ print_person::person#2 idx#3 ] ( print_person:1 [ print_person::person#2 idx#3 ] { }  print_person:3 [ print_person::person#2 idx#3 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Removing always clobbered register reg byte a as potential for zp[1]:8 [ idx#3 ]
Statement [11] print_person::$1 = (char *)print_person::person#2 + OFFSET_STRUCT_PERSON_NAME [ print_person::person#2 print_person::i#2 idx#15 print_person::$1 ] ( print_person:1 [ print_person::person#2 print_person::i#2 idx#15 print_person::$1 ] { }  print_person:3 [ print_person::person#2 print_person::i#2 idx#15 print_person::$1 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Removing always clobbered register reg byte a as potential for zp[1]:2 [ print_person::i#2 print_person::i#1 ]
Removing always clobbered register reg byte a as potential for zp[1]:7 [ idx#15 idx#4 idx#5 ]
Statement [12] if(0!=print_person::$1[print_person::i#2]) goto print_person::@2 [ print_person::person#2 print_person::i#2 idx#15 ] ( print_person:1 [ print_person::person#2 print_person::i#2 idx#15 ] { }  print_person:3 [ print_person::person#2 print_person::i#2 idx#15 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Statement [13] SCREEN[idx#15] = ' ' [ idx#15 ] ( print_person:1 [ idx#15 ] { }  print_person:3 [ idx#15 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Statement [16] print_person::$2 = (char *)print_person::person#2 + OFFSET_STRUCT_PERSON_NAME [ print_person::person#2 print_person::i#2 idx#15 print_person::$2 ] ( print_person:1 [ print_person::person#2 print_person::i#2 idx#15 print_person::$2 ] { }  print_person:3 [ print_person::person#2 print_person::i#2 idx#15 print_person::$2 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Statement [17] SCREEN[idx#15] = print_person::$2[print_person::i#2] [ print_person::person#2 print_person::i#2 idx#15 ] ( print_person:1 [ print_person::person#2 print_person::i#2 idx#15 ] { }  print_person:3 [ print_person::person#2 print_person::i#2 idx#15 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Statement [6] SCREEN[idx#14] = DIGIT[*((char *)print_person::person#2)] [ print_person::person#2 idx#14 ] ( print_person:1 [ print_person::person#2 idx#14 ] { }  print_person:3 [ print_person::person#2 idx#14 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a reg byte y 
Statement [8] SCREEN[idx#3] = ' ' [ print_person::person#2 idx#3 ] ( print_person:1 [ print_person::person#2 idx#3 ] { }  print_person:3 [ print_person::person#2 idx#3 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Statement [11] print_person::$1 = (char *)print_person::person#2 + OFFSET_STRUCT_PERSON_NAME [ print_person::person#2 print_person::i#2 idx#15 print_person::$1 ] ( print_person:1 [ print_person::person#2 print_person::i#2 idx#15 print_person::$1 ] { }  print_person:3 [ print_person::person#2 print_person::i#2 idx#15 print_person::$1 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Statement [12] if(0!=print_person::$1[print_person::i#2]) goto print_person::@2 [ print_person::person#2 print_person::i#2 idx#15 ] ( print_person:1 [ print_person::person#2 print_person::i#2 idx#15 ] { }  print_person:3 [ print_person::person#2 print_person::i#2 idx#15 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Statement [13] SCREEN[idx#15] = ' ' [ idx#15 ] ( print_person:1 [ idx#15 ] { }  print_person:3 [ idx#15 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Statement [16] print_person::$2 = (char *)print_person::person#2 + OFFSET_STRUCT_PERSON_NAME [ print_person::person#2 print_person::i#2 idx#15 print_person::$2 ] ( print_person:1 [ print_person::person#2 print_person::i#2 idx#15 print_person::$2 ] { }  print_person:3 [ print_person::person#2 print_person::i#2 idx#15 print_person::$2 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Statement [17] SCREEN[idx#15] = print_person::$2[print_person::i#2] [ print_person::person#2 print_person::i#2 idx#15 ] ( print_person:1 [ print_person::person#2 print_person::i#2 idx#15 ] { }  print_person:3 [ print_person::person#2 print_person::i#2 idx#15 ] { { idx#14 = idx#17 } }  ) always clobbers reg byte a 
Potential registers zp[2]:10 [ print_person::person#2 ] : zp[2]:10 , 
Potential registers zp[1]:9 [ idx#14 idx#17 ] : zp[1]:9 , reg byte x , 
Potential registers zp[1]:2 [ print_person::i#2 print_person::i#1 ] : zp[1]:2 , reg byte x , reg byte y , 
Potential registers zp[1]:7 [ idx#15 idx#4 idx#5 ] : zp[1]:7 , reg byte x , reg byte y , 
Potential registers zp[1]:8 [ idx#3 ] : zp[1]:8 , reg byte x , reg byte y , 
Potential registers zp[2]:3 [ print_person::$1 ] : zp[2]:3 , 
Potential registers zp[2]:5 [ print_person::$2 ] : zp[2]:5 , 

REGISTER UPLIFT SCOPES
Uplift Scope [print_person] 269.33: zp[1]:2 [ print_person::i#2 print_person::i#1 ] 202: zp[2]:3 [ print_person::$1 ] 202: zp[2]:5 [ print_person::$2 ] 0: zp[2]:10 [ print_person::person#2 ] 
Uplift Scope [] 179: zp[1]:7 [ idx#15 idx#4 idx#5 ] 16.5: zp[1]:8 [ idx#3 ] 15.25: zp[1]:9 [ idx#14 idx#17 ] 
Uplift Scope [Person] 
Uplift Scope [main] 

Uplifting [print_person] best 899 combination reg byte y [ print_person::i#2 print_person::i#1 ] zp[2]:3 [ print_person::$1 ] zp[2]:5 [ print_person::$2 ] zp[2]:10 [ print_person::person#2 ] 
Uplifting [] best 809 combination reg byte x [ idx#15 idx#4 idx#5 ] reg byte x [ idx#3 ] reg byte x [ idx#14 idx#17 ] 
Uplifting [Person] best 809 combination 
Uplifting [main] best 809 combination 
Allocated (was zp[2]:3) zp[2]:2 [ print_person::$1 ]
Allocated (was zp[2]:5) zp[2]:4 [ print_person::$2 ]
Allocated (was zp[2]:10) zp[2]:6 [ print_person::person#2 ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Example of a struct containing an array
  // Upstart
  // Commodore 64 PRG executable file
.file [name="struct-ptr-31.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_PERSON = $11
  .const OFFSET_STRUCT_PERSON_NAME = 1
  .label SCREEN = $400
.segment Code
  // main
main: {
    // [1] call print_person
    // [5] phi from main to print_person [phi:main->print_person]
  print_person_from_main:
    // [5] phi idx#14 = 0 [phi:main->print_person#0] -- vbuxx=vbuc1 
    ldx #0
    // [5] phi print_person::person#2 = persons [phi:main->print_person#1] -- pssz1=pssc1 
    lda #<persons
    sta.z print_person.person
    lda #>persons
    sta.z print_person.person+1
    jsr print_person
    // [2] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    jmp __b1
    // main::@1
  __b1:
    // [3] call print_person
    // [5] phi from main::@1 to print_person [phi:main::@1->print_person]
  print_person_from___b1:
    // [5] phi idx#14 = idx#17 [phi:main::@1->print_person#0] -- register_copy 
    // [5] phi print_person::person#2 = persons+1*SIZEOF_STRUCT_PERSON [phi:main::@1->print_person#1] -- pssz1=pssc1 
    lda #<persons+1*SIZEOF_STRUCT_PERSON
    sta.z print_person.person
    lda #>persons+1*SIZEOF_STRUCT_PERSON
    sta.z print_person.person+1
    jsr print_person
    jmp __breturn
    // main::@return
  __breturn:
    // [4] return 
    rts
}
  // print_person
// void print_person(__zp(6) struct Person *person)
print_person: {
    .label __1 = 2
    .label __2 = 4
    .label person = 6
    // [6] SCREEN[idx#14] = DIGIT[*((char *)print_person::person#2)] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_(_deref_pbuz1) 
    ldy #0
    lda (person),y
    tay
    lda DIGIT,y
    sta SCREEN,x
    // [7] idx#3 = ++ idx#14 -- vbuxx=_inc_vbuxx 
    inx
    // [8] SCREEN[idx#3] = ' ' -- pbuc1_derefidx_vbuxx=vbuc2 
    lda #' '
    sta SCREEN,x
    // [9] idx#4 = ++ idx#3 -- vbuxx=_inc_vbuxx 
    inx
    // [10] phi from print_person to print_person::@1 [phi:print_person->print_person::@1]
  __b1_from_print_person:
    // [10] phi idx#15 = idx#4 [phi:print_person->print_person::@1#0] -- register_copy 
    // [10] phi print_person::i#2 = 0 [phi:print_person->print_person::@1#1] -- vbuyy=vbuc1 
    ldy #0
    jmp __b1
    // print_person::@1
  __b1:
    // [11] print_person::$1 = (char *)print_person::person#2 + OFFSET_STRUCT_PERSON_NAME -- pbuz1=pbuz2_plus_vbuc1 
    lda #OFFSET_STRUCT_PERSON_NAME
    clc
    adc.z person
    sta.z __1
    lda #0
    adc.z person+1
    sta.z __1+1
    // [12] if(0!=print_person::$1[print_person::i#2]) goto print_person::@2 -- 0_neq_pbuz1_derefidx_vbuyy_then_la1 
    lda (__1),y
    cmp #0
    bne __b2
    jmp __b3
    // print_person::@3
  __b3:
    // [13] SCREEN[idx#15] = ' ' -- pbuc1_derefidx_vbuxx=vbuc2 
    lda #' '
    sta SCREEN,x
    // [14] idx#17 = ++ idx#15 -- vbuxx=_inc_vbuxx 
    inx
    jmp __breturn
    // print_person::@return
  __breturn:
    // [15] return 
    rts
    // print_person::@2
  __b2:
    // [16] print_person::$2 = (char *)print_person::person#2 + OFFSET_STRUCT_PERSON_NAME -- pbuz1=pbuz2_plus_vbuc1 
    lda #OFFSET_STRUCT_PERSON_NAME
    clc
    adc.z person
    sta.z __2
    lda #0
    adc.z person+1
    sta.z __2+1
    // [17] SCREEN[idx#15] = print_person::$2[print_person::i#2] -- pbuc1_derefidx_vbuxx=pbuz1_derefidx_vbuyy 
    lda (__2),y
    sta SCREEN,x
    // [18] idx#5 = ++ idx#15 -- vbuxx=_inc_vbuxx 
    inx
    // [19] print_person::i#1 = ++ print_person::i#2 -- vbuyy=_inc_vbuyy 
    iny
    // [10] phi from print_person::@2 to print_person::@1 [phi:print_person::@2->print_person::@1]
  __b1_from___b2:
    // [10] phi idx#15 = idx#5 [phi:print_person::@2->print_person::@1#0] -- register_copy 
    // [10] phi print_person::i#2 = print_person::i#1 [phi:print_person::@2->print_person::@1#1] -- register_copy 
    jmp __b1
}
  // File Data
.segment Data
  persons: .byte 4
  .text "jesper"
  .byte 0
  .fill 9, 0
  .byte 7
  .text "henriette"
  .byte 0
  .fill 6, 0
  DIGIT: .text "0123456789"
  .byte 0

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __b3
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1_from_main:
Removing instruction print_person_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction print_person_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __b1_from_print_person:
Removing instruction __b3:
Removing instruction __breturn:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
__constant char DIGIT[] = "0123456789"
__constant char OFFSET_STRUCT_PERSON_NAME = 1
__constant char * const SCREEN = (char *) 1024
__constant char SIZEOF_STRUCT_PERSON = $11
char idx
char idx#14 // reg byte x 12.0
char idx#15 // reg byte x 55.999999999999986
char idx#17 // reg byte x 3.25
char idx#3 // reg byte x 16.5
char idx#4 // reg byte x 22.0
char idx#5 // reg byte x 101.0
void main()
__constant struct Person persons[] = { { id: 4, name: "jesper" }, { id: 7, name: "henriette" } }
void print_person(struct Person *person)
char *print_person::$1 // zp[2]:2 202.0
char *print_person::$2 // zp[2]:4 202.0
char print_person::i
char print_person::i#1 // reg byte y 202.0
char print_person::i#2 // reg byte y 67.33333333333333
struct Person *print_person::person
struct Person *print_person::person#2 // person zp[2]:6

zp[2]:6 [ print_person::person#2 ]
reg byte x [ idx#14 idx#17 ]
reg byte y [ print_person::i#2 print_person::i#1 ]
reg byte x [ idx#15 idx#4 idx#5 ]
reg byte x [ idx#3 ]
zp[2]:2 [ print_person::$1 ]
zp[2]:4 [ print_person::$2 ]


FINAL ASSEMBLER
Score: 740

  // File Comments
// Example of a struct containing an array
  // Upstart
  // Commodore 64 PRG executable file
.file [name="struct-ptr-31.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_PERSON = $11
  .const OFFSET_STRUCT_PERSON_NAME = 1
  .label SCREEN = $400
.segment Code
  // main
main: {
    // print_person(persons)
    // [1] call print_person
    // [5] phi from main to print_person [phi:main->print_person]
    // [5] phi idx#14 = 0 [phi:main->print_person#0] -- vbuxx=vbuc1 
    ldx #0
    // [5] phi print_person::person#2 = persons [phi:main->print_person#1] -- pssz1=pssc1 
    lda #<persons
    sta.z print_person.person
    lda #>persons
    sta.z print_person.person+1
    jsr print_person
    // [2] phi from main to main::@1 [phi:main->main::@1]
    // main::@1
    // print_person(persons+1)
    // [3] call print_person
    // [5] phi from main::@1 to print_person [phi:main::@1->print_person]
    // [5] phi idx#14 = idx#17 [phi:main::@1->print_person#0] -- register_copy 
    // [5] phi print_person::person#2 = persons+1*SIZEOF_STRUCT_PERSON [phi:main::@1->print_person#1] -- pssz1=pssc1 
    lda #<persons+1*SIZEOF_STRUCT_PERSON
    sta.z print_person.person
    lda #>persons+1*SIZEOF_STRUCT_PERSON
    sta.z print_person.person+1
    jsr print_person
    // main::@return
    // }
    // [4] return 
    rts
}
  // print_person
// void print_person(__zp(6) struct Person *person)
print_person: {
    .label __1 = 2
    .label __2 = 4
    .label person = 6
    // SCREEN[idx++] = DIGIT[person->id]
    // [6] SCREEN[idx#14] = DIGIT[*((char *)print_person::person#2)] -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_(_deref_pbuz1) 
    ldy #0
    lda (person),y
    tay
    lda DIGIT,y
    sta SCREEN,x
    // SCREEN[idx++] = DIGIT[person->id];
    // [7] idx#3 = ++ idx#14 -- vbuxx=_inc_vbuxx 
    inx
    // SCREEN[idx++] = ' '
    // [8] SCREEN[idx#3] = ' ' -- pbuc1_derefidx_vbuxx=vbuc2 
    lda #' '
    sta SCREEN,x
    // SCREEN[idx++] = ' ';
    // [9] idx#4 = ++ idx#3 -- vbuxx=_inc_vbuxx 
    inx
    // [10] phi from print_person to print_person::@1 [phi:print_person->print_person::@1]
    // [10] phi idx#15 = idx#4 [phi:print_person->print_person::@1#0] -- register_copy 
    // [10] phi print_person::i#2 = 0 [phi:print_person->print_person::@1#1] -- vbuyy=vbuc1 
    ldy #0
    // print_person::@1
  __b1:
    // for(byte i=0; person->name[i]; i++)
    // [11] print_person::$1 = (char *)print_person::person#2 + OFFSET_STRUCT_PERSON_NAME -- pbuz1=pbuz2_plus_vbuc1 
    lda #OFFSET_STRUCT_PERSON_NAME
    clc
    adc.z person
    sta.z __1
    lda #0
    adc.z person+1
    sta.z __1+1
    // [12] if(0!=print_person::$1[print_person::i#2]) goto print_person::@2 -- 0_neq_pbuz1_derefidx_vbuyy_then_la1 
    lda (__1),y
    cmp #0
    bne __b2
    // print_person::@3
    // SCREEN[idx++] = ' '
    // [13] SCREEN[idx#15] = ' ' -- pbuc1_derefidx_vbuxx=vbuc2 
    lda #' '
    sta SCREEN,x
    // SCREEN[idx++] = ' ';
    // [14] idx#17 = ++ idx#15 -- vbuxx=_inc_vbuxx 
    inx
    // print_person::@return
    // }
    // [15] return 
    rts
    // print_person::@2
  __b2:
    // SCREEN[idx++] = person->name[i]
    // [16] print_person::$2 = (char *)print_person::person#2 + OFFSET_STRUCT_PERSON_NAME -- pbuz1=pbuz2_plus_vbuc1 
    lda #OFFSET_STRUCT_PERSON_NAME
    clc
    adc.z person
    sta.z __2
    lda #0
    adc.z person+1
    sta.z __2+1
    // [17] SCREEN[idx#15] = print_person::$2[print_person::i#2] -- pbuc1_derefidx_vbuxx=pbuz1_derefidx_vbuyy 
    lda (__2),y
    sta SCREEN,x
    // SCREEN[idx++] = person->name[i];
    // [18] idx#5 = ++ idx#15 -- vbuxx=_inc_vbuxx 
    inx
    // for(byte i=0; person->name[i]; i++)
    // [19] print_person::i#1 = ++ print_person::i#2 -- vbuyy=_inc_vbuyy 
    iny
    // [10] phi from print_person::@2 to print_person::@1 [phi:print_person::@2->print_person::@1]
    // [10] phi idx#15 = idx#5 [phi:print_person::@2->print_person::@1#0] -- register_copy 
    // [10] phi print_person::i#2 = print_person::i#1 [phi:print_person::@2->print_person::@1#1] -- register_copy 
    jmp __b1
}
  // File Data
.segment Data
  persons: .byte 4
  .text "jesper"
  .byte 0
  .fill 9, 0
  .byte 7
  .text "henriette"
  .byte 0
  .fill 6, 0
  DIGIT: .text "0123456789"
  .byte 0

