Warning! Adding boolean cast to non-boolean condition *((byte*) strcpy::src)
Identified constant variable (byte*) SCREEN
Inlined call (byte~) vicSelectGfxBank::$0 ← call toDd00 (byte*) vicSelectGfxBank::gfx 
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3
Culled Empty Block (label) @4
Culled Empty Block (label) memcpy::@4
Culled Empty Block (label) memcpy::@5
Culled Empty Block (label) memcpy::@6
Culled Empty Block (label) memcpy::@7
Culled Empty Block (label) @5
Culled Empty Block (label) @6
Culled Empty Block (label) @7
Culled Empty Block (label) main::@4
Culled Empty Block (label) main::@3
Culled Empty Block (label) main::@5
Culled Empty Block (label) main::@6

CONTROL FLOW GRAPH SSA
@begin: scope:[]  from
  (byte*) BGCOL#0 ← ((byte*)) (number) $d021
  (byte*) COLS#0 ← ((byte*)) (number) $d800
  (byte) BLACK#0 ← (number) 0
  to:@8
memcpy: scope:[memcpy]  from main main::@7
  (word) memcpy::num#2 ← phi( main/(word) memcpy::num#0 main::@7/(word) memcpy::num#1 )
  (void*) memcpy::destination#2 ← phi( main/(void*) memcpy::destination#0 main::@7/(void*) memcpy::destination#1 )
  (void*) memcpy::source#2 ← phi( main/(void*) memcpy::source#0 main::@7/(void*) memcpy::source#1 )
  (byte*) memcpy::src#0 ← ((byte*)) (void*) memcpy::source#2
  (byte*) memcpy::dst#0 ← ((byte*)) (void*) memcpy::destination#2
  (byte*~) memcpy::$0 ← ((byte*)) (void*) memcpy::source#2
  (byte*~) memcpy::$1 ← (byte*~) memcpy::$0 + (word) memcpy::num#2
  (byte*) memcpy::src_end#0 ← (byte*~) memcpy::$1
  to:memcpy::@1
memcpy::@1: scope:[memcpy]  from memcpy memcpy::@2
  (void*) memcpy::destination#4 ← phi( memcpy/(void*) memcpy::destination#2 memcpy::@2/(void*) memcpy::destination#5 )
  (byte*) memcpy::dst#3 ← phi( memcpy/(byte*) memcpy::dst#0 memcpy::@2/(byte*) memcpy::dst#1 )
  (byte*) memcpy::src_end#1 ← phi( memcpy/(byte*) memcpy::src_end#0 memcpy::@2/(byte*) memcpy::src_end#2 )
  (byte*) memcpy::src#2 ← phi( memcpy/(byte*) memcpy::src#0 memcpy::@2/(byte*) memcpy::src#1 )
  (bool~) memcpy::$2 ← (byte*) memcpy::src#2 != (byte*) memcpy::src_end#1
  if((bool~) memcpy::$2) goto memcpy::@2
  to:memcpy::@3
memcpy::@2: scope:[memcpy]  from memcpy::@1
  (void*) memcpy::destination#5 ← phi( memcpy::@1/(void*) memcpy::destination#4 )
  (byte*) memcpy::src_end#2 ← phi( memcpy::@1/(byte*) memcpy::src_end#1 )
  (byte*) memcpy::dst#2 ← phi( memcpy::@1/(byte*) memcpy::dst#3 )
  (byte*) memcpy::src#3 ← phi( memcpy::@1/(byte*) memcpy::src#2 )
  *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#3)
  (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
  (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#3
  to:memcpy::@1
memcpy::@3: scope:[memcpy]  from memcpy::@1
  (void*) memcpy::destination#3 ← phi( memcpy::@1/(void*) memcpy::destination#4 )
  (void*) memcpy::return#0 ← (void*) memcpy::destination#3
  to:memcpy::@return
memcpy::@return: scope:[memcpy]  from memcpy::@3
  (void*) memcpy::return#4 ← phi( memcpy::@3/(void*) memcpy::return#0 )
  (void*) memcpy::return#1 ← (void*) memcpy::return#4
  return 
  to:@return
@8: scope:[]  from @begin
  (byte[$3e8]) MEDUSA_SCREEN#0 ← kickasm {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)
 }}
  (byte[]) MEDUSA_COLORS#0 ← kickasm {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)
 }}
  (byte*) SCREEN#0 ← ((byte*)) (number) $400
  to:@9
