Eliminating unused variable with no statement memcpy::$0

CONTROL FLOW GRAPH SSA

void * memcpy(void *destination , void *source , unsigned int num)
memcpy: scope:[memcpy]  from main::@4 main::@5
  memcpy::num#2 = phi( main::@4/memcpy::num#0, main::@5/memcpy::num#1 )
  memcpy::destination#2 = phi( main::@4/memcpy::destination#0, main::@5/memcpy::destination#1 )
  memcpy::source#2 = phi( main::@4/memcpy::source#0, main::@5/memcpy::source#1 )
  memcpy::src#0 = ((char *)) memcpy::source#2
  memcpy::dst#0 = ((char *)) memcpy::destination#2
  memcpy::$2 = (char *)memcpy::source#2
  memcpy::src_end#0 = memcpy::$2 + memcpy::num#2
  to:memcpy::@1
memcpy::@1: scope:[memcpy]  from memcpy memcpy::@2
  memcpy::destination#4 = phi( memcpy/memcpy::destination#2, memcpy::@2/memcpy::destination#5 )
  memcpy::dst#3 = phi( memcpy/memcpy::dst#0, memcpy::@2/memcpy::dst#1 )
  memcpy::src_end#1 = phi( memcpy/memcpy::src_end#0, memcpy::@2/memcpy::src_end#2 )
  memcpy::src#2 = phi( memcpy/memcpy::src#0, memcpy::@2/memcpy::src#1 )
  memcpy::$1 = memcpy::src#2 != memcpy::src_end#1
  if(memcpy::$1) goto memcpy::@2
  to:memcpy::@3
memcpy::@2: scope:[memcpy]  from memcpy::@1
  memcpy::destination#5 = phi( memcpy::@1/memcpy::destination#4 )
  memcpy::src_end#2 = phi( memcpy::@1/memcpy::src_end#1 )
  memcpy::dst#2 = phi( memcpy::@1/memcpy::dst#3 )
  memcpy::src#3 = phi( memcpy::@1/memcpy::src#2 )
  *memcpy::dst#2 = *memcpy::src#3
  memcpy::dst#1 = ++ memcpy::dst#2
  memcpy::src#1 = ++ memcpy::src#3
  to:memcpy::@1
memcpy::@3: scope:[memcpy]  from memcpy::@1
  memcpy::destination#3 = phi( memcpy::@1/memcpy::destination#4 )
  memcpy::return#0 = memcpy::destination#3
  to:memcpy::@return
memcpy::@return: scope:[memcpy]  from memcpy::@3
  memcpy::return#4 = phi( memcpy::@3/memcpy::return#0 )
  memcpy::return#1 = memcpy::return#4
  return 
  to:@return

void main()
main: scope:[main]  from __start
  main::sc#0 = SCREEN
  main::camelot#0 = CAMELOT
  main::i#0 = 0
  to:main::@1
main::@1: scope:[main]  from main main::@1
  main::i#2 = phi( main/main::i#0, main::@1/main::i#1 )
  main::sc#2 = phi( main/main::sc#0, main::@1/main::sc#1 )
  main::camelot#2 = phi( main/main::camelot#0, main::@1/main::camelot#1 )
  *main::sc#2 = *main::camelot#2
  main::sc#1 = ++ main::sc#2
  main::camelot#1 = ++ main::camelot#2
  main::i#1 = main::i#2 + rangenext(0,6)
  main::$2 = main::i#1 != rangelast(0,6)
  if(main::$2) goto main::@1
  to:main::@2
main::@2: scope:[main]  from main::@1
  main::sc2#0 = SCREEN+$28
  main::reigns#0 = main::$4
  main::i1#0 = 0
  to:main::@3
main::@3: scope:[main]  from main::@2 main::@3
  main::i1#2 = phi( main::@2/main::i1#0, main::@3/main::i1#1 )
  main::sc2#2 = phi( main::@2/main::sc2#0, main::@3/main::sc2#1 )
  main::reigns#2 = phi( main::@2/main::reigns#0, main::@3/main::reigns#1 )
  *main::sc2#2 = *main::reigns#2
  main::sc2#1 = ++ main::sc2#2
  main::reigns#1 = ++ main::reigns#2
  main::i1#1 = main::i1#2 + rangenext(0,5)
  main::$3 = main::i1#1 != rangelast(0,5)
  if(main::$3) goto main::@3
  to:main::@4
main::@4: scope:[main]  from main::@3
  memcpy::destination#0 = (void *)SCREEN+$a
  memcpy::source#0 = (void *)CAMELOT
  memcpy::num#0 = 7
  call memcpy
  memcpy::return#2 = memcpy::return#1
  to:main::@5
main::@5: scope:[main]  from main::@4
  memcpy::destination#1 = (void *)SCREEN+$32
  memcpy::source#1 = (void *)main::$5
  memcpy::num#1 = 5
  call memcpy
  memcpy::return#3 = memcpy::return#1
  to:main::@6
main::@6: scope:[main]  from main::@5
  to:main::@return
main::@return: scope:[main]  from main::@6
  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 const char CAMELOT[] = "camelot"
