Inlined call call __init
Calling convention STACK_CALL adding prepare/execute/finalize for call *do10::fn 

CONTROL FLOW GRAPH SSA

void do10(void (*fn)())
do10: scope:[do10]  from main main::@1
  do10::fn#3 = phi( main/do10::fn#0, main::@1/do10::fn#1 )
  do10::i#0 = 0
  to:do10::@1
do10::@1: scope:[do10]  from do10 do10::@2
  do10::i#3 = phi( do10/do10::i#0, do10::@2/do10::i#1 )
  do10::fn#2 = phi( do10/do10::fn#3, do10::@2/do10::fn#4 )
  callexecute *do10::fn#2 
  to:do10::@2
do10::@2: scope:[do10]  from do10::@1
  do10::fn#4 = phi( do10::@1/do10::fn#2 )
  do10::i#2 = phi( do10::@1/do10::i#3 )
  do10::i#1 = do10::i#2 + rangenext(0,9)
  do10::$1 = do10::i#1 != rangelast(0,9)
  if(do10::$1) goto do10::@1
  to:do10::@return
do10::@return: scope:[do10]  from do10::@2
  return 
  to:@return

void hello()
hello: scope:[hello]  from
  print::msg#0 = hello::msg
  call print
  to:hello::@1
hello::@1: scope:[hello]  from hello
  to:hello::@return
hello::@return: scope:[hello]  from hello::@1
  return 
  to:@return

void world()
world: scope:[world]  from
  print::msg#1 = world::msg
  call print
  to:world::@1
world::@1: scope:[world]  from world
  to:world::@return
world::@return: scope:[world]  from world::@1
  return 
  to:@return

void main()
main: scope:[main]  from __start::@1
  do10::fn#0 = &hello
  call do10
  to:main::@1
main::@1: scope:[main]  from main
  do10::fn#1 = &world
  call do10
  to:main::@2
main::@2: scope:[main]  from main::@1
  to:main::@return
main::@return: scope:[main]  from main::@2
  return 
  to:@return

void print(char *msg)
print: scope:[print]  from hello world
  print::msg#3 = phi( hello/print::msg#0, world/print::msg#1 )
  print::i#0 = 0
  to:print::@1
print::@1: scope:[print]  from print print::@1
  print::i#2 = phi( print/print::i#0, print::@1/print::i#1 )
  print::msg#2 = phi( print/print::msg#3, print::@1/print::msg#2 )
  SCREEN[idx] = print::msg#2[print::i#2]
  idx = ++ idx
  print::i#1 = ++ print::i#2
  print::$0 = 0 != print::msg#2[print::i#1]
  if(print::$0) goto print::@1
  to:print::@return
print::@return: scope:[print]  from print::@1
  return 
  to:@return

void __start()
__start: scope:[__start]  from
  to:__start::__init1
__start::__init1: scope:[__start]  from __start
  idx = 0
  to:__start::@1
__start::@1: scope:[__start]  from __start::__init1
  call main
  to:__start::@2
__start::@2: scope:[__start]  from __start::@1
  to:__start::@return
__start::@return: scope:[__start]  from __start::@2
  return 
  to:@return

SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
void do10(void (*fn)())
bool do10::$1
void (*do10::fn)()
void (*do10::fn#0)()
void (*do10::fn#1)()
void (*do10::fn#2)()
void (*do10::fn#3)()
void (*do10::fn#4)()
char do10::i
char do10::i#0
char do10::i#1
char do10::i#2
char do10::i#3
void hello()
__constant char hello::msg[7] = "hello "
__loadstore volatile char idx
void main()
void print(char *msg)
bool print::$0
char print::i
char print::i#0
char print::i#1
char print::i#2
char *print::msg
char *print::msg#0
char *print::msg#1
char *print::msg#2
char *print::msg#3
void world()
__constant char world::msg[7] = "world "

Adding number conversion cast (unumber) 0 in print::$0 = 0 != print::msg#2[print::i#1]
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias do10::i#2 = do10::i#3 
Alias do10::fn#2 = do10::fn#4 
Successful SSA optimization Pass2AliasElimination
Identical Phi Values do10::fn#2 do10::fn#3
Identical Phi Values print::msg#2 print::msg#3
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition do10::$1 [6] if(do10::i#1!=rangelast(0,9)) goto do10::@1
Simple Condition print::$0 [26] if(0!=print::msg#3[print::i#1]) goto print::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant do10::i#0 = 0
Constant print::msg#0 = hello::msg
Constant print::msg#1 = world::msg
Constant do10::fn#0 = &hello
Constant do10::fn#1 = &world
Constant print::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value [4] do10::i#1 = ++ do10::i#2 to ++
Resolved ranged comparison value [6] if(do10::i#1!=rangelast(0,9)) goto do10::@1 to $a
Adding number conversion cast (unumber) $a in if(do10::i#1!=$a) goto do10::@1
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast $a
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) $a
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inlining constant with var siblings do10::i#0
Inlining constant with var siblings do10::fn#0
Inlining constant with var siblings do10::fn#1
Inlining constant with var siblings print::msg#0
Inlining constant with var siblings print::msg#1
Inlining constant with var siblings print::i#0
Constant inlined do10::i#0 = 0
Constant inlined print::i#0 = 0
Constant inlined do10::fn#1 = &world
Constant inlined do10::fn#0 = &hello
Constant inlined print::msg#1 = world::msg
Constant inlined print::msg#0 = hello::msg
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting do10::@3(between do10::@2 and do10::@1)
Added new block during phi lifting print::@2(between print::@1 and print::@1)
Adding NOP phi() at start of __start
Adding NOP phi() at start of __start::@1
Adding NOP phi() at start of __start::@2
Adding NOP phi() at start of world
Adding NOP phi() at start of world::@1
Adding NOP phi() at start of hello
Adding NOP phi() at start of hello::@1
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@2
CALL GRAPH
Calls in [__start] to main:3 
Calls in [world] to print:7 
Calls in [hello] to print:11 
Calls in [main] to do10:15 do10:17 
Calls in [do10] to null:30 

Created 4 initial phi equivalence classes
Coalesced [27] print::i#3 = print::i#1
Coalesced [34] do10::i#4 = do10::i#1
Coalesced down to 4 phi equivalence classes
Culled Empty Block label __start::@2
Culled Empty Block label world::@1
Culled Empty Block label hello::@1
Culled Empty Block label main::@2
Culled Empty Block label print::@2
Culled Empty Block label do10::@3
Adding NOP phi() at start of __start
Adding NOP phi() at start of __start::@1
Adding NOP phi() at start of world
Adding NOP phi() at start of hello
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1

FINAL CONTROL FLOW GRAPH

void __start()
__start: scope:[__start]  from
  [0] phi()
  to:__start::__init1
__start::__init1: scope:[__start]  from __start
  [1] idx = 0
  to:__start::@1
__start::@1: scope:[__start]  from __start::__init1
  [2] phi()
  [3] call main
  to:__start::@return
__start::@return: scope:[__start]  from __start::@1
  [4] return 
  to:@return

void world()
world: scope:[world]  from
  [5] phi()
  [6] call print
  to:world::@return
world::@return: scope:[world]  from world
  [7] return 
  to:@return

void hello()
hello: scope:[hello]  from
  [8] phi()
  [9] call print
  to:hello::@return
hello::@return: scope:[hello]  from hello
  [10] return 
  to:@return

void main()
main: scope:[main]  from __start::@1
  [11] phi()
  [12] call do10
  to:main::@1
main::@1: scope:[main]  from main
  [13] phi()
  [14] call do10
  to:main::@return
main::@return: scope:[main]  from main::@1
  [15] return 
  to:@return

void print(char *msg)
print: scope:[print]  from hello world
  [16] print::msg#3 = phi( hello/hello::msg, world/world::msg )
  to:print::@1
print::@1: scope:[print]  from print print::@1
  [17] print::i#2 = phi( print/0, print::@1/print::i#1 )
  [18] SCREEN[idx] = print::msg#3[print::i#2]
  [19] idx = ++ idx
  [20] print::i#1 = ++ print::i#2
  [21] if(0!=print::msg#3[print::i#1]) goto print::@1
  to:print::@return
print::@return: scope:[print]  from print::@1
  [22] return 
  to:@return

void do10(void (*fn)())
do10: scope:[do10]  from main main::@1
  [23] do10::fn#3 = phi( main/&hello, main::@1/&world )
  to:do10::@1
do10::@1: scope:[do10]  from do10 do10::@2
  [24] do10::i#2 = phi( do10/0, do10::@2/do10::i#1 )
  [25] callexecute *do10::fn#3 
  to:do10::@2
do10::@2: scope:[do10]  from do10::@1
  [26] do10::i#1 = ++ do10::i#2
  [27] if(do10::i#1!=$a) goto do10::@1
  to:do10::@return
do10::@return: scope:[do10]  from do10::@2
  [28] return 
  to:@return


VARIABLE REGISTER WEIGHTS
void __start()
void do10(void (*fn)())
void (*do10::fn)()
void (*do10::fn#3)()
char do10::i
char do10::i#1 // 1501.5
char do10::i#2 // 2002.0
void hello()
__loadstore volatile char idx // 38.125
void main()
void print(char *msg)
char print::i
char print::i#1 // 151.5
char print::i#2 // 101.0
char *print::msg
char *print::msg#3 // 33.666666666666664
void world()

Initial phi equivalence classes
[ print::msg#3 ]
[ print::i#2 print::i#1 ]
[ do10::fn#3 ]
[ do10::i#2 do10::i#1 ]
Added variable idx to live range equivalence class [ idx ]
Complete equivalence classes
[ print::msg#3 ]
[ print::i#2 print::i#1 ]
[ do10::fn#3 ]
[ do10::i#2 do10::i#1 ]
[ idx ]
Allocated zp[1]:2 [ do10::i#2 do10::i#1 ]
Allocated zp[1]:3 [ print::i#2 print::i#1 ]
Allocated zp[1]:4 [ idx ]
Allocated zp[2]:5 [ print::msg#3 ]
Allocated zp[2]:7 [ do10::fn#3 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] idx = 0 [ ] (  [ ] { }  ) always clobbers reg byte a 
Statement [18] SCREEN[idx] = print::msg#3[print::i#2] [ idx print::msg#3 print::i#2 ] ( print:6 [ idx print::msg#3 print::i#2 ] { }  print:9 [ idx print::msg#3 print::i#2 ] { }  ) always clobbers reg byte a reg byte x 
Removing always clobbered register reg byte a as potential for zp[1]:3 [ print::i#2 print::i#1 ]
Removing always clobbered register reg byte x as potential for zp[1]:3 [ print::i#2 print::i#1 ]
Statement [21] if(0!=print::msg#3[print::i#1]) goto print::@1 [ idx print::msg#3 print::i#1 ] ( print:6 [ idx print::msg#3 print::i#1 ] { }  print:9 [ idx print::msg#3 print::i#1 ] { }  ) always clobbers reg byte a 
Statement [25] callexecute *do10::fn#3  [ do10::i#2 ] ( main:3::do10:12 [ do10::i#2 ] { }  main:3::do10:14 [ do10::i#2 ] { }  ) always clobbers reg byte a reg byte x reg byte y 
Removing always clobbered register reg byte a as potential for zp[1]:2 [ do10::i#2 do10::i#1 ]
Removing always clobbered register reg byte x as potential for zp[1]:2 [ do10::i#2 do10::i#1 ]
Removing always clobbered register reg byte y as potential for zp[1]:2 [ do10::i#2 do10::i#1 ]
Statement [27] if(do10::i#1!=$a) goto do10::@1 [ do10::i#1 ] ( main:3::do10:12 [ do10::i#1 ] { }  main:3::do10:14 [ do10::i#1 ] { }  ) always clobbers reg byte a 
Statement [1] idx = 0 [ ] (  [ ] { }  ) always clobbers reg byte a 
Statement [18] SCREEN[idx] = print::msg#3[print::i#2] [ idx print::msg#3 print::i#2 ] ( print:6 [ idx print::msg#3 print::i#2 ] { }  print:9 [ idx print::msg#3 print::i#2 ] { }  ) always clobbers reg byte a reg byte x 
Statement [21] if(0!=print::msg#3[print::i#1]) goto print::@1 [ idx print::msg#3 print::i#1 ] ( print:6 [ idx print::msg#3 print::i#1 ] { }  print:9 [ idx print::msg#3 print::i#1 ] { }  ) always clobbers reg byte a 
Statement [25] callexecute *do10::fn#3  [ do10::i#2 ] ( main:3::do10:12 [ do10::i#2 ] { }  main:3::do10:14 [ do10::i#2 ] { }  ) always clobbers reg byte a reg byte x reg byte y 
Statement [27] if(do10::i#1!=$a) goto do10::@1 [ do10::i#1 ] ( main:3::do10:12 [ do10::i#1 ] { }  main:3::do10:14 [ do10::i#1 ] { }  ) always clobbers reg byte a 
Potential registers zp[2]:5 [ print::msg#3 ] : zp[2]:5 , 
Potential registers zp[1]:3 [ print::i#2 print::i#1 ] : zp[1]:3 , reg byte y , 
Potential registers zp[2]:7 [ do10::fn#3 ] : zp[2]:7 , 
Potential registers zp[1]:2 [ do10::i#2 do10::i#1 ] : zp[1]:2 , 
Potential registers zp[1]:4 [ idx ] : zp[1]:4 , 

REGISTER UPLIFT SCOPES
Uplift Scope [do10] 3,503.5: zp[1]:2 [ do10::i#2 do10::i#1 ] 0: zp[2]:7 [ do10::fn#3 ] 
Uplift Scope [print] 252.5: zp[1]:3 [ print::i#2 print::i#1 ] 33.67: zp[2]:5 [ print::msg#3 ] 
Uplift Scope [] 38.12: zp[1]:4 [ idx ] 
Uplift Scope [hello] 
Uplift Scope [world] 
Uplift Scope [main] 
Uplift Scope [__start] 

Uplifting [do10] best 1099 combination zp[1]:2 [ do10::i#2 do10::i#1 ] zp[2]:7 [ do10::fn#3 ] 
Uplifting [print] best 979 combination reg byte y [ print::i#2 print::i#1 ] zp[2]:5 [ print::msg#3 ] 
Uplifting [] best 979 combination zp[1]:4 [ idx ] 
Uplifting [hello] best 979 combination 
Uplifting [world] best 979 combination 
Uplifting [main] best 979 combination 
Uplifting [__start] best 979 combination 
Attempting to uplift remaining variables inzp[1]:2 [ do10::i#2 do10::i#1 ]
Uplifting [do10] best 979 combination zp[1]:2 [ do10::i#2 do10::i#1 ] 
Attempting to uplift remaining variables inzp[1]:4 [ idx ]
Uplifting [] best 979 combination zp[1]:4 [ idx ] 
Allocated (was zp[1]:4) zp[1]:3 [ idx ]
Allocated (was zp[2]:5) zp[2]:4 [ print::msg#3 ]
Allocated (was zp[2]:7) zp[2]:6 [ do10::fn#3 ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Tests calling into different function pointers which call a common sub-method
  // Upstart
  // Commodore 64 PRG executable file
.file [name="function-pointer-noarg-call-10.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(__start)
  // Global Constants & labels
  .label SCREEN = $400
  .label idx = 3
.segment Code
  // __start
__start: {
    jmp __init1
    // __start::__init1
  __init1:
    // [1] idx = 0 -- vbuz1=vbuc1 
    lda #0
    sta.z idx
    // [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1]
  __b1_from___init1:
    jmp __b1
    // __start::@1
  __b1:
    // [3] call main
    // [11] phi from __start::@1 to main [phi:__start::@1->main]
  main_from___b1:
    jsr main
    jmp __breturn
    // __start::@return
  __breturn:
    // [4] return 
    rts
}
  // world
world: {
    // [6] call print
    // [16] phi from world to print [phi:world->print]
  print_from_world:
    // [16] phi print::msg#3 = world::msg [phi:world->print#0] -- pbuz1=pbuc1 
    lda #<msg
    sta.z print.msg
    lda #>msg
    sta.z print.msg+1
    jsr print
    jmp __breturn
    // world::@return
  __breturn:
    // [7] return 
    rts
  .segment Data
    msg: .text "world "
    .byte 0
}
.segment Code
  // hello
hello: {
    // [9] call print
    // [16] phi from hello to print [phi:hello->print]
  print_from_hello:
    // [16] phi print::msg#3 = hello::msg [phi:hello->print#0] -- pbuz1=pbuc1 
    lda #<msg
    sta.z print.msg
    lda #>msg
    sta.z print.msg+1
    jsr print
    jmp __breturn
    // hello::@return
  __breturn:
    // [10] return 
    rts
  .segment Data
    msg: .text "hello "
    .byte 0
}
.segment Code
  // main
main: {
    // [12] call do10
    // [23] phi from main to do10 [phi:main->do10]
  do10_from_main:
    // [23] phi do10::fn#3 = &hello [phi:main->do10#0] -- pprz1=pprc1 
    lda #<hello
    sta.z do10.fn
    lda #>hello
    sta.z do10.fn+1
    jsr do10
    // [13] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    jmp __b1
    // main::@1
  __b1:
    // [14] call do10
    // [23] phi from main::@1 to do10 [phi:main::@1->do10]
  do10_from___b1:
    // [23] phi do10::fn#3 = &world [phi:main::@1->do10#0] -- pprz1=pprc1 
    lda #<world
    sta.z do10.fn
    lda #>world
    sta.z do10.fn+1
    jsr do10
    jmp __breturn
    // main::@return
  __breturn:
    // [15] return 
    rts
}
  // print
// void print(__zp(4) char *msg)
print: {
    .label msg = 4
    // [17] phi from print to print::@1 [phi:print->print::@1]
  __b1_from_print:
    // [17] phi print::i#2 = 0 [phi:print->print::@1#0] -- vbuyy=vbuc1 
    ldy #0
    jmp __b1
    // [17] phi from print::@1 to print::@1 [phi:print::@1->print::@1]
  __b1_from___b1:
    // [17] phi print::i#2 = print::i#1 [phi:print::@1->print::@1#0] -- register_copy 
    jmp __b1
    // print::@1
  __b1:
    // [18] SCREEN[idx] = print::msg#3[print::i#2] -- pbuc1_derefidx_vbuz1=pbuz2_derefidx_vbuyy 
    lda (msg),y
    ldx.z idx
    sta SCREEN,x
    // [19] idx = ++ idx -- vbuz1=_inc_vbuz1 
    inc.z idx
    // [20] print::i#1 = ++ print::i#2 -- vbuyy=_inc_vbuyy 
    iny
    // [21] if(0!=print::msg#3[print::i#1]) goto print::@1 -- 0_neq_pbuz1_derefidx_vbuyy_then_la1 
    lda (msg),y
    cmp #0
    bne __b1_from___b1
    jmp __breturn
    // print::@return
  __breturn:
    // [22] return 
    rts
}
  // do10
// void do10(__zp(6) void (*fn)())
do10: {
    .label i = 2
    .label fn = 6
    // [24] phi from do10 to do10::@1 [phi:do10->do10::@1]
  __b1_from_do10:
    // [24] phi do10::i#2 = 0 [phi:do10->do10::@1#0] -- vbuz1=vbuc1 
    lda #0
    sta.z i
    jmp __b1
    // [24] phi from do10::@2 to do10::@1 [phi:do10::@2->do10::@1]
  __b1_from___b2:
    // [24] phi do10::i#2 = do10::i#1 [phi:do10::@2->do10::@1#0] -- register_copy 
    jmp __b1
    // do10::@1
  __b1:
    // [25] callexecute *do10::fn#3  -- call__deref_pprz1 
    jsr icall1
    jmp __b2
    // do10::@2
  __b2:
    // [26] do10::i#1 = ++ do10::i#2 -- vbuz1=_inc_vbuz1 
    inc.z i
    // [27] if(do10::i#1!=$a) goto do10::@1 -- vbuz1_neq_vbuc1_then_la1 
    lda #$a
    cmp.z i
    bne __b1_from___b2
    jmp __breturn
    // do10::@return
  __breturn:
    // [28] return 
    rts
    // Outside Flow
  icall1:
    jmp (fn)
}
  // File Data

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __init1
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __b1_from___b1 with __b1
Replacing label __b1_from___b2 with __b1
Removing instruction __b1_from___init1:
Removing instruction main_from___b1:
Removing instruction __b1_from_main:
Removing instruction do10_from___b1:
Removing instruction __b1_from___b1:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __init1:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction print_from_world:
Removing instruction __breturn:
Removing instruction print_from_hello:
Removing instruction __breturn:
Removing instruction do10_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __b1_from_print:
Removing instruction __breturn:
Removing instruction __b1_from_do10:
Removing instruction __b2:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jmp __b1
Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination

FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void __start()
void do10(void (*fn)())
void (*do10::fn)()
void (*do10::fn#3)() // fn zp[2]:6
char do10::i
char do10::i#1 // i zp[1]:2 1501.5
char do10::i#2 // i zp[1]:2 2002.0
void hello()
__constant char hello::msg[7] = "hello "
__loadstore volatile char idx // zp[1]:3 38.125
void main()
void print(char *msg)
char print::i
char print::i#1 // reg byte y 151.5
char print::i#2 // reg byte y 101.0
char *print::msg
char *print::msg#3 // msg zp[2]:4 33.666666666666664
void world()
__constant char world::msg[7] = "world "

zp[2]:4 [ print::msg#3 ]
reg byte y [ print::i#2 print::i#1 ]
zp[2]:6 [ do10::fn#3 ]
zp[1]:2 [ do10::i#2 do10::i#1 ]
zp[1]:3 [ idx ]


FINAL ASSEMBLER
Score: 721

  // File Comments
// Tests calling into different function pointers which call a common sub-method
  // Upstart
  // Commodore 64 PRG executable file
.file [name="function-pointer-noarg-call-10.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(__start)
  // Global Constants & labels
  .label SCREEN = $400
  .label idx = 3
.segment Code
  // __start
__start: {
    // __start::__init1
    // volatile byte idx = 0
    // [1] idx = 0 -- vbuz1=vbuc1 
    lda #0
    sta.z idx
    // [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1]
    // __start::@1
    // [3] call main
    // [11] phi from __start::@1 to main [phi:__start::@1->main]
    jsr main
    // __start::@return
    // [4] return 
    rts
}
  // world
world: {
    // print("world ")
    // [6] call print
    // [16] phi from world to print [phi:world->print]
    // [16] phi print::msg#3 = world::msg [phi:world->print#0] -- pbuz1=pbuc1 
    lda #<msg
    sta.z print.msg
    lda #>msg
    sta.z print.msg+1
    jsr print
    // world::@return
    // }
    // [7] return 
    rts
  .segment Data
    msg: .text "world "
    .byte 0
}
.segment Code
  // hello
hello: {
    // print("hello ")
    // [9] call print
    // [16] phi from hello to print [phi:hello->print]
    // [16] phi print::msg#3 = hello::msg [phi:hello->print#0] -- pbuz1=pbuc1 
    lda #<msg
    sta.z print.msg
    lda #>msg
    sta.z print.msg+1
    jsr print
    // hello::@return
    // }
    // [10] return 
    rts
  .segment Data
    msg: .text "hello "
    .byte 0
}
.segment Code
  // main
main: {
    // do10(&hello)
    // [12] call do10
    // [23] phi from main to do10 [phi:main->do10]
    // [23] phi do10::fn#3 = &hello [phi:main->do10#0] -- pprz1=pprc1 
    lda #<hello
    sta.z do10.fn
    lda #>hello
    sta.z do10.fn+1
    jsr do10
    // [13] phi from main to main::@1 [phi:main->main::@1]
    // main::@1
    // do10(&world)
    // [14] call do10
    // [23] phi from main::@1 to do10 [phi:main::@1->do10]
    // [23] phi do10::fn#3 = &world [phi:main::@1->do10#0] -- pprz1=pprc1 
    lda #<world
    sta.z do10.fn
    lda #>world
    sta.z do10.fn+1
    jsr do10
    // main::@return
    // }
    // [15] return 
    rts
}
  // print
// void print(__zp(4) char *msg)
print: {
    .label msg = 4
    // [17] phi from print to print::@1 [phi:print->print::@1]
    // [17] phi print::i#2 = 0 [phi:print->print::@1#0] -- vbuyy=vbuc1 
    ldy #0
    // [17] phi from print::@1 to print::@1 [phi:print::@1->print::@1]
    // [17] phi print::i#2 = print::i#1 [phi:print::@1->print::@1#0] -- register_copy 
    // print::@1
  __b1:
    // SCREEN[idx++] = msg[i++]
    // [18] SCREEN[idx] = print::msg#3[print::i#2] -- pbuc1_derefidx_vbuz1=pbuz2_derefidx_vbuyy 
    lda (msg),y
    ldx.z idx
    sta SCREEN,x
    // SCREEN[idx++] = msg[i++];
    // [19] idx = ++ idx -- vbuz1=_inc_vbuz1 
    inc.z idx
    // [20] print::i#1 = ++ print::i#2 -- vbuyy=_inc_vbuyy 
    iny
    // while(msg[i])
    // [21] if(0!=print::msg#3[print::i#1]) goto print::@1 -- 0_neq_pbuz1_derefidx_vbuyy_then_la1 
    lda (msg),y
    cmp #0
    bne __b1
    // print::@return
    // }
    // [22] return 
    rts
}
  // do10
// void do10(__zp(6) void (*fn)())
do10: {
    .label i = 2
    .label fn = 6
    // [24] phi from do10 to do10::@1 [phi:do10->do10::@1]
    // [24] phi do10::i#2 = 0 [phi:do10->do10::@1#0] -- vbuz1=vbuc1 
    lda #0
    sta.z i
    // [24] phi from do10::@2 to do10::@1 [phi:do10::@2->do10::@1]
    // [24] phi do10::i#2 = do10::i#1 [phi:do10::@2->do10::@1#0] -- register_copy 
    // do10::@1
  __b1:
    // (*fn)()
    // [25] callexecute *do10::fn#3  -- call__deref_pprz1 
    jsr icall1
    // do10::@2
    // for( byte i: 0..9)
    // [26] do10::i#1 = ++ do10::i#2 -- vbuz1=_inc_vbuz1 
    inc.z i
    // [27] if(do10::i#1!=$a) goto do10::@1 -- vbuz1_neq_vbuc1_then_la1 
    lda #$a
    cmp.z i
    bne __b1
    // do10::@return
    // }
    // [28] return 
    rts
    // Outside Flow
  icall1:
    jmp (fn)
}
  // File Data