main: scope:[main]  from @9
  *((byte*) BGCOL#0) ← (byte) BLACK#0
  (void*) memcpy::destination#0 ← (void*)(byte*) SCREEN#0
  (void*) memcpy::source#0 ← (void*)(byte[$3e8]) MEDUSA_SCREEN#0
  (word) memcpy::num#0 ← (number) $3e8
  call memcpy 
  (void*) memcpy::return#2 ← (void*) memcpy::return#1
  to:main::@7
main::@7: scope:[main]  from main
  (void*) memcpy::destination#1 ← (void*)(byte*) COLS#0
  (void*) memcpy::source#1 ← (void*)(byte[]) MEDUSA_COLORS#0
  (word) memcpy::num#1 ← (number) $3e8
  call memcpy 
  (void*) memcpy::return#3 ← (void*) memcpy::return#1
  to:main::@8
main::@8: scope:[main]  from main::@7
  to:main::@1
main::@1: scope:[main]  from main::@2 main::@8
  if(true) goto main::@2
  to:main::@return
main::@2: scope:[main]  from main::@1
  (byte*~) main::$2 ← (byte*) SCREEN#0 + (number) $3e7
  *((byte*~) main::$2) ← *((byte*~) main::$2) ^ (number) $e
  to:main::@1
main::@return: scope:[main]  from main::@1
  return 
  to:@return
@9: scope:[]  from @8
  call main 
  to:@10
@10: scope:[]  from @9
  to:@end
@end: scope:[]  from @10

SYMBOL TABLE SSA
(label) @10
(label) @8
(label) @9
(label) @begin
(label) @end
(byte*) BGCOL
(byte*) BGCOL#0
(byte) BLACK
(byte) BLACK#0
(byte*) COLS
(byte*) COLS#0
(byte[]) MEDUSA_COLORS
(byte[]) MEDUSA_COLORS#0
(byte[$3e8]) MEDUSA_SCREEN
(byte[$3e8]) MEDUSA_SCREEN#0
(byte*) SCREEN
(byte*) SCREEN#0
(void()) main()
(byte*~) main::$2
(label) main::@1
(label) main::@2
(label) main::@7
(label) main::@8
(label) main::@return
(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
(byte*~) memcpy::$0
(byte*~) memcpy::$1
(bool~) memcpy::$2
(label) memcpy::@1
(label) memcpy::@2
(label) memcpy::@3
(label) memcpy::@return
(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
(byte*) memcpy::dst
(byte*) memcpy::dst#0
(byte*) memcpy::dst#1
(byte*) memcpy::dst#2
(byte*) memcpy::dst#3
(word) memcpy::num
(word) memcpy::num#0
(word) memcpy::num#1
(word) 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
(byte*) memcpy::src
(byte*) memcpy::src#0
(byte*) memcpy::src#1
(byte*) memcpy::src#2
(byte*) memcpy::src#3
(byte*) memcpy::src_end
(byte*) memcpy::src_end#0
(byte*) memcpy::src_end#1
(byte*) memcpy::src_end#2

Adding number conversion cast (unumber) 0 in (byte) BLACK#0 ← (number) 0
Adding number conversion cast (unumber) $3e8 in (word) memcpy::num#0 ← (number) $3e8
Adding number conversion cast (unumber) $3e8 in (word) memcpy::num#1 ← (number) $3e8
Adding number conversion cast (unumber) $3e7 in (byte*~) main::$2 ← (byte*) SCREEN#0 + (number) $3e7
Adding number conversion cast (unumber) $e in *((byte*~) main::$2) ← *((byte*~) main::$2) ^ (number) $e
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte*) BGCOL#0 ← (byte*)(number) $d021
Inlining cast (byte*) COLS#0 ← (byte*)(number) $d800
Inlining cast (byte) BLACK#0 ← (unumber)(number) 0
Inlining cast (byte*) memcpy::src#0 ← (byte*)(void*) memcpy::source#2
Inlining cast (byte*) memcpy::dst#0 ← (byte*)(void*) memcpy::destination#2
Inlining cast (byte*~) memcpy::$0 ← (byte*)(void*) memcpy::source#2
Inlining cast (byte*) SCREEN#0 ← (byte*)(number) $400
Inlining cast (word) memcpy::num#0 ← (unumber)(number) $3e8
Inlining cast (word) memcpy::num#1 ← (unumber)(number) $3e8
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 53281
Simplifying constant pointer cast (byte*) 55296
Simplifying constant integer cast 0
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast $3e8
Simplifying constant integer cast $3e8
Simplifying constant integer cast $3e7
Simplifying constant integer cast $e
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (word) $3e8
Finalized unsigned number type (word) $3e8
Finalized unsigned number type (word) $3e7
Finalized unsigned number type (byte) $e
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte*) memcpy::src_end#0 = (byte*~) memcpy::$1 
Alias (byte*) memcpy::src#2 = (byte*) memcpy::src#3 
Alias (byte*) memcpy::dst#2 = (byte*) memcpy::dst#3 
Alias (byte*) memcpy::src_end#1 = (byte*) memcpy::src_end#2 
Alias (void*) memcpy::destination#3 = (void*) memcpy::destination#5 (void*) memcpy::destination#4 (void*) memcpy::return#0 (void*) memcpy::return#4 (void*) memcpy::return#1 
Successful SSA optimization Pass2AliasElimination
Self Phi Eliminated (byte*) memcpy::src_end#1
Self Phi Eliminated (void*) memcpy::destination#3
Successful SSA optimization Pass2SelfPhiElimination
Identical Phi Values (byte*) memcpy::src_end#1 (byte*) memcpy::src_end#0
Identical Phi Values (void*) memcpy::destination#3 (void*) memcpy::destination#2
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition (bool~) memcpy::$2 [11] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) BGCOL#0 = (byte*) 53281
Constant (const byte*) COLS#0 = (byte*) 55296
Constant (const byte) BLACK#0 = 0
Constant (const byte[$3e8]) MEDUSA_SCREEN#0 = kickasm {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)
 }}
