Inlined call vicSelectGfxBank::$0 = call toDd00(vicSelectGfxBank::gfx)

CONTROL FLOW GRAPH SSA

void main()
main: scope:[main]  from __start
  main::xpos#0 = $c8
  main::s#0 = 0
  to:main::@1
main::@1: scope:[main]  from main main::@2
  main::xpos#2 = phi( main/main::xpos#0, main::@2/main::xpos#1 )
  main::s#2 = phi( main/main::s#0, main::@2/main::s#1 )
  position_sprite::spriteno#0 = main::s#2
  position_sprite::x#0 = main::xpos#2
  position_sprite::y#0 = $32
  call position_sprite
  to:main::@2
main::@2: scope:[main]  from main::@1
  main::s#3 = phi( main::@1/main::s#2 )
  main::xpos#3 = phi( main::@1/main::xpos#2 )
  main::xpos#1 = main::xpos#3 + $a
  main::s#1 = main::s#3 + rangenext(0,7)
  main::$1 = main::s#1 != rangelast(0,7)
  if(main::$1) goto main::@1
  to:main::@return
main::@return: scope:[main]  from main::@2
  return 
  to:@return

void position_sprite(char spriteno , unsigned int x , char y)
position_sprite: scope:[position_sprite]  from main::@1
  position_sprite::x#1 = phi( main::@1/position_sprite::x#0 )
  position_sprite::y#1 = phi( main::@1/position_sprite::y#0 )
  position_sprite::spriteno#1 = phi( main::@1/position_sprite::spriteno#0 )
  position_sprite::$0 = position_sprite::spriteno#1 * 2
  SPRITES_YPOS[position_sprite::$0] = position_sprite::y#1
  position_sprite::$1 = position_sprite::spriteno#1 * 2
  position_sprite::$2 = byte0  position_sprite::x#1
  SPRITES_XPOS[position_sprite::$1] = position_sprite::$2
  position_sprite::$3 = position_sprite::x#1 > $ff
  if(position_sprite::$3) goto position_sprite::@1
  to:position_sprite::@2
position_sprite::@1: scope:[position_sprite]  from position_sprite
  position_sprite::spriteno#2 = phi( position_sprite/position_sprite::spriteno#1 )
  position_sprite::$6 = 1 << position_sprite::spriteno#2
  *SPRITES_XMSB = *SPRITES_XMSB | position_sprite::$6
  to:position_sprite::@return
position_sprite::@2: scope:[position_sprite]  from position_sprite
  position_sprite::spriteno#3 = phi( position_sprite/position_sprite::spriteno#1 )
  position_sprite::$4 = 1 << position_sprite::spriteno#3
  position_sprite::$5 = position_sprite::$4 ^ $ff
  *SPRITES_XMSB = *SPRITES_XMSB & position_sprite::$5
  to:position_sprite::@return
position_sprite::@return: scope:[position_sprite]  from position_sprite::@1 position_sprite::@2
  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 char * const SPRITES_XMSB = (char *)$d010
__constant char * const SPRITES_XPOS = (char *)$d000
__constant char * const SPRITES_YPOS = (char *)$d001
void __start()
void main()
bool main::$1
char main::s
char main::s#0
char main::s#1
char main::s#2
char main::s#3
unsigned int main::xpos
unsigned int main::xpos#0
unsigned int main::xpos#1
unsigned int main::xpos#2
unsigned int main::xpos#3
void position_sprite(char spriteno , unsigned int x , char y)
number position_sprite::$0
number position_sprite::$1
char position_sprite::$2
bool position_sprite::$3
number position_sprite::$4
number position_sprite::$5
number position_sprite::$6
char position_sprite::spriteno
char position_sprite::spriteno#0
char position_sprite::spriteno#1
char position_sprite::spriteno#2
char position_sprite::spriteno#3
unsigned int position_sprite::x
unsigned int position_sprite::x#0
unsigned int position_sprite::x#1
char position_sprite::y
char position_sprite::y#0
char position_sprite::y#1

