Inlined call call __init

CONTROL FLOW GRAPH SSA

void main()
main: scope:[main]  from __start::@1
  w2#18 = phi( __start::@1/w2#17 )
  w1#16 = phi( __start::@1/w1#18 )
  call incw1
  to:main::@1
main::@1: scope:[main]  from main
  w2#15 = phi( main/w2#18 )
  w1#8 = phi( main/w1#4 )
  w1#0 = w1#8
  call incw2
  to:main::@2
main::@2: scope:[main]  from main::@1
  w1#17 = phi( main::@1/w1#0 )
  w2#8 = phi( main::@1/w2#4 )
  w2#0 = w2#8
  call incw1
  to:main::@3
main::@3: scope:[main]  from main::@2
  w2#16 = phi( main::@2/w2#0 )
  w1#9 = phi( main::@2/w1#4 )
  w1#1 = w1#9
  call incw2
  to:main::@4
main::@4: scope:[main]  from main::@3
  w1#10 = phi( main::@3/w1#1 )
  w2#9 = phi( main::@3/w2#4 )
  w2#1 = w2#9
  main::$4 = 0 * SIZEOF_UNSIGNED_INT
  main::SCREEN[main::$4] = w1#10
  main::$5 = 2 * SIZEOF_UNSIGNED_INT
  main::SCREEN[main::$5] = w2#1
  to:main::@return
main::@return: scope:[main]  from main::@4
  w2#10 = phi( main::@4/w2#1 )
  w1#11 = phi( main::@4/w1#10 )
  w1#2 = w1#11
  w2#2 = w2#10
  return 
  to:@return

void incw1()
incw1: scope:[incw1]  from main main::@2
  w1#12 = phi( main/w1#16, main::@2/w1#17 )
  w1#3 = ++ w1#12
  to:incw1::@return
incw1::@return: scope:[incw1]  from incw1
  w1#13 = phi( incw1/w1#3 )
  w1#4 = w1#13
  return 
  to:@return

void incw2()
incw2: scope:[incw2]  from main::@1 main::@3
  w2#11 = phi( main::@1/w2#15, main::@3/w2#16 )
  w2#3 = ++ w2#11
  to:incw2::@return
incw2::@return: scope:[incw2]  from incw2
  w2#12 = phi( incw2/w2#3 )
  w2#4 = w2#12
  return 
  to:@return

void __start()
__start: scope:[__start]  from
  to:__start::__init1
__start::__init1: scope:[__start]  from __start
  w1#5 = 0
  w2#5 = 0
  to:__start::@1
__start::@1: scope:[__start]  from __start::__init1
  w2#17 = phi( __start::__init1/w2#5 )
  w1#18 = phi( __start::__init1/w1#5 )
  call main
  to:__start::@2
__start::@2: scope:[__start]  from __start::@1
  w2#13 = phi( __start::@1/w2#2 )
  w1#14 = phi( __start::@1/w1#2 )
  w1#6 = w1#14
  w2#6 = w2#13
  to:__start::@return
__start::@return: scope:[__start]  from __start::@2
  w2#14 = phi( __start::@2/w2#6 )
  w1#15 = phi( __start::@2/w1#6 )
  w1#7 = w1#15
  w2#7 = w2#14
  return 
  to:@return

SYMBOL TABLE SSA
__constant char SIZEOF_UNSIGNED_INT = 2
void __start()
void incw1()
void incw2()
void main()
number main::$4
number main::$5
__constant unsigned int *main::SCREEN = (char *)$400
unsigned int w1
unsigned int w1#0
unsigned int w1#1
unsigned int w1#10
unsigned int w1#11
unsigned int w1#12
unsigned int w1#13
unsigned int w1#14
unsigned int w1#15
unsigned int w1#16
unsigned int w1#17
unsigned int w1#18
unsigned int w1#2
unsigned int w1#3
unsigned int w1#4
unsigned int w1#5
unsigned int w1#6
unsigned int w1#7
unsigned int w1#8
unsigned int w1#9
unsigned int w2
unsigned int w2#0
unsigned int w2#1
unsigned int w2#10
unsigned int w2#11
unsigned int w2#12
unsigned int w2#13
unsigned int w2#14
unsigned int w2#15
unsigned int w2#16
unsigned int w2#17
unsigned int w2#18
unsigned int w2#2
unsigned int w2#3
unsigned int w2#4
unsigned int w2#5
unsigned int w2#6
unsigned int w2#7
unsigned int w2#8
unsigned int w2#9