Constant (const byte[]) MEDUSA_COLORS#0 = kickasm {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)
 }}
Constant (const byte*) SCREEN#0 = (byte*) 1024
Constant (const word) memcpy::num#0 = $3e8
Constant (const word) memcpy::num#1 = $3e8
Successful SSA optimization Pass2ConstantIdentification
Constant value identified (void*)SCREEN#0 in [25] (void*) memcpy::destination#0 ← (void*)(const byte*) SCREEN#0
Constant value identified (void*)MEDUSA_SCREEN#0 in [26] (void*) memcpy::source#0 ← (void*)(const byte[$3e8]) MEDUSA_SCREEN#0
Constant value identified (void*)COLS#0 in [30] (void*) memcpy::destination#1 ← (void*)(const byte*) COLS#0
Constant value identified (void*)MEDUSA_COLORS#0 in [31] (void*) memcpy::source#1 ← (void*)(const byte[]) MEDUSA_COLORS#0
Successful SSA optimization Pass2ConstantValues
if() condition always true - replacing block destination [35] if(true) goto main::@2
Successful SSA optimization Pass2ConstantIfs
Eliminating unused variable (void*) memcpy::return#2 and assignment [15] (void*) memcpy::return#2 ← (void*) memcpy::destination#2
Eliminating unused variable (void*) memcpy::return#3 and assignment [19] (void*) memcpy::return#3 ← (void*) memcpy::destination#2
Successful SSA optimization PassNEliminateUnusedVars
Removing unused block main::@return
Successful SSA optimization Pass2EliminateUnusedBlocks
Constant right-side identified [18] (byte*~) main::$2 ← (const byte*) SCREEN#0 + (word) $3e7
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const void*) memcpy::destination#0 = (void*)SCREEN#0
Constant (const void*) memcpy::source#0 = (void*)MEDUSA_SCREEN#0
Constant (const void*) memcpy::destination#1 = (void*)COLS#0
Constant (const void*) memcpy::source#1 = (void*)MEDUSA_COLORS#0
Constant (const byte*) main::$2 = SCREEN#0+$3e7
Successful SSA optimization Pass2ConstantIdentification
Inlining Noop Cast [1] (byte*) memcpy::src#0 ← (byte*)(void*) memcpy::source#2 keeping memcpy::source#2
Inlining Noop Cast [2] (byte*) memcpy::dst#0 ← (byte*)(void*) memcpy::destination#2 keeping memcpy::destination#2
Inlining Noop Cast [3] (byte*~) memcpy::$0 ← (byte*)(void*) memcpy::source#2 keeping memcpy::source#2
Successful SSA optimization Pass2NopCastInlining
Inlining constant with var siblings (const word) memcpy::num#0
Inlining constant with var siblings (const word) memcpy::num#1
Inlining constant with var siblings (const void*) memcpy::destination#0
Inlining constant with var siblings (const void*) memcpy::source#0
Inlining constant with var siblings (const void*) memcpy::destination#1
Inlining constant with var siblings (const void*) memcpy::source#1
Constant inlined memcpy::num#1 = (word) $3e8
Constant inlined memcpy::num#0 = (word) $3e8
Constant inlined memcpy::source#1 = (void*)(const byte[]) MEDUSA_COLORS#0
Constant inlined main::$2 = (const byte*) SCREEN#0+(word) $3e7
Constant inlined memcpy::destination#0 = (void*)(const byte*) SCREEN#0
Constant inlined memcpy::destination#1 = (void*)(const byte*) COLS#0
Constant inlined memcpy::source#0 = (void*)(const byte[$3e8]) MEDUSA_SCREEN#0
Successful SSA optimization Pass2ConstantInlining
Identical Phi Values (word) memcpy::num#2 (word) $3e8
Successful SSA optimization Pass2IdenticalPhiElimination
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @8
Adding NOP phi() at start of @9
Adding NOP phi() at start of @10
Adding NOP phi() at start of @end
Adding NOP phi() at start of main::@7
Adding NOP phi() at start of main::@8
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of memcpy::@3
CALL GRAPH
Calls in [] to main:3 
Calls in [main] to memcpy:7 memcpy:9 

