Inlined call call __init

CONTROL FLOW GRAPH SSA

void str_cpy(char *dst , const char *src)
str_cpy: scope:[str_cpy]  from main main::@1
  str_cpy::dst#4 = phi( main/str_cpy::dst#1, main::@1/str_cpy::dst#2 )
  str_cpy::src#4 = phi( main/str_cpy::src#1, main::@1/str_cpy::src#2 )
  to:str_cpy::@1
str_cpy::@1: scope:[str_cpy]  from str_cpy str_cpy::@1
  str_cpy::dst#3 = phi( str_cpy/str_cpy::dst#4, str_cpy::@1/str_cpy::dst#0 )
  str_cpy::src#3 = phi( str_cpy/str_cpy::src#4, str_cpy::@1/str_cpy::src#0 )
  *str_cpy::dst#3 = *str_cpy::src#3
  str_cpy::$0 = *str_cpy::dst#3
  str_cpy::dst#0 = ++ str_cpy::dst#3
  str_cpy::src#0 = ++ str_cpy::src#3
  str_cpy::$1 = 0 != str_cpy::$0
  if(str_cpy::$1) goto str_cpy::@1
  to:str_cpy::@return
str_cpy::@return: scope:[str_cpy]  from str_cpy::@1
  return 
  to:@return

void main()
main: scope:[main]  from __start::@1
  str_cpy::dst#1 = dst1
  str_cpy::src#1 = main::src
  call str_cpy
  to:main::@1
main::@1: scope:[main]  from main
  str_cpy::dst#2 = dst2
  str_cpy::src#2 = main::src1
  call str_cpy
  to:main::@2
main::@2: scope:[main]  from main::@1
  to:main::@return
main::@return: scope:[main]  from main::@2
  return 
  to:@return

void __start()
__start: scope:[__start]  from
  to:__start::__init1
__start::__init1: scope:[__start]  from __start
  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
void __start()
__constant char *dst1 = (char *)$400
__constant char *dst2 = (char *)$428
void main()
__constant char main::src[6] = "hello"
__constant char main::src1[6] = "world"
void str_cpy(char *dst , const char *src)
char str_cpy::$0
bool str_cpy::$1
char *str_cpy::dst
char *str_cpy::dst#0
char *str_cpy::dst#1
char *str_cpy::dst#2
char *str_cpy::dst#3
char *str_cpy::dst#4
const char *str_cpy::src
const char *str_cpy::src#0
const char *str_cpy::src#1
const char *str_cpy::src#2
const char *str_cpy::src#3
const char *str_cpy::src#4

