PARSING src/test/java/dk/camelot64/kickc/test/kc/fillscreen.kc
byte *SCREEN = $0400;

void main() {
    byte c = (*SCREEN);
    fillscreen(c);
}

void fillscreen(byte c) {
    for(byte j : 0..255) {
        byte* SCREEN2 = SCREEN+$100;
        byte* SCREEN3 = SCREEN+$200;
        byte* SCREEN4 = SCREEN+$3e8;
        SCREEN[j] = c;
        SCREEN2[j] = c;
        SCREEN3[j] = c;
        SCREEN4[j] = c;
    }
}



STATEMENTS
  (byte*) SCREEN ← (word/signed word/dword/signed dword) 1024
proc (void()) main()
  (byte) main::c ← *((byte*) SCREEN)
  (void~) main::$0 ← call fillscreen (byte) main::c 
main::@return:
  return 
endproc // main()
proc (void()) fillscreen((byte) fillscreen::c)
  (byte) fillscreen::j ← (byte/signed byte/word/signed word/dword/signed dword) 0
fillscreen::@1:
  (byte*~) fillscreen::$0 ← (byte*) SCREEN + (word/signed word/dword/signed dword) 256
  (byte*) fillscreen::SCREEN2 ← (byte*~) fillscreen::$0
  (byte*~) fillscreen::$1 ← (byte*) SCREEN + (word/signed word/dword/signed dword) 512
  (byte*) fillscreen::SCREEN3 ← (byte*~) fillscreen::$1
  (byte*~) fillscreen::$2 ← (byte*) SCREEN + (word/signed word/dword/signed dword) 1000
  (byte*) fillscreen::SCREEN4 ← (byte*~) fillscreen::$2
  *((byte*) SCREEN + (byte) fillscreen::j) ← (byte) fillscreen::c
  *((byte*) fillscreen::SCREEN2 + (byte) fillscreen::j) ← (byte) fillscreen::c
  *((byte*) fillscreen::SCREEN3 + (byte) fillscreen::j) ← (byte) fillscreen::c
  *((byte*) fillscreen::SCREEN4 + (byte) fillscreen::j) ← (byte) fillscreen::c
  (byte) fillscreen::j ← ++ (byte) fillscreen::j
  (boolean~) fillscreen::$3 ← (byte) fillscreen::j != (byte/signed byte/word/signed word/dword/signed dword) 0
  if((boolean~) fillscreen::$3) goto fillscreen::@1
fillscreen::@return:
  return 
endproc // fillscreen()
  call main 

SYMBOLS
(byte*) SCREEN
(void()) fillscreen((byte) fillscreen::c)
(byte*~) fillscreen::$0
(byte*~) fillscreen::$1
(byte*~) fillscreen::$2
(boolean~) fillscreen::$3
(label) fillscreen::@1
(label) fillscreen::@return
(byte*) fillscreen::SCREEN2
(byte*) fillscreen::SCREEN3
(byte*) fillscreen::SCREEN4
(byte) fillscreen::c
(byte) fillscreen::j
(void()) main()
(void~) main::$0
(label) main::@return
(byte) main::c

Promoting word/signed word/dword/signed dword to byte* in SCREEN ← ((byte*)) 1024
INITIAL CONTROL FLOW GRAPH
@begin: scope:[]  from
  (byte*) SCREEN ← ((byte*)) (word/signed word/dword/signed dword) 1024
  to:@1
main: scope:[main]  from
  (byte) main::c ← *((byte*) SCREEN)
  (void~) main::$0 ← call fillscreen (byte) main::c 
  to:main::@return
main::@return: scope:[main]  from main
  return 
  to:@return
@1: scope:[]  from @begin
  to:@2
fillscreen: scope:[fillscreen]  from
  (byte) fillscreen::j ← (byte/signed byte/word/signed word/dword/signed dword) 0
  to:fillscreen::@1