Created 4 initial phi equivalence classes
Coalesced [24] memcpy::src#5 ← memcpy::src#1
Coalesced [25] memcpy::dst#5 ← memcpy::dst#1
Coalesced down to 4 phi equivalence classes
Culled Empty Block (label) @8
Culled Empty Block (label) @10
Culled Empty Block (label) main::@8
Culled Empty Block (label) main::@1
Culled Empty Block (label) memcpy::@3
Renumbering block @9 to @1
Renumbering block main::@2 to main::@1
Renumbering block main::@7 to main::@2
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
Adding NOP phi() at start of main::@2

FINAL CONTROL FLOW GRAPH
@begin: scope:[]  from
  [0] phi()
  to:@1
@1: scope:[]  from @begin
  [1] phi()
  [2] call main 
  to:@end
@end: scope:[]  from @1
  [3] phi()
main: scope:[main]  from @1
  [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0
  [5] call memcpy 
  to:main::@2
main::@2: scope:[main]  from main
  [6] phi()
  [7] call memcpy 
  to:main::@1
main::@1: scope:[main]  from main::@1 main::@2
  [8] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e
  to:main::@1
memcpy: scope:[memcpy]  from main main::@2
  [9] (void*) memcpy::destination#2 ← phi( main/(void*)(const byte*) SCREEN#0 main::@2/(void*)(const byte*) COLS#0 )
  [9] (void*) memcpy::source#2 ← phi( main/(void*)(const byte[$3e8]) MEDUSA_SCREEN#0 main::@2/(void*)(const byte[]) MEDUSA_COLORS#0 )
  [10] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) $3e8
  [11] (byte*~) memcpy::src#4 ← (byte*)(void*) memcpy::source#2
  [12] (byte*~) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2
  to:memcpy::@1
memcpy::@1: scope:[memcpy]  from memcpy memcpy::@2
  [13] (byte*) memcpy::dst#2 ← phi( memcpy/(byte*~) memcpy::dst#4 memcpy::@2/(byte*) memcpy::dst#1 )
  [13] (byte*) memcpy::src#2 ← phi( memcpy/(byte*~) memcpy::src#4 memcpy::@2/(byte*) memcpy::src#1 )
  [14] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2
  to:memcpy::@return
memcpy::@return: scope:[memcpy]  from memcpy::@1
  [15] return 
  to:@return
memcpy::@2: scope:[memcpy]  from memcpy::@1
  [16] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2)
  [17] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2
  [18] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2
  to:memcpy::@1