Adding number conversion cast (unumber) 0 in str_cpy::$1 = 0 != str_cpy::$0
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (char *) 1024
Simplifying constant pointer cast (char *) 1064
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simple Condition str_cpy::$1 [7] if(0!=str_cpy::$0) goto str_cpy::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant str_cpy::dst#1 = dst1
Constant str_cpy::src#1 = main::src
Constant str_cpy::dst#2 = dst2
Constant str_cpy::src#2 = main::src1
Successful SSA optimization Pass2ConstantIdentification
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 str_cpy::dst#1
Inlining constant with var siblings str_cpy::src#1
Inlining constant with var siblings str_cpy::dst#2
Inlining constant with var siblings str_cpy::src#2
Constant inlined str_cpy::src#1 = main::src
Constant inlined str_cpy::src#2 = main::src1
Constant inlined str_cpy::dst#1 = dst1
Constant inlined str_cpy::dst#2 = dst2
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting str_cpy::@2(between str_cpy::@1 and str_cpy::@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 [main] to str_cpy:1 str_cpy:3 

Created 4 initial phi equivalence classes
Coalesced [7] str_cpy::src#5 = str_cpy::src#4
Coalesced [8] str_cpy::dst#5 = str_cpy::dst#4
Coalesced [16] str_cpy::src#6 = str_cpy::src#0
Coalesced [17] str_cpy::dst#6 = str_cpy::dst#0
Coalesced down to 2 phi equivalence classes
Culled Empty Block label main::@2
Culled Empty Block label str_cpy::@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 str_cpy
  to:main::@1
main::@1: scope:[main]  from main
  [2] phi()
  [3] call str_cpy
  to:main::@return
main::@return: scope:[main]  from main::@1
  [4] return 
  to:@return

void str_cpy(char *dst , const char *src)
str_cpy: scope:[str_cpy]  from main main::@1
  [5] str_cpy::dst#4 = phi( main/dst1, main::@1/dst2 )
  [5] str_cpy::src#4 = phi( main/main::src, main::@1/main::src1 )
  to:str_cpy::@1
str_cpy::@1: scope:[str_cpy]  from str_cpy str_cpy::@1
  [6] str_cpy::dst#3 = phi( str_cpy/str_cpy::dst#4, str_cpy::@1/str_cpy::dst#0 )
  [6] str_cpy::src#3 = phi( str_cpy/str_cpy::src#4, str_cpy::@1/str_cpy::src#0 )
  [7] *str_cpy::dst#3 = *str_cpy::src#3
  [8] str_cpy::$0 = *str_cpy::dst#3
  [9] str_cpy::dst#0 = ++ str_cpy::dst#3
  [10] str_cpy::src#0 = ++ str_cpy::src#3
  [11] if(0!=str_cpy::$0) goto str_cpy::@1
  to:str_cpy::@return
str_cpy::@return: scope:[str_cpy]  from str_cpy::@1
  [12] return 
  to:@return


VARIABLE REGISTER WEIGHTS
void main()
void str_cpy(char *dst , const char *src)
char str_cpy::$0 // 67.33333333333333
char *str_cpy::dst
char *str_cpy::dst#0 // 67.33333333333333
char *str_cpy::dst#3 // 138.33333333333331
char *str_cpy::dst#4 // 11.0
const char *str_cpy::src
const char *str_cpy::src#0 // 101.0
const char *str_cpy::src#3 // 78.5
const char *str_cpy::src#4 // 11.0

Initial phi equivalence classes
[ str_cpy::src#3 str_cpy::src#4 str_cpy::src#0 ]
[ str_cpy::dst#3 str_cpy::dst#4 str_cpy::dst#0 ]
Added variable str_cpy::$0 to live range equivalence class [ str_cpy::$0 ]
Complete equivalence classes
[ str_cpy::src#3 str_cpy::src#4 str_cpy::src#0 ]
[ str_cpy::dst#3 str_cpy::dst#4 str_cpy::dst#0 ]
[ str_cpy::$0 ]
Allocated zp[2]:2 [ str_cpy::dst#3 str_cpy::dst#4 str_cpy::dst#0 ]
Allocated zp[2]:4 [ str_cpy::src#3 str_cpy::src#4 str_cpy::src#0 ]
Allocated zp[1]:6 [ str_cpy::$0 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [7] *str_cpy::dst#3 = *str_cpy::src#3 [ str_cpy::src#3 str_cpy::dst#3 ] ( str_cpy:1 [ str_cpy::src#3 str_cpy::dst#3 ] { }  str_cpy:3 [ str_cpy::src#3 str_cpy::dst#3 ] { }  ) always clobbers reg byte a reg byte y 
Statement [8] str_cpy::$0 = *str_cpy::dst#3 [ str_cpy::src#3 str_cpy::dst#3 str_cpy::$0 ] ( str_cpy:1 [ str_cpy::src#3 str_cpy::dst#3 str_cpy::$0 ] { }  str_cpy:3 [ str_cpy::src#3 str_cpy::dst#3 str_cpy::$0 ] { }  ) always clobbers reg byte a reg byte y 
Potential registers zp[2]:4 [ str_cpy::src#3 str_cpy::src#4 str_cpy::src#0 ] : zp[2]:4 , 
Potential registers zp[2]:2 [ str_cpy::dst#3 str_cpy::dst#4 str_cpy::dst#0 ] : zp[2]:2 , 
Potential registers zp[1]:6 [ str_cpy::$0 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y , 

REGISTER UPLIFT SCOPES
Uplift Scope [str_cpy] 216.67: zp[2]:2 [ str_cpy::dst#3 str_cpy::dst#4 str_cpy::dst#0 ] 190.5: zp[2]:4 [ str_cpy::src#3 str_cpy::src#4 str_cpy::src#0 ] 67.33: zp[1]:6 [ str_cpy::$0 ] 
Uplift Scope [main] 
Uplift Scope [] 

Uplifting [str_cpy] best 655 combination zp[2]:2 [ str_cpy::dst#3 str_cpy::dst#4 str_cpy::dst#0 ] zp[2]:4 [ str_cpy::src#3 str_cpy::src#4 str_cpy::src#0 ] reg byte a [ str_cpy::$0 ] 
Uplifting [main] best 655 combination 
Uplifting [] best 655 combination 

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
  // Upstart
  // Commodore 64 PRG executable file
.file [name="strcpy-0.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 dst1 = $400
  .label dst2 = $428
.segment Code
  // main
main: {
    // [1] call str_cpy
    // [5] phi from main to str_cpy [phi:main->str_cpy]
  str_cpy_from_main:
    // [5] phi str_cpy::dst#4 = dst1 [phi:main->str_cpy#0] -- pbuz1=pbuc1 
    lda #<dst1
    sta.z str_cpy.dst
    lda #>dst1
    sta.z str_cpy.dst+1
    // [5] phi str_cpy::src#4 = main::src [phi:main->str_cpy#1] -- pbuz1=pbuc1 
    lda #<src
    sta.z str_cpy.src
    lda #>src
    sta.z str_cpy.src+1
    jsr str_cpy
    // [2] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    jmp __b1
    // main::@1
  __b1:
    // [3] call str_cpy
    // [5] phi from main::@1 to str_cpy [phi:main::@1->str_cpy]
  str_cpy_from___b1:
    // [5] phi str_cpy::dst#4 = dst2 [phi:main::@1->str_cpy#0] -- pbuz1=pbuc1 
    lda #<dst2
    sta.z str_cpy.dst
    lda #>dst2
    sta.z str_cpy.dst+1
    // [5] phi str_cpy::src#4 = main::src1 [phi:main::@1->str_cpy#1] -- pbuz1=pbuc1 
    lda #<src1
    sta.z str_cpy.src
    lda #>src1
    sta.z str_cpy.src+1
    jsr str_cpy
    jmp __breturn
    // main::@return
  __breturn:
    // [4] return 
    rts
  .segment Data
    src: .text "hello"
    .byte 0
    src1: .text "world"
    .byte 0
}
.segment Code
  // str_cpy
// void str_cpy(__zp(2) char *dst, __zp(4) const char *src)
str_cpy: {
    .label dst = 2
    .label src = 4
    // [6] phi from str_cpy str_cpy::@1 to str_cpy::@1 [phi:str_cpy/str_cpy::@1->str_cpy::@1]
  __b1_from_str_cpy:
  __b1_from___b1:
    // [6] phi str_cpy::dst#3 = str_cpy::dst#4 [phi:str_cpy/str_cpy::@1->str_cpy::@1#0] -- register_copy 
    // [6] phi str_cpy::src#3 = str_cpy::src#4 [phi:str_cpy/str_cpy::@1->str_cpy::@1#1] -- register_copy 
    jmp __b1
    // str_cpy::@1
  __b1:
    // [7] *str_cpy::dst#3 = *str_cpy::src#3 -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (src),y
    ldy #0
    sta (dst),y
    // [8] str_cpy::$0 = *str_cpy::dst#3 -- vbuaa=_deref_pbuz1 
    ldy #0
    lda (dst),y
    // [9] str_cpy::dst#0 = ++ str_cpy::dst#3 -- pbuz1=_inc_pbuz1 
    inc.z dst
    bne !+
    inc.z dst+1
  !:
    // [10] str_cpy::src#0 = ++ str_cpy::src#3 -- pbuz1=_inc_pbuz1 
    inc.z src
    bne !+
    inc.z src+1
  !:
    // [11] if(0!=str_cpy::$0) goto str_cpy::@1 -- 0_neq_vbuaa_then_la1 
    cmp #0
    bne __b1_from___b1
    jmp __breturn
    // str_cpy::@return
  __breturn:
    // [12] return 
    rts
}
  // File Data

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction ldy #0
Removing instruction ldy #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __b1_from___b1 with __b1
Removing instruction __b1_from_main:
Removing instruction str_cpy_from___b1:
Removing instruction __b1_from_str_cpy:
Removing instruction __b1_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction str_cpy_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
__constant char *dst1 = (char *) 1024
__constant char *dst2 = (char *) 1064
void main()
__constant char main::src[6] = "hello"
__constant char main::src1[6] = "world"
void str_cpy(char *dst , const char *src)
char str_cpy::$0 // reg byte a 67.33333333333333
char *str_cpy::dst
char *str_cpy::dst#0 // dst zp[2]:2 67.33333333333333
char *str_cpy::dst#3 // dst zp[2]:2 138.33333333333331
char *str_cpy::dst#4 // dst zp[2]:2 11.0
const char *str_cpy::src
const char *str_cpy::src#0 // src zp[2]:4 101.0
const char *str_cpy::src#3 // src zp[2]:4 78.5
const char *str_cpy::src#4 // src zp[2]:4 11.0

zp[2]:4 [ str_cpy::src#3 str_cpy::src#4 str_cpy::src#0 ]
zp[2]:2 [ str_cpy::dst#3 str_cpy::dst#4 str_cpy::dst#0 ]
reg byte a [ str_cpy::$0 ]


FINAL ASSEMBLER
Score: 549

  // File Comments
  // Upstart
  // Commodore 64 PRG executable file
.file [name="strcpy-0.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 dst1 = $400
  .label dst2 = $428
.segment Code
  // main
main: {
    // str_cpy(dst1, "hello")
    // [1] call str_cpy
    // [5] phi from main to str_cpy [phi:main->str_cpy]
    // [5] phi str_cpy::dst#4 = dst1 [phi:main->str_cpy#0] -- pbuz1=pbuc1 
    lda #<dst1
    sta.z str_cpy.dst
    lda #>dst1
    sta.z str_cpy.dst+1
    // [5] phi str_cpy::src#4 = main::src [phi:main->str_cpy#1] -- pbuz1=pbuc1 
    lda #<src
    sta.z str_cpy.src
    lda #>src
    sta.z str_cpy.src+1
    jsr str_cpy
    // [2] phi from main to main::@1 [phi:main->main::@1]
    // main::@1
    // str_cpy(dst2, "world")
    // [3] call str_cpy
    // [5] phi from main::@1 to str_cpy [phi:main::@1->str_cpy]
    // [5] phi str_cpy::dst#4 = dst2 [phi:main::@1->str_cpy#0] -- pbuz1=pbuc1 
    lda #<dst2
    sta.z str_cpy.dst
    lda #>dst2
    sta.z str_cpy.dst+1
    // [5] phi str_cpy::src#4 = main::src1 [phi:main::@1->str_cpy#1] -- pbuz1=pbuc1 
    lda #<src1
    sta.z str_cpy.src
    lda #>src1
    sta.z str_cpy.src+1
    jsr str_cpy
    // main::@return
    // }
    // [4] return 
    rts
  .segment Data
    src: .text "hello"
    .byte 0
    src1: .text "world"
    .byte 0
}
.segment Code
  // str_cpy
// void str_cpy(__zp(2) char *dst, __zp(4) const char *src)
str_cpy: {
    .label dst = 2
    .label src = 4
    // [6] phi from str_cpy str_cpy::@1 to str_cpy::@1 [phi:str_cpy/str_cpy::@1->str_cpy::@1]
    // [6] phi str_cpy::dst#3 = str_cpy::dst#4 [phi:str_cpy/str_cpy::@1->str_cpy::@1#0] -- register_copy 
    // [6] phi str_cpy::src#3 = str_cpy::src#4 [phi:str_cpy/str_cpy::@1->str_cpy::@1#1] -- register_copy 
    // str_cpy::@1
  __b1:
    // *dst++ = *src++
    // [7] *str_cpy::dst#3 = *str_cpy::src#3 -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (src),y
    sta (dst),y
    // while ( *dst++ = *src++ )
    // [8] str_cpy::$0 = *str_cpy::dst#3 -- vbuaa=_deref_pbuz1 
    lda (dst),y
    // [9] str_cpy::dst#0 = ++ str_cpy::dst#3 -- pbuz1=_inc_pbuz1 
    inc.z dst
    bne !+
    inc.z dst+1
  !:
    // [10] str_cpy::src#0 = ++ str_cpy::src#3 -- pbuz1=_inc_pbuz1 
    inc.z src
    bne !+
    inc.z src+1
  !:
    // [11] if(0!=str_cpy::$0) goto str_cpy::@1 -- 0_neq_vbuaa_then_la1 
    cmp #0
    bne __b1
    // str_cpy::@return
    // }
    // [12] return 
    rts
}
  // File Data

