Culled Empty Block (label) @1
Culled Empty Block (label) strip::@4
Culled Empty Block (label) print::@2

CONTROL FLOW GRAPH SSA
@begin: scope:[]  from
  to:@2

(void()) main()
main: scope:[main]  from @3
  (byte*) screen#17 ← phi( @3/(byte*) screen#16 )
  (byte*) strip::p#0 ← (const byte*) msg1
  (byte) strip::c#0 ← (byte) ' '
  call strip 
  to:main::@1
main::@1: scope:[main]  from main
  (byte*) screen#13 ← phi( main/(byte*) screen#17 )
  (byte*) print::msg#0 ← (const byte*) msg1
  call print 
  to:main::@2
main::@2: scope:[main]  from main::@1
  (byte*) screen#7 ← phi( main::@1/(byte*) screen#5 )
  (byte*) screen#0 ← (byte*) screen#7
  (byte*) strip::p#1 ← (const byte*) msg2
  (byte) strip::c#1 ← (byte) 'y'
  call strip 
  to:main::@3
main::@3: scope:[main]  from main::@2
  (byte*) screen#14 ← phi( main::@2/(byte*) screen#0 )
  (byte*) print::msg#1 ← (const byte*) msg2
  call print 
  to:main::@4
main::@4: scope:[main]  from main::@3
  (byte*) screen#8 ← phi( main::@3/(byte*) screen#5 )
  (byte*) screen#1 ← (byte*) screen#8
  to:main::@return
main::@return: scope:[main]  from main::@4
  (byte*) screen#9 ← phi( main::@4/(byte*) screen#1 )
  (byte*) screen#2 ← (byte*) screen#9
  return 
  to:@return

(void()) strip((byte*) strip::p , (byte) strip::c)
strip: scope:[strip]  from main main::@2
  (byte) strip::c#3 ← phi( main/(byte) strip::c#0 main::@2/(byte) strip::c#1 )
  (byte*) strip::p#3 ← phi( main/(byte*) strip::p#0 main::@2/(byte*) strip::p#1 )
  (byte*) strip::dest#0 ← (byte*) strip::p#3
  to:strip::@1