VARIABLE REGISTER WEIGHTS
(byte*) BGCOL
(byte) BLACK
(byte*) COLS
(byte[]) MEDUSA_COLORS
(byte[$3e8]) MEDUSA_SCREEN
(byte*) SCREEN
(void()) main()
(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
(void*) memcpy::destination
(void*) memcpy::destination#2
(byte*) memcpy::dst
(byte*) memcpy::dst#1 11.0
(byte*) memcpy::dst#2 11.666666666666666
(byte*~) memcpy::dst#4 4.0
(word) memcpy::num
(void*) memcpy::return
(void*) memcpy::source
(void*) memcpy::source#2
(byte*) memcpy::src
(byte*) memcpy::src#1 22.0
(byte*) memcpy::src#2 11.5
(byte*~) memcpy::src#4 2.0
(byte*) memcpy::src_end
(byte*) memcpy::src_end#0 1.625

Initial phi equivalence classes
[ memcpy::source#2 ]
[ memcpy::destination#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 zero page equivalence class [ memcpy::src_end#0 ]
Complete equivalence classes
[ memcpy::source#2 ]
[ memcpy::destination#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 ZP_WORD:2 [ memcpy::source#2 ]
Allocated zp ZP_WORD:4 [ memcpy::destination#2 ]
Allocated zp ZP_WORD:6 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
Allocated zp ZP_WORD:8 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
Allocated zp ZP_WORD:10 [ memcpy::src_end#0 ]

INITIAL ASM
  // File Comments
// Display  MEDUSA PETSCII by Buzz_clik
// https://csdb.dk/release/?id=178673
  // Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .label BGCOL = $d021
  // Color Ram
  .label COLS = $d800
  // The colors of the C64
  .const BLACK = 0
  .label SCREEN = $400
  // @begin
bbegin:
  // [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
  jmp b1
  // @1
b1:
  // [2] call main 
  jsr main
  // [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
  jmp bend
  // @end
bend:
  // main
main: {
    // [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 
    lda #BLACK
    sta BGCOL
    // [5] call memcpy 
    // [9] phi from main to memcpy [phi:main->memcpy]
  memcpy_from_main:
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) SCREEN#0 [phi:main->memcpy#0] -- pvoz1=pvoc1 
    lda #<SCREEN
    sta memcpy.destination
    lda #>SCREEN
    sta memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte[$3e8]) MEDUSA_SCREEN#0 [phi:main->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_SCREEN
    sta memcpy.source
    lda #>MEDUSA_SCREEN
    sta memcpy.source+1
    jsr memcpy
    // [6] phi from main to main::@2 [phi:main->main::@2]
  b2_from_main:
    jmp b2
    // main::@2
  b2:
    // [7] call memcpy 
    // [9] phi from main::@2 to memcpy [phi:main::@2->memcpy]
  memcpy_from_b2:
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) COLS#0 [phi:main::@2->memcpy#0] -- pvoz1=pvoc1 
    lda #<COLS
    sta memcpy.destination
    lda #>COLS
    sta memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte[]) MEDUSA_COLORS#0 [phi:main::@2->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_COLORS
    sta memcpy.source
    lda #>MEDUSA_COLORS
    sta memcpy.source+1
    jsr memcpy
    jmp b1
    // main::@1
  b1:
    // [8] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2 
    lda #$e
    eor SCREEN+$3e7
    sta SCREEN+$3e7
    jmp b1
}
  // 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.
// memcpy(void* zeropage(4) destination, void* zeropage(2) source)
memcpy: {
    .label src_end = $a
    .label dst = 8
    .label src = 6
    .label source = 2
    .label destination = 4
    // [10] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) $3e8 -- pbuz1=pbuz2_plus_vwuc1 
    lda source
    clc
    adc #<$3e8
    sta src_end
    lda source+1
    adc #>$3e8
    sta src_end+1
    // [11] (byte*~) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 -- pbuz1=pbuz2 
    lda source
    sta src
    lda source+1
    sta src+1
    // [12] (byte*~) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 -- pbuz1=pbuz2 
    lda destination
    sta dst
    lda destination+1
    sta dst+1
    // [13] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
  b1_from_memcpy:
  b1_from_b2:
    // [13] phi (byte*) memcpy::dst#2 = (byte*~) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy 
    // [13] phi (byte*) memcpy::src#2 = (byte*~) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy 
    jmp b1
    // memcpy::@1
  b1:
    // [14] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1 
    lda src+1
    cmp src_end+1
    bne b2
    lda src
    cmp src_end
    bne b2
    jmp breturn
    // memcpy::@return
  breturn:
    // [15] return 
    rts
    // memcpy::@2
  b2:
    // [16] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (src),y
    ldy #0
    sta (dst),y
    // [17] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1 
    inc dst
    bne !+
    inc dst+1
  !:
    // [18] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1 
    inc src
    bne !+
    inc src+1
  !:
    jmp b1_from_b2
}
  // File Data
MEDUSA_SCREEN:
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)

MEDUSA_COLORS:
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)


REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [8] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e [ ] ( main:2 [ ] ) always clobbers reg byte a 
Statement [10] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) $3e8 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ( main:2::memcpy:5 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] main:2::memcpy:7 [ memcpy::source#2 memcpy::destination#2 memcpy::src_end#0 ] ) always clobbers reg byte a 
Statement [11] (byte*~) memcpy::src#4 ← (byte*)(void*) memcpy::source#2 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ( main:2::memcpy:5 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] main:2::memcpy:7 [ memcpy::destination#2 memcpy::src_end#0 memcpy::src#4 ] ) always clobbers reg byte a 
Statement [12] (byte*~) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ( main:2::memcpy:5 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] main:2::memcpy:7 [ memcpy::src_end#0 memcpy::src#4 memcpy::dst#4 ] ) always clobbers reg byte a 
Statement [14] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:2::memcpy:5 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] main:2::memcpy:7 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ) always clobbers reg byte a 
Statement [16] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ( main:2::memcpy:5 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] main:2::memcpy:7 [ memcpy::src_end#0 memcpy::src#2 memcpy::dst#2 ] ) always clobbers reg byte a reg byte y 
Potential registers zp ZP_WORD:2 [ memcpy::source#2 ] : zp ZP_WORD:2 , 
Potential registers zp ZP_WORD:4 [ memcpy::destination#2 ] : zp ZP_WORD:4 , 
Potential registers zp ZP_WORD:6 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] : zp ZP_WORD:6 , 
Potential registers zp ZP_WORD:8 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] : zp ZP_WORD:8 , 
Potential registers zp ZP_WORD:10 [ memcpy::src_end#0 ] : zp ZP_WORD:10 , 

REGISTER UPLIFT SCOPES
Uplift Scope [memcpy] 35.5: zp ZP_WORD:6 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] 26.67: zp ZP_WORD:8 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] 1.62: zp ZP_WORD:10 [ memcpy::src_end#0 ] 0: zp ZP_WORD:2 [ memcpy::source#2 ] 0: zp ZP_WORD:4 [ memcpy::destination#2 ] 
Uplift Scope [main] 
Uplift Scope [] 

Uplifting [memcpy] best 919 combination zp ZP_WORD:6 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] zp ZP_WORD:8 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] zp ZP_WORD:10 [ memcpy::src_end#0 ] zp ZP_WORD:2 [ memcpy::source#2 ] zp ZP_WORD:4 [ memcpy::destination#2 ] 
Uplifting [main] best 919 combination 
Uplifting [] best 919 combination 
Coalescing zero page register with common assignment [ zp ZP_WORD:2 [ memcpy::source#2 ] ] with [ zp ZP_WORD:6 [ memcpy::src#2 memcpy::src#4 memcpy::src#1 ] ] - score: 1
Coalescing zero page register with common assignment [ zp ZP_WORD:4 [ memcpy::destination#2 ] ] with [ zp ZP_WORD:8 [ memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] ] - score: 1
Allocated (was zp ZP_WORD:10) zp ZP_WORD:6 [ memcpy::src_end#0 ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Display  MEDUSA PETSCII by Buzz_clik
// https://csdb.dk/release/?id=178673
  // Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .label BGCOL = $d021
  // Color Ram
  .label COLS = $d800
  // The colors of the C64
  .const BLACK = 0
  .label SCREEN = $400
  // @begin
bbegin:
  // [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
  jmp b1
  // @1
b1:
  // [2] call main 
  jsr main
  // [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
  jmp bend
  // @end
bend:
  // main
main: {
    // [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 
    lda #BLACK
    sta BGCOL
    // [5] call memcpy 
    // [9] phi from main to memcpy [phi:main->memcpy]
  memcpy_from_main:
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) SCREEN#0 [phi:main->memcpy#0] -- pvoz1=pvoc1 
    lda #<SCREEN
    sta memcpy.destination
    lda #>SCREEN
    sta memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte[$3e8]) MEDUSA_SCREEN#0 [phi:main->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_SCREEN
    sta memcpy.source
    lda #>MEDUSA_SCREEN
    sta memcpy.source+1
    jsr memcpy
    // [6] phi from main to main::@2 [phi:main->main::@2]
  b2_from_main:
    jmp b2
    // main::@2
  b2:
    // [7] call memcpy 
    // [9] phi from main::@2 to memcpy [phi:main::@2->memcpy]
  memcpy_from_b2:
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) COLS#0 [phi:main::@2->memcpy#0] -- pvoz1=pvoc1 
    lda #<COLS
    sta memcpy.destination
    lda #>COLS
    sta memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte[]) MEDUSA_COLORS#0 [phi:main::@2->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_COLORS
    sta memcpy.source
    lda #>MEDUSA_COLORS
    sta memcpy.source+1
    jsr memcpy
    jmp b1
    // main::@1
  b1:
    // [8] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2 
    lda #$e
    eor SCREEN+$3e7
    sta SCREEN+$3e7
    jmp b1
}
  // 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.
// memcpy(void* zeropage(4) destination, void* zeropage(2) source)
memcpy: {
    .label src_end = 6
    .label dst = 4
    .label src = 2
    .label source = 2
    .label destination = 4
    // [10] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) $3e8 -- pbuz1=pbuz2_plus_vwuc1 
    lda source
    clc
    adc #<$3e8
    sta src_end
    lda source+1
    adc #>$3e8
    sta src_end+1
    // [11] (byte*~) memcpy::src#4 ← (byte*)(void*) memcpy::source#2
    // [12] (byte*~) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2
    // [13] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
  b1_from_memcpy:
  b1_from_b2:
    // [13] phi (byte*) memcpy::dst#2 = (byte*~) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy 
    // [13] phi (byte*) memcpy::src#2 = (byte*~) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy 
    jmp b1
    // memcpy::@1
  b1:
    // [14] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1 
    lda src+1
    cmp src_end+1
    bne b2
    lda src
    cmp src_end
    bne b2
    jmp breturn
    // memcpy::@return
  breturn:
    // [15] return 
    rts
    // memcpy::@2
  b2:
    // [16] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (src),y
    ldy #0
    sta (dst),y
    // [17] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1 
    inc dst
    bne !+
    inc dst+1
  !:
    // [18] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1 
    inc src
    bne !+
    inc src+1
  !:
    jmp b1_from_b2
}
  // File Data
MEDUSA_SCREEN:
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)

MEDUSA_COLORS:
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)


ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b2
Removing instruction jmp b1
Removing instruction jmp b1
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction ldy #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label b1_from_b2 with b1
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction bend_from_b1:
Removing instruction b2_from_main:
Removing instruction memcpy_from_b2:
Removing instruction b1_from_memcpy:
Removing instruction b1_from_b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction memcpy_from_main:
Removing instruction b2:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(byte*) BGCOL
(const byte*) BGCOL#0 BGCOL = (byte*) 53281
(byte) BLACK
(const byte) BLACK#0 BLACK = (byte) 0
(byte*) COLS
(const byte*) COLS#0 COLS = (byte*) 55296
(byte[]) MEDUSA_COLORS
(const byte[]) MEDUSA_COLORS#0 MEDUSA_COLORS = kickasm {{ .var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)
 }}