Adding number conversion cast (unumber) $32 in position_sprite::y#0 = $32
Adding number conversion cast (unumber) $a in main::xpos#1 = main::xpos#3 + $a
Adding number conversion cast (unumber) 2 in position_sprite::$0 = position_sprite::spriteno#1 * 2
Adding number conversion cast (unumber) position_sprite::$0 in position_sprite::$0 = position_sprite::spriteno#1 * (unumber)2
Adding number conversion cast (unumber) 2 in position_sprite::$1 = position_sprite::spriteno#1 * 2
Adding number conversion cast (unumber) position_sprite::$1 in position_sprite::$1 = position_sprite::spriteno#1 * (unumber)2
Adding number conversion cast (unumber) $ff in position_sprite::$3 = position_sprite::x#1 > $ff
Adding number conversion cast (unumber) 1 in position_sprite::$6 = 1 << position_sprite::spriteno#2
Adding number conversion cast (unumber) position_sprite::$6 in position_sprite::$6 = (unumber)1 << position_sprite::spriteno#2
Adding number conversion cast (unumber) 1 in position_sprite::$4 = 1 << position_sprite::spriteno#3
Adding number conversion cast (unumber) position_sprite::$4 in position_sprite::$4 = (unumber)1 << position_sprite::spriteno#3
Adding number conversion cast (unumber) $ff in position_sprite::$5 = position_sprite::$4 ^ $ff
Adding number conversion cast (unumber) position_sprite::$5 in position_sprite::$5 = position_sprite::$4 ^ (unumber)$ff
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast position_sprite::y#0 = (unumber)$32
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 53248
Simplifying constant pointer cast (char *) 53249
Simplifying constant pointer cast (char *) 53264
Simplifying constant integer cast $32
Simplifying constant integer cast $a
Simplifying constant integer cast 2
Simplifying constant integer cast 2
Simplifying constant integer cast $ff
Simplifying constant integer cast 1
Simplifying constant integer cast 1
Simplifying constant integer cast $ff
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) $32
Finalized unsigned number type (char) $a
Finalized unsigned number type (char) 2
Finalized unsigned number type (char) 2
Finalized unsigned number type (char) $ff
Finalized unsigned number type (char) 1
Finalized unsigned number type (char) 1
Finalized unsigned number type (char) $ff
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to char in position_sprite::$0 = position_sprite::spriteno#1 * 2
Inferred type updated to char in position_sprite::$1 = position_sprite::spriteno#1 * 2
Inferred type updated to char in position_sprite::$6 = 1 << position_sprite::spriteno#2
Inferred type updated to char in position_sprite::$4 = 1 << position_sprite::spriteno#3
Inferred type updated to char in position_sprite::$5 = position_sprite::$4 ^ $ff
Alias main::xpos#2 = main::xpos#3 
Alias main::s#2 = main::s#3 
Alias position_sprite::spriteno#1 = position_sprite::spriteno#2 position_sprite::spriteno#3 
Successful SSA optimization Pass2AliasElimination
Identical Phi Values position_sprite::spriteno#1 position_sprite::spriteno#0
Identical Phi Values position_sprite::y#1 position_sprite::y#0
Identical Phi Values position_sprite::x#1 position_sprite::x#0
Successful SSA optimization Pass2IdenticalPhiElimination
Identified duplicate assignment right side [16] position_sprite::$1 = position_sprite::spriteno#0 * 2
Successful SSA optimization Pass2DuplicateRValueIdentification
Simple Condition main::$1 [10] if(main::s#1!=rangelast(0,7)) goto main::@1
Simple Condition position_sprite::$3 [19] if(position_sprite::x#0>$ff) goto position_sprite::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant main::xpos#0 = $c8
Constant main::s#0 = 0
Constant position_sprite::y#0 = $32
Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value [8] main::s#1 = ++ main::s#2 to ++
Resolved ranged comparison value [10] if(main::s#1!=rangelast(0,7)) goto main::@1 to 8
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
Adding number conversion cast (unumber) 8 in [6] if(main::s#1!=8) goto main::@1
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 8
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 8
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias position_sprite::$1 = position_sprite::$0 
Successful SSA optimization Pass2AliasElimination
Rewriting multiplication to use shift [8] position_sprite::$1 = position_sprite::spriteno#0 * 2
Successful SSA optimization Pass2MultiplyToShiftRewriting
Inlining constant with var siblings main::xpos#0
Inlining constant with var siblings main::s#0
Constant inlined main::xpos#0 = $c8
Constant inlined main::s#0 = 0
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@3(between main::@2 and main::@1)
Adding NOP phi() at start of main
CALL GRAPH
Calls in [main] to position_sprite:4 

Created 2 initial phi equivalence classes
Coalesced [9] main::s#4 = main::s#1
Coalesced [10] main::xpos#4 = main::xpos#1
Coalesced down to 2 phi equivalence classes
Culled Empty Block label main::@3
Adding NOP phi() at start of main

FINAL CONTROL FLOW GRAPH

void main()
main: scope:[main]  from
  [0] phi()
  to:main::@1
main::@1: scope:[main]  from main main::@2
  [1] main::xpos#2 = phi( main/$c8, main::@2/main::xpos#1 )
  [1] main::s#2 = phi( main/0, main::@2/main::s#1 )
  [2] position_sprite::spriteno#0 = main::s#2
  [3] position_sprite::x#0 = main::xpos#2
  [4] call position_sprite
  to:main::@2
main::@2: scope:[main]  from main::@1
  [5] main::xpos#1 = main::xpos#2 + $a
  [6] main::s#1 = ++ main::s#2
  [7] if(main::s#1!=8) goto main::@1
  to:main::@return
main::@return: scope:[main]  from main::@2
  [8] return 
  to:@return

void position_sprite(char spriteno , unsigned int x , char y)
position_sprite: scope:[position_sprite]  from main::@1
  [9] position_sprite::$1 = position_sprite::spriteno#0 << 1
  [10] SPRITES_YPOS[position_sprite::$1] = position_sprite::y#0
  [11] position_sprite::$2 = byte0  position_sprite::x#0
  [12] SPRITES_XPOS[position_sprite::$1] = position_sprite::$2
  [13] if(position_sprite::x#0>$ff) goto position_sprite::@1
  to:position_sprite::@2
position_sprite::@2: scope:[position_sprite]  from position_sprite
  [14] position_sprite::$4 = 1 << position_sprite::spriteno#0
  [15] position_sprite::$5 = position_sprite::$4 ^ $ff
  [16] *SPRITES_XMSB = *SPRITES_XMSB & position_sprite::$5
  to:position_sprite::@return
position_sprite::@return: scope:[position_sprite]  from position_sprite::@1 position_sprite::@2
  [17] return 
  to:@return
position_sprite::@1: scope:[position_sprite]  from position_sprite
  [18] position_sprite::$6 = 1 << position_sprite::spriteno#0
  [19] *SPRITES_XMSB = *SPRITES_XMSB | position_sprite::$6
  to:position_sprite::@return


VARIABLE REGISTER WEIGHTS
void main()
char main::s
char main::s#1 // 16.5
char main::s#2 // 6.6000000000000005
unsigned int main::xpos
unsigned int main::xpos#1 // 7.333333333333333
unsigned int main::xpos#2 // 8.25
void position_sprite(char spriteno , unsigned int x , char y)
char position_sprite::$1 // 101.0
char position_sprite::$2 // 202.0
char position_sprite::$4 // 202.0
char position_sprite::$5 // 202.0
char position_sprite::$6 // 202.0
char position_sprite::spriteno
char position_sprite::spriteno#0 // 44.85714285714286
unsigned int position_sprite::x
unsigned int position_sprite::x#0 // 42.599999999999994
char position_sprite::y

Initial phi equivalence classes
[ main::s#2 main::s#1 ]
[ main::xpos#2 main::xpos#1 ]
Added variable position_sprite::spriteno#0 to live range equivalence class [ position_sprite::spriteno#0 ]
Added variable position_sprite::x#0 to live range equivalence class [ position_sprite::x#0 ]
Added variable position_sprite::$1 to live range equivalence class [ position_sprite::$1 ]
Added variable position_sprite::$2 to live range equivalence class [ position_sprite::$2 ]
Added variable position_sprite::$4 to live range equivalence class [ position_sprite::$4 ]
Added variable position_sprite::$5 to live range equivalence class [ position_sprite::$5 ]
Added variable position_sprite::$6 to live range equivalence class [ position_sprite::$6 ]
Complete equivalence classes
[ main::s#2 main::s#1 ]
[ main::xpos#2 main::xpos#1 ]
[ position_sprite::spriteno#0 ]
[ position_sprite::x#0 ]
[ position_sprite::$1 ]
[ position_sprite::$2 ]
[ position_sprite::$4 ]
[ position_sprite::$5 ]
[ position_sprite::$6 ]
Allocated zp[1]:2 [ position_sprite::$2 ]
Allocated zp[1]:3 [ position_sprite::$4 ]
Allocated zp[1]:4 [ position_sprite::$5 ]
Allocated zp[1]:5 [ position_sprite::$6 ]
Allocated zp[1]:6 [ position_sprite::$1 ]
Allocated zp[1]:7 [ position_sprite::spriteno#0 ]
Allocated zp[2]:8 [ position_sprite::x#0 ]
Allocated zp[1]:10 [ main::s#2 main::s#1 ]
Allocated zp[2]:11 [ main::xpos#2 main::xpos#1 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [3] position_sprite::x#0 = main::xpos#2 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 ] (  [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Removing always clobbered register reg byte a as potential for zp[1]:10 [ main::s#2 main::s#1 ]
Removing always clobbered register reg byte a as potential for zp[1]:7 [ position_sprite::spriteno#0 ]
Statement [5] main::xpos#1 = main::xpos#2 + $a [ main::s#2 main::xpos#1 ] (  [ main::s#2 main::xpos#1 ] { }  ) always clobbers reg byte a 
Statement [9] position_sprite::$1 = position_sprite::spriteno#0 << 1 [ position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [10] SPRITES_YPOS[position_sprite::$1] = position_sprite::y#0 [ position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Removing always clobbered register reg byte a as potential for zp[1]:6 [ position_sprite::$1 ]
Statement [13] if(position_sprite::x#0>$ff) goto position_sprite::@1 [ position_sprite::spriteno#0 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [14] position_sprite::$4 = 1 << position_sprite::spriteno#0 [ position_sprite::$4 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::$4 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [15] position_sprite::$5 = position_sprite::$4 ^ $ff [ position_sprite::$5 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::$5 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [16] *SPRITES_XMSB = *SPRITES_XMSB & position_sprite::$5 [ ] ( position_sprite:4 [ main::s#2 main::xpos#2 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [18] position_sprite::$6 = 1 << position_sprite::spriteno#0 [ position_sprite::$6 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::$6 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [19] *SPRITES_XMSB = *SPRITES_XMSB | position_sprite::$6 [ ] ( position_sprite:4 [ main::s#2 main::xpos#2 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [3] position_sprite::x#0 = main::xpos#2 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 ] (  [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [5] main::xpos#1 = main::xpos#2 + $a [ main::s#2 main::xpos#1 ] (  [ main::s#2 main::xpos#1 ] { }  ) always clobbers reg byte a 
Statement [9] position_sprite::$1 = position_sprite::spriteno#0 << 1 [ position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [10] SPRITES_YPOS[position_sprite::$1] = position_sprite::y#0 [ position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 position_sprite::x#0 position_sprite::$1 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [13] if(position_sprite::x#0>$ff) goto position_sprite::@1 [ position_sprite::spriteno#0 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::spriteno#0 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [14] position_sprite::$4 = 1 << position_sprite::spriteno#0 [ position_sprite::$4 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::$4 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [15] position_sprite::$5 = position_sprite::$4 ^ $ff [ position_sprite::$5 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::$5 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [16] *SPRITES_XMSB = *SPRITES_XMSB & position_sprite::$5 [ ] ( position_sprite:4 [ main::s#2 main::xpos#2 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [18] position_sprite::$6 = 1 << position_sprite::spriteno#0 [ position_sprite::$6 ] ( position_sprite:4 [ main::s#2 main::xpos#2 position_sprite::$6 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Statement [19] *SPRITES_XMSB = *SPRITES_XMSB | position_sprite::$6 [ ] ( position_sprite:4 [ main::s#2 main::xpos#2 ] { { position_sprite::spriteno#0 = main::s#2 } { position_sprite::x#0 = main::xpos#2 } }  ) always clobbers reg byte a 
Potential registers zp[1]:10 [ main::s#2 main::s#1 ] : zp[1]:10 , reg byte x , reg byte y , 
Potential registers zp[2]:11 [ main::xpos#2 main::xpos#1 ] : zp[2]:11 , 
Potential registers zp[1]:7 [ position_sprite::spriteno#0 ] : zp[1]:7 , reg byte x , reg byte y , 
Potential registers zp[2]:8 [ position_sprite::x#0 ] : zp[2]:8 , 
Potential registers zp[1]:6 [ position_sprite::$1 ] : zp[1]:6 , reg byte x , reg byte y , 
Potential registers zp[1]:2 [ position_sprite::$2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , 
Potential registers zp[1]:3 [ position_sprite::$4 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y , 
Potential registers zp[1]:4 [ position_sprite::$5 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y , 
Potential registers zp[1]:5 [ position_sprite::$6 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , 

REGISTER UPLIFT SCOPES
Uplift Scope [position_sprite] 202: zp[1]:2 [ position_sprite::$2 ] 202: zp[1]:3 [ position_sprite::$4 ] 202: zp[1]:4 [ position_sprite::$5 ] 202: zp[1]:5 [ position_sprite::$6 ] 101: zp[1]:6 [ position_sprite::$1 ] 44.86: zp[1]:7 [ position_sprite::spriteno#0 ] 42.6: zp[2]:8 [ position_sprite::x#0 ] 
Uplift Scope [main] 23.1: zp[1]:10 [ main::s#2 main::s#1 ] 15.58: zp[2]:11 [ main::xpos#2 main::xpos#1 ] 
Uplift Scope [MOS6526_CIA] 
Uplift Scope [MOS6569_VICII] 
Uplift Scope [MOS6581_SID] 
Uplift Scope [] 

Uplifting [position_sprite] best 923 combination reg byte a [ position_sprite::$2 ] reg byte a [ position_sprite::$4 ] reg byte a [ position_sprite::$5 ] reg byte a [ position_sprite::$6 ] zp[1]:6 [ position_sprite::$1 ] zp[1]:7 [ position_sprite::spriteno#0 ] zp[2]:8 [ position_sprite::x#0 ] 
Limited combination testing to 100 combinations of 2304 possible.
Uplifting [main] best 803 combination reg byte x [ main::s#2 main::s#1 ] zp[2]:11 [ main::xpos#2 main::xpos#1 ] 
Uplifting [MOS6526_CIA] best 803 combination 
Uplifting [MOS6569_VICII] best 803 combination 
Uplifting [MOS6581_SID] best 803 combination 
Uplifting [] best 803 combination 
Attempting to uplift remaining variables inzp[1]:6 [ position_sprite::$1 ]
Uplifting [position_sprite] best 796 combination reg byte y [ position_sprite::$1 ] 
Attempting to uplift remaining variables inzp[1]:7 [ position_sprite::spriteno#0 ]
Uplifting [position_sprite] best 796 combination zp[1]:7 [ position_sprite::spriteno#0 ] 
Coalescing zero page register [ zp[2]:11 [ main::xpos#2 main::xpos#1 ] ] with [ zp[2]:8 [ position_sprite::x#0 ] ] - score: 1
Allocated (was zp[2]:11) zp[2]:2 [ main::xpos#2 main::xpos#1 position_sprite::x#0 ]
Allocated (was zp[1]:7) zp[1]:4 [ position_sprite::spriteno#0 ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Tests rolling sprite MSB by variable amount
  // Upstart
  // Commodore 64 PRG executable file
.file [name="roll-sprite-msb.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
  /// Sprite X position register for sprite #0
  .label SPRITES_XPOS = $d000
  /// Sprite Y position register for sprite #0
  .label SPRITES_YPOS = $d001
  /// Sprite X position MSB register
  .label SPRITES_XMSB = $d010
.segment Code
  // main
main: {
    .label xpos = 2
    // [1] phi from main to main::@1 [phi:main->main::@1]
  __b1_from_main:
    // [1] phi main::xpos#2 = $c8 [phi:main->main::@1#0] -- vwuz1=vwuc1 
    lda #<$c8
    sta.z xpos
    lda #>$c8
    sta.z xpos+1
    // [1] phi main::s#2 = 0 [phi:main->main::@1#1] -- vbuxx=vbuc1 
    ldx #0
    jmp __b1
    // [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
  __b1_from___b2:
    // [1] phi main::xpos#2 = main::xpos#1 [phi:main::@2->main::@1#0] -- register_copy 
    // [1] phi main::s#2 = main::s#1 [phi:main::@2->main::@1#1] -- register_copy 
    jmp __b1
    // main::@1
  __b1:
    // [2] position_sprite::spriteno#0 = main::s#2 -- vbuz1=vbuxx 
    stx.z position_sprite.spriteno
    // [3] position_sprite::x#0 = main::xpos#2
    // [4] call position_sprite
    jsr position_sprite
    jmp __b2
    // main::@2
  __b2:
    // [5] main::xpos#1 = main::xpos#2 + $a -- vwuz1=vwuz1_plus_vbuc1 
    lda #$a
    clc
    adc.z xpos
    sta.z xpos
    bcc !+
    inc.z xpos+1
  !:
    // [6] main::s#1 = ++ main::s#2 -- vbuxx=_inc_vbuxx 
    inx
    // [7] if(main::s#1!=8) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 
    cpx #8
    bne __b1_from___b2
    jmp __breturn
    // main::@return
  __breturn:
    // [8] return 
    rts
}
  // position_sprite
// void position_sprite(__zp(4) char spriteno, __zp(2) unsigned int x, char y)
position_sprite: {
    .const y = $32
    .label spriteno = 4
    .label x = 2
    // [9] position_sprite::$1 = position_sprite::spriteno#0 << 1 -- vbuyy=vbuz1_rol_1 
    lda.z spriteno
    asl
    tay
    // [10] SPRITES_YPOS[position_sprite::$1] = position_sprite::y#0 -- pbuc1_derefidx_vbuyy=vbuc2 
    lda #y
    sta SPRITES_YPOS,y
    // [11] position_sprite::$2 = byte0  position_sprite::x#0 -- vbuaa=_byte0_vwuz1 
    lda.z x
    // [12] SPRITES_XPOS[position_sprite::$1] = position_sprite::$2 -- pbuc1_derefidx_vbuyy=vbuaa 
    sta SPRITES_XPOS,y
    // [13] if(position_sprite::x#0>$ff) goto position_sprite::@1 -- vwuz1_gt_vbuc1_then_la1 
    lda.z x+1
    bne __b1
    lda #$ff
    cmp.z x
    bcc __b1
    jmp __b2
    // position_sprite::@2
  __b2:
    // [14] position_sprite::$4 = 1 << position_sprite::spriteno#0 -- vbuaa=vbuc1_rol_vbuz1 
    lda #1
    ldy.z spriteno
    cpy #0
    beq !e+
  !:
    asl
    dey
    bne !-
  !e:
    // [15] position_sprite::$5 = position_sprite::$4 ^ $ff -- vbuaa=vbuaa_bxor_vbuc1 
    eor #$ff
    // [16] *SPRITES_XMSB = *SPRITES_XMSB & position_sprite::$5 -- _deref_pbuc1=_deref_pbuc1_band_vbuaa 
    and SPRITES_XMSB
    sta SPRITES_XMSB
    jmp __breturn
    // position_sprite::@return
  __breturn:
    // [17] return 
    rts
    // position_sprite::@1
  __b1:
    // [18] position_sprite::$6 = 1 << position_sprite::spriteno#0 -- vbuaa=vbuc1_rol_vbuz1 
    lda #1
    ldy.z spriteno
    cpy #0
    beq !e+
  !:
    asl
    dey
    bne !-
  !e:
    // [19] *SPRITES_XMSB = *SPRITES_XMSB | position_sprite::$6 -- _deref_pbuc1=_deref_pbuc1_bor_vbuaa 
    ora SPRITES_XMSB
    sta SPRITES_XMSB
    jmp __breturn
}
  // File Data

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn
Removing instruction jmp __b2
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __b1_from___b2 with __b1
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1_from_main:
Removing instruction __b2:
Removing instruction __breturn:
Removing instruction __b2:
Succesful ASM optimization Pass5UnusedLabelElimination
Replacing jump to rts with rts in jmp __breturn
Succesful ASM optimization Pass5DoubleJumpElimination
Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
__constant char * const SPRITES_XMSB = (char *) 53264
__constant char * const SPRITES_XPOS = (char *) 53248
__constant char * const SPRITES_YPOS = (char *) 53249
void main()
char main::s
char main::s#1 // reg byte x 16.5
char main::s#2 // reg byte x 6.6000000000000005
unsigned int main::xpos
unsigned int main::xpos#1 // xpos zp[2]:2 7.333333333333333
unsigned int main::xpos#2 // xpos zp[2]:2 8.25
void position_sprite(char spriteno , unsigned int x , char y)
char position_sprite::$1 // reg byte y 101.0
char position_sprite::$2 // reg byte a 202.0
char position_sprite::$4 // reg byte a 202.0
char position_sprite::$5 // reg byte a 202.0
char position_sprite::$6 // reg byte a 202.0
char position_sprite::spriteno
char position_sprite::spriteno#0 // spriteno zp[1]:4 44.85714285714286
unsigned int position_sprite::x
unsigned int position_sprite::x#0 // x zp[2]:2 42.599999999999994
char position_sprite::y
__constant char position_sprite::y#0 = $32 // y

reg byte x [ main::s#2 main::s#1 ]
zp[2]:2 [ main::xpos#2 main::xpos#1 position_sprite::x#0 ]
zp[1]:4 [ position_sprite::spriteno#0 ]
reg byte y [ position_sprite::$1 ]
reg byte a [ position_sprite::$2 ]
reg byte a [ position_sprite::$4 ]
reg byte a [ position_sprite::$5 ]
reg byte a [ position_sprite::$6 ]


FINAL ASSEMBLER
Score: 553

  // File Comments
// Tests rolling sprite MSB by variable amount
  // Upstart
  // Commodore 64 PRG executable file
.file [name="roll-sprite-msb.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
  /// Sprite X position register for sprite #0
  .label SPRITES_XPOS = $d000
  /// Sprite Y position register for sprite #0
  .label SPRITES_YPOS = $d001
  /// Sprite X position MSB register
  .label SPRITES_XMSB = $d010
.segment Code
  // main
main: {
    .label xpos = 2
    // [1] phi from main to main::@1 [phi:main->main::@1]
    // [1] phi main::xpos#2 = $c8 [phi:main->main::@1#0] -- vwuz1=vwuc1 
    lda #<$c8
    sta.z xpos
    lda #>$c8
    sta.z xpos+1
    // [1] phi main::s#2 = 0 [phi:main->main::@1#1] -- vbuxx=vbuc1 
    ldx #0
    // [1] phi from main::@2 to main::@1 [phi:main::@2->main::@1]
    // [1] phi main::xpos#2 = main::xpos#1 [phi:main::@2->main::@1#0] -- register_copy 
    // [1] phi main::s#2 = main::s#1 [phi:main::@2->main::@1#1] -- register_copy 
    // main::@1
  __b1:
    // position_sprite(s, xpos, 50)
    // [2] position_sprite::spriteno#0 = main::s#2 -- vbuz1=vbuxx 
    stx.z position_sprite.spriteno
    // [3] position_sprite::x#0 = main::xpos#2
    // [4] call position_sprite
    jsr position_sprite
    // main::@2
    // xpos += 10
    // [5] main::xpos#1 = main::xpos#2 + $a -- vwuz1=vwuz1_plus_vbuc1 
    lda #$a
    clc
    adc.z xpos
    sta.z xpos
    bcc !+
    inc.z xpos+1
  !:
    // for(byte s: 0..7)
    // [6] main::s#1 = ++ main::s#2 -- vbuxx=_inc_vbuxx 
    inx
    // [7] if(main::s#1!=8) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 
    cpx #8
    bne __b1
    // main::@return
    // }
    // [8] return 
    rts
}
  // position_sprite
// void position_sprite(__zp(4) char spriteno, __zp(2) unsigned int x, char y)
position_sprite: {
    .const y = $32
    .label spriteno = 4
    .label x = 2
    // spriteno * 2
    // [9] position_sprite::$1 = position_sprite::spriteno#0 << 1 -- vbuyy=vbuz1_rol_1 
    lda.z spriteno
    asl
    tay
    // SPRITES_YPOS[spriteno * 2] = y
    // [10] SPRITES_YPOS[position_sprite::$1] = position_sprite::y#0 -- pbuc1_derefidx_vbuyy=vbuc2 
    lda #y
    sta SPRITES_YPOS,y
    // BYTE0(x)
    // [11] position_sprite::$2 = byte0  position_sprite::x#0 -- vbuaa=_byte0_vwuz1 
    lda.z x
    // SPRITES_XPOS[spriteno * 2] = BYTE0(x)
    // [12] SPRITES_XPOS[position_sprite::$1] = position_sprite::$2 -- pbuc1_derefidx_vbuyy=vbuaa 
    sta SPRITES_XPOS,y
    // if (x > 255)
    // [13] if(position_sprite::x#0>$ff) goto position_sprite::@1 -- vwuz1_gt_vbuc1_then_la1 
    lda.z x+1
    bne __b1
    lda #$ff
    cmp.z x
    bcc __b1
    // position_sprite::@2
    // 1 << spriteno
    // [14] position_sprite::$4 = 1 << position_sprite::spriteno#0 -- vbuaa=vbuc1_rol_vbuz1 
    lda #1
    ldy.z spriteno
    cpy #0
    beq !e+
  !:
    asl
    dey
    bne !-
  !e:
    // (1 << spriteno) ^ $ff
    // [15] position_sprite::$5 = position_sprite::$4 ^ $ff -- vbuaa=vbuaa_bxor_vbuc1 
    eor #$ff
    // *SPRITES_XMSB &= (1 << spriteno) ^ $ff
    // [16] *SPRITES_XMSB = *SPRITES_XMSB & position_sprite::$5 -- _deref_pbuc1=_deref_pbuc1_band_vbuaa 
    and SPRITES_XMSB
    sta SPRITES_XMSB
    // position_sprite::@return
    // }
    // [17] return 
    rts
    // position_sprite::@1
  __b1:
    // 1 << spriteno
    // [18] position_sprite::$6 = 1 << position_sprite::spriteno#0 -- vbuaa=vbuc1_rol_vbuz1 
    lda #1
    ldy.z spriteno
    cpy #0
    beq !e+
  !:
    asl
    dey
    bne !-
  !e:
    // *SPRITES_XMSB |= 1 << spriteno
    // [19] *SPRITES_XMSB = *SPRITES_XMSB | position_sprite::$6 -- _deref_pbuc1=_deref_pbuc1_bor_vbuaa 
    ora SPRITES_XMSB
    sta SPRITES_XMSB
    rts
}
  // File Data