__constant char * const SCREEN = (char *)$400
void __start()
void main()
bool main::$2
bool main::$3
__constant char main::$4[7] = "reigns"
__constant char main::$5[6] = "rules"
char *main::camelot
char *main::camelot#0
char *main::camelot#1
char *main::camelot#2
char main::i
char main::i#0
char main::i#1
char main::i#2
char main::i1
char main::i1#0
char main::i1#1
char main::i1#2
char *main::reigns
char *main::reigns#0
char *main::reigns#1
char *main::reigns#2
char *main::sc
char *main::sc#0
char *main::sc#1
char *main::sc#2
char *main::sc2
char *main::sc2#0
char *main::sc2#1
char *main::sc2#2
void * memcpy(void *destination , void *source , unsigned int num)
bool memcpy::$1
char *memcpy::$2
void *memcpy::destination
void *memcpy::destination#0
void *memcpy::destination#1
void *memcpy::destination#2
void *memcpy::destination#3
void *memcpy::destination#4
void *memcpy::destination#5
char *memcpy::dst
char *memcpy::dst#0
char *memcpy::dst#1
char *memcpy::dst#2
char *memcpy::dst#3
unsigned int memcpy::num
unsigned int memcpy::num#0
unsigned int memcpy::num#1
unsigned int memcpy::num#2
void *memcpy::return
void *memcpy::return#0
void *memcpy::return#1
void *memcpy::return#2
void *memcpy::return#3
void *memcpy::return#4
void *memcpy::source
void *memcpy::source#0
void *memcpy::source#1
void *memcpy::source#2
char *memcpy::src
char *memcpy::src#0
char *memcpy::src#1
char *memcpy::src#2
char *memcpy::src#3
char *memcpy::src_end
char *memcpy::src_end#0
char *memcpy::src_end#1
char *memcpy::src_end#2