(byte[$3e8]) MEDUSA_SCREEN
(const byte[$3e8]) MEDUSA_SCREEN#0 MEDUSA_SCREEN = kickasm {{ .var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)
 }}
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = (byte*) 1024
(void()) main()
(label) main::@1
(label) main::@2
(void*()) memcpy((void*) memcpy::destination , (void*) memcpy::source , (word) memcpy::num)
(label) memcpy::@1
(label) memcpy::@2
(label) memcpy::@return
(void*) memcpy::destination
(void*) memcpy::destination#2 destination zp ZP_WORD:4
(byte*) memcpy::dst
(byte*) memcpy::dst#1 dst zp ZP_WORD:4 11.0
(byte*) memcpy::dst#2 dst zp ZP_WORD:4 11.666666666666666
(byte*~) memcpy::dst#4 dst zp ZP_WORD:4 4.0
(word) memcpy::num
(void*) memcpy::return
(void*) memcpy::source
(void*) memcpy::source#2 source zp ZP_WORD:2
(byte*) memcpy::src
(byte*) memcpy::src#1 src zp ZP_WORD:2 22.0
(byte*) memcpy::src#2 src zp ZP_WORD:2 11.5
(byte*~) memcpy::src#4 src zp ZP_WORD:2 2.0
(byte*) memcpy::src_end
(byte*) memcpy::src_end#0 src_end zp ZP_WORD:6 1.625