strip::@1: scope:[strip]  from strip strip::@2
  (byte*) strip::dest#3 ← phi( strip/(byte*) strip::dest#0 strip::@2/(byte*) strip::dest#4 )
  (byte) strip::c#2 ← phi( strip/(byte) strip::c#3 strip::@2/(byte) strip::c#4 )
  (byte*) strip::p#4 ← phi( strip/(byte*) strip::p#3 strip::@2/(byte*) strip::p#2 )
  (bool~) strip::$0 ← *((byte*) strip::p#4) != (byte) strip::c#2
  (bool~) strip::$1 ← ! (bool~) strip::$0
  if((bool~) strip::$1) goto strip::@2
  to:strip::@3
strip::@2: scope:[strip]  from strip::@1 strip::@3
  (byte*) strip::dest#4 ← phi( strip::@1/(byte*) strip::dest#3 strip::@3/(byte*) strip::dest#1 )
  (byte) strip::c#4 ← phi( strip::@1/(byte) strip::c#2 strip::@3/(byte) strip::c#5 )
  (byte*) strip::p#5 ← phi( strip::@1/(byte*) strip::p#4 strip::@3/(byte*) strip::p#6 )
  (bool~) strip::$2 ← *((byte*) strip::p#5) != (number) 0
  (byte*) strip::p#2 ← ++ (byte*) strip::p#5
  if((bool~) strip::$2) goto strip::@1
  to:strip::@return
strip::@3: scope:[strip]  from strip::@1
  (byte) strip::c#5 ← phi( strip::@1/(byte) strip::c#2 )
  (byte*) strip::dest#2 ← phi( strip::@1/(byte*) strip::dest#3 )
  (byte*) strip::p#6 ← phi( strip::@1/(byte*) strip::p#4 )
  *((byte*) strip::dest#2) ← *((byte*) strip::p#6)
  (byte*) strip::dest#1 ← ++ (byte*) strip::dest#2
  to:strip::@2
strip::@return: scope:[strip]  from strip::@2
  return 
  to:@return
@2: scope:[]  from @begin
  (byte*) screen#3 ← (byte*)(number) $400
  to:@3

(void()) print((byte*) print::msg)
print: scope:[print]  from main::@1 main::@3
  (byte*) screen#15 ← phi( main::@1/(byte*) screen#13 main::@3/(byte*) screen#14 )
  (byte*) print::msg#4 ← phi( main::@1/(byte*) print::msg#0 main::@3/(byte*) print::msg#1 )
  to:print::@1
print::@1: scope:[print]  from print print::@1
  (byte*) screen#10 ← phi( print/(byte*) screen#15 print::@1/(byte*) screen#4 )
  (byte*) print::msg#3 ← phi( print/(byte*) print::msg#4 print::@1/(byte*) print::msg#2 )
  *((byte*) screen#10) ← *((byte*) print::msg#3)
  (byte*) screen#4 ← ++ (byte*) screen#10
  (byte*) print::msg#2 ← ++ (byte*) print::msg#3
  (bool~) print::$0 ← *((byte*) print::msg#2) != (number) 0
  if((bool~) print::$0) goto print::@1
  to:print::@return
print::@return: scope:[print]  from print::@1
  (byte*) screen#11 ← phi( print::@1/(byte*) screen#4 )
  (byte*) screen#5 ← (byte*) screen#11
  return 
  to:@return
@3: scope:[]  from @2
  (byte*) screen#16 ← phi( @2/(byte*) screen#3 )
  call main 
  to:@4
@4: scope:[]  from @3
  (byte*) screen#12 ← phi( @3/(byte*) screen#2 )
  (byte*) screen#6 ← (byte*) screen#12
  to:@end
@end: scope:[]  from @4

SYMBOL TABLE SSA
(label) @2
(label) @3
(label) @4
(label) @begin
(label) @end
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::@return
(const byte*) msg1[]  = (byte*) "hello world!"
(const byte*) msg2[]  = (byte*) "goodbye blue sky!"
(void()) print((byte*) print::msg)
(bool~) print::$0
(label) print::@1
(label) print::@return
(byte*) print::msg
(byte*) print::msg#0
(byte*) print::msg#1
(byte*) print::msg#2
(byte*) print::msg#3
(byte*) print::msg#4
(byte*) screen
(byte*) screen#0
(byte*) screen#1
(byte*) screen#10
(byte*) screen#11
(byte*) screen#12
(byte*) screen#13
(byte*) screen#14
(byte*) screen#15
(byte*) screen#16
(byte*) screen#17
(byte*) screen#2
(byte*) screen#3
(byte*) screen#4
(byte*) screen#5
(byte*) screen#6
(byte*) screen#7
(byte*) screen#8
(byte*) screen#9
(void()) strip((byte*) strip::p , (byte) strip::c)
(bool~) strip::$0
(bool~) strip::$1
(bool~) strip::$2
(label) strip::@1
(label) strip::@2
(label) strip::@3
(label) strip::@return
(byte) strip::c
(byte) strip::c#0
(byte) strip::c#1
(byte) strip::c#2
(byte) strip::c#3
(byte) strip::c#4
(byte) strip::c#5
(byte*) strip::dest
(byte*) strip::dest#0
(byte*) strip::dest#1
(byte*) strip::dest#2
(byte*) strip::dest#3
(byte*) strip::dest#4
(byte*) strip::p
(byte*) strip::p#0
(byte*) strip::p#1
(byte*) strip::p#2
(byte*) strip::p#3
(byte*) strip::p#4
(byte*) strip::p#5
(byte*) strip::p#6

Adding number conversion cast (unumber) 0 in (bool~) strip::$2 ← *((byte*) strip::p#5) != (number) 0
Adding number conversion cast (unumber) 0 in (bool~) print::$0 ← *((byte*) print::msg#2) != (number) 0
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 0
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inversing boolean not [24] (bool~) strip::$1 ← *((byte*) strip::p#4) == (byte) strip::c#2 from [23] (bool~) strip::$0 ← *((byte*) strip::p#4) != (byte) strip::c#2
Successful SSA optimization Pass2UnaryNotSimplification
Alias (byte*) screen#13 = (byte*) screen#17 
Alias (byte*) screen#0 = (byte*) screen#7 (byte*) screen#14 
Alias (byte*) screen#1 = (byte*) screen#8 (byte*) screen#9 (byte*) screen#2 
Alias (byte*) strip::dest#0 = (byte*) strip::p#3 
Alias (byte*) strip::p#4 = (byte*) strip::p#6 
Alias (byte*) strip::dest#2 = (byte*) strip::dest#3 
Alias (byte) strip::c#2 = (byte) strip::c#5 
Alias (byte*) screen#11 = (byte*) screen#4 (byte*) screen#5 
Alias (byte*) screen#16 = (byte*) screen#3 
Alias (byte*) screen#12 = (byte*) screen#6 
Successful SSA optimization Pass2AliasElimination
Alias (byte*) strip::p#4 = (byte*) strip::p#5 
Alias (byte) strip::c#2 = (byte) strip::c#4 
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte*) screen#13 (byte*) screen#16
Identical Phi Values (byte*) screen#0 (byte*) screen#11
Identical Phi Values (byte*) screen#1 (byte*) screen#11
Identical Phi Values (byte) strip::c#2 (byte) strip::c#3
Identical Phi Values (byte*) screen#12 (byte*) screen#1
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition (bool~) strip::$1 [17] if(*((byte*) strip::p#4)==(byte) strip::c#3) goto strip::@2
Simple Condition (bool~) strip::$2 [21] if(*((byte*) strip::p#4)!=(byte) 0) goto strip::@1
Simple Condition (bool~) print::$0 [32] if(*((byte*) print::msg#2)!=(byte) 0) goto print::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) strip::p#0 = msg1
Constant (const byte) strip::c#0 = ' '
Constant (const byte*) print::msg#0 = msg1
Constant (const byte*) strip::p#1 = msg2
Constant (const byte) strip::c#1 = 'y'
Constant (const byte*) print::msg#1 = msg2
Constant (const byte*) screen#16 = (byte*) 1024
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with var siblings (const byte*) strip::p#0
Inlining constant with var siblings (const byte) strip::c#0
Inlining constant with var siblings (const byte*) strip::p#1
Inlining constant with var siblings (const byte) strip::c#1
Inlining constant with var siblings (const byte*) print::msg#0
Inlining constant with var siblings (const byte*) print::msg#1
Inlining constant with var siblings (const byte*) screen#16
Constant inlined strip::p#0 = (const byte*) msg1
Constant inlined print::msg#1 = (const byte*) msg2
Constant inlined strip::p#1 = (const byte*) msg2
Constant inlined print::msg#0 = (const byte*) msg1
Constant inlined strip::c#0 = (byte) ' '
Constant inlined strip::c#1 = (byte) 'y'
Constant inlined screen#16 = (byte*) 1024
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting strip::@5(between strip::@2 and strip::@1)
Added new block during phi lifting strip::@6(between strip::@1 and strip::@2)
Added new block during phi lifting print::@3(between print::@1 and print::@1)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2
Adding NOP phi() at start of @3
Adding NOP phi() at start of @4
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@2
Adding NOP phi() at start of main::@4
CALL GRAPH
Calls in [] to main:3 
Calls in [main] to strip:7 print:9 strip:11 print:13 

Created 9 initial phi equivalence classes
Coalesced [12] screen#18 ← screen#11
Coalesced [17] print::msg#5 ← print::msg#4
Coalesced [18] screen#19 ← screen#15
Coalesced [25] print::msg#6 ← print::msg#2
Coalesced (already) [26] screen#20 ← screen#11
Not coalescing [28] strip::p#7 ← strip::dest#0
Coalesced [29] strip::dest#5 ← strip::dest#0
Coalesced [34] strip::dest#8 ← strip::dest#1
Not coalescing [39] strip::p#8 ← strip::p#2
Coalesced [40] strip::dest#6 ← strip::dest#4
Coalesced (already) [41] strip::dest#7 ← strip::dest#2
Coalesced down to 6 phi equivalence classes
Culled Empty Block (label) @2
Culled Empty Block (label) @4
Culled Empty Block (label) main::@4
Culled Empty Block (label) print::@3
Culled Empty Block (label) strip::@6
Renumbering block @3 to @1
Renumbering block strip::@5 to strip::@4
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
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@2
Adding NOP phi() at start of main::@3

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()

(void()) main()
main: scope:[main]  from @1
  [4] phi()
  [5] call strip 
  to:main::@1
main::@1: scope:[main]  from main
  [6] phi()
  [7] call print 
  to:main::@2
main::@2: scope:[main]  from main::@1
  [8] phi()
  [9] call strip 
  to:main::@3
main::@3: scope:[main]  from main::@2
  [10] phi()
  [11] call print 
  to:main::@return
main::@return: scope:[main]  from main::@3
  [12] return 
  to:@return

(void()) print((byte*) print::msg)
print: scope:[print]  from main::@1 main::@3
  [13] (byte*) screen#15 ← phi( main::@1/(byte*) 1024 main::@3/(byte*) screen#11 )
  [13] (byte*) print::msg#4 ← phi( main::@1/(const byte*) msg1 main::@3/(const byte*) msg2 )
  to:print::@1
print::@1: scope:[print]  from print print::@1
  [14] (byte*) screen#10 ← phi( print/(byte*) screen#15 print::@1/(byte*) screen#11 )
  [14] (byte*) print::msg#3 ← phi( print/(byte*) print::msg#4 print::@1/(byte*) print::msg#2 )
  [15] *((byte*) screen#10) ← *((byte*) print::msg#3)
  [16] (byte*) screen#11 ← ++ (byte*) screen#10
  [17] (byte*) print::msg#2 ← ++ (byte*) print::msg#3
  [18] if(*((byte*) print::msg#2)!=(byte) 0) goto print::@1
  to:print::@return
print::@return: scope:[print]  from print::@1
  [19] return 
  to:@return

(void()) strip((byte*) strip::p , (byte) strip::c)
strip: scope:[strip]  from main main::@2
  [20] (byte) strip::c#3 ← phi( main/(byte) ' ' main::@2/(byte) 'y' )
  [20] (byte*) strip::dest#0 ← phi( main/(const byte*) msg1 main::@2/(const byte*) msg2 )
  [21] (byte*) strip::p#7 ← (byte*) strip::dest#0
  to:strip::@1
strip::@1: scope:[strip]  from strip strip::@4
  [22] (byte*) strip::dest#2 ← phi( strip/(byte*) strip::dest#0 strip::@4/(byte*) strip::dest#4 )
  [22] (byte*) strip::p#4 ← phi( strip/(byte*) strip::p#7 strip::@4/(byte*) strip::p#8 )
  [23] if(*((byte*) strip::p#4)==(byte) strip::c#3) goto strip::@2
  to:strip::@3
strip::@3: scope:[strip]  from strip::@1
  [24] *((byte*) strip::dest#2) ← *((byte*) strip::p#4)
  [25] (byte*) strip::dest#1 ← ++ (byte*) strip::dest#2
  to:strip::@2
strip::@2: scope:[strip]  from strip::@1 strip::@3
  [26] (byte*) strip::dest#4 ← phi( strip::@1/(byte*) strip::dest#2 strip::@3/(byte*) strip::dest#1 )
  [27] (byte*) strip::p#2 ← ++ (byte*) strip::p#4
  [28] if(*((byte*) strip::p#4)!=(byte) 0) goto strip::@4
  to:strip::@return
strip::@return: scope:[strip]  from strip::@2
  [29] return 
  to:@return
strip::@4: scope:[strip]  from strip::@2
  [30] (byte*) strip::p#8 ← (byte*) strip::p#2
  to:strip::@1


VARIABLE REGISTER WEIGHTS
(void()) main()
(void()) print((byte*) print::msg)
(byte*) print::msg
(byte*) print::msg#2 16.5
(byte*) print::msg#3 11.666666666666666
(byte*) print::msg#4 2.0
(byte*) screen
(byte*) screen#10 17.5
(byte*) screen#11 3.0
(byte*) screen#15 4.0
(void()) strip((byte*) strip::p , (byte) strip::c)
(byte) strip::c
(byte) strip::c#3 1.1
(byte*) strip::dest
(byte*) strip::dest#0 2.0
(byte*) strip::dest#1 22.0
(byte*) strip::dest#2 15.333333333333332
(byte*) strip::dest#4 8.25
(byte*) strip::p
(byte*) strip::p#2 11.0
(byte*) strip::p#4 9.5
(byte*) strip::p#7 4.0
(byte*) strip::p#8 22.0

Initial phi equivalence classes
[ print::msg#3 print::msg#4 print::msg#2 ]
[ screen#10 screen#15 screen#11 ]
[ strip::c#3 ]
[ strip::p#4 strip::p#7 strip::p#8 ]
[ strip::dest#2 strip::dest#0 strip::dest#4 strip::dest#1 ]
Added variable strip::p#2 to live range equivalence class [ strip::p#2 ]
Complete equivalence classes
[ print::msg#3 print::msg#4 print::msg#2 ]
[ screen#10 screen#15 screen#11 ]
[ strip::c#3 ]
[ strip::p#4 strip::p#7 strip::p#8 ]
[ strip::dest#2 strip::dest#0 strip::dest#4 strip::dest#1 ]
[ strip::p#2 ]
Allocated zp[2]:2 [ print::msg#3 print::msg#4 print::msg#2 ]
Allocated zp[2]:4 [ screen#10 screen#15 screen#11 ]
Allocated zp[1]:6 [ strip::c#3 ]
Allocated zp[2]:7 [ strip::p#4 strip::p#7 strip::p#8 ]
Allocated zp[2]:9 [ strip::dest#2 strip::dest#0 strip::dest#4 strip::dest#1 ]
Allocated zp[2]:11 [ strip::p#2 ]

INITIAL ASM
Target platform is c64basic / MOS6502X
  // File Comments
// Tests of strip() function from https://news.ycombinator.com/item?id=12080871
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .label screen = 4
  // @begin
__bbegin:
  // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
  jmp __b1
  // @1
__b1:
  // [2] call main 
  // [4] phi from @1 to main [phi:@1->main]
main_from___b1:
  jsr main
  // [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
  jmp __bend
  // @end
__bend:
  // main
main: {
    // [5] call strip 
    // [20] phi from main to strip [phi:main->strip]
  strip_from_main:
    // [20] phi (byte) strip::c#3 = (byte) ' ' [phi:main->strip#0] -- vbuz1=vbuc1 
    lda #' '
    sta.z strip.c
    // [20] phi (byte*) strip::dest#0 = (const byte*) msg1 [phi:main->strip#1] -- pbuz1=pbuc1 
    lda #<msg1
    sta.z strip.dest
    lda #>msg1
    sta.z strip.dest+1
    jsr strip
    // [6] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    jmp __b1
    // main::@1
  __b1:
    // [7] call print 
    // [13] phi from main::@1 to print [phi:main::@1->print]
  print_from___b1:
    // [13] phi (byte*) screen#15 = (byte*) 1024 [phi:main::@1->print#0] -- pbuz1=pbuc1 
    lda #<$400
    sta.z screen
    lda #>$400
    sta.z screen+1
    // [13] phi (byte*) print::msg#4 = (const byte*) msg1 [phi:main::@1->print#1] -- pbuz1=pbuc1 
    lda #<msg1
    sta.z print.msg
    lda #>msg1
    sta.z print.msg+1
    jsr print
    // [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
  __b2_from___b1:
    jmp __b2
    // main::@2
  __b2:
    // [9] call strip 
    // [20] phi from main::@2 to strip [phi:main::@2->strip]
  strip_from___b2:
    // [20] phi (byte) strip::c#3 = (byte) 'y' [phi:main::@2->strip#0] -- vbuz1=vbuc1 
    lda #'y'
    sta.z strip.c
    // [20] phi (byte*) strip::dest#0 = (const byte*) msg2 [phi:main::@2->strip#1] -- pbuz1=pbuc1 
    lda #<msg2
    sta.z strip.dest
    lda #>msg2
    sta.z strip.dest+1
    jsr strip
    // [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
  __b3_from___b2:
    jmp __b3
    // main::@3
  __b3:
    // [11] call print 
    // [13] phi from main::@3 to print [phi:main::@3->print]
  print_from___b3:
    // [13] phi (byte*) screen#15 = (byte*) screen#11 [phi:main::@3->print#0] -- register_copy 
    // [13] phi (byte*) print::msg#4 = (const byte*) msg2 [phi:main::@3->print#1] -- pbuz1=pbuc1 
    lda #<msg2
    sta.z print.msg
    lda #>msg2
    sta.z print.msg+1
    jsr print
    jmp __breturn
    // main::@return
  __breturn:
    // [12] return 
    rts
}
  // print
// print(byte* zp(2) msg)
print: {
    .label msg = 2
    // [14] phi from print print::@1 to print::@1 [phi:print/print::@1->print::@1]
  __b1_from_print:
  __b1_from___b1:
    // [14] phi (byte*) screen#10 = (byte*) screen#15 [phi:print/print::@1->print::@1#0] -- register_copy 
    // [14] phi (byte*) print::msg#3 = (byte*) print::msg#4 [phi:print/print::@1->print::@1#1] -- register_copy 
    jmp __b1
    // print::@1
  __b1:
    // [15] *((byte*) screen#10) ← *((byte*) print::msg#3) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (msg),y
    ldy #0
    sta (screen),y
    // [16] (byte*) screen#11 ← ++ (byte*) screen#10 -- pbuz1=_inc_pbuz1 
    inc.z screen
    bne !+
    inc.z screen+1
  !:
    // [17] (byte*) print::msg#2 ← ++ (byte*) print::msg#3 -- pbuz1=_inc_pbuz1 
    inc.z msg
    bne !+
    inc.z msg+1
  !:
    // [18] if(*((byte*) print::msg#2)!=(byte) 0) goto print::@1 -- _deref_pbuz1_neq_0_then_la1 
    ldy #0
    lda (msg),y
    cmp #0
    bne __b1_from___b1
    jmp __breturn
    // print::@return
  __breturn:
    // [19] return 
    rts
}
  // strip
// strip(byte* zp($b) p, byte zp(6) c)
strip: {
    .label dest = 9
    .label p = $b
    .label p_1 = 7
    .label c = 6
    // [21] (byte*) strip::p#7 ← (byte*) strip::dest#0 -- pbuz1=pbuz2 
    lda.z dest
    sta.z p_1
    lda.z dest+1
    sta.z p_1+1
    // [22] phi from strip strip::@4 to strip::@1 [phi:strip/strip::@4->strip::@1]
  __b1_from_strip:
  __b1_from___b4:
    // [22] phi (byte*) strip::dest#2 = (byte*) strip::dest#0 [phi:strip/strip::@4->strip::@1#0] -- register_copy 
    // [22] phi (byte*) strip::p#4 = (byte*) strip::p#7 [phi:strip/strip::@4->strip::@1#1] -- register_copy 
    jmp __b1
    // strip::@1
  __b1:
    // [23] if(*((byte*) strip::p#4)==(byte) strip::c#3) goto strip::@2 -- _deref_pbuz1_eq_vbuz2_then_la1 
    lda.z c
    ldy #0
    cmp (p_1),y
    beq __b2_from___b1
    jmp __b3
    // strip::@3
  __b3:
    // [24] *((byte*) strip::dest#2) ← *((byte*) strip::p#4) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (p_1),y
    ldy #0
    sta (dest),y
    // [25] (byte*) strip::dest#1 ← ++ (byte*) strip::dest#2 -- pbuz1=_inc_pbuz1 
    inc.z dest
    bne !+
    inc.z dest+1
  !:
    // [26] phi from strip::@1 strip::@3 to strip::@2 [phi:strip::@1/strip::@3->strip::@2]
  __b2_from___b1:
  __b2_from___b3:
    // [26] phi (byte*) strip::dest#4 = (byte*) strip::dest#2 [phi:strip::@1/strip::@3->strip::@2#0] -- register_copy 
    jmp __b2
    // strip::@2
  __b2:
    // [27] (byte*) strip::p#2 ← ++ (byte*) strip::p#4 -- pbuz1=_inc_pbuz2 
    lda.z p_1
    clc
    adc #1
    sta.z p
    lda.z p_1+1
    adc #0
    sta.z p+1
    // [28] if(*((byte*) strip::p#4)!=(byte) 0) goto strip::@4 -- _deref_pbuz1_neq_0_then_la1 
    ldy #0
    lda (p_1),y
    cmp #0
    bne __b4
    jmp __breturn
    // strip::@return
  __breturn:
    // [29] return 
    rts
    // strip::@4
  __b4:
    // [30] (byte*) strip::p#8 ← (byte*) strip::p#2 -- pbuz1=pbuz2 
    lda.z p
    sta.z p_1
    lda.z p+1
    sta.z p_1+1
    jmp __b1_from___b4
}
  // File Data
  msg1: .text "hello world!"
  .byte 0
  msg2: .text "goodbye blue sky!"
  .byte 0

REGISTER UPLIFT POTENTIAL REGISTERS
Statement [15] *((byte*) screen#10) ← *((byte*) print::msg#3) [ print::msg#3 screen#10 ] ( main:2::print:7 [ print::msg#3 screen#10 ] main:2::print:11 [ print::msg#3 screen#10 ] ) always clobbers reg byte a reg byte y 
Statement [18] if(*((byte*) print::msg#2)!=(byte) 0) goto print::@1 [ screen#11 print::msg#2 ] ( main:2::print:7 [ screen#11 print::msg#2 ] main:2::print:11 [ screen#11 print::msg#2 ] ) always clobbers reg byte a reg byte y 
Statement [21] (byte*) strip::p#7 ← (byte*) strip::dest#0 [ strip::dest#0 strip::c#3 strip::p#7 ] ( main:2::strip:5 [ strip::dest#0 strip::c#3 strip::p#7 ] main:2::strip:9 [ screen#11 strip::dest#0 strip::c#3 strip::p#7 ] ) always clobbers reg byte a 
Removing always clobbered register reg byte a as potential for zp[1]:6 [ strip::c#3 ]
Statement [23] if(*((byte*) strip::p#4)==(byte) strip::c#3) goto strip::@2 [ strip::c#3 strip::p#4 strip::dest#2 ] ( main:2::strip:5 [ strip::c#3 strip::p#4 strip::dest#2 ] main:2::strip:9 [ screen#11 strip::c#3 strip::p#4 strip::dest#2 ] ) always clobbers reg byte a reg byte y 
Removing always clobbered register reg byte y as potential for zp[1]:6 [ strip::c#3 ]
Statement [24] *((byte*) strip::dest#2) ← *((byte*) strip::p#4) [ strip::c#3 strip::p#4 strip::dest#2 ] ( main:2::strip:5 [ strip::c#3 strip::p#4 strip::dest#2 ] main:2::strip:9 [ screen#11 strip::c#3 strip::p#4 strip::dest#2 ] ) always clobbers reg byte a reg byte y 
Statement [27] (byte*) strip::p#2 ← ++ (byte*) strip::p#4 [ strip::c#3 strip::p#4 strip::dest#4 strip::p#2 ] ( main:2::strip:5 [ strip::c#3 strip::p#4 strip::dest#4 strip::p#2 ] main:2::strip:9 [ screen#11 strip::c#3 strip::p#4 strip::dest#4 strip::p#2 ] ) always clobbers reg byte a 
Statement [28] if(*((byte*) strip::p#4)!=(byte) 0) goto strip::@4 [ strip::c#3 strip::dest#4 strip::p#2 ] ( main:2::strip:5 [ strip::c#3 strip::dest#4 strip::p#2 ] main:2::strip:9 [ screen#11 strip::c#3 strip::dest#4 strip::p#2 ] ) always clobbers reg byte a reg byte y 
Statement [30] (byte*) strip::p#8 ← (byte*) strip::p#2 [ strip::c#3 strip::p#8 strip::dest#4 ] ( main:2::strip:5 [ strip::c#3 strip::p#8 strip::dest#4 ] main:2::strip:9 [ screen#11 strip::c#3 strip::p#8 strip::dest#4 ] ) always clobbers reg byte a 
Statement [15] *((byte*) screen#10) ← *((byte*) print::msg#3) [ print::msg#3 screen#10 ] ( main:2::print:7 [ print::msg#3 screen#10 ] main:2::print:11 [ print::msg#3 screen#10 ] ) always clobbers reg byte a reg byte y 
Statement [18] if(*((byte*) print::msg#2)!=(byte) 0) goto print::@1 [ screen#11 print::msg#2 ] ( main:2::print:7 [ screen#11 print::msg#2 ] main:2::print:11 [ screen#11 print::msg#2 ] ) always clobbers reg byte a reg byte y 
Statement [21] (byte*) strip::p#7 ← (byte*) strip::dest#0 [ strip::dest#0 strip::c#3 strip::p#7 ] ( main:2::strip:5 [ strip::dest#0 strip::c#3 strip::p#7 ] main:2::strip:9 [ screen#11 strip::dest#0 strip::c#3 strip::p#7 ] ) always clobbers reg byte a 
Statement [23] if(*((byte*) strip::p#4)==(byte) strip::c#3) goto strip::@2 [ strip::c#3 strip::p#4 strip::dest#2 ] ( main:2::strip:5 [ strip::c#3 strip::p#4 strip::dest#2 ] main:2::strip:9 [ screen#11 strip::c#3 strip::p#4 strip::dest#2 ] ) always clobbers reg byte a reg byte y 
Statement [24] *((byte*) strip::dest#2) ← *((byte*) strip::p#4) [ strip::c#3 strip::p#4 strip::dest#2 ] ( main:2::strip:5 [ strip::c#3 strip::p#4 strip::dest#2 ] main:2::strip:9 [ screen#11 strip::c#3 strip::p#4 strip::dest#2 ] ) always clobbers reg byte a reg byte y 
Statement [27] (byte*) strip::p#2 ← ++ (byte*) strip::p#4 [ strip::c#3 strip::p#4 strip::dest#4 strip::p#2 ] ( main:2::strip:5 [ strip::c#3 strip::p#4 strip::dest#4 strip::p#2 ] main:2::strip:9 [ screen#11 strip::c#3 strip::p#4 strip::dest#4 strip::p#2 ] ) always clobbers reg byte a 
Statement [28] if(*((byte*) strip::p#4)!=(byte) 0) goto strip::@4 [ strip::c#3 strip::dest#4 strip::p#2 ] ( main:2::strip:5 [ strip::c#3 strip::dest#4 strip::p#2 ] main:2::strip:9 [ screen#11 strip::c#3 strip::dest#4 strip::p#2 ] ) always clobbers reg byte a reg byte y 
Statement [30] (byte*) strip::p#8 ← (byte*) strip::p#2 [ strip::c#3 strip::p#8 strip::dest#4 ] ( main:2::strip:5 [ strip::c#3 strip::p#8 strip::dest#4 ] main:2::strip:9 [ screen#11 strip::c#3 strip::p#8 strip::dest#4 ] ) always clobbers reg byte a 
Potential registers zp[2]:2 [ print::msg#3 print::msg#4 print::msg#2 ] : zp[2]:2 , 
Potential registers zp[2]:4 [ screen#10 screen#15 screen#11 ] : zp[2]:4 , 
Potential registers zp[1]:6 [ strip::c#3 ] : zp[1]:6 , reg byte x , 
Potential registers zp[2]:7 [ strip::p#4 strip::p#7 strip::p#8 ] : zp[2]:7 , 
Potential registers zp[2]:9 [ strip::dest#2 strip::dest#0 strip::dest#4 strip::dest#1 ] : zp[2]:9 , 
Potential registers zp[2]:11 [ strip::p#2 ] : zp[2]:11 , 

REGISTER UPLIFT SCOPES
Uplift Scope [strip] 47.58: zp[2]:9 [ strip::dest#2 strip::dest#0 strip::dest#4 strip::dest#1 ] 35.5: zp[2]:7 [ strip::p#4 strip::p#7 strip::p#8 ] 11: zp[2]:11 [ strip::p#2 ] 1.1: zp[1]:6 [ strip::c#3 ] 
Uplift Scope [print] 30.17: zp[2]:2 [ print::msg#3 print::msg#4 print::msg#2 ] 
Uplift Scope [] 24.5: zp[2]:4 [ screen#10 screen#15 screen#11 ] 
Uplift Scope [main] 

Uplifting [strip] best 1687 combination zp[2]:9 [ strip::dest#2 strip::dest#0 strip::dest#4 strip::dest#1 ] zp[2]:7 [ strip::p#4 strip::p#7 strip::p#8 ] zp[2]:11 [ strip::p#2 ] reg byte x [ strip::c#3 ] 
Uplifting [print] best 1687 combination zp[2]:2 [ print::msg#3 print::msg#4 print::msg#2 ] 
Uplifting [] best 1687 combination zp[2]:4 [ screen#10 screen#15 screen#11 ] 
Uplifting [main] best 1687 combination 
Coalescing zero page register [ zp[2]:7 [ strip::p#4 strip::p#7 strip::p#8 ] ] with [ zp[2]:2 [ print::msg#3 print::msg#4 print::msg#2 ] ]
Allocated (was zp[2]:4) zp[2]:2 [ screen#10 screen#15 screen#11 ]
Allocated (was zp[2]:7) zp[2]:4 [ strip::p#4 strip::p#7 strip::p#8 print::msg#3 print::msg#4 print::msg#2 ]
Allocated (was zp[2]:9) zp[2]:6 [ strip::dest#2 strip::dest#0 strip::dest#4 strip::dest#1 ]
Allocated (was zp[2]:11) zp[2]:8 [ strip::p#2 ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Tests of strip() function from https://news.ycombinator.com/item?id=12080871
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .label screen = 2
  // @begin
__bbegin:
  // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
  jmp __b1
  // @1
__b1:
  // [2] call main 
  // [4] phi from @1 to main [phi:@1->main]
main_from___b1:
  jsr main
  // [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
  jmp __bend
  // @end
__bend:
  // main
main: {
    // [5] call strip 
    // [20] phi from main to strip [phi:main->strip]
  strip_from_main:
    // [20] phi (byte) strip::c#3 = (byte) ' ' [phi:main->strip#0] -- vbuxx=vbuc1 
    ldx #' '
    // [20] phi (byte*) strip::dest#0 = (const byte*) msg1 [phi:main->strip#1] -- pbuz1=pbuc1 
    lda #<msg1
    sta.z strip.dest
    lda #>msg1
    sta.z strip.dest+1
    jsr strip
    // [6] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    jmp __b1
    // main::@1
  __b1:
    // [7] call print 
    // [13] phi from main::@1 to print [phi:main::@1->print]
  print_from___b1:
    // [13] phi (byte*) screen#15 = (byte*) 1024 [phi:main::@1->print#0] -- pbuz1=pbuc1 
    lda #<$400
    sta.z screen
    lda #>$400
    sta.z screen+1
    // [13] phi (byte*) print::msg#4 = (const byte*) msg1 [phi:main::@1->print#1] -- pbuz1=pbuc1 
    lda #<msg1
    sta.z print.msg
    lda #>msg1
    sta.z print.msg+1
    jsr print
    // [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
  __b2_from___b1:
    jmp __b2
    // main::@2
  __b2:
    // [9] call strip 
    // [20] phi from main::@2 to strip [phi:main::@2->strip]
  strip_from___b2:
    // [20] phi (byte) strip::c#3 = (byte) 'y' [phi:main::@2->strip#0] -- vbuxx=vbuc1 
    ldx #'y'
    // [20] phi (byte*) strip::dest#0 = (const byte*) msg2 [phi:main::@2->strip#1] -- pbuz1=pbuc1 
    lda #<msg2
    sta.z strip.dest
    lda #>msg2
    sta.z strip.dest+1
    jsr strip
    // [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
  __b3_from___b2:
    jmp __b3
    // main::@3
  __b3:
    // [11] call print 
    // [13] phi from main::@3 to print [phi:main::@3->print]
  print_from___b3:
    // [13] phi (byte*) screen#15 = (byte*) screen#11 [phi:main::@3->print#0] -- register_copy 
    // [13] phi (byte*) print::msg#4 = (const byte*) msg2 [phi:main::@3->print#1] -- pbuz1=pbuc1 
    lda #<msg2
    sta.z print.msg
    lda #>msg2
    sta.z print.msg+1
    jsr print
    jmp __breturn
    // main::@return
  __breturn:
    // [12] return 
    rts
}
  // print
// print(byte* zp(4) msg)
print: {
    .label msg = 4
    // [14] phi from print print::@1 to print::@1 [phi:print/print::@1->print::@1]
  __b1_from_print:
  __b1_from___b1:
    // [14] phi (byte*) screen#10 = (byte*) screen#15 [phi:print/print::@1->print::@1#0] -- register_copy 
    // [14] phi (byte*) print::msg#3 = (byte*) print::msg#4 [phi:print/print::@1->print::@1#1] -- register_copy 
    jmp __b1
    // print::@1
  __b1:
    // [15] *((byte*) screen#10) ← *((byte*) print::msg#3) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (msg),y
    ldy #0
    sta (screen),y
    // [16] (byte*) screen#11 ← ++ (byte*) screen#10 -- pbuz1=_inc_pbuz1 
    inc.z screen
    bne !+
    inc.z screen+1
  !:
    // [17] (byte*) print::msg#2 ← ++ (byte*) print::msg#3 -- pbuz1=_inc_pbuz1 
    inc.z msg
    bne !+
    inc.z msg+1
  !:
    // [18] if(*((byte*) print::msg#2)!=(byte) 0) goto print::@1 -- _deref_pbuz1_neq_0_then_la1 
    ldy #0
    lda (msg),y
    cmp #0
    bne __b1_from___b1
    jmp __breturn
    // print::@return
  __breturn:
    // [19] return 
    rts
}
  // strip
// strip(byte* zp(8) p, byte register(X) c)
strip: {
    .label dest = 6
    .label p = 8
    .label p_1 = 4
    // [21] (byte*) strip::p#7 ← (byte*) strip::dest#0 -- pbuz1=pbuz2 
    lda.z dest
    sta.z p_1
    lda.z dest+1
    sta.z p_1+1
    // [22] phi from strip strip::@4 to strip::@1 [phi:strip/strip::@4->strip::@1]
  __b1_from_strip:
  __b1_from___b4:
    // [22] phi (byte*) strip::dest#2 = (byte*) strip::dest#0 [phi:strip/strip::@4->strip::@1#0] -- register_copy 
    // [22] phi (byte*) strip::p#4 = (byte*) strip::p#7 [phi:strip/strip::@4->strip::@1#1] -- register_copy 
    jmp __b1
    // strip::@1
  __b1:
    // [23] if(*((byte*) strip::p#4)==(byte) strip::c#3) goto strip::@2 -- _deref_pbuz1_eq_vbuxx_then_la1 
    txa
    ldy #0
    cmp (p_1),y
    beq __b2_from___b1
    jmp __b3
    // strip::@3
  __b3:
    // [24] *((byte*) strip::dest#2) ← *((byte*) strip::p#4) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (p_1),y
    ldy #0
    sta (dest),y
    // [25] (byte*) strip::dest#1 ← ++ (byte*) strip::dest#2 -- pbuz1=_inc_pbuz1 
    inc.z dest
    bne !+
    inc.z dest+1
  !:
    // [26] phi from strip::@1 strip::@3 to strip::@2 [phi:strip::@1/strip::@3->strip::@2]
  __b2_from___b1:
  __b2_from___b3:
    // [26] phi (byte*) strip::dest#4 = (byte*) strip::dest#2 [phi:strip::@1/strip::@3->strip::@2#0] -- register_copy 
    jmp __b2
    // strip::@2
  __b2:
    // [27] (byte*) strip::p#2 ← ++ (byte*) strip::p#4 -- pbuz1=_inc_pbuz2 
    lda.z p_1
    clc
    adc #1
    sta.z p
    lda.z p_1+1
    adc #0
    sta.z p+1
    // [28] if(*((byte*) strip::p#4)!=(byte) 0) goto strip::@4 -- _deref_pbuz1_neq_0_then_la1 
    ldy #0
    lda (p_1),y
    cmp #0
    bne __b4
    jmp __breturn
    // strip::@return
  __breturn:
    // [29] return 
    rts
    // strip::@4
  __b4:
    // [30] (byte*) strip::p#8 ← (byte*) strip::p#2 -- pbuz1=pbuz2 
    lda.z p
    sta.z p_1
    lda.z p+1
    sta.z p_1+1
    jmp __b1_from___b4
}
  // File Data
  msg1: .text "hello world!"
  .byte 0
  msg2: .text "goodbye blue sky!"
  .byte 0

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __b3
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __b3
Removing instruction jmp __b2
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction ldy #0
Removing instruction ldy #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __bbegin with __b1
Replacing label __b1_from___b1 with __b1
Replacing label __b2_from___b1 with __b2
Replacing label __b1_from___b4 with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
Removing instruction main_from___b1:
Removing instruction __bend_from___b1:
Removing instruction __b1_from_main:
Removing instruction print_from___b1:
Removing instruction __b2_from___b1:
Removing instruction strip_from___b2:
Removing instruction __b3_from___b2:
Removing instruction print_from___b3:
Removing instruction __b1_from_print:
Removing instruction __b1_from___b1:
Removing instruction __b1_from_strip:
Removing instruction __b1_from___b4:
Removing instruction __b2_from___b1:
Removing instruction __b2_from___b3:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bend:
Removing instruction strip_from_main:
Removing instruction __b1:
Removing instruction __b2:
Removing instruction __b3:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __b3:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction ldy #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@return
(const byte*) msg1[]  = (byte*) "hello world!"
(const byte*) msg2[]  = (byte*) "goodbye blue sky!"
(void()) print((byte*) print::msg)
(label) print::@1
(label) print::@return
(byte*) print::msg
(byte*) print::msg#2 msg zp[2]:4 16.5
(byte*) print::msg#3 msg zp[2]:4 11.666666666666666
(byte*) print::msg#4 msg zp[2]:4 2.0
(byte*) screen
(byte*) screen#10 screen zp[2]:2 17.5
(byte*) screen#11 screen zp[2]:2 3.0
(byte*) screen#15 screen zp[2]:2 4.0
(void()) strip((byte*) strip::p , (byte) strip::c)
(label) strip::@1
(label) strip::@2
(label) strip::@3
(label) strip::@4
(label) strip::@return
(byte) strip::c
(byte) strip::c#3 reg byte x 1.1
(byte*) strip::dest
(byte*) strip::dest#0 dest zp[2]:6 2.0
(byte*) strip::dest#1 dest zp[2]:6 22.0
(byte*) strip::dest#2 dest zp[2]:6 15.333333333333332
(byte*) strip::dest#4 dest zp[2]:6 8.25
(byte*) strip::p
(byte*) strip::p#2 p zp[2]:8 11.0
(byte*) strip::p#4 p_1 zp[2]:4 9.5
(byte*) strip::p#7 p_1 zp[2]:4 4.0
(byte*) strip::p#8 p_1 zp[2]:4 22.0

zp[2]:2 [ screen#10 screen#15 screen#11 ]
reg byte x [ strip::c#3 ]
zp[2]:4 [ strip::p#4 strip::p#7 strip::p#8 print::msg#3 print::msg#4 print::msg#2 ]
zp[2]:6 [ strip::dest#2 strip::dest#0 strip::dest#4 strip::dest#1 ]
zp[2]:8 [ strip::p#2 ]


FINAL ASSEMBLER
Score: 1423

  // File Comments
// Tests of strip() function from https://news.ycombinator.com/item?id=12080871
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
  // Global Constants & labels
  .label screen = 2
  // @begin
  // [1] phi from @begin to @1 [phi:@begin->@1]
  // @1
  // [2] call main 
  // [4] phi from @1 to main [phi:@1->main]
  // [3] phi from @1 to @end [phi:@1->@end]
  // @end
  // main
main: {
    // strip(msg1, ' ')
    // [5] call strip 
    // [20] phi from main to strip [phi:main->strip]
    // [20] phi (byte) strip::c#3 = (byte) ' ' [phi:main->strip#0] -- vbuxx=vbuc1 
    ldx #' '
    // [20] phi (byte*) strip::dest#0 = (const byte*) msg1 [phi:main->strip#1] -- pbuz1=pbuc1 
    lda #<msg1
    sta.z strip.dest
    lda #>msg1
    sta.z strip.dest+1
    jsr strip
    // [6] phi from main to main::@1 [phi:main->main::@1]
    // main::@1
    // print(msg1)
    // [7] call print 
    // [13] phi from main::@1 to print [phi:main::@1->print]
    // [13] phi (byte*) screen#15 = (byte*) 1024 [phi:main::@1->print#0] -- pbuz1=pbuc1 
    lda #<$400
    sta.z screen
    lda #>$400
    sta.z screen+1
    // [13] phi (byte*) print::msg#4 = (const byte*) msg1 [phi:main::@1->print#1] -- pbuz1=pbuc1 
    lda #<msg1
    sta.z print.msg
    lda #>msg1
    sta.z print.msg+1
    jsr print
    // [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
    // main::@2
    // strip(msg2, 'y')
    // [9] call strip 
    // [20] phi from main::@2 to strip [phi:main::@2->strip]
    // [20] phi (byte) strip::c#3 = (byte) 'y' [phi:main::@2->strip#0] -- vbuxx=vbuc1 
    ldx #'y'
    // [20] phi (byte*) strip::dest#0 = (const byte*) msg2 [phi:main::@2->strip#1] -- pbuz1=pbuc1 
    lda #<msg2
    sta.z strip.dest
    lda #>msg2
    sta.z strip.dest+1
    jsr strip
    // [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
    // main::@3
    // print(msg2)
    // [11] call print 
    // [13] phi from main::@3 to print [phi:main::@3->print]
    // [13] phi (byte*) screen#15 = (byte*) screen#11 [phi:main::@3->print#0] -- register_copy 
    // [13] phi (byte*) print::msg#4 = (const byte*) msg2 [phi:main::@3->print#1] -- pbuz1=pbuc1 
    lda #<msg2
    sta.z print.msg
    lda #>msg2
    sta.z print.msg+1
    jsr print
    // main::@return
    // }
    // [12] return 
    rts
}
  // print
// print(byte* zp(4) msg)
print: {
    .label msg = 4
    // [14] phi from print print::@1 to print::@1 [phi:print/print::@1->print::@1]
    // [14] phi (byte*) screen#10 = (byte*) screen#15 [phi:print/print::@1->print::@1#0] -- register_copy 
    // [14] phi (byte*) print::msg#3 = (byte*) print::msg#4 [phi:print/print::@1->print::@1#1] -- register_copy 
    // print::@1
  __b1:
    // *screen++ = *msg++
    // [15] *((byte*) screen#10) ← *((byte*) print::msg#3) -- _deref_pbuz1=_deref_pbuz2 
    ldy #0
    lda (msg),y
    sta (screen),y
    // *screen++ = *msg++;
    // [16] (byte*) screen#11 ← ++ (byte*) screen#10 -- pbuz1=_inc_pbuz1 
    inc.z screen
    bne !+
    inc.z screen+1
  !:
    // [17] (byte*) print::msg#2 ← ++ (byte*) print::msg#3 -- pbuz1=_inc_pbuz1 
    inc.z msg
    bne !+
    inc.z msg+1
  !:
    // while(*msg!=0)
    // [18] if(*((byte*) print::msg#2)!=(byte) 0) goto print::@1 -- _deref_pbuz1_neq_0_then_la1 
    ldy #0
    lda (msg),y
    cmp #0
    bne __b1
    // print::@return
    // }
    // [19] return 
    rts
}
  // strip
// strip(byte* zp(8) p, byte register(X) c)
strip: {
    .label dest = 6
    .label p = 8
    .label p_1 = 4
    // [21] (byte*) strip::p#7 ← (byte*) strip::dest#0 -- pbuz1=pbuz2 
    lda.z dest
    sta.z p_1
    lda.z dest+1
    sta.z p_1+1
    // [22] phi from strip strip::@4 to strip::@1 [phi:strip/strip::@4->strip::@1]
    // [22] phi (byte*) strip::dest#2 = (byte*) strip::dest#0 [phi:strip/strip::@4->strip::@1#0] -- register_copy 
    // [22] phi (byte*) strip::p#4 = (byte*) strip::p#7 [phi:strip/strip::@4->strip::@1#1] -- register_copy 
    // strip::@1
  __b1:
    // if(*p!=c)
    // [23] if(*((byte*) strip::p#4)==(byte) strip::c#3) goto strip::@2 -- _deref_pbuz1_eq_vbuxx_then_la1 
    txa
    ldy #0
    cmp (p_1),y
    beq __b2
    // strip::@3
    // *dest++=*p
    // [24] *((byte*) strip::dest#2) ← *((byte*) strip::p#4) -- _deref_pbuz1=_deref_pbuz2 
    lda (p_1),y
    sta (dest),y
    // *dest++=*p;
    // [25] (byte*) strip::dest#1 ← ++ (byte*) strip::dest#2 -- pbuz1=_inc_pbuz1 
    inc.z dest
    bne !+
    inc.z dest+1
  !:
    // [26] phi from strip::@1 strip::@3 to strip::@2 [phi:strip::@1/strip::@3->strip::@2]
    // [26] phi (byte*) strip::dest#4 = (byte*) strip::dest#2 [phi:strip::@1/strip::@3->strip::@2#0] -- register_copy 
    // strip::@2
  __b2:
    // while(*p++!=0)
    // [27] (byte*) strip::p#2 ← ++ (byte*) strip::p#4 -- pbuz1=_inc_pbuz2 
    lda.z p_1
    clc
    adc #1
    sta.z p
    lda.z p_1+1
    adc #0
    sta.z p+1
    // [28] if(*((byte*) strip::p#4)!=(byte) 0) goto strip::@4 -- _deref_pbuz1_neq_0_then_la1 
    ldy #0
    lda (p_1),y
    cmp #0
    bne __b4
    // strip::@return
    // }
    // [29] return 
    rts
    // strip::@4
  __b4:
    // [30] (byte*) strip::p#8 ← (byte*) strip::p#2 -- pbuz1=pbuz2 
    lda.z p
    sta.z p_1
    lda.z p+1
    sta.z p_1+1
    jmp __b1
}
  // File Data
  msg1: .text "hello world!"
  .byte 0
  msg2: .text "goodbye blue sky!"
  .byte 0