Adding number conversion cast (unumber) $28 in main::sc2#0 = SCREEN+$28
Adding number conversion cast (unumber) $a in memcpy::destination#0 = (void *)SCREEN+$a
Adding number conversion cast (unumber) 7 in memcpy::num#0 = 7
Adding number conversion cast (unumber) $32 in memcpy::destination#1 = (void *)SCREEN+$32
Adding number conversion cast (unumber) 5 in memcpy::num#1 = 5
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast memcpy::src#0 = (char *)memcpy::source#2
Inlining cast memcpy::dst#0 = (char *)memcpy::destination#2
Inlining cast memcpy::num#0 = (unumber)7
Inlining cast memcpy::num#1 = (unumber)5
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast $28
Simplifying constant integer cast $a
Simplifying constant integer cast 7
Simplifying constant integer cast $32
Simplifying constant integer cast 5
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) $28
Finalized unsigned number type (char) $a
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) $32
Finalized unsigned number type (char) 5
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias memcpy::src#2 = memcpy::src#3 
Alias memcpy::dst#2 = memcpy::dst#3 
Alias memcpy::src_end#1 = memcpy::src_end#2 
Alias memcpy::destination#3 = memcpy::destination#5 memcpy::destination#4 memcpy::return#0 memcpy::return#4 memcpy::return#1 
Successful SSA optimization Pass2AliasElimination
Identical Phi Values memcpy::src_end#1 memcpy::src_end#0
Identical Phi Values memcpy::destination#3 memcpy::destination#2
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition memcpy::$1 [7] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2
Simple Condition main::$2 [21] if(main::i#1!=rangelast(0,6)) goto main::@1
Simple Condition main::$3 [31] if(main::i1#1!=rangelast(0,5)) goto main::@3
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant main::sc#0 = SCREEN
Constant main::camelot#0 = CAMELOT
Constant main::i#0 = 0
Constant main::sc2#0 = SCREEN+$28
Constant main::reigns#0 = main::$4
Constant main::i1#0 = 0
Constant memcpy::destination#0 = (void *)SCREEN+$a
Constant memcpy::source#0 = (void *)CAMELOT
Constant memcpy::num#0 = 7
Constant memcpy::destination#1 = (void *)SCREEN+$32
Constant memcpy::source#1 = (void *)main::$5
Constant memcpy::num#1 = 5
Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value [19] main::i#1 = ++ main::i#2 to ++
Resolved ranged comparison value [21] if(main::i#1!=rangelast(0,6)) goto main::@1 to 7
Resolved ranged next value [29] main::i1#1 = ++ main::i1#2 to ++
Resolved ranged comparison value [31] if(main::i1#1!=rangelast(0,5)) goto main::@3 to 6
Eliminating unused variable memcpy::return#2 and assignment [24] memcpy::return#2 = memcpy::destination#2
Eliminating unused variable memcpy::return#3 and assignment [26] memcpy::return#3 = memcpy::destination#2
Successful SSA optimization PassNEliminateUnusedVars
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
Adding number conversion cast (unumber) 7 in [16] if(main::i#1!=7) goto main::@1
Adding number conversion cast (unumber) 6 in [22] if(main::i1#1!=6) goto main::@3
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 7
Simplifying constant integer cast 6
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 6
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inlining Noop Cast [1] memcpy::src#0 = (char *)memcpy::source#2 keeping memcpy::source#2
Inlining Noop Cast [2] memcpy::dst#0 = (char *)memcpy::destination#2 keeping memcpy::destination#2
Inlining Noop Cast [3] memcpy::$2 = (char *)memcpy::source#2 keeping memcpy::source#2
Successful SSA optimization Pass2NopCastInlining
Inlining constant with var siblings memcpy::destination#0
Inlining constant with var siblings memcpy::source#0
Inlining constant with var siblings memcpy::num#0
Inlining constant with var siblings memcpy::destination#1
Inlining constant with var siblings memcpy::source#1
Inlining constant with var siblings memcpy::num#1
Inlining constant with var siblings main::sc#0
Inlining constant with var siblings main::camelot#0
Inlining constant with var siblings main::i#0
Inlining constant with var siblings main::sc2#0
Inlining constant with var siblings main::reigns#0
Inlining constant with var siblings main::i1#0
Constant inlined main::camelot#0 = CAMELOT
Constant inlined main::sc#0 = SCREEN
Constant inlined memcpy::destination#0 = (void *)SCREEN+$a
Constant inlined memcpy::destination#1 = (void *)SCREEN+$32
Constant inlined memcpy::source#0 = (void *)CAMELOT
Constant inlined memcpy::num#1 = 5
Constant inlined memcpy::num#0 = 7
Constant inlined memcpy::source#1 = (void *)main::$5
Constant inlined main::i#0 = 0
Constant inlined main::i1#0 = 0
Constant inlined main::$4 = main::reigns#0
Constant inlined main::sc2#0 = SCREEN+$28
Successful SSA optimization Pass2ConstantInlining
Inlining constant with var siblings main::reigns#0
Inlining constant with var siblings main::reigns#0
Added new block during phi lifting main::@7(between main::@1 and main::@1)
Added new block during phi lifting main::@8(between main::@3 and main::@3)
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@2
Adding NOP phi() at start of main::@4
Adding NOP phi() at start of main::@5
Adding NOP phi() at start of main::@6
Adding NOP phi() at start of memcpy::@3
CALL GRAPH
Calls in [main] to memcpy:15 memcpy:17 

Created 11 initial phi equivalence classes
Coalesced [20] main::reigns#3 = main::reigns#1
Coalesced [21] main::sc2#3 = main::sc2#1
Coalesced [22] main::i1#3 = main::i1#1
Coalesced [23] main::camelot#3 = main::camelot#1
Coalesced [24] main::sc#3 = main::sc#1
Coalesced [25] main::i#3 = main::i#1
Coalesced [37] memcpy::src#5 = memcpy::src#1
Coalesced [38] memcpy::dst#5 = memcpy::dst#1
Coalesced down to 11 phi equivalence classes
Culled Empty Block label main::@2
Culled Empty Block label main::@6
Culled Empty Block label main::@8
Culled Empty Block label main::@7
Culled Empty Block label memcpy::@3
Renumbering block main::@3 to main::@2
Renumbering block main::@4 to main::@3
Renumbering block main::@5 to main::@4
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@3
Adding NOP phi() at start of main::@4

FINAL CONTROL FLOW GRAPH

void main()
main: scope:[main]  from
  [0] phi()
  to:main::@1
main::@1: scope:[main]  from main main::@1
  [1] main::i#2 = phi( main/0, main::@1/main::i#1 )
  [1] main::sc#2 = phi( main/SCREEN, main::@1/main::sc#1 )
  [1] main::camelot#2 = phi( main/CAMELOT, main::@1/main::camelot#1 )
  [2] *main::sc#2 = *main::camelot#2
  [3] main::sc#1 = ++ main::sc#2
  [4] main::camelot#1 = ++ main::camelot#2
  [5] main::i#1 = ++ main::i#2
  [6] if(main::i#1!=7) goto main::@1
  to:main::@2
main::@2: scope:[main]  from main::@1 main::@2
  [7] main::i1#2 = phi( main::@1/0, main::@2/main::i1#1 )
  [7] main::sc2#2 = phi( main::@1/SCREEN+$28, main::@2/main::sc2#1 )
  [7] main::reigns#2 = phi( main::@1/main::reigns#0, main::@2/main::reigns#1 )
  [8] *main::sc2#2 = *main::reigns#2
  [9] main::sc2#1 = ++ main::sc2#2
  [10] main::reigns#1 = ++ main::reigns#2
  [11] main::i1#1 = ++ main::i1#2
  [12] if(main::i1#1!=6) goto main::@2
  to:main::@3
main::@3: scope:[main]  from main::@2
  [13] phi()
  [14] call memcpy
  to:main::@4
main::@4: scope:[main]  from main::@3
  [15] phi()
  [16] call memcpy
  to:main::@return
main::@return: scope:[main]  from main::@4
  [17] return 
  to:@return

void * memcpy(void *destination , void *source , unsigned int num)
memcpy: scope:[memcpy]  from main::@3 main::@4
  [18] memcpy::num#2 = phi( main::@3/7, main::@4/5 )
  [18] memcpy::destination#2 = phi( main::@3/(void *)SCREEN+$a, main::@4/(void *)SCREEN+$32 )
  [18] memcpy::source#2 = phi( main::@3/(void *)CAMELOT, main::@4/(void *)main::$5 )
  [19] memcpy::src_end#0 = (char *)memcpy::source#2 + memcpy::num#2
  [20] memcpy::src#4 = (char *)memcpy::source#2
  [21] memcpy::dst#4 = (char *)memcpy::destination#2
  to:memcpy::@1
memcpy::@1: scope:[memcpy]  from memcpy memcpy::@2
  [22] memcpy::dst#2 = phi( memcpy/memcpy::dst#4, memcpy::@2/memcpy::dst#1 )
  [22] memcpy::src#2 = phi( memcpy/memcpy::src#4, memcpy::@2/memcpy::src#1 )
  [23] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2
  to:memcpy::@return
memcpy::@return: scope:[memcpy]  from memcpy::@1
  [24] return 
  to:@return
memcpy::@2: scope:[memcpy]  from memcpy::@1
  [25] *memcpy::dst#2 = *memcpy::src#2
  [26] memcpy::dst#1 = ++ memcpy::dst#2
  [27] memcpy::src#1 = ++ memcpy::src#2
  to:memcpy::@1


VARIABLE REGISTER WEIGHTS
void main()
char *main::camelot
char *main::camelot#1 // 7.333333333333333
char *main::camelot#2 // 11.0
char main::i
char main::i#1 // 16.5
char main::i#2 // 5.5
char main::i1
char main::i1#1 // 16.5
char main::i1#2 // 5.5
char *main::reigns
char *main::reigns#1 // 7.333333333333333
char *main::reigns#2 // 11.0
char *main::sc
char *main::sc#1 // 5.5
char *main::sc#2 // 16.5
char *main::sc2
char *main::sc2#1 // 5.5
char *main::sc2#2 // 16.5
void * memcpy(void *destination , void *source , unsigned int num)
void *memcpy::destination
void *memcpy::destination#2
char *memcpy::dst
char *memcpy::dst#1 // 101.0
char *memcpy::dst#2 // 104.66666666666666
char *memcpy::dst#4 // 22.0
unsigned int memcpy::num
unsigned int memcpy::num#2 // 11.0
void *memcpy::return
void *memcpy::source
void *memcpy::source#2
char *memcpy::src
char *memcpy::src#1 // 202.0
char *memcpy::src#2 // 103.75
char *memcpy::src#4 // 11.0
char *memcpy::src_end
char *memcpy::src_end#0 // 14.0

Initial phi equivalence classes
[ main::camelot#2 main::camelot#1 ]
[ main::sc#2 main::sc#1 ]
[ main::i#2 main::i#1 ]
[ main::reigns#2 main::reigns#1 ]
[ main::sc2#2 main::sc2#1 ]
[ main::i1#2 main::i1#1 ]
[ memcpy::source#2 ]
[ memcpy::destination#2 ]
[ memcpy::num#2 ]
[ memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
[ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
Added variable memcpy::src_end#0 to live range equivalence class [ memcpy::src_end#0 ]
Complete equivalence classes
[ main::camelot#2 main::camelot#1 ]
[ main::sc#2 main::sc#1 ]
[ main::i#2 main::i#1 ]
[ main::reigns#2 main::reigns#1 ]
[ main::sc2#2 main::sc2#1 ]
[ main::i1#2 main::i1#1 ]
[ memcpy::source#2 ]
[ memcpy::destination#2 ]
[ memcpy::num#2 ]
[ memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
[ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
[ memcpy::src_end#0 ]
Allocated zp[2]:2 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
Allocated zp[2]:4 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
Allocated zp[2]:6 [ main::sc#2 main::sc#1 ]
Allocated zp[1]:8 [ main::i#2 main::i#1 ]
Allocated zp[2]:9 [ main::sc2#2 main::sc2#1 ]
Allocated zp[1]:11 [ main::i1#2 main::i1#1 ]
Allocated zp[2]:12 [ main::camelot#2 main::camelot#1 ]
Allocated zp[2]:14 [ main::reigns#2 main::reigns#1 ]
Allocated zp[2]:16 [ memcpy::src_end#0 ]
Allocated zp[2]:18 [ memcpy::num#2 ]
Allocated zp[2]:20 [ memcpy::source#2 ]
Allocated zp[2]:22 [ memcpy::destination#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [2] *main::sc#2 = *main::camelot#2 [ main::camelot#2 main::sc#2 main::i#2 ] (  [ main::camelot#2 main::sc#2 main::i#2 ] { }  ) always clobbers reg byte a reg byte y 
Removing always clobbered register reg byte a as potential for zp[1]:8 [ main::i#2 main::i#1 ]
Removing always clobbered register reg byte y as potential for zp[1]:8 [ main::i#2 main::i#1 ]
Statement [8] *main::sc2#2 = *main::reigns#2 [ main::reigns#2 main::sc2#2 main::i1#2 ] (  [ main::reigns#2 main::sc2#2 main::i1#2 ] { }  ) always clobbers reg byte a reg byte y 
Removing always clobbered register reg byte a as potential for zp[1]:11 [ main::i1#2 main::i1#1 ]
Removing always clobbered register reg byte y as potential for zp[1]:11 [ main::i1#2 main::i1#1 ]
Statement [19] memcpy::src_end#0 = (char *)memcpy::source#2 + memcpy::num#2 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( memcpy:14 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { }  memcpy:16 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { }  ) always clobbers reg byte a 
Statement [20] memcpy::src#4 = (char *)memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( memcpy:14 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { }  memcpy:16 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { }  ) always clobbers reg byte a 
Statement [21] memcpy::dst#4 = (char *)memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( memcpy:14 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { }  memcpy:16 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { }  ) always clobbers reg byte a 
Statement [23] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( memcpy:14 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { }  memcpy:16 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { }  ) always clobbers reg byte a 
Statement [25] *memcpy::dst#2 = *memcpy::src#2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( memcpy:14 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { }  memcpy:16 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { }  ) always clobbers reg byte a reg byte y 
Statement [2] *main::sc#2 = *main::camelot#2 [ main::camelot#2 main::sc#2 main::i#2 ] (  [ main::camelot#2 main::sc#2 main::i#2 ] { }  ) always clobbers reg byte a reg byte y 
Statement [8] *main::sc2#2 = *main::reigns#2 [ main::reigns#2 main::sc2#2 main::i1#2 ] (  [ main::reigns#2 main::sc2#2 main::i1#2 ] { }  ) always clobbers reg byte a reg byte y 
Statement [19] memcpy::src_end#0 = (char *)memcpy::source#2 + memcpy::num#2 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( memcpy:14 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { }  memcpy:16 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] { }  ) always clobbers reg byte a 
Statement [20] memcpy::src#4 = (char *)memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( memcpy:14 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { }  memcpy:16 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] { }  ) always clobbers reg byte a 
Statement [21] memcpy::dst#4 = (char *)memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( memcpy:14 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { }  memcpy:16 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] { }  ) always clobbers reg byte a 
Statement [23] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( memcpy:14 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { }  memcpy:16 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { }  ) always clobbers reg byte a 
Statement [25] *memcpy::dst#2 = *memcpy::src#2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( memcpy:14 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { }  memcpy:16 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] { }  ) always clobbers reg byte a reg byte y 
Potential registers zp[2]:12 [ main::camelot#2 main::camelot#1 ] : zp[2]:12 , 
Potential registers zp[2]:6 [ main::sc#2 main::sc#1 ] : zp[2]:6 , 
Potential registers zp[1]:8 [ main::i#2 main::i#1 ] : zp[1]:8 , reg byte x , 
Potential registers zp[2]:14 [ main::reigns#2 main::reigns#1 ] : zp[2]:14 , 
Potential registers zp[2]:9 [ main::sc2#2 main::sc2#1 ] : zp[2]:9 , 
Potential registers zp[1]:11 [ main::i1#2 main::i1#1 ] : zp[1]:11 , reg byte x , 
Potential registers zp[2]:20 [ memcpy::source#2 ] : zp[2]:20 , 
Potential registers zp[2]:22 [ memcpy::destination#2 ] : zp[2]:22 , 
Potential registers zp[2]:18 [ memcpy::num#2 ] : zp[2]:18 , 
Potential registers zp[2]:2 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] : zp[2]:2 , 
Potential registers zp[2]:4 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] : zp[2]:4 , 
Potential registers zp[2]:16 [ memcpy::src_end#0 ] : zp[2]:16 , 

REGISTER UPLIFT SCOPES
Uplift Scope [memcpy] 316.75: zp[2]:2 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] 227.67: zp[2]:4 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] 14: zp[2]:16 [ memcpy::src_end#0 ] 11: zp[2]:18 [ memcpy::num#2 ] 0: zp[2]:20 [ memcpy::source#2 ] 0: zp[2]:22 [ memcpy::destination#2 ] 
Uplift Scope [main] 22: zp[2]:6 [ main::sc#2 main::sc#1 ] 22: zp[1]:8 [ main::i#2 main::i#1 ] 22: zp[2]:9 [ main::sc2#2 main::sc2#1 ] 22: zp[1]:11 [ main::i1#2 main::i1#1 ] 18.33: zp[2]:12 [ main::camelot#2 main::camelot#1 ] 18.33: zp[2]:14 [ main::reigns#2 main::reigns#1 ] 
Uplift Scope [] 

Uplifting [memcpy] best 2482 combination zp[2]:2 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] zp[2]:4 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] zp[2]:16 [ memcpy::src_end#0 ] zp[2]:18 [ memcpy::num#2 ] zp[2]:20 [ memcpy::source#2 ] zp[2]:22 [ memcpy::destination#2 ] 
Uplifting [main] best 2302 combination zp[2]:6 [ main::sc#2 main::sc#1 ] reg byte x [ main::i#2 main::i#1 ] zp[2]:9 [ main::sc2#2 main::sc2#1 ] reg byte x [ main::i1#2 main::i1#1 ] zp[2]:12 [ main::camelot#2 main::camelot#1 ] zp[2]:14 [ main::reigns#2 main::reigns#1 ] 
Uplifting [] best 2302 combination 
Coalescing zero page register [ zp[2]:20 [ memcpy::source#2 ] ] with [ zp[2]:2 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] ] - score: 1
Coalescing zero page register [ zp[2]:22 [ memcpy::destination#2 ] ] with [ zp[2]:4 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] ] - score: 1
Coalescing zero page register [ zp[2]:18 [ memcpy::num#2 ] ] with [ zp[2]:16 [ memcpy::src_end#0 ] ] - score: 1
Allocated (was zp[2]:20) zp[2]:2 [ memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
Allocated (was zp[2]:22) zp[2]:4 [ memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
Allocated (was zp[2]:18) zp[2]:6 [ memcpy::num#2 memcpy::src_end#0 ]
Allocated (was zp[2]:6) zp[2]:8 [ main::sc#2 main::sc#1 ]
Allocated (was zp[2]:9) zp[2]:10 [ main::sc2#2 main::sc2#1 ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Test memcpy on strings (
  // Upstart
  // Commodore 64 PRG executable file
.file [name="memcpy-1.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: {
    // Working memory copy of string
    .label sc = 8
    .label camelot = $c
    .label sc2 = $a
    .label reigns = $e
    // [1] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    // [1] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 
    ldx #0
    // [1] phi main::sc#2 = SCREEN [phi:main->main::@1#1] -- pbuz1=pbuc1 
    lda #<SCREEN
    sta.z sc
    lda #>SCREEN
    sta.z sc+1
    // [1] phi main::camelot#2 = CAMELOT [phi:main->main::@1#2] -- pbuz1=pbuc1 
    lda #<CAMELOT
    sta.z camelot
    lda #>CAMELOT
    sta.z camelot+1
    jmp __b1
    // [1] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
  __b1_from___b1:
    // [1] phi main::i#2 = main::i#1 [phi:main::@1->main::@1#0] -- register_copy 
    // [1] phi main::sc#2 = main::sc#1 [phi:main::@1->main::@1#1] -- register_copy 
    // [1] phi main::camelot#2 = main::camelot#1 [phi:main::@1->main::@1#2] -- register_copy 
    jmp __b1
    // main::@1
  __b1:
    // [2] *main::sc#2 = *main::camelot#2 -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (camelot),y
    ldy #0
    sta (sc),y
    // [3] main::sc#1 = ++ main::sc#2 -- pbuz1=_inc_pbuz1 
    inc.z sc
    bne !+
    inc.z sc+1
  !:
    // [4] main::camelot#1 = ++ main::camelot#2 -- pbuz1=_inc_pbuz1 
    inc.z camelot
    bne !+
    inc.z camelot+1
  !:
    // [5] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx 
    inx
    // [6] if(main::i#1!=7) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 
    cpx #7
    bne __b1_from___b1
    // [7] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
  __b2_from___b1:
    // [7] phi main::i1#2 = 0 [phi:main::@1->main::@2#0] -- vbuxx=vbuc1 
    ldx #0
    // [7] phi main::sc2#2 = SCREEN+$28 [phi:main::@1->main::@2#1] -- pbuz1=pbuc1 
    lda #<SCREEN+$28
    sta.z sc2
    lda #>SCREEN+$28
    sta.z sc2+1
    // [7] phi main::reigns#2 = main::reigns#0 [phi:main::@1->main::@2#2] -- pbuz1=pbuc1 
    lda #<reigns_1
    sta.z reigns
    lda #>reigns_1
    sta.z reigns+1
    jmp __b2
    // [7] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
  __b2_from___b2:
    // [7] phi main::i1#2 = main::i1#1 [phi:main::@2->main::@2#0] -- register_copy 
    // [7] phi main::sc2#2 = main::sc2#1 [phi:main::@2->main::@2#1] -- register_copy 
    // [7] phi main::reigns#2 = main::reigns#1 [phi:main::@2->main::@2#2] -- register_copy 
    jmp __b2
    // main::@2
  __b2:
    // [8] *main::sc2#2 = *main::reigns#2 -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (reigns),y
    ldy #0
    sta (sc2),y
    // [9] main::sc2#1 = ++ main::sc2#2 -- pbuz1=_inc_pbuz1 
    inc.z sc2
    bne !+
    inc.z sc2+1
  !:
    // [10] main::reigns#1 = ++ main::reigns#2 -- pbuz1=_inc_pbuz1 
    inc.z reigns
    bne !+
    inc.z reigns+1
  !:
    // [11] main::i1#1 = ++ main::i1#2 -- vbuxx=_inc_vbuxx 
    inx
    // [12] if(main::i1#1!=6) goto main::@2 -- vbuxx_neq_vbuc1_then_la1 
    cpx #6
    bne __b2_from___b2
    // [13] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
  __b3_from___b2:
    jmp __b3
    // main::@3
  __b3:
    // [14] call memcpy
    // [18] phi from main::@3 to memcpy [phi:main::@3->memcpy]
  memcpy_from___b3:
    // [18] phi memcpy::num#2 = 7 [phi:main::@3->memcpy#0] -- vwuz1=vbuc1 
    lda #<7
    sta.z memcpy.num
    lda #>7
    sta.z memcpy.num+1
    // [18] phi memcpy::destination#2 = (void *)SCREEN+$a [phi:main::@3->memcpy#1] -- pvoz1=pvoc1 
    lda #<SCREEN+$a
    sta.z memcpy.destination
    lda #>SCREEN+$a
    sta.z memcpy.destination+1
    // [18] phi memcpy::source#2 = (void *)CAMELOT [phi:main::@3->memcpy#2] -- pvoz1=pvoc1 
    lda #<CAMELOT
    sta.z memcpy.source
    lda #>CAMELOT
    sta.z memcpy.source+1
    jsr memcpy
    // [15] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
  __b4_from___b3:
    jmp __b4
    // main::@4
  __b4:
    // [16] call memcpy
    // [18] phi from main::@4 to memcpy [phi:main::@4->memcpy]
  memcpy_from___b4:
    // [18] phi memcpy::num#2 = 5 [phi:main::@4->memcpy#0] -- vwuz1=vbuc1 
    lda #<5
    sta.z memcpy.num
    lda #>5
    sta.z memcpy.num+1
    // [18] phi memcpy::destination#2 = (void *)SCREEN+$32 [phi:main::@4->memcpy#1] -- pvoz1=pvoc1 
    lda #<SCREEN+$32
    sta.z memcpy.destination
    lda #>SCREEN+$32
    sta.z memcpy.destination+1
    // [18] phi memcpy::source#2 = (void *)main::$5 [phi:main::@4->memcpy#2] -- pvoz1=pvoc1 
    lda #<__5
    sta.z memcpy.source
    lda #>__5
    sta.z memcpy.source+1
    jsr memcpy
    jmp __breturn
    // main::@return
  __breturn:
    // [17] return 
    rts
  .segment Data
    __5: .text "rules"
    .byte 0
    reigns_1: .text "reigns"
    .byte 0
}
.segment Code
  // memcpy
// Copy block of memory (forwards)
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
// void * memcpy(__zp(4) void *destination, __zp(2) void *source, __zp(6) unsigned int num)
memcpy: {
    .label src_end = 6
    .label dst = 4
    .label src = 2
    .label source = 2
    .label destination = 4
    .label num = 6
    // [19] memcpy::src_end#0 = (char *)memcpy::source#2 + memcpy::num#2 -- pbuz1=pbuz2_plus_vwuz1 
    clc
    lda.z src_end
    adc.z source
    sta.z src_end
    lda.z src_end+1
    adc.z source+1
    sta.z src_end+1
    // [20] memcpy::src#4 = (char *)memcpy::source#2
    // [21] memcpy::dst#4 = (char *)memcpy::destination#2
    // [22] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
  __b1_from_memcpy:
  __b1_from___b2:
    // [22] phi memcpy::dst#2 = memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy 
    // [22] phi memcpy::src#2 = memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy 
    jmp __b1
    // memcpy::@1
  __b1:
    // [23] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1 
    lda.z src+1
    cmp.z src_end+1
    bne __b2
    lda.z src
    cmp.z src_end
    bne __b2
    jmp __breturn
    // memcpy::@return
  __breturn:
    // [24] return 
    rts
    // memcpy::@2
  __b2:
    // [25] *memcpy::dst#2 = *memcpy::src#2 -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (src),y
    ldy #0
    sta (dst),y
    // [26] memcpy::dst#1 = ++ memcpy::dst#2 -- pbuz1=_inc_pbuz1 
    inc.z dst
    bne !+
    inc.z dst+1
  !:
    // [27] memcpy::src#1 = ++ memcpy::src#2 -- pbuz1=_inc_pbuz1 
    inc.z src
    bne !+
    inc.z src+1
  !:
    jmp __b1_from___b2
}
  // File Data
.segment Data
  CAMELOT: .text "camelot"
  .byte 0

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __b3
Removing instruction jmp __b4
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction ldy #0
Removing instruction ldy #0
Removing instruction ldy #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __b1_from___b1 with __b1
Replacing label __b2_from___b2 with __b2
Replacing label __b1_from___b2 with __b1
Removing instruction __b1_from___b1:
Removing instruction __b2_from___b2:
Removing instruction __b3_from___b2:
Removing instruction memcpy_from___b3:
Removing instruction __b4_from___b3:
Removing instruction memcpy_from___b4:
Removing instruction __b1_from_memcpy:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1_from_main:
Removing instruction __b2_from___b1:
Removing instruction __b3:
Removing instruction __b4:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jmp __b1
Removing instruction jmp __b2
Succesful ASM optimization Pass5NextJumpElimination

FINAL SYMBOL TABLE
__constant const char CAMELOT[] = "camelot"
__constant char * const SCREEN = (char *) 1024
void main()
__constant char main::$5[6] = "rules"
char *main::camelot
char *main::camelot#1 // camelot zp[2]:12 7.333333333333333
char *main::camelot#2 // camelot zp[2]:12 11.0
char main::i
char main::i#1 // reg byte x 16.5
char main::i#2 // reg byte x 5.5
char main::i1
char main::i1#1 // reg byte x 16.5
char main::i1#2 // reg byte x 5.5
char *main::reigns
__constant char *main::reigns#0 = "reigns" // reigns_1
char *main::reigns#1 // reigns zp[2]:14 7.333333333333333
char *main::reigns#2 // reigns zp[2]:14 11.0
char *main::sc
char *main::sc#1 // sc zp[2]:8 5.5
char *main::sc#2 // sc zp[2]:8 16.5
char *main::sc2
char *main::sc2#1 // sc2 zp[2]:10 5.5
char *main::sc2#2 // sc2 zp[2]:10 16.5
void * memcpy(void *destination , void *source , unsigned int num)
void *memcpy::destination
void *memcpy::destination#2 // destination zp[2]:4
char *memcpy::dst
char *memcpy::dst#1 // dst zp[2]:4 101.0
char *memcpy::dst#2 // dst zp[2]:4 104.66666666666666
char *memcpy::dst#4 // dst zp[2]:4 22.0
unsigned int memcpy::num
unsigned int memcpy::num#2 // num zp[2]:6 11.0
void *memcpy::return
void *memcpy::source
void *memcpy::source#2 // source zp[2]:2
char *memcpy::src
char *memcpy::src#1 // src zp[2]:2 202.0
char *memcpy::src#2 // src zp[2]:2 103.75
char *memcpy::src#4 // src zp[2]:2 11.0
char *memcpy::src_end
char *memcpy::src_end#0 // src_end zp[2]:6 14.0

zp[2]:12 [ main::camelot#2 main::camelot#1 ]
zp[2]:8 [ main::sc#2 main::sc#1 ]
reg byte x [ main::i#2 main::i#1 ]
zp[2]:14 [ main::reigns#2 main::reigns#1 ]
zp[2]:10 [ main::sc2#2 main::sc2#1 ]
reg byte x [ main::i1#2 main::i1#1 ]
zp[2]:2 [ memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
zp[2]:4 [ memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
zp[2]:6 [ memcpy::num#2 memcpy::src_end#0 ]


FINAL ASSEMBLER
Score: 2029

  // File Comments
// Test memcpy on strings (
  // Upstart
  // Commodore 64 PRG executable file
.file [name="memcpy-1.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: {
    // Working memory copy of string
    .label sc = 8
    .label camelot = $c
    .label sc2 = $a
    .label reigns = $e
    // [1] phi from main to main::@1 [phi:main->main::@1]
    // [1] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuxx=vbuc1 
    ldx #0
    // [1] phi main::sc#2 = SCREEN [phi:main->main::@1#1] -- pbuz1=pbuc1 
    lda #<SCREEN
    sta.z sc
    lda #>SCREEN
    sta.z sc+1
    // [1] phi main::camelot#2 = CAMELOT [phi:main->main::@1#2] -- pbuz1=pbuc1 
    lda #<CAMELOT
    sta.z camelot
    lda #>CAMELOT
    sta.z camelot+1
    // [1] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
    // [1] phi main::i#2 = main::i#1 [phi:main::@1->main::@1#0] -- register_copy 
    // [1] phi main::sc#2 = main::sc#1 [phi:main::@1->main::@1#1] -- register_copy 
    // [1] phi main::camelot#2 = main::camelot#1 [phi:main::@1->main::@1#2] -- register_copy 
    // main::@1
  __b1:
    // *sc++ = *camelot++
    // [2] *main::sc#2 = *main::camelot#2 -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (camelot),y
    sta (sc),y
    // *sc++ = *camelot++;
    // [3] main::sc#1 = ++ main::sc#2 -- pbuz1=_inc_pbuz1 
    inc.z sc
    bne !+
    inc.z sc+1
  !:
    // [4] main::camelot#1 = ++ main::camelot#2 -- pbuz1=_inc_pbuz1 
    inc.z camelot
    bne !+
    inc.z camelot+1
  !:
    // for( char i: 0..6)
    // [5] main::i#1 = ++ main::i#2 -- vbuxx=_inc_vbuxx 
    inx
    // [6] if(main::i#1!=7) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 
    cpx #7
    bne __b1
    // [7] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
    // [7] phi main::i1#2 = 0 [phi:main::@1->main::@2#0] -- vbuxx=vbuc1 
    ldx #0
    // [7] phi main::sc2#2 = SCREEN+$28 [phi:main::@1->main::@2#1] -- pbuz1=pbuc1 
    lda #<SCREEN+$28
    sta.z sc2
    lda #>SCREEN+$28
    sta.z sc2+1
    // [7] phi main::reigns#2 = main::reigns#0 [phi:main::@1->main::@2#2] -- pbuz1=pbuc1 
    lda #<reigns_1
    sta.z reigns
    lda #>reigns_1
    sta.z reigns+1
    // [7] phi from main::@2 to main::@2 [phi:main::@2->main::@2]
    // [7] phi main::i1#2 = main::i1#1 [phi:main::@2->main::@2#0] -- register_copy 
    // [7] phi main::sc2#2 = main::sc2#1 [phi:main::@2->main::@2#1] -- register_copy 
    // [7] phi main::reigns#2 = main::reigns#1 [phi:main::@2->main::@2#2] -- register_copy 
    // main::@2
  __b2:
    // *sc2++ = *reigns++
    // [8] *main::sc2#2 = *main::reigns#2 -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (reigns),y
    sta (sc2),y
    // *sc2++ = *reigns++;
    // [9] main::sc2#1 = ++ main::sc2#2 -- pbuz1=_inc_pbuz1 
    inc.z sc2
    bne !+
    inc.z sc2+1
  !:
    // [10] main::reigns#1 = ++ main::reigns#2 -- pbuz1=_inc_pbuz1 
    inc.z reigns
    bne !+
    inc.z reigns+1
  !:
    // for( char i: 0..5)
    // [11] main::i1#1 = ++ main::i1#2 -- vbuxx=_inc_vbuxx 
    inx
    // [12] if(main::i1#1!=6) goto main::@2 -- vbuxx_neq_vbuc1_then_la1 
    cpx #6
    bne __b2
    // [13] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
    // main::@3
    // memcpy(SCREEN+10, CAMELOT, 7)
    // [14] call memcpy
    // [18] phi from main::@3 to memcpy [phi:main::@3->memcpy]
    // [18] phi memcpy::num#2 = 7 [phi:main::@3->memcpy#0] -- vwuz1=vbuc1 
    lda #<7
    sta.z memcpy.num
    lda #>7
    sta.z memcpy.num+1
    // [18] phi memcpy::destination#2 = (void *)SCREEN+$a [phi:main::@3->memcpy#1] -- pvoz1=pvoc1 
    lda #<SCREEN+$a
    sta.z memcpy.destination
    lda #>SCREEN+$a
    sta.z memcpy.destination+1
    // [18] phi memcpy::source#2 = (void *)CAMELOT [phi:main::@3->memcpy#2] -- pvoz1=pvoc1 
    lda #<CAMELOT
    sta.z memcpy.source
    lda #>CAMELOT
    sta.z memcpy.source+1
    jsr memcpy
    // [15] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
    // main::@4
    // memcpy(SCREEN+50, "rules", 5)
    // [16] call memcpy
    // [18] phi from main::@4 to memcpy [phi:main::@4->memcpy]
    // [18] phi memcpy::num#2 = 5 [phi:main::@4->memcpy#0] -- vwuz1=vbuc1 
    lda #<5
    sta.z memcpy.num
    lda #>5
    sta.z memcpy.num+1
    // [18] phi memcpy::destination#2 = (void *)SCREEN+$32 [phi:main::@4->memcpy#1] -- pvoz1=pvoc1 
    lda #<SCREEN+$32
    sta.z memcpy.destination
    lda #>SCREEN+$32
    sta.z memcpy.destination+1
    // [18] phi memcpy::source#2 = (void *)main::$5 [phi:main::@4->memcpy#2] -- pvoz1=pvoc1 
    lda #<__5
    sta.z memcpy.source
    lda #>__5
    sta.z memcpy.source+1
    jsr memcpy
    // main::@return
    // }
    // [17] return 
    rts
  .segment Data
    __5: .text "rules"
    .byte 0
    reigns_1: .text "reigns"
    .byte 0
}
.segment Code
  // memcpy
// Copy block of memory (forwards)
// Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.
// void * memcpy(__zp(4) void *destination, __zp(2) void *source, __zp(6) unsigned int num)
memcpy: {
    .label src_end = 6
    .label dst = 4
    .label src = 2
    .label source = 2
    .label destination = 4
    .label num = 6
    // char* src_end = (char*)source+num
    // [19] memcpy::src_end#0 = (char *)memcpy::source#2 + memcpy::num#2 -- pbuz1=pbuz2_plus_vwuz1 
    clc
    lda.z src_end
    adc.z source
    sta.z src_end
    lda.z src_end+1
    adc.z source+1
    sta.z src_end+1
    // [20] memcpy::src#4 = (char *)memcpy::source#2
    // [21] memcpy::dst#4 = (char *)memcpy::destination#2
    // [22] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
    // [22] phi memcpy::dst#2 = memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy 
    // [22] phi memcpy::src#2 = memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy 
    // memcpy::@1
  __b1:
    // while(src!=src_end)
    // [23] if(memcpy::src#2!=memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1 
    lda.z src+1
    cmp.z src_end+1
    bne __b2
    lda.z src
    cmp.z src_end
    bne __b2
    // memcpy::@return
    // }
    // [24] return 
    rts
    // memcpy::@2
  __b2:
    // *dst++ = *src++
    // [25] *memcpy::dst#2 = *memcpy::src#2 -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (src),y
    sta (dst),y
    // *dst++ = *src++;
    // [26] memcpy::dst#1 = ++ memcpy::dst#2 -- pbuz1=_inc_pbuz1 
    inc.z dst
    bne !+
    inc.z dst+1
  !:
    // [27] memcpy::src#1 = ++ memcpy::src#2 -- pbuz1=_inc_pbuz1 
    inc.z src
    bne !+
    inc.z src+1
  !:
    jmp __b1
}
  // File Data
.segment Data
  CAMELOT: .text "camelot"
  .byte 0