Adding number conversion cast (unumber) 0 in main::$4 = 0 * SIZEOF_UNSIGNED_INT
Adding number conversion cast (unumber) main::$4 in main::$4 = (unumber)0 * SIZEOF_UNSIGNED_INT
Adding number conversion cast (unumber) 2 in main::$5 = 2 * SIZEOF_UNSIGNED_INT
Adding number conversion cast (unumber) main::$5 in main::$5 = (unumber)2 * SIZEOF_UNSIGNED_INT
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 2
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to char in main::$4 = 0 * SIZEOF_UNSIGNED_INT
Inferred type updated to char in main::$5 = 2 * SIZEOF_UNSIGNED_INT
Alias w2#15 = w2#18 
Alias w1#0 = w1#8 w1#17 
Alias w2#0 = w2#8 w2#16 
Alias w1#1 = w1#9 w1#10 w1#11 w1#2 
Alias w2#1 = w2#9 w2#10 w2#2 
Alias w1#13 = w1#3 w1#4 
Alias w2#12 = w2#3 w2#4 
Alias w1#18 = w1#5 
Alias w2#17 = w2#5 
Alias w1#14 = w1#6 w1#15 w1#7 
Alias w2#13 = w2#6 w2#14 w2#7 
Successful SSA optimization Pass2AliasElimination
Identical Phi Values w1#16 w1#18
Identical Phi Values w2#15 w2#17
Identical Phi Values w1#0 w1#13
Identical Phi Values w2#0 w2#12
Identical Phi Values w1#1 w1#13
Identical Phi Values w2#1 w2#12
Identical Phi Values w1#14 w1#1
Identical Phi Values w2#13 w2#1
Successful SSA optimization Pass2IdenticalPhiElimination
Constant right-side identified [9] main::$4 = 0 * SIZEOF_UNSIGNED_INT
Constant right-side identified [11] main::$5 = 2 * SIZEOF_UNSIGNED_INT
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant main::$4 = 0*SIZEOF_UNSIGNED_INT
Constant main::$5 = 2*SIZEOF_UNSIGNED_INT
Constant w1#18 = 0
Constant w2#17 = 0
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero 0*SIZEOF_UNSIGNED_INT in 
Successful SSA optimization PassNSimplifyConstantZero
Simplifying expression containing zero main::SCREEN in [10] main::SCREEN[main::$4] = w1#13
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant main::$4
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::__init1
Removing unused procedure block __start::@1
Removing unused procedure block __start::@2
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Inlining constant with var siblings w1#18
Inlining constant with var siblings w2#17
Constant inlined main::$5 = 2*SIZEOF_UNSIGNED_INT
Constant inlined w2#17 = 0
Constant inlined w1#18 = 0
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(main::SCREEN+2*SIZEOF_UNSIGNED_INT)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
CALL GRAPH
Calls in [main] to incw1:1 incw2:3 incw1:5 incw2:7 

Created 2 initial phi equivalence classes
Coalesced [4] w1#19 = w1#13
Coalesced [6] w2#19 = w2#12
Coalesced down to 2 phi equivalence classes
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

void main()
main: scope:[main]  from
  [0] phi()
  [1] call incw1
  to:main::@1
main::@1: scope:[main]  from main
  [2] phi()
  [3] call incw2
  to:main::@2
main::@2: scope:[main]  from main::@1
  [4] phi()
  [5] call incw1
  to:main::@3
main::@3: scope:[main]  from main::@2
  [6] phi()
  [7] call incw2
  to:main::@4
main::@4: scope:[main]  from main::@3
  [8] *main::SCREEN = w1#13
  [9] *(main::SCREEN+2*SIZEOF_UNSIGNED_INT) = w2#12
  to:main::@return
main::@return: scope:[main]  from main::@4
  [10] return 
  to:@return

void incw1()
incw1: scope:[incw1]  from main main::@2
  [11] w1#12 = phi( main/0, main::@2/w1#13 )
  [12] w1#13 = ++ w1#12
  to:incw1::@return
incw1::@return: scope:[incw1]  from incw1
  [13] return 
  to:@return

void incw2()
incw2: scope:[incw2]  from main::@1 main::@3
  [14] w2#11 = phi( main::@1/0, main::@3/w2#12 )
  [15] w2#12 = ++ w2#11
  to:incw2::@return
incw2::@return: scope:[incw2]  from incw2
  [16] return 
  to:@return