zp ZP_WORD:2 [ memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ]
zp ZP_WORD:4 [ memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ]
zp ZP_WORD:6 [ memcpy::src_end#0 ]


FINAL ASSEMBLER
Score: 797

  // File Comments
// Display  MEDUSA PETSCII by Buzz_clik
// https://csdb.dk/release/?id=178673
  // Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
  // Global Constants & labels
  .label BGCOL = $d021
  // Color Ram
  .label COLS = $d800
  // The colors of the C64
  .const BLACK = 0
  .label SCREEN = $400
  // @begin
  // [1] phi from @begin to @1 [phi:@begin->@1]
  // @1
  // [2] call main 
  // [3] phi from @1 to @end [phi:@1->@end]
  // @end
  // main
main: {
    // *BGCOL = BLACK
    // [4] *((const byte*) BGCOL#0) ← (const byte) BLACK#0 -- _deref_pbuc1=vbuc2 
    lda #BLACK
    sta BGCOL
    // memcpy(SCREEN, MEDUSA_SCREEN, 1000)
    // [5] call memcpy 
    // [9] phi from main to memcpy [phi:main->memcpy]
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) SCREEN#0 [phi:main->memcpy#0] -- pvoz1=pvoc1 
    lda #<SCREEN
    sta memcpy.destination
    lda #>SCREEN
    sta memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte[$3e8]) MEDUSA_SCREEN#0 [phi:main->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_SCREEN
    sta memcpy.source
    lda #>MEDUSA_SCREEN
    sta memcpy.source+1
    jsr memcpy
    // [6] phi from main to main::@2 [phi:main->main::@2]
    // main::@2
    // memcpy(COLS, MEDUSA_COLORS, 1000)
    // [7] call memcpy 
    // [9] phi from main::@2 to memcpy [phi:main::@2->memcpy]
    // [9] phi (void*) memcpy::destination#2 = (void*)(const byte*) COLS#0 [phi:main::@2->memcpy#0] -- pvoz1=pvoc1 
    lda #<COLS
    sta memcpy.destination
    lda #>COLS
    sta memcpy.destination+1
    // [9] phi (void*) memcpy::source#2 = (void*)(const byte[]) MEDUSA_COLORS#0 [phi:main::@2->memcpy#1] -- pvoz1=pvoc1 
    lda #<MEDUSA_COLORS
    sta memcpy.source
    lda #>MEDUSA_COLORS
    sta memcpy.source+1
    jsr memcpy
    // main::@1
  b1:
    // (*(SCREEN+999)) ^= 0x0e
    // [8] *((const byte*) SCREEN#0+(word) $3e7) ← *((const byte*) SCREEN#0+(word) $3e7) ^ (byte) $e -- _deref_pbuc1=_deref_pbuc1_bxor_vbuc2 
    lda #$e
    eor SCREEN+$3e7
    sta SCREEN+$3e7
    jmp b1
}
  // 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.
