Inlined call call __init

CONTROL FLOW GRAPH SSA

void main()
main: scope:[main]  from __start::@1
  idx#23 = phi( __start::@1/idx#26 )
  print::msg#0 = main::msg
  call print
  to:main::@1
main::@1: scope:[main]  from main
  idx#12 = phi( main/idx#8 )
  idx#0 = idx#12
  print::msg#1 = main::msg1
  call print
  to:main::@2
main::@2: scope:[main]  from main::@1
  idx#13 = phi( main::@1/idx#8 )
  idx#1 = idx#13
  call print1
  to:main::@3
main::@3: scope:[main]  from main::@2
  idx#14 = phi( main::@2/idx#6 )
  idx#2 = idx#14
  to:main::@return
main::@return: scope:[main]  from main::@3
  idx#15 = phi( main::@3/idx#2 )
  idx#3 = idx#15
  return 
  to:@return

void print1()
print1: scope:[print1]  from main::@2
  idx#24 = phi( main::@2/idx#1 )
  print::msg#2 = print1::msg
  call print
  to:print1::@1
print1::@1: scope:[print1]  from print1
  idx#16 = phi( print1/idx#8 )
  idx#4 = idx#16
  print::msg#3 = print1::msg1
  call print
  to:print1::@2
print1::@2: scope:[print1]  from print1::@1
  idx#17 = phi( print1::@1/idx#8 )
  idx#5 = idx#17
  to:print1::@return
print1::@return: scope:[print1]  from print1::@2
  idx#18 = phi( print1::@2/idx#5 )
  idx#6 = idx#18
  return 
  to:@return

void print(char *msg)
print: scope:[print]  from main main::@1 print1 print1::@1
  idx#27 = phi( main/idx#23, main::@1/idx#0, print1/idx#24, print1::@1/idx#4 )
  print::msg#7 = phi( main/print::msg#0, main::@1/print::msg#1, print1/print::msg#2, print1::@1/print::msg#3 )
  to:print::@1
print::@1: scope:[print]  from print print::@2
  idx#25 = phi( print/idx#27, print::@2/idx#7 )
  print::msg#5 = phi( print/print::msg#7, print::@2/print::msg#4 )
  print::$0 = 0 != *print::msg#5
  if(print::$0) goto print::@2
  to:print::@return