VARIABLE REGISTER WEIGHTS
void incw1()
void incw2()
void main()
unsigned int w1
unsigned int w1#12 // 13.0
unsigned int w1#13 // 1.6666666666666667
unsigned int w2
unsigned int w2#11 // 13.0
unsigned int w2#12 // 1.875

Initial phi equivalence classes
[ w1#12 w1#13 ]
[ w2#11 w2#12 ]
Complete equivalence classes
[ w1#12 w1#13 ]
[ w2#11 w2#12 ]
Allocated zp[2]:2 [ w2#11 w2#12 ]
Allocated zp[2]:4 [ w1#12 w1#13 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [8] *main::SCREEN = w1#13 [ w2#12 ] (  [ w2#12 ] { }  ) always clobbers reg byte a 
Statement [9] *(main::SCREEN+2*SIZEOF_UNSIGNED_INT) = w2#12 [ ] (  [ ] { }  ) always clobbers reg byte a 
Potential registers zp[2]:4 [ w1#12 w1#13 ] : zp[2]:4 , 
Potential registers zp[2]:2 [ w2#11 w2#12 ] : zp[2]:2 , 

REGISTER UPLIFT SCOPES
Uplift Scope [] 14.88: zp[2]:2 [ w2#11 w2#12 ] 14.67: zp[2]:4 [ w1#12 w1#13 ] 
Uplift Scope [main] 
Uplift Scope [incw1] 
Uplift Scope [incw2] 

Uplifting [] best 135 combination zp[2]:2 [ w2#11 w2#12 ] zp[2]:4 [ w1#12 w1#13 ] 
Uplifting [main] best 135 combination 
Uplifting [incw1] best 135 combination 
Uplifting [incw2] best 135 combination 

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Live ranges were not functioning properly, when multiple method calls were chained - each modifying different vars.
// w1 and w2 ended up having the same zero-page register as their live range was not propagated properly
  // Upstart
  // Commodore 64 PRG executable file
.file [name="liverange-call-problem.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(main)
  // Global Constants & labels
  .const SIZEOF_UNSIGNED_INT = 2
  .label w1 = 4
  .label w2 = 2
.segment Code
  // main
main: {
    .label SCREEN = $400
    // [1] call incw1
    // [11] phi from main to incw1 [phi:main->incw1]
  incw1_from_main:
    // [11] phi w1#12 = 0 [phi:main->incw1#0] -- vwuz1=vwuc1 
    lda #<0
    sta.z w1
    lda #>0
    sta.z w1+1
    jsr incw1
    // [2] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    jmp __b1
    // main::@1
  __b1:
    // [3] call incw2
    // [14] phi from main::@1 to incw2 [phi:main::@1->incw2]
  incw2_from___b1:
    // [14] phi w2#11 = 0 [phi:main::@1->incw2#0] -- vwuz1=vwuc1 
    lda #<0
    sta.z w2
    lda #>0
    sta.z w2+1
    jsr incw2
    // [4] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
  __b2_from___b1:
    jmp __b2
    // main::@2
  __b2:
    // [5] call incw1
    // [11] phi from main::@2 to incw1 [phi:main::@2->incw1]
  incw1_from___b2:
    // [11] phi w1#12 = w1#13 [phi:main::@2->incw1#0] -- register_copy 
    jsr incw1
    // [6] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
  __b3_from___b2:
    jmp __b3
    // main::@3
  __b3:
    // [7] call incw2
    // [14] phi from main::@3 to incw2 [phi:main::@3->incw2]
  incw2_from___b3:
    // [14] phi w2#11 = w2#12 [phi:main::@3->incw2#0] -- register_copy 
    jsr incw2
    jmp __b4
    // main::@4
  __b4:
    // [8] *main::SCREEN = w1#13 -- _deref_pwuc1=vwuz1 
    lda.z w1
    sta SCREEN
    lda.z w1+1
    sta SCREEN+1
    // [9] *(main::SCREEN+2*SIZEOF_UNSIGNED_INT) = w2#12 -- _deref_pwuc1=vwuz1 
    lda.z w2
    sta SCREEN+2*SIZEOF_UNSIGNED_INT
    lda.z w2+1
    sta SCREEN+2*SIZEOF_UNSIGNED_INT+1
    jmp __breturn
    // main::@return
  __breturn:
    // [10] return 
    rts
}
  // incw1
incw1: {
    // [12] w1#13 = ++ w1#12 -- vwuz1=_inc_vwuz1 
    inc.z w1
    bne !+
    inc.z w1+1
  !:
    jmp __breturn
    // incw1::@return
  __breturn:
    // [13] return 
    rts
}
  // incw2
incw2: {
    // [15] w2#12 = ++ w2#11 -- vwuz1=_inc_vwuz1 
    inc.z w2
    bne !+
    inc.z w2+1
  !:
    jmp __breturn
    // incw2::@return
  __breturn:
    // [16] return 
    rts
}
  // File Data

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __b3
Removing instruction jmp __b4
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #>0
Removing instruction lda #>0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __b1_from_main:
Removing instruction incw2_from___b1:
Removing instruction __b2_from___b1:
Removing instruction incw1_from___b2:
Removing instruction __b3_from___b2:
Removing instruction incw2_from___b3:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction incw1_from_main:
Removing instruction __b1:
Removing instruction __b2:
Removing instruction __b3:
Removing instruction __b4:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
__constant char SIZEOF_UNSIGNED_INT = 2
void incw1()
void incw2()
void main()
__constant unsigned int *main::SCREEN = (char *) 1024
unsigned int w1
unsigned int w1#12 // w1 zp[2]:4 13.0
unsigned int w1#13 // w1 zp[2]:4 1.6666666666666667
unsigned int w2
unsigned int w2#11 // w2 zp[2]:2 13.0
unsigned int w2#12 // w2 zp[2]:2 1.875

zp[2]:4 [ w1#12 w1#13 ]
zp[2]:2 [ w2#11 w2#12 ]


FINAL ASSEMBLER
Score: 110

  // File Comments
// Live ranges were not functioning properly, when multiple method calls were chained - each modifying different vars.
// w1 and w2 ended up having the same zero-page register as their live range was not propagated properly
  // Upstart
  // Commodore 64 PRG executable file
.file [name="liverange-call-problem.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(main)
  // Global Constants & labels
  .const SIZEOF_UNSIGNED_INT = 2
  .label w1 = 4
  .label w2 = 2
.segment Code
  // main
main: {
    .label SCREEN = $400
    // incw1()
    // [1] call incw1
    // [11] phi from main to incw1 [phi:main->incw1]
    // [11] phi w1#12 = 0 [phi:main->incw1#0] -- vwuz1=vwuc1 
    lda #<0
    sta.z w1
    sta.z w1+1
    jsr incw1
    // [2] phi from main to main::@1 [phi:main->main::@1]
    // main::@1
    // incw2()
    // [3] call incw2
    // [14] phi from main::@1 to incw2 [phi:main::@1->incw2]
    // [14] phi w2#11 = 0 [phi:main::@1->incw2#0] -- vwuz1=vwuc1 
    lda #<0
    sta.z w2
    sta.z w2+1
    jsr incw2
    // [4] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
    // main::@2
    // incw1()
    // [5] call incw1
    // [11] phi from main::@2 to incw1 [phi:main::@2->incw1]
    // [11] phi w1#12 = w1#13 [phi:main::@2->incw1#0] -- register_copy 
    jsr incw1
    // [6] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
    // main::@3
    // incw2()
    // [7] call incw2
    // [14] phi from main::@3 to incw2 [phi:main::@3->incw2]
    // [14] phi w2#11 = w2#12 [phi:main::@3->incw2#0] -- register_copy 
    jsr incw2
    // main::@4
    // SCREEN[0] = w1
    // [8] *main::SCREEN = w1#13 -- _deref_pwuc1=vwuz1 
    lda.z w1
    sta SCREEN
    lda.z w1+1
    sta SCREEN+1
    // SCREEN[2] = w2
    // [9] *(main::SCREEN+2*SIZEOF_UNSIGNED_INT) = w2#12 -- _deref_pwuc1=vwuz1 
    lda.z w2
    sta SCREEN+2*SIZEOF_UNSIGNED_INT
    lda.z w2+1
    sta SCREEN+2*SIZEOF_UNSIGNED_INT+1
    // main::@return
    // }
    // [10] return 
    rts
}
  // incw1
incw1: {
    // w1++;
    // [12] w1#13 = ++ w1#12 -- vwuz1=_inc_vwuz1 
    inc.z w1
    bne !+
    inc.z w1+1
  !:
    // incw1::@return
    // }
    // [13] return 
    rts
}
  // incw2
incw2: {
    // w2++;
    // [15] w2#12 = ++ w2#11 -- vwuz1=_inc_vwuz1 
    inc.z w2
    bne !+
    inc.z w2+1
  !:
    // incw2::@return
    // }
    // [16] return 
    rts
}
  // File Data