// memcpy(void* zeropage(4) destination, void* zeropage(2) source)
memcpy: {
    .label src_end = 6
    .label dst = 4
    .label src = 2
    .label source = 2
    .label destination = 4
    // src_end = (char*)source+num
    // [10] (byte*) memcpy::src_end#0 ← (byte*)(void*) memcpy::source#2 + (word) $3e8 -- pbuz1=pbuz2_plus_vwuc1 
    lda source
    clc
    adc #<$3e8
    sta src_end
    lda source+1
    adc #>$3e8
    sta src_end+1
    // [11] (byte*~) memcpy::src#4 ← (byte*)(void*) memcpy::source#2
    // [12] (byte*~) memcpy::dst#4 ← (byte*)(void*) memcpy::destination#2
    // [13] phi from memcpy memcpy::@2 to memcpy::@1 [phi:memcpy/memcpy::@2->memcpy::@1]
    // [13] phi (byte*) memcpy::dst#2 = (byte*~) memcpy::dst#4 [phi:memcpy/memcpy::@2->memcpy::@1#0] -- register_copy 
    // [13] phi (byte*) memcpy::src#2 = (byte*~) memcpy::src#4 [phi:memcpy/memcpy::@2->memcpy::@1#1] -- register_copy 
    // memcpy::@1
  b1:
    // while(src!=src_end)
    // [14] if((byte*) memcpy::src#2!=(byte*) memcpy::src_end#0) goto memcpy::@2 -- pbuz1_neq_pbuz2_then_la1 
    lda src+1
    cmp src_end+1
    bne b2
    lda src
    cmp src_end
    bne b2
    // memcpy::@return
    // }
    // [15] return 
    rts
    // memcpy::@2
  b2:
    // *dst++ = *src++
    // [16] *((byte*) memcpy::dst#2) ← *((byte*) memcpy::src#2) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (src),y
    sta (dst),y
    // *dst++ = *src++;
    // [17] (byte*) memcpy::dst#1 ← ++ (byte*) memcpy::dst#2 -- pbuz1=_inc_pbuz1 
    inc dst
    bne !+
    inc dst+1
  !:
    // [18] (byte*) memcpy::src#1 ← ++ (byte*) memcpy::src#2 -- pbuz1=_inc_pbuz1 
    inc src
    bne !+
    inc src+1
  !:
    jmp b1
}
  // File Data
MEDUSA_SCREEN:
.var fileScreen = LoadBinary("medusas.prg", BF_C64FILE)
    .fill fileScreen.getSize(), fileScreen.get(i)

MEDUSA_COLORS:
.var fileCols = LoadBinary("medusac.prg", BF_C64FILE)
    .fill fileCols.getSize(), fileCols.get(i)


