Inlined call call print (byte*) screen (byte*) main::hello 
Inlined call call print (byte*~) main::$2 (byte*) main::hello 

CONTROL FLOW GRAPH SSA
@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::hello#0 ← (const string) main::$4
  (byte*) main::print1_at#0 ← (byte*) screen#1
  (byte*) main::print1_msg#0 ← (byte*) main::hello#0
  to:main::print1
main::print1: scope:[main]  from main
  (byte*) main::hello#3 ← phi( main/(byte*) main::hello#0 )
  (byte*) screen#5 ← phi( main/(byte*) screen#1 )
  (byte*) main::print1_at#2 ← phi( main/(byte*) main::print1_at#0 )
  (byte*) main::print1_msg#2 ← phi( main/(byte*) main::print1_msg#0 )
  (byte) main::print1_j#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
  (byte) main::print1_i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
  to:main::print1_@1
main::print1_@1: scope:[main]  from main::print1 main::print1_@1
  (byte*) main::hello#2 ← phi( main::print1/(byte*) main::hello#3 main::print1_@1/(byte*) main::hello#2 )
  (byte*) screen#4 ← phi( main::print1/(byte*) screen#5 main::print1_@1/(byte*) screen#4 )
  (byte) main::print1_j#2 ← phi( main::print1/(byte) main::print1_j#0 main::print1_@1/(byte) main::print1_j#1 )
  (byte*) main::print1_at#1 ← phi( main::print1/(byte*) main::print1_at#2 main::print1_@1/(byte*) main::print1_at#1 )
  (byte) main::print1_i#2 ← phi( main::print1/(byte) main::print1_i#0 main::print1_@1/(byte) main::print1_i#1 )
  (byte*) main::print1_msg#1 ← phi( main::print1/(byte*) main::print1_msg#2 main::print1_@1/(byte*) main::print1_msg#1 )
  *((byte*) main::print1_at#1 + (byte) main::print1_j#2) ← *((byte*) main::print1_msg#1 + (byte) main::print1_i#2)
  (byte) main::print1_j#1 ← (byte) main::print1_j#2 + (byte/signed byte/word/signed word/dword/signed dword) 2
  (byte) main::print1_i#1 ← ++ (byte) main::print1_i#2
  (bool) main::print1_$0#0 ← *((byte*) main::print1_msg#1 + (byte) main::print1_i#1) != (byte) '@'
  if((bool) main::print1_$0#0) goto main::print1_@1
  to:main::@1
main::@1: scope:[main]  from main::print1_@1
  (byte*) main::hello#1 ← phi( main::print1_@1/(byte*) main::hello#2 )
  (byte*) screen#2 ← phi( main::print1_@1/(byte*) screen#4 )
  (byte/signed byte/word/signed word/dword/signed dword~) main::$1 ← (byte/signed byte/word/signed word/dword/signed dword) 2 * (byte/signed byte/word/signed word/dword/signed dword) 40
  (byte*~) main::$2 ← (byte*) screen#2 + (byte/signed byte/word/signed word/dword/signed dword~) main::$1
  (byte*) main::print2_at#0 ← (byte*~) main::$2
  (byte*) main::print2_msg#0 ← (byte*) main::hello#1
  to:main::print2
main::print2: scope:[main]  from main::@1
  (byte*) main::print2_at#2 ← phi( main::@1/(byte*) main::print2_at#0 )
  (byte*) main::print2_msg#2 ← phi( main::@1/(byte*) main::print2_msg#0 )
  (byte) main::print2_j#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
  (byte) main::print2_i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
  to:main::print2_@1
main::print2_@1: scope:[main]  from main::print2 main::print2_@1
  (byte) main::print2_j#2 ← phi( main::print2/(byte) main::print2_j#0 main::print2_@1/(byte) main::print2_j#1 )
  (byte*) main::print2_at#1 ← phi( main::print2/(byte*) main::print2_at#2 main::print2_@1/(byte*) main::print2_at#1 )
  (byte) main::print2_i#2 ← phi( main::print2/(byte) main::print2_i#0 main::print2_@1/(byte) main::print2_i#1 )
  (byte*) main::print2_msg#1 ← phi( main::print2/(byte*) main::print2_msg#2 main::print2_@1/(byte*) main::print2_msg#1 )
  *((byte*) main::print2_at#1 + (byte) main::print2_j#2) ← *((byte*) main::print2_msg#1 + (byte) main::print2_i#2)
  (byte) main::print2_j#1 ← (byte) main::print2_j#2 + (byte/signed byte/word/signed word/dword/signed dword) 2
  (byte) main::print2_i#1 ← ++ (byte) main::print2_i#2
  (bool) main::print2_$0#0 ← *((byte*) main::print2_msg#1 + (byte) main::print2_i#1) != (byte) '@'
  if((bool) main::print2_$0#0) goto main::print2_@1
  to:main::@return
main::@return: scope:[main]  from main::print2_@1
  return 
  to:@return
@2: scope:[]  from @begin
  (byte*) screen#3 ← phi( @begin/(byte*) screen#0 )
  call main 
  to:@3
@3: scope:[]  from @2
  to:@end
@end: scope:[]  from @3

SYMBOL TABLE SSA
(label) @2
(label) @3
(label) @begin
(label) @end
(void()) main()
(byte/signed byte/word/signed word/dword/signed dword~) main::$1
(byte*~) main::$2
(const string) main::$4 = (string) "hello world!@"
(label) main::@1
(label) main::@return
(byte*) main::hello
(byte*) main::hello#0
(byte*) main::hello#1
(byte*) main::hello#2
(byte*) main::hello#3
(label) main::print1
(bool~) main::print1_$0
(bool) main::print1_$0#0
(label) main::print1_@1
(byte*) main::print1_at
(byte*) main::print1_at#0
(byte*) main::print1_at#1
(byte*) main::print1_at#2
(byte) main::print1_i
(byte) main::print1_i#0
(byte) main::print1_i#1
(byte) main::print1_i#2
(byte) main::print1_j
(byte) main::print1_j#0
(byte) main::print1_j#1
(byte) main::print1_j#2
(byte*) main::print1_msg
(byte*) main::print1_msg#0
(byte*) main::print1_msg#1
(byte*) main::print1_msg#2
(label) main::print2
(bool~) main::print2_$0
(bool) main::print2_$0#0
(label) main::print2_@1
(byte*) main::print2_at
(byte*) main::print2_at#0
(byte*) main::print2_at#1
(byte*) main::print2_at#2
(byte) main::print2_i
(byte) main::print2_i#0
(byte) main::print2_i#1
(byte) main::print2_i#2
(byte) main::print2_j
(byte) main::print2_j#0
(byte) main::print2_j#1
(byte) main::print2_j#2
(byte*) main::print2_msg
(byte*) main::print2_msg#0
(byte*) main::print2_msg#1
(byte*) main::print2_msg#2
(byte*) screen
(byte*) screen#0
(byte*) screen#1
(byte*) screen#2
(byte*) screen#3
(byte*) screen#4
(byte*) screen#5

Culled Empty Block (label) @3
Successful SSA optimization Pass2CullEmptyBlocks
Alias (byte*) main::print1_msg#0 = (byte*) main::hello#0 (byte*) main::print1_msg#2 (byte*) main::hello#3 
Alias (byte*) main::print1_at#0 = (byte*) main::print1_at#2 
Alias (byte*) screen#1 = (byte*) screen#5 
Alias (byte*) screen#2 = (byte*) screen#4 
Alias (byte*) main::hello#1 = (byte*) main::hello#2 (byte*) main::print2_msg#0 (byte*) main::print2_msg#2 
Alias (byte*) main::print2_at#0 = (byte*~) main::$2 (byte*) main::print2_at#2 
Alias (byte*) screen#0 = (byte*) screen#3 
Successful SSA optimization Pass2AliasElimination
Self Phi Eliminated (byte*) main::print1_msg#1
Self Phi Eliminated (byte*) main::print1_at#1
Self Phi Eliminated (byte*) screen#2
Self Phi Eliminated (byte*) main::hello#1
Self Phi Eliminated (byte*) main::print2_msg#1
Self Phi Eliminated (byte*) main::print2_at#1
Successful SSA optimization Pass2SelfPhiElimination
Redundant Phi (byte*) screen#1 (byte*) screen#0
Redundant Phi (byte*) main::print1_msg#1 (byte*) main::print1_msg#0
Redundant Phi (byte*) main::print1_at#1 (byte*) main::print1_at#0
Redundant Phi (byte*) screen#2 (byte*) screen#1
Redundant Phi (byte*) main::hello#1 (byte*) main::print1_msg#0
Redundant Phi (byte*) main::print2_msg#1 (byte*) main::hello#1
Redundant Phi (byte*) main::print2_at#1 (byte*) main::print2_at#0
Successful SSA optimization Pass2RedundantPhiElimination
Simple Condition (bool) main::print1_$0#0 [13] if(*((byte*) main::print1_msg#0 + (byte) main::print1_i#1)!=(byte) '@') goto main::print1_@1
Simple Condition (bool) main::print2_$0#0 [27] if(*((byte*) main::print1_msg#0 + (byte) main::print2_i#1)!=(byte) '@') goto main::print2_@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) screen#0 = ((byte*))1024
Constant (const byte*) main::print1_msg#0 = main::$4
Constant (const byte) main::print1_j#0 = 0
Constant (const byte) main::print1_i#0 = 0
Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$1 = 2*40
Constant (const byte) main::print2_j#0 = 0
Constant (const byte) main::print2_i#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte*) main::print1_at#0 = screen#0
Constant (const byte*) main::print2_at#0 = screen#0+main::$1
Successful SSA optimization Pass2ConstantIdentification
Culled Empty Block (label) main::@1
Successful SSA optimization Pass2CullEmptyBlocks
Inlining constant with var siblings (const byte) main::print1_j#0
Inlining constant with var siblings (const byte) main::print1_i#0
Inlining constant with var siblings (const byte) main::print2_j#0
Inlining constant with var siblings (const byte) main::print2_i#0
Constant inlined main::print2_j#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::print1_at#0 = (const byte*) screen#0
Constant inlined main::print2_i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::$1 = (byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) 40
Constant inlined main::$4 = (const byte*) main::print1_msg#0
Constant inlined main::print1_i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined main::print1_j#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@3(between main::print1_@1 and main::print1_@1)
Added new block during phi lifting main::@4(between main::print2_@1 and main::print2_@1)
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 main
Adding NOP phi() at start of main::print1
Adding NOP phi() at start of main::print2
CALL GRAPH
Calls in [] to main:2 

Created 4 initial phi equivalence classes
Coalesced [18] main::print2_i#3 ← main::print2_i#1
Coalesced [19] main::print2_j#3 ← main::print2_j#1
Coalesced [20] main::print1_i#3 ← main::print1_i#1
Coalesced [21] main::print1_j#3 ← main::print1_j#1
Coalesced down to 4 phi equivalence classes
Culled Empty Block (label) main::@4
Culled Empty Block (label) main::@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 main
Adding NOP phi() at start of main::print1
Adding NOP phi() at start of main::print2

FINAL CONTROL FLOW GRAPH
@begin: scope:[]  from
  [0] phi()
  to:@2
@2: scope:[]  from @begin
  [1] phi()
  [2] call main 
  to:@end
@end: scope:[]  from @2
  [3] phi()
main: scope:[main]  from @2
  [4] phi()
  to:main::print1
main::print1: scope:[main]  from main
  [5] phi()
  to:main::print1_@1
main::print1_@1: scope:[main]  from main::print1 main::print1_@1
  [6] (byte) main::print1_j#2 ← phi( main::print1/(byte/signed byte/word/signed word/dword/signed dword) 0 main::print1_@1/(byte) main::print1_j#1 )
  [6] (byte) main::print1_i#2 ← phi( main::print1/(byte/signed byte/word/signed word/dword/signed dword) 0 main::print1_@1/(byte) main::print1_i#1 )
  [7] *((const byte*) screen#0 + (byte) main::print1_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print1_i#2)
  [8] (byte) main::print1_j#1 ← (byte) main::print1_j#2 + (byte/signed byte/word/signed word/dword/signed dword) 2
  [9] (byte) main::print1_i#1 ← ++ (byte) main::print1_i#2
  [10] if(*((const byte*) main::print1_msg#0 + (byte) main::print1_i#1)!=(byte) '@') goto main::print1_@1
  to:main::print2
main::print2: scope:[main]  from main::print1_@1
  [11] phi()
  to:main::print2_@1
main::print2_@1: scope:[main]  from main::print2 main::print2_@1
  [12] (byte) main::print2_j#2 ← phi( main::print2/(byte/signed byte/word/signed word/dword/signed dword) 0 main::print2_@1/(byte) main::print2_j#1 )
  [12] (byte) main::print2_i#2 ← phi( main::print2/(byte/signed byte/word/signed word/dword/signed dword) 0 main::print2_@1/(byte) main::print2_i#1 )
  [13] *((const byte*) main::print2_at#0 + (byte) main::print2_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print2_i#2)
  [14] (byte) main::print2_j#1 ← (byte) main::print2_j#2 + (byte/signed byte/word/signed word/dword/signed dword) 2
  [15] (byte) main::print2_i#1 ← ++ (byte) main::print2_i#2
  [16] if(*((const byte*) main::print1_msg#0 + (byte) main::print2_i#1)!=(byte) '@') goto main::print2_@1
  to:main::@return
main::@return: scope:[main]  from main::print2_@1
  [17] return 
  to:@return


VARIABLE REGISTER WEIGHTS
(void()) main()
(byte*) main::hello
(bool~) main::print1_$0
(byte*) main::print1_at
(byte) main::print1_i
(byte) main::print1_i#1 16.5
(byte) main::print1_i#2 11.0
(byte) main::print1_j
(byte) main::print1_j#1 7.333333333333333
(byte) main::print1_j#2 16.5
(byte*) main::print1_msg
(bool~) main::print2_$0
(byte*) main::print2_at
(byte) main::print2_i
(byte) main::print2_i#1 16.5
(byte) main::print2_i#2 11.0
(byte) main::print2_j
(byte) main::print2_j#1 7.333333333333333
(byte) main::print2_j#2 16.5
(byte*) main::print2_msg
(byte*) screen

Initial phi equivalence classes
[ main::print1_i#2 main::print1_i#1 ]
[ main::print1_j#2 main::print1_j#1 ]
[ main::print2_i#2 main::print2_i#1 ]
[ main::print2_j#2 main::print2_j#1 ]
Complete equivalence classes
[ main::print1_i#2 main::print1_i#1 ]
[ main::print1_j#2 main::print1_j#1 ]
[ main::print2_i#2 main::print2_i#1 ]
[ main::print2_j#2 main::print2_j#1 ]
Allocated zp ZP_BYTE:2 [ main::print1_i#2 main::print1_i#1 ]
Allocated zp ZP_BYTE:3 [ main::print1_j#2 main::print1_j#1 ]
Allocated zp ZP_BYTE:4 [ main::print2_i#2 main::print2_i#1 ]
Allocated zp ZP_BYTE:5 [ main::print2_j#2 main::print2_j#1 ]

INITIAL ASM
//SEG0 File Comments
// TEst inlining a slightly complex print function (containing a loop)
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
  .label screen = $400
//SEG3 @begin
bbegin:
//SEG4 [1] phi from @begin to @2 [phi:@begin->@2]
b2_from_bbegin:
  jmp b2
//SEG5 @2
b2:
//SEG6 [2] call main 
//SEG7 [4] phi from @2 to main [phi:@2->main]
main_from_b2:
  jsr main
//SEG8 [3] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
  jmp bend
//SEG9 @end
bend:
//SEG10 main
main: {
    .label print2_at = screen+2*$28
    .label print1_j = 3
    .label print1_i = 2
    .label print2_j = 5
    .label print2_i = 4
  //SEG11 [5] phi from main to main::print1 [phi:main->main::print1]
  print1_from_main:
    jmp print1
  //SEG12 main::print1
  print1:
  //SEG13 [6] phi from main::print1 to main::print1_@1 [phi:main::print1->main::print1_@1]
  print1_b1_from_print1:
  //SEG14 [6] phi (byte) main::print1_j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print1->main::print1_@1#0] -- vbuz1=vbuc1 
    lda #0
    sta print1_j
  //SEG15 [6] phi (byte) main::print1_i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print1->main::print1_@1#1] -- vbuz1=vbuc1 
    lda #0
    sta print1_i
    jmp print1_b1
  //SEG16 [6] phi from main::print1_@1 to main::print1_@1 [phi:main::print1_@1->main::print1_@1]
  print1_b1_from_print1_b1:
  //SEG17 [6] phi (byte) main::print1_j#2 = (byte) main::print1_j#1 [phi:main::print1_@1->main::print1_@1#0] -- register_copy 
  //SEG18 [6] phi (byte) main::print1_i#2 = (byte) main::print1_i#1 [phi:main::print1_@1->main::print1_@1#1] -- register_copy 
    jmp print1_b1
  //SEG19 main::print1_@1
  print1_b1:
  //SEG20 [7] *((const byte*) screen#0 + (byte) main::print1_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print1_i#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz2 
    ldy print1_i
    lda print1_msg,y
    ldy print1_j
    sta screen,y
  //SEG21 [8] (byte) main::print1_j#1 ← (byte) main::print1_j#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuz1=vbuz1_plus_2 
    lda print1_j
    clc
    adc #2
    sta print1_j
  //SEG22 [9] (byte) main::print1_i#1 ← ++ (byte) main::print1_i#2 -- vbuz1=_inc_vbuz1 
    inc print1_i
  //SEG23 [10] if(*((const byte*) main::print1_msg#0 + (byte) main::print1_i#1)!=(byte) '@') goto main::print1_@1 -- pbuc1_derefidx_vbuz1_neq_vbuc2_then_la1 
    ldy print1_i
    lda print1_msg,y
    cmp #'@'
    bne print1_b1_from_print1_b1
  //SEG24 [11] phi from main::print1_@1 to main::print2 [phi:main::print1_@1->main::print2]
  print2_from_print1_b1:
    jmp print2
  //SEG25 main::print2
  print2:
  //SEG26 [12] phi from main::print2 to main::print2_@1 [phi:main::print2->main::print2_@1]
  print2_b1_from_print2:
  //SEG27 [12] phi (byte) main::print2_j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print2->main::print2_@1#0] -- vbuz1=vbuc1 
    lda #0
    sta print2_j
  //SEG28 [12] phi (byte) main::print2_i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print2->main::print2_@1#1] -- vbuz1=vbuc1 
    lda #0
    sta print2_i
    jmp print2_b1
  //SEG29 [12] phi from main::print2_@1 to main::print2_@1 [phi:main::print2_@1->main::print2_@1]
  print2_b1_from_print2_b1:
  //SEG30 [12] phi (byte) main::print2_j#2 = (byte) main::print2_j#1 [phi:main::print2_@1->main::print2_@1#0] -- register_copy 
  //SEG31 [12] phi (byte) main::print2_i#2 = (byte) main::print2_i#1 [phi:main::print2_@1->main::print2_@1#1] -- register_copy 
    jmp print2_b1
  //SEG32 main::print2_@1
  print2_b1:
  //SEG33 [13] *((const byte*) main::print2_at#0 + (byte) main::print2_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print2_i#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz2 
    ldy print2_i
    lda print1_msg,y
    ldy print2_j
    sta print2_at,y
  //SEG34 [14] (byte) main::print2_j#1 ← (byte) main::print2_j#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuz1=vbuz1_plus_2 
    lda print2_j
    clc
    adc #2
    sta print2_j
  //SEG35 [15] (byte) main::print2_i#1 ← ++ (byte) main::print2_i#2 -- vbuz1=_inc_vbuz1 
    inc print2_i
  //SEG36 [16] if(*((const byte*) main::print1_msg#0 + (byte) main::print2_i#1)!=(byte) '@') goto main::print2_@1 -- pbuc1_derefidx_vbuz1_neq_vbuc2_then_la1 
    ldy print2_i
    lda print1_msg,y
    cmp #'@'
    bne print2_b1_from_print2_b1
    jmp breturn
  //SEG37 main::@return
  breturn:
  //SEG38 [17] return 
    rts
    print1_msg: .text "hello world!@"
}

REGISTER UPLIFT POTENTIAL REGISTERS
Statement [7] *((const byte*) screen#0 + (byte) main::print1_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print1_i#2) [ main::print1_i#2 main::print1_j#2 ] ( main:2 [ main::print1_i#2 main::print1_j#2 ] ) always clobbers reg byte a 
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::print1_i#2 main::print1_i#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ main::print1_j#2 main::print1_j#1 ]
Statement [10] if(*((const byte*) main::print1_msg#0 + (byte) main::print1_i#1)!=(byte) '@') goto main::print1_@1 [ main::print1_i#1 main::print1_j#1 ] ( main:2 [ main::print1_i#1 main::print1_j#1 ] ) always clobbers reg byte a 
Statement [13] *((const byte*) main::print2_at#0 + (byte) main::print2_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print2_i#2) [ main::print2_i#2 main::print2_j#2 ] ( main:2 [ main::print2_i#2 main::print2_j#2 ] ) always clobbers reg byte a 
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ main::print2_i#2 main::print2_i#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ main::print2_j#2 main::print2_j#1 ]
Statement [16] if(*((const byte*) main::print1_msg#0 + (byte) main::print2_i#1)!=(byte) '@') goto main::print2_@1 [ main::print2_i#1 main::print2_j#1 ] ( main:2 [ main::print2_i#1 main::print2_j#1 ] ) always clobbers reg byte a 
Statement [7] *((const byte*) screen#0 + (byte) main::print1_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print1_i#2) [ main::print1_i#2 main::print1_j#2 ] ( main:2 [ main::print1_i#2 main::print1_j#2 ] ) always clobbers reg byte a 
Statement [10] if(*((const byte*) main::print1_msg#0 + (byte) main::print1_i#1)!=(byte) '@') goto main::print1_@1 [ main::print1_i#1 main::print1_j#1 ] ( main:2 [ main::print1_i#1 main::print1_j#1 ] ) always clobbers reg byte a 
Statement [13] *((const byte*) main::print2_at#0 + (byte) main::print2_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print2_i#2) [ main::print2_i#2 main::print2_j#2 ] ( main:2 [ main::print2_i#2 main::print2_j#2 ] ) always clobbers reg byte a 
Statement [16] if(*((const byte*) main::print1_msg#0 + (byte) main::print2_i#1)!=(byte) '@') goto main::print2_@1 [ main::print2_i#1 main::print2_j#1 ] ( main:2 [ main::print2_i#1 main::print2_j#1 ] ) always clobbers reg byte a 
Potential registers zp ZP_BYTE:2 [ main::print1_i#2 main::print1_i#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , 
Potential registers zp ZP_BYTE:3 [ main::print1_j#2 main::print1_j#1 ] : zp ZP_BYTE:3 , reg byte x , reg byte y , 
Potential registers zp ZP_BYTE:4 [ main::print2_i#2 main::print2_i#1 ] : zp ZP_BYTE:4 , reg byte x , reg byte y , 
Potential registers zp ZP_BYTE:5 [ main::print2_j#2 main::print2_j#1 ] : zp ZP_BYTE:5 , reg byte x , reg byte y , 

REGISTER UPLIFT SCOPES
Uplift Scope [main] 27.5: zp ZP_BYTE:2 [ main::print1_i#2 main::print1_i#1 ] 27.5: zp ZP_BYTE:4 [ main::print2_i#2 main::print2_i#1 ] 23.83: zp ZP_BYTE:3 [ main::print1_j#2 main::print1_j#1 ] 23.83: zp ZP_BYTE:5 [ main::print2_j#2 main::print2_j#1 ] 
Uplift Scope [] 

Uplifting [main] best 744 combination reg byte y [ main::print1_i#2 main::print1_i#1 ] reg byte y [ main::print2_i#2 main::print2_i#1 ] reg byte x [ main::print1_j#2 main::print1_j#1 ] reg byte x [ main::print2_j#2 main::print2_j#1 ] 
Uplifting [] best 744 combination 

ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// TEst inlining a slightly complex print function (containing a loop)
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
  .label screen = $400
//SEG3 @begin
bbegin:
//SEG4 [1] phi from @begin to @2 [phi:@begin->@2]
b2_from_bbegin:
  jmp b2
//SEG5 @2
b2:
//SEG6 [2] call main 
//SEG7 [4] phi from @2 to main [phi:@2->main]
main_from_b2:
  jsr main
//SEG8 [3] phi from @2 to @end [phi:@2->@end]
bend_from_b2:
  jmp bend
//SEG9 @end
bend:
//SEG10 main
main: {
    .label print2_at = screen+2*$28
  //SEG11 [5] phi from main to main::print1 [phi:main->main::print1]
  print1_from_main:
    jmp print1
  //SEG12 main::print1
  print1:
  //SEG13 [6] phi from main::print1 to main::print1_@1 [phi:main::print1->main::print1_@1]
  print1_b1_from_print1:
  //SEG14 [6] phi (byte) main::print1_j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print1->main::print1_@1#0] -- vbuxx=vbuc1 
    ldx #0
  //SEG15 [6] phi (byte) main::print1_i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print1->main::print1_@1#1] -- vbuyy=vbuc1 
    ldy #0
    jmp print1_b1
  //SEG16 [6] phi from main::print1_@1 to main::print1_@1 [phi:main::print1_@1->main::print1_@1]
  print1_b1_from_print1_b1:
  //SEG17 [6] phi (byte) main::print1_j#2 = (byte) main::print1_j#1 [phi:main::print1_@1->main::print1_@1#0] -- register_copy 
  //SEG18 [6] phi (byte) main::print1_i#2 = (byte) main::print1_i#1 [phi:main::print1_@1->main::print1_@1#1] -- register_copy 
    jmp print1_b1
  //SEG19 main::print1_@1
  print1_b1:
  //SEG20 [7] *((const byte*) screen#0 + (byte) main::print1_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print1_i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy 
    lda print1_msg,y
    sta screen,x
  //SEG21 [8] (byte) main::print1_j#1 ← (byte) main::print1_j#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuxx=vbuxx_plus_2 
    inx
    inx
  //SEG22 [9] (byte) main::print1_i#1 ← ++ (byte) main::print1_i#2 -- vbuyy=_inc_vbuyy 
    iny
  //SEG23 [10] if(*((const byte*) main::print1_msg#0 + (byte) main::print1_i#1)!=(byte) '@') goto main::print1_@1 -- pbuc1_derefidx_vbuyy_neq_vbuc2_then_la1 
    lda print1_msg,y
    cmp #'@'
    bne print1_b1_from_print1_b1
  //SEG24 [11] phi from main::print1_@1 to main::print2 [phi:main::print1_@1->main::print2]
  print2_from_print1_b1:
    jmp print2
  //SEG25 main::print2
  print2:
  //SEG26 [12] phi from main::print2 to main::print2_@1 [phi:main::print2->main::print2_@1]
  print2_b1_from_print2:
  //SEG27 [12] phi (byte) main::print2_j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print2->main::print2_@1#0] -- vbuxx=vbuc1 
    ldx #0
  //SEG28 [12] phi (byte) main::print2_i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print2->main::print2_@1#1] -- vbuyy=vbuc1 
    ldy #0
    jmp print2_b1
  //SEG29 [12] phi from main::print2_@1 to main::print2_@1 [phi:main::print2_@1->main::print2_@1]
  print2_b1_from_print2_b1:
  //SEG30 [12] phi (byte) main::print2_j#2 = (byte) main::print2_j#1 [phi:main::print2_@1->main::print2_@1#0] -- register_copy 
  //SEG31 [12] phi (byte) main::print2_i#2 = (byte) main::print2_i#1 [phi:main::print2_@1->main::print2_@1#1] -- register_copy 
    jmp print2_b1
  //SEG32 main::print2_@1
  print2_b1:
  //SEG33 [13] *((const byte*) main::print2_at#0 + (byte) main::print2_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print2_i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy 
    lda print1_msg,y
    sta print2_at,x
  //SEG34 [14] (byte) main::print2_j#1 ← (byte) main::print2_j#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuxx=vbuxx_plus_2 
    inx
    inx
  //SEG35 [15] (byte) main::print2_i#1 ← ++ (byte) main::print2_i#2 -- vbuyy=_inc_vbuyy 
    iny
  //SEG36 [16] if(*((const byte*) main::print1_msg#0 + (byte) main::print2_i#1)!=(byte) '@') goto main::print2_@1 -- pbuc1_derefidx_vbuyy_neq_vbuc2_then_la1 
    lda print1_msg,y
    cmp #'@'
    bne print2_b1_from_print2_b1
    jmp breturn
  //SEG37 main::@return
  breturn:
  //SEG38 [17] return 
    rts
    print1_msg: .text "hello world!@"
}

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b2
Removing instruction jmp bend
Removing instruction jmp print1
Removing instruction jmp print1_b1
Removing instruction jmp print2
Removing instruction jmp print2_b1
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label print1_b1_from_print1_b1 with print1_b1
Replacing label print2_b1_from_print2_b1 with print2_b1
Removing instruction b2_from_bbegin:
Removing instruction b2:
Removing instruction main_from_b2:
Removing instruction bend_from_b2:
Removing instruction print1_from_main:
Removing instruction print1_b1_from_print1:
Removing instruction print1_b1_from_print1_b1:
Removing instruction print2_from_print1_b1:
Removing instruction print2_b1_from_print2:
Removing instruction print2_b1_from_print2_b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction print1:
Removing instruction print2:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction jmp print1_b1
Removing instruction jmp print2_b1
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
(label) @2
(label) @begin
(label) @end
(void()) main()
(label) main::@return
(byte*) main::hello
(label) main::print1
(bool~) main::print1_$0
(label) main::print1_@1
(byte*) main::print1_at
(byte) main::print1_i
(byte) main::print1_i#1 reg byte y 16.5
(byte) main::print1_i#2 reg byte y 11.0
(byte) main::print1_j
(byte) main::print1_j#1 reg byte x 7.333333333333333
(byte) main::print1_j#2 reg byte x 16.5
(byte*) main::print1_msg
(const byte*) main::print1_msg#0 print1_msg = (string) "hello world!@"
(label) main::print2
(bool~) main::print2_$0
(label) main::print2_@1
(byte*) main::print2_at
(const byte*) main::print2_at#0 print2_at = (const byte*) screen#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) 40
(byte) main::print2_i
(byte) main::print2_i#1 reg byte y 16.5
(byte) main::print2_i#2 reg byte y 11.0
(byte) main::print2_j
(byte) main::print2_j#1 reg byte x 7.333333333333333
(byte) main::print2_j#2 reg byte x 16.5
(byte*) main::print2_msg
(byte*) screen
(const byte*) screen#0 screen = ((byte*))(word/signed word/dword/signed dword) 1024

reg byte y [ main::print1_i#2 main::print1_i#1 ]
reg byte x [ main::print1_j#2 main::print1_j#1 ]
reg byte y [ main::print2_i#2 main::print2_i#1 ]
reg byte x [ main::print2_j#2 main::print2_j#1 ]


FINAL ASSEMBLER
Score: 576

//SEG0 File Comments
// TEst inlining a slightly complex print function (containing a loop)
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
  .label screen = $400
//SEG3 @begin
//SEG4 [1] phi from @begin to @2 [phi:@begin->@2]
//SEG5 @2
//SEG6 [2] call main 
//SEG7 [4] phi from @2 to main [phi:@2->main]
//SEG8 [3] phi from @2 to @end [phi:@2->@end]
//SEG9 @end
//SEG10 main
main: {
    .label print2_at = screen+2*$28
  //SEG11 [5] phi from main to main::print1 [phi:main->main::print1]
  //SEG12 main::print1
  //SEG13 [6] phi from main::print1 to main::print1_@1 [phi:main::print1->main::print1_@1]
  //SEG14 [6] phi (byte) main::print1_j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print1->main::print1_@1#0] -- vbuxx=vbuc1 
    ldx #0
  //SEG15 [6] phi (byte) main::print1_i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print1->main::print1_@1#1] -- vbuyy=vbuc1 
    ldy #0
  //SEG16 [6] phi from main::print1_@1 to main::print1_@1 [phi:main::print1_@1->main::print1_@1]
  //SEG17 [6] phi (byte) main::print1_j#2 = (byte) main::print1_j#1 [phi:main::print1_@1->main::print1_@1#0] -- register_copy 
  //SEG18 [6] phi (byte) main::print1_i#2 = (byte) main::print1_i#1 [phi:main::print1_@1->main::print1_@1#1] -- register_copy 
  //SEG19 main::print1_@1
  print1_b1:
  //SEG20 [7] *((const byte*) screen#0 + (byte) main::print1_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print1_i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy 
    lda print1_msg,y
    sta screen,x
  //SEG21 [8] (byte) main::print1_j#1 ← (byte) main::print1_j#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuxx=vbuxx_plus_2 
    inx
    inx
  //SEG22 [9] (byte) main::print1_i#1 ← ++ (byte) main::print1_i#2 -- vbuyy=_inc_vbuyy 
    iny
  //SEG23 [10] if(*((const byte*) main::print1_msg#0 + (byte) main::print1_i#1)!=(byte) '@') goto main::print1_@1 -- pbuc1_derefidx_vbuyy_neq_vbuc2_then_la1 
    lda print1_msg,y
    cmp #'@'
    bne print1_b1
  //SEG24 [11] phi from main::print1_@1 to main::print2 [phi:main::print1_@1->main::print2]
  //SEG25 main::print2
  //SEG26 [12] phi from main::print2 to main::print2_@1 [phi:main::print2->main::print2_@1]
  //SEG27 [12] phi (byte) main::print2_j#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print2->main::print2_@1#0] -- vbuxx=vbuc1 
    ldx #0
  //SEG28 [12] phi (byte) main::print2_i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main::print2->main::print2_@1#1] -- vbuyy=vbuc1 
    ldy #0
  //SEG29 [12] phi from main::print2_@1 to main::print2_@1 [phi:main::print2_@1->main::print2_@1]
  //SEG30 [12] phi (byte) main::print2_j#2 = (byte) main::print2_j#1 [phi:main::print2_@1->main::print2_@1#0] -- register_copy 
  //SEG31 [12] phi (byte) main::print2_i#2 = (byte) main::print2_i#1 [phi:main::print2_@1->main::print2_@1#1] -- register_copy 
  //SEG32 main::print2_@1
  print2_b1:
  //SEG33 [13] *((const byte*) main::print2_at#0 + (byte) main::print2_j#2) ← *((const byte*) main::print1_msg#0 + (byte) main::print2_i#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy 
    lda print1_msg,y
    sta print2_at,x
  //SEG34 [14] (byte) main::print2_j#1 ← (byte) main::print2_j#2 + (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuxx=vbuxx_plus_2 
    inx
    inx
  //SEG35 [15] (byte) main::print2_i#1 ← ++ (byte) main::print2_i#2 -- vbuyy=_inc_vbuyy 
    iny
  //SEG36 [16] if(*((const byte*) main::print1_msg#0 + (byte) main::print2_i#1)!=(byte) '@') goto main::print2_@1 -- pbuc1_derefidx_vbuyy_neq_vbuc2_then_la1 
    lda print1_msg,y
    cmp #'@'
    bne print2_b1
  //SEG37 main::@return
  //SEG38 [17] return 
    rts
    print1_msg: .text "hello world!@"
}

