Adding parameter assignment in __stackcall procedure plus::b = param(plus::b)
Adding parameter assignment in __stackcall procedure plus::a = param(plus::a)
Calling convention __stackcall adding prepare/execute/finalize for main::$0 = call plus($1234, $2345)
Calling convention STACK_CALL replacing param(plus::a) with stackidx(unsigned int,plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param(plus::b) with stackidx(unsigned int,plus::OFFSET_STACK_B)
Calling convention STACK_CALL adding stack return stackidx(unsigned int,plus::OFFSET_STACK_RETURN_2) = plus::return
Calling convention STACK_CALL adding stack pull main::$0 = stackpull(unsigned int)
Calling convention STACK_CALL adding stack push stackpush(unsigned int) = $1234
Calling convention STACK_CALL adding stack push stackpush(unsigned int) = $2345

CONTROL FLOW GRAPH SSA

void main()
main: scope:[main]  from __start
  stackpush(unsigned int) = $1234
  stackpush(unsigned int) = $2345
  callexecute plus 
  sideeffect stackpullbytes(2)
  main::$0 = stackpull(unsigned int)
  main::$1 = 0 * SIZEOF_UNSIGNED_INT
  SCREEN[main::$1] = main::$0
  to:main::@return
main::@return: scope:[main]  from main
  return 
  to:@return

__stackcall unsigned int plus(unsigned int a , unsigned int b)
plus: scope:[plus]  from
  plus::a#0 = stackidx(unsigned int,plus::OFFSET_STACK_A)
  plus::b#0 = stackidx(unsigned int,plus::OFFSET_STACK_B)
  plus::$0 = plus::a#0 + plus::b#0
  plus::return#0 = plus::$0
  to:plus::@return
plus::@return: scope:[plus]  from plus
  plus::return#1 = phi( plus/plus::return#0 )
  stackidx(unsigned int,plus::OFFSET_STACK_RETURN_2) = plus::return#1
  return 
  to:@return

void __start()
__start: scope:[__start]  from
  call main
  to:__start::@1
__start::@1: scope:[__start]  from __start
  to:__start::@return
__start::@return: scope:[__start]  from __start::@1
  return 
  to:@return

SYMBOL TABLE SSA
__constant unsigned int * const SCREEN = (char *)$400
__constant char SIZEOF_UNSIGNED_INT = 2
__constant unsigned int STACK_BASE = $103
void __start()
void main()
unsigned int main::$0
number main::$1
__stackcall unsigned int plus(unsigned int a , unsigned int b)
unsigned int plus::$0
__constant char plus::OFFSET_STACK_A = 2
__constant char plus::OFFSET_STACK_B = 0
__constant char plus::OFFSET_STACK_RETURN_2 = 2
unsigned int plus::a
unsigned int plus::a#0
unsigned int plus::b
unsigned int plus::b#0
unsigned int plus::return
unsigned int plus::return#0
unsigned int plus::return#1

Adding number conversion cast (unumber) $1234 in stackpush(unsigned int) = $1234
Adding number conversion cast (unumber) $2345 in stackpush(unsigned int) = $2345
Adding number conversion cast (unumber) 0 in main::$1 = 0 * SIZEOF_UNSIGNED_INT
Adding number conversion cast (unumber) main::$1 in main::$1 = (unumber)0 * SIZEOF_UNSIGNED_INT
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast stackpush(unsigned int) = (unumber)$1234
Inlining cast stackpush(unsigned int) = (unumber)$2345
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast $1234
Simplifying constant integer cast $2345
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (unsigned int) $1234
Finalized unsigned number type (unsigned int) $2345
Finalized unsigned number type (char) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to char in main::$1 = 0 * SIZEOF_UNSIGNED_INT
Alias plus::return#0 = plus::$0 plus::return#1 
Successful SSA optimization Pass2AliasElimination
Constant right-side identified [5] main::$1 = 0 * SIZEOF_UNSIGNED_INT
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant main::$1 = 0*SIZEOF_UNSIGNED_INT
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero 0*SIZEOF_UNSIGNED_INT in 
Successful SSA optimization PassNSimplifyConstantZero
Simplifying expression containing zero SCREEN in [6] SCREEN[main::$1] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant main::$1
Eliminating unused constant SIZEOF_UNSIGNED_INT
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::@1
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Finalized unsigned number type (char) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
CALL GRAPH
Calls in [main] to plus:7 

Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes

FINAL CONTROL FLOW GRAPH

__stackcall unsigned int plus(unsigned int a , unsigned int b)
plus: scope:[plus]  from
  [0] plus::a#0 = stackidx(unsigned int,plus::OFFSET_STACK_A)
  [1] plus::b#0 = stackidx(unsigned int,plus::OFFSET_STACK_B)
  [2] plus::return#0 = plus::a#0 + plus::b#0
  to:plus::@return
plus::@return: scope:[plus]  from plus
  [3] stackidx(unsigned int,plus::OFFSET_STACK_RETURN_2) = plus::return#0
  [4] return 
  to:@return

void main()
main: scope:[main]  from
  [5] stackpush(unsigned int) = $1234
  [6] stackpush(unsigned int) = $2345
  [7] callexecute plus 
  sideeffect stackpullbytes(2)
  [9] main::$0 = stackpull(unsigned int)
  [10] *SCREEN = main::$0
  to:main::@return
main::@return: scope:[main]  from main
  [11] return 
  to:@return


VARIABLE REGISTER WEIGHTS
void main()
unsigned int main::$0 // 4.0
__stackcall unsigned int plus(unsigned int a , unsigned int b)
unsigned int plus::a
unsigned int plus::a#0 // 11.0
unsigned int plus::b
unsigned int plus::b#0 // 22.0
unsigned int plus::return
unsigned int plus::return#0 // 22.0

Initial phi equivalence classes
Added variable plus::a#0 to live range equivalence class [ plus::a#0 ]
Added variable plus::b#0 to live range equivalence class [ plus::b#0 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Complete equivalence classes
[ plus::a#0 ]
[ plus::b#0 ]
[ plus::return#0 ]
[ main::$0 ]
Allocated zp[2]:2 [ plus::b#0 ]
Allocated zp[2]:4 [ plus::return#0 ]
Allocated zp[2]:6 [ plus::a#0 ]
Allocated zp[2]:8 [ main::$0 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] plus::a#0 = stackidx(unsigned int,plus::OFFSET_STACK_A) [ plus::a#0 ] ( plus:7 [ plus::a#0 ] { }  ) always clobbers reg byte a reg byte x 
Statement [1] plus::b#0 = stackidx(unsigned int,plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( plus:7 [ plus::a#0 plus::b#0 ] { }  ) always clobbers reg byte a reg byte x 
Statement [2] plus::return#0 = plus::a#0 + plus::b#0 [ plus::return#0 ] ( plus:7 [ plus::return#0 ] { }  ) always clobbers reg byte a 
Statement [3] stackidx(unsigned int,plus::OFFSET_STACK_RETURN_2) = plus::return#0 [ ] ( plus:7 [ ] { }  ) always clobbers reg byte a reg byte x 
Statement [5] stackpush(unsigned int) = $1234 [ ] (  [ ] { }  ) always clobbers reg byte a 
Statement [6] stackpush(unsigned int) = $2345 [ ] (  [ ] { }  ) always clobbers reg byte a 
Statement sideeffect stackpullbytes(2) always clobbers reg byte a 
Statement [9] main::$0 = stackpull(unsigned int) [ main::$0 ] (  [ main::$0 ] { }  ) always clobbers reg byte a 
Statement [10] *SCREEN = main::$0 [ ] (  [ ] { }  ) always clobbers reg byte a 
Potential registers zp[2]:6 [ plus::a#0 ] : zp[2]:6 , 
Potential registers zp[2]:2 [ plus::b#0 ] : zp[2]:2 , 
Potential registers zp[2]:4 [ plus::return#0 ] : zp[2]:4 , 
Potential registers zp[2]:8 [ main::$0 ] : zp[2]:8 , 

REGISTER UPLIFT SCOPES
Uplift Scope [plus] 22: zp[2]:2 [ plus::b#0 ] 22: zp[2]:4 [ plus::return#0 ] 11: zp[2]:6 [ plus::a#0 ] 
Uplift Scope [main] 4: zp[2]:8 [ main::$0 ] 
Uplift Scope [] 

Uplifting [plus] best 152 combination zp[2]:2 [ plus::b#0 ] zp[2]:4 [ plus::return#0 ] zp[2]:6 [ plus::a#0 ] 
Uplifting [main] best 152 combination zp[2]:8 [ main::$0 ] 
Uplifting [] best 152 combination 
Coalescing zero page register [ zp[2]:6 [ plus::a#0 ] ] with [ zp[2]:4 [ plus::return#0 ] ] - score: 1
Coalescing zero page register [ zp[2]:8 [ main::$0 ] ] with [ zp[2]:6 [ plus::a#0 plus::return#0 ] ]
Allocated (was zp[2]:8) zp[2]:2 [ main::$0 plus::a#0 plus::return#0 ]
Allocated (was zp[2]:2) zp[2]:4 [ plus::b#0 ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Test a procedure with calling convention stack - and enough parameters to use fast ASM for cleaning stack
  // Upstart
  // Commodore 64 PRG executable file
.file [name="procedure-callingconvention-stack-2.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 STACK_BASE = $103
  .label SCREEN = $400
.segment Code
  // plus
// __zp(2) unsigned int plus(__zp(2) unsigned int a, __zp(4) unsigned int b)
plus: {
    .const OFFSET_STACK_A = 2
    .const OFFSET_STACK_B = 0
    .const OFFSET_STACK_RETURN_2 = 2
    .label a = 2
    .label b = 4
    .label return = 2
    // [0] plus::a#0 = stackidx(unsigned int,plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 
    tsx
    lda STACK_BASE+OFFSET_STACK_A,x
    sta.z a
    lda STACK_BASE+OFFSET_STACK_A+1,x
    sta.z a+1
    // [1] plus::b#0 = stackidx(unsigned int,plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 
    tsx
    lda STACK_BASE+OFFSET_STACK_B,x
    sta.z b
    lda STACK_BASE+OFFSET_STACK_B+1,x
    sta.z b+1
    // [2] plus::return#0 = plus::a#0 + plus::b#0 -- vwuz1=vwuz1_plus_vwuz2 
    clc
    lda.z return
    adc.z b
    sta.z return
    lda.z return+1
    adc.z b+1
    sta.z return+1
    jmp __breturn
    // plus::@return
  __breturn:
    // [3] stackidx(unsigned int,plus::OFFSET_STACK_RETURN_2) = plus::return#0 -- _stackidxword_vbuc1=vwuz1 
    tsx
    lda.z return
    sta STACK_BASE+OFFSET_STACK_RETURN_2,x
    lda.z return+1
    sta STACK_BASE+OFFSET_STACK_RETURN_2+1,x
    // [4] return 
    rts
}
  // main
main: {
    .label __0 = 2
    // [5] stackpush(unsigned int) = $1234 -- _stackpushword_=vwuc1 
    lda #>$1234
    pha
    lda #<$1234
    pha
    // [6] stackpush(unsigned int) = $2345 -- _stackpushword_=vwuc1 
    lda #>$2345
    pha
    lda #<$2345
    pha
    // [7] callexecute plus  -- call_vprc1 
    jsr plus
    // sideeffect stackpullbytes(2) -- _stackpullbyte_2 
    pla
    pla
    // [9] main::$0 = stackpull(unsigned int) -- vwuz1=_stackpullword_ 
    pla
    sta.z __0
    pla
    sta.z __0+1
    // [10] *SCREEN = main::$0 -- _deref_pwuc1=vwuz1 
    lda.z __0
    sta SCREEN
    lda.z __0+1
    sta SCREEN+1
    jmp __breturn
    // main::@return
  __breturn:
    // [11] return 
    rts
}
  // File Data

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
__constant unsigned int * const SCREEN = (char *) 1024
__constant unsigned int STACK_BASE = $103
void main()
unsigned int main::$0 // zp[2]:2 4.0
__stackcall unsigned int plus(unsigned int a , unsigned int b)
__constant char plus::OFFSET_STACK_A = 2
__constant char plus::OFFSET_STACK_B = 0
__constant char plus::OFFSET_STACK_RETURN_2 = 2
unsigned int plus::a
unsigned int plus::a#0 // a zp[2]:2 11.0
unsigned int plus::b
unsigned int plus::b#0 // b zp[2]:4 22.0
unsigned int plus::return
unsigned int plus::return#0 // return zp[2]:2 22.0

zp[2]:4 [ plus::b#0 ]
zp[2]:2 [ main::$0 plus::a#0 plus::return#0 ]


FINAL ASSEMBLER
Score: 146

  // File Comments
// Test a procedure with calling convention stack - and enough parameters to use fast ASM for cleaning stack
  // Upstart
  // Commodore 64 PRG executable file
.file [name="procedure-callingconvention-stack-2.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 STACK_BASE = $103
  .label SCREEN = $400
.segment Code
  // plus
// __zp(2) unsigned int plus(__zp(2) unsigned int a, __zp(4) unsigned int b)
plus: {
    .const OFFSET_STACK_A = 2
    .const OFFSET_STACK_B = 0
    .const OFFSET_STACK_RETURN_2 = 2
    .label a = 2
    .label b = 4
    .label return = 2
    // [0] plus::a#0 = stackidx(unsigned int,plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1 
    tsx
    lda STACK_BASE+OFFSET_STACK_A,x
    sta.z a
    lda STACK_BASE+OFFSET_STACK_A+1,x
    sta.z a+1
    // [1] plus::b#0 = stackidx(unsigned int,plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1 
    tsx
    lda STACK_BASE+OFFSET_STACK_B,x
    sta.z b
    lda STACK_BASE+OFFSET_STACK_B+1,x
    sta.z b+1
    // return a+b;
    // [2] plus::return#0 = plus::a#0 + plus::b#0 -- vwuz1=vwuz1_plus_vwuz2 
    clc
    lda.z return
    adc.z b
    sta.z return
    lda.z return+1
    adc.z b+1
    sta.z return+1
    // plus::@return
    // }
    // [3] stackidx(unsigned int,plus::OFFSET_STACK_RETURN_2) = plus::return#0 -- _stackidxword_vbuc1=vwuz1 
    tsx
    lda.z return
    sta STACK_BASE+OFFSET_STACK_RETURN_2,x
    lda.z return+1
    sta STACK_BASE+OFFSET_STACK_RETURN_2+1,x
    // [4] return 
    rts
}
  // main
main: {
    .label __0 = 2
    // plus(0x1234, 0x2345)
    // [5] stackpush(unsigned int) = $1234 -- _stackpushword_=vwuc1 
    lda #>$1234
    pha
    lda #<$1234
    pha
    // [6] stackpush(unsigned int) = $2345 -- _stackpushword_=vwuc1 
    lda #>$2345
    pha
    lda #<$2345
    pha
    // [7] callexecute plus  -- call_vprc1 
    jsr plus
    // sideeffect stackpullbytes(2) -- _stackpullbyte_2 
    pla
    pla
    // [9] main::$0 = stackpull(unsigned int) -- vwuz1=_stackpullword_ 
    pla
    sta.z __0
    pla
    sta.z __0+1
    // SCREEN[0] = plus(0x1234, 0x2345)
    // [10] *SCREEN = main::$0 -- _deref_pwuc1=vwuz1 
    lda.z __0
    sta SCREEN
    lda.z __0+1
    sta SCREEN+1
    // main::@return
    // }
    // [11] return 
    rts
}
  // File Data