fillscreen::@1: scope:[fillscreen]  from fillscreen fillscreen::@1
  (byte*~) fillscreen::$0 ← (byte*) SCREEN + (word/signed word/dword/signed dword) 256
  (byte*) fillscreen::SCREEN2 ← (byte*~) fillscreen::$0
  (byte*~) fillscreen::$1 ← (byte*) SCREEN + (word/signed word/dword/signed dword) 512
  (byte*) fillscreen::SCREEN3 ← (byte*~) fillscreen::$1
  (byte*~) fillscreen::$2 ← (byte*) SCREEN + (word/signed word/dword/signed dword) 1000
  (byte*) fillscreen::SCREEN4 ← (byte*~) fillscreen::$2
  *((byte*) SCREEN + (byte) fillscreen::j) ← (byte) fillscreen::c
  *((byte*) fillscreen::SCREEN2 + (byte) fillscreen::j) ← (byte) fillscreen::c
  *((byte*) fillscreen::SCREEN3 + (byte) fillscreen::j) ← (byte) fillscreen::c
  *((byte*) fillscreen::SCREEN4 + (byte) fillscreen::j) ← (byte) fillscreen::c
  (byte) fillscreen::j ← ++ (byte) fillscreen::j
  (boolean~) fillscreen::$3 ← (byte) fillscreen::j != (byte/signed byte/word/signed word/dword/signed dword) 0
  if((boolean~) fillscreen::$3) goto fillscreen::@1
  to:fillscreen::@2
fillscreen::@2: scope:[fillscreen]  from fillscreen::@1
  to:fillscreen::@return
fillscreen::@return: scope:[fillscreen]  from fillscreen::@2
  return 
  to:@return
@2: scope:[]  from @1
  call main 
  to:@end
@end: scope:[]  from @2

Eliminating unused variable - keeping the call (void~) main::$0
Removing empty block @1
Removing empty block fillscreen::@2
PROCEDURE MODIFY VARIABLE ANALYSIS

Completing Phi functions...
Completing Phi functions...

CONTROL FLOW GRAPH SSA WITH ASSIGNMENT CALL & RETURN
@begin: scope:[]  from
  (byte*) SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) 1024
  to:@2
main: scope:[main]  from @2
  (byte*) SCREEN#1 ← phi( @2/(byte*) SCREEN#3 )
  (byte) main::c#0 ← *((byte*) SCREEN#1)
  (byte) fillscreen::c#0 ← (byte) main::c#0
  call fillscreen param-assignment
  to:main::@1
main::@1: scope:[main]  from main
  to:main::@return
main::@return: scope:[main]  from main::@1
  return 
  to:@return
fillscreen: scope:[fillscreen]  from main
  (byte) fillscreen::c#2 ← phi( main/(byte) fillscreen::c#0 )
  (byte*) SCREEN#4 ← phi( main/(byte*) SCREEN#1 )
  (byte) fillscreen::j#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
  to:fillscreen::@1
