Converting variable modified inside __stackcall procedure main() to load/store val
Inlined call call __init
Calling convention __stackcall adding prepare/execute/finalize for call pval
Calling convention __stackcall adding prepare/execute/finalize for call printother
Calling convention __stackcall adding prepare/execute/finalize for call ival
Calling convention __stackcall adding prepare/execute/finalize for call printval
Calling convention __stackcall adding prepare/execute/finalize for call incval
Calling convention __stackcall adding prepare/execute/finalize for call main

CONTROL FLOW GRAPH SSA

__stackcall void main()
main: scope:[main]  from
  main::i#0 = 0
  to:main::@1
main::@1: scope:[main]  from main main::@1
  main::i#2 = phi( main/main::i#0, main::@1/main::i#1 )
  callexecute pval 
  callexecute printother 
  callexecute ival 
  main::i#1 = main::i#2 + rangenext(0,5)
  main::$3 = main::i#1 != rangelast(0,5)
  if(main::$3) goto main::@1
  to:main::@return
main::@return: scope:[main]  from main::@1
  return 
  to:@return

__stackcall void pval()
pval: scope:[pval]  from
  callexecute printval 
  to:pval::@return
pval::@return: scope:[pval]  from pval
  return 
  to:@return

__stackcall void ival()
ival: scope:[ival]  from
  callexecute incval 
  to:ival::@return
ival::@return: scope:[ival]  from ival
  return 
  to:@return

__stackcall void printval()
printval: scope:[printval]  from
  SCREEN[0] = val
  to:printval::@return
printval::@return: scope:[printval]  from printval
  return 
  to:@return

__stackcall void incval()
incval: scope:[incval]  from
  val = ++ val
  to:incval::@return
incval::@return: scope:[incval]  from incval
  return 
  to:@return

__stackcall void printother()
printother: scope:[printother]  from
  printother::i#0 = 0
  to:printother::@1