print::@2: scope:[print]  from print::@1
  idx#19 = phi( print::@1/idx#25 )
  print::msg#6 = phi( print::@1/print::msg#5 )
  SCREEN[idx#19] = *print::msg#6
  idx#7 = ++ idx#19
  print::msg#4 = ++ print::msg#6
  to:print::@1
print::@return: scope:[print]  from print::@1
  idx#20 = phi( print::@1/idx#25 )
  idx#8 = idx#20
  return 
  to:@return

void __start()
__start: scope:[__start]  from
  to:__start::__init1
__start::__init1: scope:[__start]  from __start
  idx#9 = 0
  to:__start::@1
__start::@1: scope:[__start]  from __start::__init1
  idx#26 = phi( __start::__init1/idx#9 )
  call main
  to:__start::@2
__start::@2: scope:[__start]  from __start::@1
  idx#21 = phi( __start::@1/idx#3 )
  idx#10 = idx#21
  to:__start::@return
__start::@return: scope:[__start]  from __start::@2
  idx#22 = phi( __start::@2/idx#10 )
  idx#11 = idx#22
  return 
  to:@return

SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
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#23
char idx#24
char idx#25
char idx#26
char idx#27
char idx#3
char idx#4
char idx#5
char idx#6
char idx#7
char idx#8
char idx#9
void main()
__constant char main::msg[2] = "a"
__constant char main::msg1[2] = "b"
void print(char *msg)
bool print::$0
char *print::msg
char *print::msg#0
char *print::msg#1
char *print::msg#2
char *print::msg#3
char *print::msg#4
char *print::msg#5
char *print::msg#6
char *print::msg#7
void print1()
__constant char print1::msg[2] = "c"
__constant char print1::msg1[2] = "a"

Adding number conversion cast (unumber) 0 in print::$0 = 0 != *print::msg#5
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 idx#0 = idx#12 
Alias idx#1 = idx#13 
Alias idx#14 = idx#2 idx#15 idx#3 
Alias idx#16 = idx#4 
Alias idx#17 = idx#5 idx#18 idx#6 
Alias print::msg#5 = print::msg#6 
Alias idx#19 = idx#25 idx#20 idx#8 
Alias idx#26 = idx#9 
Alias idx#10 = idx#21 idx#22 idx#11 
Successful SSA optimization Pass2AliasElimination
Identical Phi Values idx#23 idx#26
Identical Phi Values idx#0 idx#19
Identical Phi Values idx#1 idx#19
Identical Phi Values idx#14 idx#17
Identical Phi Values idx#24 idx#1
Identical Phi Values idx#16 idx#19
Identical Phi Values idx#17 idx#19
Identical Phi Values idx#10 idx#14
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition print::$0 [21] if(0!=*print::msg#5) goto print::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant print::msg#0 = main::msg
Constant print::msg#1 = main::msg1
Constant print::msg#2 = print1::msg
Constant print::msg#3 = print1::msg1
Constant idx#26 = 0
Successful SSA optimization Pass2ConstantIdentification
Consolidated constant strings into msg
Successful SSA optimization Pass2ConstantStringConsolidation
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 constant with var siblings print::msg#0
Inlining constant with var siblings print::msg#1
Inlining constant with var siblings print::msg#2
Inlining constant with var siblings print::msg#3
Inlining constant with var siblings idx#26
Constant inlined print::msg#3 = msg
Constant inlined print::msg#2 = print1::msg
Constant inlined print::msg#1 = main::msg1
Constant inlined print::msg#0 = msg
Constant inlined print1::msg1 = msg
Constant inlined main::msg = msg
Constant inlined idx#26 = 0
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@2
Adding NOP phi() at start of main::@3
Adding NOP phi() at start of print1::@2
CALL GRAPH
Calls in [main] to print:1 print:3 print1:5 
Calls in [print1] to print:20 print:22 

Created 4 initial phi equivalence classes
Coalesced [2] idx#28 = idx#19
Coalesced [9] print::msg#8 = print::msg#7
Coalesced (already) [10] idx#31 = idx#27
Coalesced [17] print::msg#9 = print::msg#4
Coalesced [18] idx#32 = idx#7
Coalesced (already) [19] idx#29 = idx#19
Coalesced (already) [21] idx#30 = idx#19
Coalesced down to 2 phi equivalence classes
Culled Empty Block label main::@3
Culled Empty Block label print1::@2
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@2
Adding NOP phi() at start of print1
Adding NOP phi() at start of print1::@1

FINAL CONTROL FLOW GRAPH

void main()
main: scope:[main]  from
  [0] phi()
  [1] call print
  to:main::@1
main::@1: scope:[main]  from main
  [2] phi()
  [3] call print
  to:main::@2
main::@2: scope:[main]  from main::@1
  [4] phi()
  [5] call print1
  to:main::@return
main::@return: scope:[main]  from main::@2
  [6] return 
  to:@return

void print(char *msg)
print: scope:[print]  from main main::@1 print1 print1::@1
  [7] idx#27 = phi( main/0, main::@1/idx#19, print1/idx#19, print1::@1/idx#19 )
  [7] print::msg#7 = phi( main/msg, main::@1/main::msg1, print1/print1::msg, print1::@1/msg )
  to:print::@1
print::@1: scope:[print]  from print print::@2
  [8] idx#19 = phi( print/idx#27, print::@2/idx#7 )
  [8] print::msg#5 = phi( print/print::msg#7, print::@2/print::msg#4 )
  [9] if(0!=*print::msg#5) goto print::@2
  to:print::@return
print::@return: scope:[print]  from print::@1
  [10] return 
  to:@return
print::@2: scope:[print]  from print::@1
  [11] SCREEN[idx#19] = *print::msg#5
  [12] idx#7 = ++ idx#19
  [13] print::msg#4 = ++ print::msg#5
  to:print::@1

void print1()
print1: scope:[print1]  from main::@2
  [14] phi()
  [15] call print
  to:print1::@1
print1::@1: scope:[print1]  from print1
  [16] phi()
  [17] call print
  to:print1::@return
print1::@return: scope:[print1]  from print1::@1
  [18] return 
  to:@return


VARIABLE REGISTER WEIGHTS
char idx
char idx#19 // 284.3636363636364
char idx#27 // 125.0
char idx#7 // 1001.0
void main()
void print(char *msg)
char *print::msg
char *print::msg#4 // 2002.0
char *print::msg#5 // 1026.25
char *print::msg#7 // 101.0
void print1()

Initial phi equivalence classes
[ idx#27 idx#19 idx#7 ]
[ print::msg#5 print::msg#7 print::msg#4 ]
Complete equivalence classes
[ idx#27 idx#19 idx#7 ]
[ print::msg#5 print::msg#7 print::msg#4 ]
Allocated zp[2]:2 [ print::msg#5 print::msg#7 print::msg#4 ]
Allocated zp[1]:4 [ idx#27 idx#19 idx#7 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [9] if(0!=*print::msg#5) goto print::@2 [ idx#19 print::msg#5 ] ( print:1 [ idx#19 print::msg#5 ] { }  print:3 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  print1:5::print:15 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  print1:5::print:17 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  ) always clobbers reg byte a reg byte y 
Removing always clobbered register reg byte a as potential for zp[1]:4 [ idx#27 idx#19 idx#7 ]
Removing always clobbered register reg byte y as potential for zp[1]:4 [ idx#27 idx#19 idx#7 ]
Statement [11] SCREEN[idx#19] = *print::msg#5 [ idx#19 print::msg#5 ] ( print:1 [ idx#19 print::msg#5 ] { }  print:3 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  print1:5::print:15 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  print1:5::print:17 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  ) always clobbers reg byte a reg byte y 
Statement [9] if(0!=*print::msg#5) goto print::@2 [ idx#19 print::msg#5 ] ( print:1 [ idx#19 print::msg#5 ] { }  print:3 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  print1:5::print:15 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  print1:5::print:17 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  ) always clobbers reg byte a reg byte y 
Statement [11] SCREEN[idx#19] = *print::msg#5 [ idx#19 print::msg#5 ] ( print:1 [ idx#19 print::msg#5 ] { }  print:3 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  print1:5::print:15 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  print1:5::print:17 [ idx#19 print::msg#5 ] { { idx#19 = idx#27 } }  ) always clobbers reg byte a reg byte y 
Potential registers zp[1]:4 [ idx#27 idx#19 idx#7 ] : zp[1]:4 , reg byte x , 
Potential registers zp[2]:2 [ print::msg#5 print::msg#7 print::msg#4 ] : zp[2]:2 , 

REGISTER UPLIFT SCOPES
Uplift Scope [print] 3,129.25: zp[2]:2 [ print::msg#5 print::msg#7 print::msg#4 ] 
Uplift Scope [] 1,410.36: zp[1]:4 [ idx#27 idx#19 idx#7 ] 
Uplift Scope [main] 
Uplift Scope [print1] 

Uplifting [print] best 648 combination zp[2]:2 [ print::msg#5 print::msg#7 print::msg#4 ] 
Uplifting [] best 585 combination reg byte x [ idx#27 idx#19 idx#7 ] 
Uplifting [main] best 585 combination 
Uplifting [print1] best 585 combination 

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Demonstrates problems with local labels overwriting global labels
// This should produce "abca" - but produces "abcc" because the local variable containing "c" overrides the global variable containing "a"
  // Upstart
  // Commodore 64 PRG executable file
.file [name="global-label-problem.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
  // Screen pointer and index
  .label SCREEN = $400
.segment Code
  // main
main: {
    // [1] call print
    // [7] phi from main to print [phi:main->print]
  print_from_main:
    // [7] phi idx#27 = 0 [phi:main->print#0] -- vbuxx=vbuc1 
    ldx #0
    // [7] phi print::msg#7 = msg [phi:main->print#1] -- pbuz1=pbuc1 
    lda #<msg
    sta.z print.msg
    lda #>msg
    sta.z print.msg+1
    jsr print
    // [2] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    jmp __b1
    // main::@1
  __b1:
    // [3] call print
    // [7] phi from main::@1 to print [phi:main::@1->print]
  print_from___b1:
    // [7] phi idx#27 = idx#19 [phi:main::@1->print#0] -- register_copy 
    // [7] phi print::msg#7 = main::msg1 [phi:main::@1->print#1] -- pbuz1=pbuc1 
    lda #<msg1
    sta.z print.msg
    lda #>msg1
    sta.z print.msg+1
    jsr print
    // [4] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
  __b2_from___b1:
    jmp __b2
    // main::@2
  __b2:
    // [5] call print1
    // [14] phi from main::@2 to print1 [phi:main::@2->print1]
  print1_from___b2:
    jsr print1
    jmp __breturn
    // main::@return
  __breturn:
    // [6] return 
    rts
  .segment Data
    msg1: .text "b"
    .byte 0
}
.segment Code
  // print
// void print(__zp(2) char *msg)
print: {
    .label msg = 2
    // [8] phi from print print::@2 to print::@1 [phi:print/print::@2->print::@1]
  __b1_from_print:
  __b1_from___b2:
    // [8] phi idx#19 = idx#27 [phi:print/print::@2->print::@1#0] -- register_copy 
    // [8] phi print::msg#5 = print::msg#7 [phi:print/print::@2->print::@1#1] -- register_copy 
    jmp __b1
    // print::@1
  __b1:
    // [9] if(0!=*print::msg#5) goto print::@2 -- 0_neq__deref_pbuz1_then_la1 
    ldy #0
    lda (msg),y
    cmp #0
    bne __b2
    jmp __breturn
    // print::@return
  __breturn:
    // [10] return 
    rts
    // print::@2
  __b2:
    // [11] SCREEN[idx#19] = *print::msg#5 -- pbuc1_derefidx_vbuxx=_deref_pbuz1 
    ldy #0
    lda (msg),y
    sta SCREEN,x
    // [12] idx#7 = ++ idx#19 -- vbuxx=_inc_vbuxx 
    inx
    // [13] print::msg#4 = ++ print::msg#5 -- pbuz1=_inc_pbuz1 
    inc.z msg
    bne !+
    inc.z msg+1
  !:
    jmp __b1_from___b2
}
  // print1
print1: {
    // [15] call print
    // [7] phi from print1 to print [phi:print1->print]
  print_from_print1:
    // [7] phi idx#27 = idx#19 [phi:print1->print#0] -- register_copy 
    // [7] phi print::msg#7 = print1::msg [phi:print1->print#1] -- pbuz1=pbuc1 
    lda #<msg
    sta.z print.msg
    lda #>msg
    sta.z print.msg+1
    jsr print
    // [16] phi from print1 to print1::@1 [phi:print1->print1::@1]
  __b1_from_print1:
    jmp __b1
    // print1::@1
  __b1:
    // [17] call print
    // [7] phi from print1::@1 to print [phi:print1::@1->print]
  print_from___b1:
    // [7] phi idx#27 = idx#19 [phi:print1::@1->print#0] -- register_copy 
    // [7] phi print::msg#7 = msg [phi:print1::@1->print#1] -- pbuz1=pbuc1 
    lda #<@msg
    sta.z print.msg
    lda #>@msg
    sta.z print.msg+1
    jsr print
    jmp __breturn
    // print1::@return
  __breturn:
    // [18] return 
    rts
  .segment Data
    msg: .text "c"
    .byte 0
}
  // File Data
  msg: .text "a"
  .byte 0

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __b1_from___b2 with __b1
Removing instruction __b1_from_main:
Removing instruction print_from___b1:
Removing instruction __b2_from___b1:
Removing instruction print1_from___b2:
Removing instruction __b1_from_print:
Removing instruction __b1_from___b2:
Removing instruction __b1_from_print1:
Removing instruction print_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction print_from_main:
Removing instruction __b1:
Removing instruction __b2:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction print_from_print1:
Removing instruction __b1:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
char idx
char idx#19 // reg byte x 284.3636363636364
char idx#27 // reg byte x 125.0
char idx#7 // reg byte x 1001.0
void main()
__constant char main::msg1[2] = "b"
__constant char msg[2] = "a"
void print(char *msg)
char *print::msg
char *print::msg#4 // msg zp[2]:2 2002.0
char *print::msg#5 // msg zp[2]:2 1026.25
char *print::msg#7 // msg zp[2]:2 101.0
void print1()
__constant char print1::msg[2] = "c"

reg byte x [ idx#27 idx#19 idx#7 ]
zp[2]:2 [ print::msg#5 print::msg#7 print::msg#4 ]


FINAL ASSEMBLER
Score: 510

  // File Comments
// Demonstrates problems with local labels overwriting global labels
// This should produce "abca" - but produces "abcc" because the local variable containing "c" overrides the global variable containing "a"
  // Upstart
  // Commodore 64 PRG executable file
.file [name="global-label-problem.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
  // Screen pointer and index
  .label SCREEN = $400
.segment Code
  // main
main: {
    // print("a")
    // [1] call print
    // [7] phi from main to print [phi:main->print]
    // [7] phi idx#27 = 0 [phi:main->print#0] -- vbuxx=vbuc1 
    ldx #0
    // [7] phi print::msg#7 = msg [phi:main->print#1] -- pbuz1=pbuc1 
    lda #<msg
    sta.z print.msg
    lda #>msg
    sta.z print.msg+1
    jsr print
    // [2] phi from main to main::@1 [phi:main->main::@1]
    // main::@1
    // print("b")
    // [3] call print
    // [7] phi from main::@1 to print [phi:main::@1->print]
    // [7] phi idx#27 = idx#19 [phi:main::@1->print#0] -- register_copy 
    // [7] phi print::msg#7 = main::msg1 [phi:main::@1->print#1] -- pbuz1=pbuc1 
    lda #<msg1
    sta.z print.msg
    lda #>msg1
    sta.z print.msg+1
    jsr print
    // [4] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
    // main::@2
    // print1()
    // [5] call print1
    // [14] phi from main::@2 to print1 [phi:main::@2->print1]
    jsr print1
    // main::@return
    // }
    // [6] return 
    rts
  .segment Data
    msg1: .text "b"
    .byte 0
}
.segment Code
  // print
// void print(__zp(2) char *msg)
print: {
    .label msg = 2
    // [8] phi from print print::@2 to print::@1 [phi:print/print::@2->print::@1]
    // [8] phi idx#19 = idx#27 [phi:print/print::@2->print::@1#0] -- register_copy 
    // [8] phi print::msg#5 = print::msg#7 [phi:print/print::@2->print::@1#1] -- register_copy 
    // print::@1
  __b1:
    // while(*msg)
    // [9] if(0!=*print::msg#5) goto print::@2 -- 0_neq__deref_pbuz1_then_la1 
    ldy #0
    lda (msg),y
    cmp #0
    bne __b2
    // print::@return
    // }
    // [10] return 
    rts
    // print::@2
  __b2:
    // SCREEN[idx++] = *msg++
    // [11] SCREEN[idx#19] = *print::msg#5 -- pbuc1_derefidx_vbuxx=_deref_pbuz1 
    ldy #0
    lda (msg),y
    sta SCREEN,x
    // SCREEN[idx++] = *msg++;
    // [12] idx#7 = ++ idx#19 -- vbuxx=_inc_vbuxx 
    inx
    // [13] print::msg#4 = ++ print::msg#5 -- pbuz1=_inc_pbuz1 
    inc.z msg
    bne !+
    inc.z msg+1
  !:
    jmp __b1
}
  // print1
print1: {
    // print("c")
    // [15] call print
    // [7] phi from print1 to print [phi:print1->print]
    // [7] phi idx#27 = idx#19 [phi:print1->print#0] -- register_copy 
    // [7] phi print::msg#7 = print1::msg [phi:print1->print#1] -- pbuz1=pbuc1 
    lda #<msg
    sta.z print.msg
    lda #>msg
    sta.z print.msg+1
    jsr print
    // [16] phi from print1 to print1::@1 [phi:print1->print1::@1]
    // print1::@1
    // print("a")
    // [17] call print
    // [7] phi from print1::@1 to print [phi:print1::@1->print]
    // [7] phi idx#27 = idx#19 [phi:print1::@1->print#0] -- register_copy 
    // [7] phi print::msg#7 = msg [phi:print1::@1->print#1] -- pbuz1=pbuc1 
    lda #<@msg
    sta.z print.msg
    lda #>@msg
    sta.z print.msg+1
    jsr print
    // print1::@return
    // }
    // [18] return 
    rts
  .segment Data
    msg: .text "c"
    .byte 0
}
  // File Data
  msg: .text "a"
  .byte 0