fillscreen::@1: scope:[fillscreen]  from fillscreen fillscreen::@1
  (byte) fillscreen::j#2 ← phi( fillscreen/(byte) fillscreen::j#0 fillscreen::@1/(byte) fillscreen::j#1 )
  (byte) fillscreen::c#1 ← phi( fillscreen/(byte) fillscreen::c#2 fillscreen::@1/(byte) fillscreen::c#1 )
  (byte*) SCREEN#2 ← phi( fillscreen/(byte*) SCREEN#4 fillscreen::@1/(byte*) SCREEN#2 )
  (byte*~) fillscreen::$0 ← (byte*) SCREEN#2 + (word/signed word/dword/signed dword) 256
  (byte*) fillscreen::SCREEN2#0 ← (byte*~) fillscreen::$0
  (byte*~) fillscreen::$1 ← (byte*) SCREEN#2 + (word/signed word/dword/signed dword) 512
  (byte*) fillscreen::SCREEN3#0 ← (byte*~) fillscreen::$1
  (byte*~) fillscreen::$2 ← (byte*) SCREEN#2 + (word/signed word/dword/signed dword) 1000
  (byte*) fillscreen::SCREEN4#0 ← (byte*~) fillscreen::$2
  *((byte*) SCREEN#2 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#1
  *((byte*) fillscreen::SCREEN2#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#1
  *((byte*) fillscreen::SCREEN3#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#1
  *((byte*) fillscreen::SCREEN4#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#1
  (byte) fillscreen::j#1 ← ++ (byte) fillscreen::j#2
  (boolean~) fillscreen::$3 ← (byte) fillscreen::j#1 != (byte/signed byte/word/signed word/dword/signed dword) 0
  if((boolean~) fillscreen::$3) goto fillscreen::@1
  to:fillscreen::@return
fillscreen::@return: scope:[fillscreen]  from fillscreen::@1
  return 
  to:@return
@2: scope:[]  from @begin
  (byte*) SCREEN#3 ← phi( @begin/(byte*) SCREEN#0 )
  call main param-assignment
  to:@3
@3: scope:[]  from @2
  to:@end
@end: scope:[]  from @3

SYMBOL TABLE SSA
(label) @2
(label) @3
(label) @begin
(label) @end
(byte*) SCREEN
(byte*) SCREEN#0
(byte*) SCREEN#1
(byte*) SCREEN#2
(byte*) SCREEN#3
(byte*) SCREEN#4
(void()) fillscreen((byte) fillscreen::c)
(byte*~) fillscreen::$0
(byte*~) fillscreen::$1
(byte*~) fillscreen::$2
(boolean~) fillscreen::$3
(label) fillscreen::@1
(label) fillscreen::@return
(byte*) fillscreen::SCREEN2
(byte*) fillscreen::SCREEN2#0
(byte*) fillscreen::SCREEN3
(byte*) fillscreen::SCREEN3#0
(byte*) fillscreen::SCREEN4
(byte*) fillscreen::SCREEN4#0
(byte) fillscreen::c
(byte) fillscreen::c#0
(byte) fillscreen::c#1
(byte) fillscreen::c#2
(byte) fillscreen::j
(byte) fillscreen::j#0
(byte) fillscreen::j#1
(byte) fillscreen::j#2
(void()) main()
(label) main::@1
(label) main::@return
(byte) main::c
(byte) main::c#0

OPTIMIZING CONTROL FLOW GRAPH
Culled Empty Block (label) main::@1
Culled Empty Block (label) @3
Succesful SSA optimization Pass2CullEmptyBlocks
Not aliassing across scopes: SCREEN#1 SCREEN#3
Not aliassing across scopes: fillscreen::c#0 main::c#0
Not aliassing across scopes: SCREEN#4 SCREEN#1
Not aliassing across scopes: fillscreen::c#2 fillscreen::c#0
Alias (byte*) fillscreen::SCREEN2#0 = (byte*~) fillscreen::$0 
Alias (byte*) fillscreen::SCREEN3#0 = (byte*~) fillscreen::$1 
Alias (byte*) fillscreen::SCREEN4#0 = (byte*~) fillscreen::$2 
Alias (byte*) SCREEN#0 = (byte*) SCREEN#3 
Succesful SSA optimization Pass2AliasElimination
Not aliassing across scopes: SCREEN#1 SCREEN#0
Not aliassing across scopes: fillscreen::c#0 main::c#0
Not aliassing across scopes: SCREEN#4 SCREEN#1
Not aliassing across scopes: fillscreen::c#2 fillscreen::c#0
Self Phi Eliminated (byte*) SCREEN#2
Self Phi Eliminated (byte) fillscreen::c#1
Succesful SSA optimization Pass2SelfPhiElimination
Redundant Phi (byte*) SCREEN#1 (byte*) SCREEN#0
Redundant Phi (byte*) SCREEN#4 (byte*) SCREEN#1
Redundant Phi (byte) fillscreen::c#2 (byte) fillscreen::c#0
Redundant Phi (byte*) SCREEN#2 (byte*) SCREEN#4
Redundant Phi (byte) fillscreen::c#1 (byte) fillscreen::c#2
Succesful SSA optimization Pass2RedundantPhiElimination
Simple Condition (boolean~) fillscreen::$3 if((byte) fillscreen::j#1!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto fillscreen::@1
Succesful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) SCREEN#0 = ((byte*))1024
Constant (const byte) fillscreen::j#0 = 0
Succesful SSA optimization Pass2ConstantIdentification
Constant (const byte*) fillscreen::SCREEN2#0 = SCREEN#0+256
Constant (const byte*) fillscreen::SCREEN3#0 = SCREEN#0+512
Constant (const byte*) fillscreen::SCREEN4#0 = SCREEN#0+1000
Succesful SSA optimization Pass2ConstantIdentification
Not aliassing across scopes: fillscreen::c#0 main::c#0
OPTIMIZING CONTROL FLOW GRAPH
Inlining constant with var siblings (const byte) fillscreen::j#0
Inlining constant with var siblings (const byte) fillscreen::j#0
Constant inlined fillscreen::j#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Succesful SSA optimization Pass2ConstantInlining
Block Sequence Planned @begin @2 @end main main::@return fillscreen fillscreen::@1 fillscreen::@return 
Added new block during phi lifting fillscreen::@3(between fillscreen::@1 and fillscreen::@1)
Block Sequence Planned @begin @2 @end main main::@return fillscreen fillscreen::@1 fillscreen::@return fillscreen::@3 
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Adding NOP phi() at start of fillscreen
CALL GRAPH
Calls in [] to main:2 
Calls in [main] to fillscreen:6 

Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Created 1 initial phi equivalence classes
Coalesced [17] fillscreen::j#3 ← fillscreen::j#1
Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) fillscreen::@3
Block Sequence Planned @begin @2 @end main main::@return fillscreen fillscreen::@1 fillscreen::@return 
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Adding NOP phi() at start of fillscreen
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...
Propagating live ranges...

FINAL CONTROL FLOW GRAPH
@begin: scope:[]  from
  [0] phi() [ ] ( )
  to:@2
@2: scope:[]  from @begin
  [1] phi() [ ] ( )
  [2] call main param-assignment [ ] ( )
  to:@end
@end: scope:[]  from @2
  [3] phi() [ ] ( )
main: scope:[main]  from @2
  [4] (byte) main::c#0 ← *((const byte*) SCREEN#0) [ main::c#0 ] ( main:2 [ main::c#0 ] )
  [5] (byte) fillscreen::c#0 ← (byte) main::c#0 [ fillscreen::c#0 ] ( main:2 [ fillscreen::c#0 ] )
  [6] call fillscreen param-assignment [ ] ( main:2 [ ] )
  to:main::@return
main::@return: scope:[main]  from main
  [7] return  [ ] ( main:2 [ ] )
  to:@return
fillscreen: scope:[fillscreen]  from main
  [8] phi() [ fillscreen::c#0 ] ( main:2::fillscreen:6 [ fillscreen::c#0 ] )
  to:fillscreen::@1
fillscreen::@1: scope:[fillscreen]  from fillscreen fillscreen::@1
  [9] (byte) fillscreen::j#2 ← phi( fillscreen/(byte/signed byte/word/signed word/dword/signed dword) 0 fillscreen::@1/(byte) fillscreen::j#1 ) [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] )
  [10] *((const byte*) SCREEN#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] )
  [11] *((const byte*) fillscreen::SCREEN2#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] )
  [12] *((const byte*) fillscreen::SCREEN3#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] )
  [13] *((const byte*) fillscreen::SCREEN4#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] )
  [14] (byte) fillscreen::j#1 ← ++ (byte) fillscreen::j#2 [ fillscreen::c#0 fillscreen::j#1 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#1 ] )
  [15] if((byte) fillscreen::j#1!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto fillscreen::@1 [ fillscreen::c#0 fillscreen::j#1 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#1 ] )
  to:fillscreen::@return
fillscreen::@return: scope:[fillscreen]  from fillscreen::@1
  [16] return  [ ] ( main:2::fillscreen:6 [ ] )
  to:@return

DOMINATORS
@begin dominated by  @begin 
@2 dominated by  @2 @begin 
@end dominated by  @2 @begin @end 
main dominated by  @2 @begin main 
main::@return dominated by  main::@return @2 @begin main 
fillscreen dominated by  @2 @begin fillscreen main 
fillscreen::@1 dominated by  @2 @begin fillscreen main fillscreen::@1 
fillscreen::@return dominated by  @2 @begin fillscreen main fillscreen::@1 fillscreen::@return 

NATURAL LOOPS
Found back edge: Loop head: fillscreen::@1 tails: fillscreen::@1 blocks: null
Populated: Loop head: fillscreen::@1 tails: fillscreen::@1 blocks: fillscreen::@1 
Loop head: fillscreen::@1 tails: fillscreen::@1 blocks: fillscreen::@1 

NATURAL LOOPS WITH DEPTH
Found 0 loops in scope []
Found 0 loops in scope [main]
Found 1 loops in scope [fillscreen]
  Loop head: fillscreen::@1 tails: fillscreen::@1 blocks: fillscreen::@1 
Loop head: fillscreen::@1 tails: fillscreen::@1 blocks: fillscreen::@1  depth: 1


VARIABLE REGISTER WEIGHTS
(byte*) SCREEN
(void()) fillscreen((byte) fillscreen::c)
(byte*) fillscreen::SCREEN2
(byte*) fillscreen::SCREEN3
(byte*) fillscreen::SCREEN4
(byte) fillscreen::c
(byte) fillscreen::c#0 5.111111111111112
(byte) fillscreen::j
(byte) fillscreen::j#1 16.5
(byte) fillscreen::j#2 13.2
(void()) main()
(byte) main::c
(byte) main::c#0 4.0

Initial phi equivalence classes
[ fillscreen::j#2 fillscreen::j#1 ]
Added variable main::c#0 to zero page equivalence class [ main::c#0 ]
Added variable fillscreen::c#0 to zero page equivalence class [ fillscreen::c#0 ]
Complete equivalence classes
[ fillscreen::j#2 fillscreen::j#1 ]
[ main::c#0 ]
[ fillscreen::c#0 ]
Allocated zp ZP_BYTE:2 [ fillscreen::j#2 fillscreen::j#1 ]
Allocated zp ZP_BYTE:3 [ main::c#0 ]
Allocated zp ZP_BYTE:4 [ fillscreen::c#0 ]

INITIAL ASM
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
  .label SCREEN = $400
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @2 [phi:@begin->@2]
b2_from_bbegin:
  jmp b2
//SEG4 @2
b2:
//SEG5 [2] call main param-assignment [ ] ( )
  jsr main
//SEG6 [3] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
  jmp bend
//SEG7 @end
bend:
//SEG8 main
main: {
    .label c = 3
  //SEG9 [4] (byte) main::c#0 ← *((const byte*) SCREEN#0) [ main::c#0 ] ( main:2 [ main::c#0 ] ) -- vbuz1=_deref_pbuc1 
    lda SCREEN
    sta c
  //SEG10 [5] (byte) fillscreen::c#0 ← (byte) main::c#0 [ fillscreen::c#0 ] ( main:2 [ fillscreen::c#0 ] ) -- vbuz1=vbuz2 
    lda c
    sta fillscreen.c
  //SEG11 [6] call fillscreen param-assignment [ ] ( main:2 [ ] )
  //SEG12 [8] phi from main to fillscreen [phi:main->fillscreen]
  fillscreen_from_main:
    jsr fillscreen
    jmp breturn
  //SEG13 main::@return
  breturn:
  //SEG14 [7] return  [ ] ( main:2 [ ] )
    rts
}
//SEG15 fillscreen
fillscreen: {
    .label SCREEN2 = SCREEN+$100
    .label SCREEN3 = SCREEN+$200
    .label SCREEN4 = SCREEN+$3e8
    .label c = 4
    .label j = 2
  //SEG16 [9] phi from fillscreen to fillscreen::@1 [phi:fillscreen->fillscreen::@1]
  b1_from_fillscreen:
  //SEG17 [9] phi (byte) fillscreen::j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:fillscreen->fillscreen::@1#0] -- vbuz1=vbuc1 
    lda #0
    sta j
    jmp b1
  //SEG18 [9] phi from fillscreen::@1 to fillscreen::@1 [phi:fillscreen::@1->fillscreen::@1]
  b1_from_b1:
  //SEG19 [9] phi (byte) fillscreen::j#2 = (byte) fillscreen::j#1 [phi:fillscreen::@1->fillscreen::@1#0] -- register_copy 
    jmp b1
  //SEG20 fillscreen::@1
  b1:
  //SEG21 [10] *((const byte*) SCREEN#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuz1=vbuz2 
    lda c
    ldy j
    sta SCREEN,y
  //SEG22 [11] *((const byte*) fillscreen::SCREEN2#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuz1=vbuz2 
    lda c
    ldy j
    sta SCREEN2,y
  //SEG23 [12] *((const byte*) fillscreen::SCREEN3#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuz1=vbuz2 
    lda c
    ldy j
    sta SCREEN3,y
  //SEG24 [13] *((const byte*) fillscreen::SCREEN4#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuz1=vbuz2 
    lda c
    ldy j
    sta SCREEN4,y
  //SEG25 [14] (byte) fillscreen::j#1 ← ++ (byte) fillscreen::j#2 [ fillscreen::c#0 fillscreen::j#1 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#1 ] ) -- vbuz1=_inc_vbuz1 
    inc j
  //SEG26 [15] if((byte) fillscreen::j#1!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto fillscreen::@1 [ fillscreen::c#0 fillscreen::j#1 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#1 ] ) -- vbuz1_neq_0_then_la1 
    lda j
    bne b1_from_b1
    jmp breturn
  //SEG27 fillscreen::@return
  breturn:
  //SEG28 [16] return  [ ] ( main:2::fillscreen:6 [ ] )
    rts
}

REGISTER UPLIFT POTENTIAL REGISTERS
Potential registers zp ZP_BYTE:2 [ fillscreen::j#2 fillscreen::j#1 ] : zp ZP_BYTE:2 , reg byte a , reg byte x , reg byte y , 
Potential registers zp ZP_BYTE:3 [ main::c#0 ] : zp ZP_BYTE:3 , reg byte a , reg byte x , reg byte y , 
Potential registers zp ZP_BYTE:4 [ fillscreen::c#0 ] : zp ZP_BYTE:4 , reg byte a , reg byte x , reg byte y , 

REGISTER UPLIFT SCOPES
Uplift Scope [fillscreen] 29.7: zp ZP_BYTE:2 [ fillscreen::j#2 fillscreen::j#1 ] 5.11: zp ZP_BYTE:4 [ fillscreen::c#0 ] 
Uplift Scope [main] 4: zp ZP_BYTE:3 [ main::c#0 ] 
Uplift Scope [] 

Uplifting [fillscreen] best 418 combination reg byte x [ fillscreen::j#2 fillscreen::j#1 ] reg byte a [ fillscreen::c#0 ] 
Uplifting [main] best 412 combination reg byte a [ main::c#0 ] 
Uplifting [] best 412 combination 

ASSEMBLER BEFORE OPTIMIZATION
//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
  .label SCREEN = $400
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @2 [phi:@begin->@2]
b2_from_bbegin:
  jmp b2
//SEG4 @2
b2:
//SEG5 [2] call main param-assignment [ ] ( )
  jsr main
//SEG6 [3] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
  jmp bend
//SEG7 @end
bend:
//SEG8 main
main: {
  //SEG9 [4] (byte) main::c#0 ← *((const byte*) SCREEN#0) [ main::c#0 ] ( main:2 [ main::c#0 ] ) -- vbuaa=_deref_pbuc1 
    lda SCREEN
  //SEG10 [5] (byte) fillscreen::c#0 ← (byte) main::c#0 [ fillscreen::c#0 ] ( main:2 [ fillscreen::c#0 ] )
    // (byte) fillscreen::c#0 = (byte) main::c#0  // register copy reg byte a
  //SEG11 [6] call fillscreen param-assignment [ ] ( main:2 [ ] )
  //SEG12 [8] phi from main to fillscreen [phi:main->fillscreen]
  fillscreen_from_main:
    jsr fillscreen
    jmp breturn
  //SEG13 main::@return
  breturn:
  //SEG14 [7] return  [ ] ( main:2 [ ] )
    rts
}
//SEG15 fillscreen
fillscreen: {
    .label SCREEN2 = SCREEN+$100
    .label SCREEN3 = SCREEN+$200
    .label SCREEN4 = SCREEN+$3e8
  //SEG16 [9] phi from fillscreen to fillscreen::@1 [phi:fillscreen->fillscreen::@1]
  b1_from_fillscreen:
  //SEG17 [9] phi (byte) fillscreen::j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:fillscreen->fillscreen::@1#0] -- vbuxx=vbuc1 
    ldx #0
    jmp b1
  //SEG18 [9] phi from fillscreen::@1 to fillscreen::@1 [phi:fillscreen::@1->fillscreen::@1]
  b1_from_b1:
  //SEG19 [9] phi (byte) fillscreen::j#2 = (byte) fillscreen::j#1 [phi:fillscreen::@1->fillscreen::@1#0] -- register_copy 
    jmp b1
  //SEG20 fillscreen::@1
  b1:
  //SEG21 [10] *((const byte*) SCREEN#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuxx=vbuaa 
    sta SCREEN,x
  //SEG22 [11] *((const byte*) fillscreen::SCREEN2#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuxx=vbuaa 
    sta SCREEN2,x
  //SEG23 [12] *((const byte*) fillscreen::SCREEN3#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuxx=vbuaa 
    sta SCREEN3,x
  //SEG24 [13] *((const byte*) fillscreen::SCREEN4#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuxx=vbuaa 
    sta SCREEN4,x
  //SEG25 [14] (byte) fillscreen::j#1 ← ++ (byte) fillscreen::j#2 [ fillscreen::c#0 fillscreen::j#1 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#1 ] ) -- vbuxx=_inc_vbuxx 
    inx
  //SEG26 [15] if((byte) fillscreen::j#1!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto fillscreen::@1 [ fillscreen::c#0 fillscreen::j#1 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#1 ] ) -- vbuxx_neq_0_then_la1 
    cpx #0
    bne b1_from_b1
    jmp breturn
  //SEG27 fillscreen::@return
  breturn:
  //SEG28 [16] return  [ ] ( main:2::fillscreen:6 [ ] )
    rts
}

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b2
Removing instruction jmp bend
Removing instruction jmp breturn
Removing instruction jmp b1
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label b1_from_b1 with b1
Removing instruction bbegin:
Removing instruction b2_from_bbegin:
Removing instruction bend_from_b2:
Removing instruction b1_from_b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction b2:
Removing instruction bend:
Removing instruction fillscreen_from_main:
Removing instruction breturn:
Removing instruction b1_from_fillscreen:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jmp b1
Succesful ASM optimization Pass5NextJumpElimination

FINAL SYMBOL TABLE
(label) @2
(label) @begin
(label) @end
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024
(void()) fillscreen((byte) fillscreen::c)
(label) fillscreen::@1
(label) fillscreen::@return
(byte*) fillscreen::SCREEN2
(const byte*) fillscreen::SCREEN2#0 SCREEN2 = (const byte*) SCREEN#0+(word/signed word/dword/signed dword) 256
(byte*) fillscreen::SCREEN3
(const byte*) fillscreen::SCREEN3#0 SCREEN3 = (const byte*) SCREEN#0+(word/signed word/dword/signed dword) 512
(byte*) fillscreen::SCREEN4
(const byte*) fillscreen::SCREEN4#0 SCREEN4 = (const byte*) SCREEN#0+(word/signed word/dword/signed dword) 1000
(byte) fillscreen::c
(byte) fillscreen::c#0 reg byte a 5.111111111111112
(byte) fillscreen::j
(byte) fillscreen::j#1 reg byte x 16.5
(byte) fillscreen::j#2 reg byte x 13.2
(void()) main()
(label) main::@return
(byte) main::c
(byte) main::c#0 reg byte a 4.0

reg byte x [ fillscreen::j#2 fillscreen::j#1 ]
reg byte a [ main::c#0 ]
reg byte a [ fillscreen::c#0 ]


FINAL ASSEMBLER
Score: 313

//SEG0 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG1 Global Constants & labels
  .label SCREEN = $400
//SEG2 @begin
//SEG3 [1] phi from @begin to @2 [phi:@begin->@2]
//SEG4 @2
//SEG5 [2] call main param-assignment [ ] ( )
  jsr main
//SEG6 [3] phi from @2 to @end [phi:@2->@end]
//SEG7 @end
//SEG8 main
main: {
  //SEG9 [4] (byte) main::c#0 ← *((const byte*) SCREEN#0) [ main::c#0 ] ( main:2 [ main::c#0 ] ) -- vbuaa=_deref_pbuc1 
    lda SCREEN
  //SEG10 [5] (byte) fillscreen::c#0 ← (byte) main::c#0 [ fillscreen::c#0 ] ( main:2 [ fillscreen::c#0 ] )
    // (byte) fillscreen::c#0 = (byte) main::c#0  // register copy reg byte a
  //SEG11 [6] call fillscreen param-assignment [ ] ( main:2 [ ] )
  //SEG12 [8] phi from main to fillscreen [phi:main->fillscreen]
    jsr fillscreen
  //SEG13 main::@return
  //SEG14 [7] return  [ ] ( main:2 [ ] )
    rts
}
//SEG15 fillscreen
fillscreen: {
    .label SCREEN2 = SCREEN+$100
    .label SCREEN3 = SCREEN+$200
    .label SCREEN4 = SCREEN+$3e8
  //SEG16 [9] phi from fillscreen to fillscreen::@1 [phi:fillscreen->fillscreen::@1]
  //SEG17 [9] phi (byte) fillscreen::j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:fillscreen->fillscreen::@1#0] -- vbuxx=vbuc1 
    ldx #0
  //SEG18 [9] phi from fillscreen::@1 to fillscreen::@1 [phi:fillscreen::@1->fillscreen::@1]
  //SEG19 [9] phi (byte) fillscreen::j#2 = (byte) fillscreen::j#1 [phi:fillscreen::@1->fillscreen::@1#0] -- register_copy 
  //SEG20 fillscreen::@1
  b1:
  //SEG21 [10] *((const byte*) SCREEN#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuxx=vbuaa 
    sta SCREEN,x
  //SEG22 [11] *((const byte*) fillscreen::SCREEN2#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuxx=vbuaa 
    sta SCREEN2,x
  //SEG23 [12] *((const byte*) fillscreen::SCREEN3#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuxx=vbuaa 
    sta SCREEN3,x
  //SEG24 [13] *((const byte*) fillscreen::SCREEN4#0 + (byte) fillscreen::j#2) ← (byte) fillscreen::c#0 [ fillscreen::c#0 fillscreen::j#2 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#2 ] ) -- pbuc1_derefidx_vbuxx=vbuaa 
    sta SCREEN4,x
  //SEG25 [14] (byte) fillscreen::j#1 ← ++ (byte) fillscreen::j#2 [ fillscreen::c#0 fillscreen::j#1 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#1 ] ) -- vbuxx=_inc_vbuxx 
    inx
  //SEG26 [15] if((byte) fillscreen::j#1!=(byte/signed byte/word/signed word/dword/signed dword) 0) goto fillscreen::@1 [ fillscreen::c#0 fillscreen::j#1 ] ( main:2::fillscreen:6 [ fillscreen::c#0 fillscreen::j#1 ] ) -- vbuxx_neq_0_then_la1 
    cpx #0
    bne b1
  //SEG27 fillscreen::@return
  //SEG28 [16] return  [ ] ( main:2::fillscreen:6 [ ] )
    rts
}