printother::@1: scope:[printother]  from printother printother::@1
  printother::i#2 = phi( printother/printother::i#0, printother::@1/printother::i#1 )
  (SCREEN+$28)[printother::i#2] = ++ (SCREEN+$28)[printother::i#2]
  printother::i#1 = printother::i#2 + rangenext(0,5)
  printother::$1 = printother::i#1 != rangelast(0,5)
  if(printother::$1) goto printother::@1
  to:printother::@return
printother::@return: scope:[printother]  from printother::@1
  return 
  to:@return

void __start()
__start: scope:[__start]  from
  to:__start::__init1
__start::__init1: scope:[__start]  from __start
  val = 0
  to:__start::@1
__start::@1: scope:[__start]  from __start::__init1
  callexecute main 
  to:__start::@return
__start::@return: scope:[__start]  from __start::@1
  return 
  to:@return

SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
__stackcall void incval()
__stackcall void ival()
__stackcall void main()
bool main::$3
char main::i
char main::i#0
char main::i#1
char main::i#2
__stackcall void printother()
bool printother::$1
char printother::i
char printother::i#0
char printother::i#1
char printother::i#2
__stackcall void printval()
__stackcall void pval()
__loadstore char val

Adding number conversion cast (unumber) 0 in SCREEN[0] = val
Adding number conversion cast (unumber) $28 in (SCREEN+$28)[printother::i#2] = ++ (SCREEN+$28)[printother::i#2]
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast $28
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 0
Finalized unsigned number type (char) $28
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simple Condition main::$3 [7] if(main::i#1!=rangelast(0,5)) goto main::@1
Simple Condition printother::$1 [22] if(printother::i#1!=rangelast(0,5)) goto printother::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant main::i#0 = 0
Constant printother::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value [5] main::i#1 = ++ main::i#2 to ++
Resolved ranged comparison value [7] if(main::i#1!=rangelast(0,5)) goto main::@1 to 6
Resolved ranged next value [20] printother::i#1 = ++ printother::i#2 to ++
Resolved ranged comparison value [22] if(printother::i#1!=rangelast(0,5)) goto printother::@1 to 6
Simplifying expression containing zero SCREEN in [13] SCREEN[0] = val
Successful SSA optimization PassNSimplifyExpressionWithZero
Adding number conversion cast (unumber) 6 in if(main::i#1!=6) goto main::@1
Adding number conversion cast (unumber) 6 in if(printother::i#1!=6) goto printother::@1
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 6
Simplifying constant integer cast 6
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 6
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inlining constant with var siblings main::i#0
Inlining constant with var siblings printother::i#0
Constant inlined main::i#0 = 0
Constant inlined printother::i#0 = 0
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@2(between main::@1 and main::@1)
Added new block during phi lifting printother::@2(between printother::@1 and printother::@1)
Adding NOP phi() at start of __start
Adding NOP phi() at start of __start::@1
Adding NOP phi() at start of printother
Adding NOP phi() at start of ival
Adding NOP phi() at start of pval
Adding NOP phi() at start of main
CALL GRAPH
Calls in [__start] to main:3 
Calls in [ival] to incval:17 
Calls in [pval] to printval:20 
Calls in [main] to pval:24 printother:25 ival:26 

Created 2 initial phi equivalence classes
Coalesced [11] printother::i#3 = printother::i#1
Coalesced [30] main::i#3 = main::i#1
Coalesced down to 2 phi equivalence classes
Culled Empty Block label printother::@2
Culled Empty Block label main::@2
Adding NOP phi() at start of __start
Adding NOP phi() at start of __start::@1
Adding NOP phi() at start of printother
Adding NOP phi() at start of ival
Adding NOP phi() at start of pval
Adding NOP phi() at start of main

FINAL CONTROL FLOW GRAPH

void __start()
__start: scope:[__start]  from
  [0] phi()
  to:__start::__init1
__start::__init1: scope:[__start]  from __start
  [1] val = 0
  to:__start::@1
__start::@1: scope:[__start]  from __start::__init1
  [2] phi()
  [3] callexecute main 
  to:__start::@return
__start::@return: scope:[__start]  from __start::@1
  [4] return 
  to:@return

__stackcall void printother()
printother: scope:[printother]  from
  [5] phi()
  to:printother::@1
printother::@1: scope:[printother]  from printother printother::@1
  [6] printother::i#2 = phi( printother/0, printother::@1/printother::i#1 )
  [7] (SCREEN+$28)[printother::i#2] = ++ (SCREEN+$28)[printother::i#2]
  [8] printother::i#1 = ++ printother::i#2
  [9] if(printother::i#1!=6) goto printother::@1
  to:printother::@return
printother::@return: scope:[printother]  from printother::@1
  [10] return 
  to:@return

__stackcall void incval()
incval: scope:[incval]  from
  [11] val = ++ val
  to:incval::@return
incval::@return: scope:[incval]  from incval
  [12] return 
  to:@return

__stackcall void printval()
printval: scope:[printval]  from
  [13] *SCREEN = val
  to:printval::@return
printval::@return: scope:[printval]  from printval
  [14] return 
  to:@return

__stackcall void ival()
ival: scope:[ival]  from
  [15] phi()
  [16] callexecute incval 
  to:ival::@return
ival::@return: scope:[ival]  from ival
  [17] return 
  to:@return

__stackcall void pval()
pval: scope:[pval]  from
  [18] phi()
  [19] callexecute printval 
  to:pval::@return
pval::@return: scope:[pval]  from pval
  [20] return 
  to:@return

__stackcall void main()
main: scope:[main]  from
  [21] phi()
  to:main::@1
main::@1: scope:[main]  from main main::@1
  [22] main::i#2 = phi( main/0, main::@1/main::i#1 )
  [23] callexecute pval 
  [24] callexecute printother 
  [25] callexecute ival 
  [26] main::i#1 = ++ main::i#2
  [27] if(main::i#1!=6) goto main::@1
  to:main::@return
main::@return: scope:[main]  from main::@1
  [28] return 
  to:@return

null depth in calling loop Loop head: main::@1 tails: main::@1 blocks: main::@1  in scope printother
null depth in calling loop Loop head: main::@1 tails: main::@1 blocks: main::@1  in scope ival
null depth in calling loop Loop head: main::@1 tails: main::@1 blocks: main::@1  in scope pval
null depth in calling loop Loop head: main::@1 tails: main::@1 blocks: main::@1  in scope ival
null depth in calling loop Loop head: main::@1 tails: main::@1 blocks: main::@1  in scope pval

VARIABLE REGISTER WEIGHTS
void __start()
__stackcall void incval()
__stackcall void ival()
__stackcall void main()
char main::i
char main::i#1 // 151.5
char main::i#2 // 50.5
__stackcall void printother()
char printother::i
char printother::i#1 // 15001.5
char printother::i#2 // 20002.0
__stackcall void printval()
__stackcall void pval()
__loadstore char val // 1579.2105263157896

Initial phi equivalence classes
[ printother::i#2 printother::i#1 ]
[ main::i#2 main::i#1 ]
Added variable val to live range equivalence class [ val ]
Complete equivalence classes
[ printother::i#2 printother::i#1 ]
[ main::i#2 main::i#1 ]
[ val ]
Allocated zp[1]:2 [ printother::i#2 printother::i#1 ]
Allocated zp[1]:3 [ val ]
Allocated zp[1]:4 [ main::i#2 main::i#1 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] val = 0 [ val ] (  [ val ] { }  ) always clobbers reg byte a 
Statement [13] *SCREEN = val [ val ] ( main:3::pval:23::printval:19 [ main::i#2 val ] { }  ) always clobbers reg byte a 
Removing always clobbered register reg byte a as potential for zp[1]:4 [ main::i#2 main::i#1 ]
Statement [1] val = 0 [ val ] (  [ val ] { }  ) always clobbers reg byte a 
Statement [13] *SCREEN = val [ val ] ( main:3::pval:23::printval:19 [ main::i#2 val ] { }  ) always clobbers reg byte a 
Potential registers zp[1]:2 [ printother::i#2 printother::i#1 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , 
Potential registers zp[1]:4 [ main::i#2 main::i#1 ] : zp[1]:4 , reg byte x , reg byte y , 
Potential registers zp[1]:3 [ val ] : zp[1]:3 , 

REGISTER UPLIFT SCOPES
Uplift Scope [printother] 35,003.5: zp[1]:2 [ printother::i#2 printother::i#1 ] 
Uplift Scope [] 1,579.21: zp[1]:3 [ val ] 
Uplift Scope [main] 202: zp[1]:4 [ main::i#2 main::i#1 ] 
Uplift Scope [pval] 
Uplift Scope [ival] 
Uplift Scope [printval] 
Uplift Scope [incval] 
Uplift Scope [__start] 

Uplifting [printother] best 815 combination reg byte x [ printother::i#2 printother::i#1 ] 
Uplifting [] best 815 combination zp[1]:3 [ val ] 
Uplifting [main] best 725 combination reg byte y [ main::i#2 main::i#1 ] 
Uplifting [pval] best 725 combination 
Uplifting [ival] best 725 combination 
Uplifting [printval] best 725 combination 
Uplifting [incval] best 725 combination 
Uplifting [__start] best 725 combination 
Attempting to uplift remaining variables inzp[1]:3 [ val ]
Uplifting [] best 725 combination zp[1]:3 [ val ] 
Allocated (was zp[1]:3) zp[1]:2 [ val ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Test a procedure with calling convention stack
// Illustrates live range problem with function variable printother::i and global variable val
  // Upstart
  // Commodore 64 PRG executable file
.file [name="procedure-callingconvention-stack-9.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(__start)
  // Global Constants & labels
  .label SCREEN = $400
  .label val = 2
.segment Code
  // __start
__start: {
    jmp __init1
    // __start::__init1
  __init1:
    // [1] val = 0 -- vbuz1=vbuc1 
    lda #0
    sta.z val
    // [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1]
  __b1_from___init1:
    jmp __b1
    // __start::@1
  __b1:
    // [3] callexecute main  -- call_vprc1 
    jsr main
    jmp __breturn
    // __start::@return
  __breturn:
    // [4] return 
    rts
}
  // printother
printother: {
    // [6] phi from printother to printother::@1 [phi:printother->printother::@1]
  __b1_from_printother:
    // [6] phi printother::i#2 = 0 [phi:printother->printother::@1#0] -- vbuxx=vbuc1 
    ldx #0
    jmp __b1
    // [6] phi from printother::@1 to printother::@1 [phi:printother::@1->printother::@1]
  __b1_from___b1:
    // [6] phi printother::i#2 = printother::i#1 [phi:printother::@1->printother::@1#0] -- register_copy 
    jmp __b1
    // printother::@1
  __b1:
    // [7] (SCREEN+$28)[printother::i#2] = ++ (SCREEN+$28)[printother::i#2] -- pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx 
    inc SCREEN+$28,x
    // [8] printother::i#1 = ++ printother::i#2 -- vbuxx=_inc_vbuxx 
    inx
    // [9] if(printother::i#1!=6) goto printother::@1 -- vbuxx_neq_vbuc1_then_la1 
    cpx #6
    bne __b1_from___b1
    jmp __breturn
    // printother::@return
  __breturn:
    // [10] return 
    rts
}
  // incval
incval: {
    // [11] val = ++ val -- vbuz1=_inc_vbuz1 
    inc.z val
    jmp __breturn
    // incval::@return
  __breturn:
    // [12] return 
    rts
}
  // printval
printval: {
    // [13] *SCREEN = val -- _deref_pbuc1=vbuz1 
    lda.z val
    sta SCREEN
    jmp __breturn
    // printval::@return
  __breturn:
    // [14] return 
    rts
}
  // ival
ival: {
    // [16] callexecute incval  -- call_vprc1 
    jsr incval
    jmp __breturn
    // ival::@return
  __breturn:
    // [17] return 
    rts
}
  // pval
pval: {
    // [19] callexecute printval  -- call_vprc1 
    jsr printval
    jmp __breturn
    // pval::@return
  __breturn:
    // [20] return 
    rts
}
  // main
main: {
    // [22] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    // [22] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuyy=vbuc1 
    ldy #0
    jmp __b1
    // [22] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
  __b1_from___b1:
    // [22] phi main::i#2 = main::i#1 [phi:main::@1->main::@1#0] -- register_copy 
    jmp __b1
    // main::@1
  __b1:
    // [23] callexecute pval  -- call_vprc1 
    jsr pval
    // [24] callexecute printother  -- call_vprc1 
    jsr printother
    // [25] callexecute ival  -- call_vprc1 
    jsr ival
    // [26] main::i#1 = ++ main::i#2 -- vbuyy=_inc_vbuyy 
    iny
    // [27] if(main::i#1!=6) goto main::@1 -- vbuyy_neq_vbuc1_then_la1 
    cpy #6
    bne __b1_from___b1
    jmp __breturn
    // main::@return
  __breturn:
    // [28] return 
    rts
}
  // File Data

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __init1
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __b1_from___b1 with __b1
Replacing label __b1_from___b1 with __b1
Removing instruction __b1_from___init1:
Removing instruction __b1_from___b1:
Removing instruction __b1_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __init1:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __b1_from_printother:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __b1_from_main:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jmp __b1
Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination

FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
void __start()
__stackcall void incval()
__stackcall void ival()
__stackcall void main()
char main::i
char main::i#1 // reg byte y 151.5
char main::i#2 // reg byte y 50.5
__stackcall void printother()
char printother::i
char printother::i#1 // reg byte x 15001.5
char printother::i#2 // reg byte x 20002.0
__stackcall void printval()
__stackcall void pval()
__loadstore char val // zp[1]:2 1579.2105263157896

reg byte x [ printother::i#2 printother::i#1 ]
reg byte y [ main::i#2 main::i#1 ]
zp[1]:2 [ val ]


FINAL ASSEMBLER
Score: 497

  // File Comments
// Test a procedure with calling convention stack
// Illustrates live range problem with function variable printother::i and global variable val
  // Upstart
  // Commodore 64 PRG executable file
.file [name="procedure-callingconvention-stack-9.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(__start)
  // Global Constants & labels
  .label SCREEN = $400
  .label val = 2
.segment Code
  // __start
__start: {
    // __start::__init1
    // char val = 0
    // [1] val = 0 -- vbuz1=vbuc1 
    lda #0
    sta.z val
    // [2] phi from __start::__init1 to __start::@1 [phi:__start::__init1->__start::@1]
    // __start::@1
    // [3] callexecute main  -- call_vprc1 
    jsr main
    // __start::@return
    // [4] return 
    rts
}
  // printother
printother: {
    // [6] phi from printother to printother::@1 [phi:printother->printother::@1]
    // [6] phi printother::i#2 = 0 [phi:printother->printother::@1#0] -- vbuxx=vbuc1 
    ldx #0
    // [6] phi from printother::@1 to printother::@1 [phi:printother::@1->printother::@1]
    // [6] phi printother::i#2 = printother::i#1 [phi:printother::@1->printother::@1#0] -- register_copy 
    // printother::@1
  __b1:
    // (SCREEN+40)[i]++;
    // [7] (SCREEN+$28)[printother::i#2] = ++ (SCREEN+$28)[printother::i#2] -- pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx 
    inc SCREEN+$28,x
    // for(char i:0..5)
    // [8] printother::i#1 = ++ printother::i#2 -- vbuxx=_inc_vbuxx 
    inx
    // [9] if(printother::i#1!=6) goto printother::@1 -- vbuxx_neq_vbuc1_then_la1 
    cpx #6
    bne __b1
    // printother::@return
    // }
    // [10] return 
    rts
}
  // incval
incval: {
    // val++;
    // [11] val = ++ val -- vbuz1=_inc_vbuz1 
    inc.z val
    // incval::@return
    // }
    // [12] return 
    rts
}
  // printval
printval: {
    // SCREEN[0] = val
    // [13] *SCREEN = val -- _deref_pbuc1=vbuz1 
    lda.z val
    sta SCREEN
    // printval::@return
    // }
    // [14] return 
    rts
}
  // ival
ival: {
    // incval()
    // [16] callexecute incval  -- call_vprc1 
    jsr incval
    // ival::@return
    // }
    // [17] return 
    rts
}
  // pval
pval: {
    // printval()
    // [19] callexecute printval  -- call_vprc1 
    jsr printval
    // pval::@return
    // }
    // [20] return 
    rts
}
  // main
main: {
    // [22] phi from main to main::@1 [phi:main->main::@1]
    // [22] phi main::i#2 = 0 [phi:main->main::@1#0] -- vbuyy=vbuc1 
    ldy #0
    // [22] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
    // [22] phi main::i#2 = main::i#1 [phi:main::@1->main::@1#0] -- register_copy 
    // main::@1
  __b1:
    // pval()
    // [23] callexecute pval  -- call_vprc1 
    jsr pval
    // printother()
    // [24] callexecute printother  -- call_vprc1 
    jsr printother
    // ival()
    // [25] callexecute ival  -- call_vprc1 
    jsr ival
    // for(char i:0..5)
    // [26] main::i#1 = ++ main::i#2 -- vbuyy=_inc_vbuyy 
    iny
    // [27] if(main::i#1!=6) goto main::@1 -- vbuyy_neq_vbuc1_then_la1 
    cpy #6
    bne __b1
    // main::@return
    // }
    // [28] return 
    rts
}
  // File Data

