Fixing pointer array-indexing *((struct pos[$40]) p + (byte) idx)
Fixing pointer array-indexing *((struct pos[$40]) p + (byte) idx)
Rewriting struct pointer member access *((struct pos[$40]) p + (byte~) main::$2).y
Rewriting struct pointer member access *((struct pos[$40]) p + (byte~) main::$3).x
Identified constant variable (byte) OFFSET
Identified constant variable (byte) XSPACE
Identified constant variable (byte) YSPACE
Culled Empty Block (label) main::@11
Culled Empty Block (label) main::@3
Culled Empty Block (label) main::@12
Culled Empty Block (label) main::@7
Culled Empty Block (label) main::@8
Culled Empty Block (label) main::@9
Culled Empty Block (label) main::@10

CONTROL FLOW GRAPH SSA
@begin: scope:[]  from
  (byte) XSPACE#0 ← (number) $14
  (byte) YSPACE#0 ← (number) $14
  (struct pos[$40]) p#0 ← { fill( $40, 0) }
  (byte) idx#0 ← (byte) 0
  (byte) line#0 ← (byte) 0
  (byte) row#0 ← (byte) 0
  (byte) x#0 ← (byte) 0
  (byte) y#0 ← (byte) 0
  to:@1
main: scope:[main]  from @1
  (byte) y#11 ← phi( @1/(byte) y#10 )
  (byte) idx#10 ← phi( @1/(byte) idx#9 )
  (byte) row#11 ← phi( @1/(byte) row#10 )
  (byte) x#12 ← phi( @1/(byte) x#11 )
  (byte) line#1 ← (number) 0
  to:main::@1
main::@1: scope:[main]  from main main::@6
  (byte) y#9 ← phi( main/(byte) y#11 main::@6/(byte) y#1 )
  (byte) idx#8 ← phi( main/(byte) idx#10 main::@6/(byte) idx#11 )
  (byte) row#9 ← phi( main/(byte) row#11 main::@6/(byte) row#12 )
  (byte) x#9 ← phi( main/(byte) x#12 main::@6/(byte) x#13 )
  (byte) line#5 ← phi( main/(byte) line#1 main::@6/(byte) line#2 )
  (bool~) main::$0 ← (byte) line#5 < (number) 8
  if((bool~) main::$0) goto main::@2
  to:main::@return
main::@2: scope:[main]  from main::@1
  (byte) line#11 ← phi( main::@1/(byte) line#5 )
  (byte) y#12 ← phi( main::@1/(byte) y#9 )
  (byte) idx#12 ← phi( main::@1/(byte) idx#8 )
  (byte) x#5 ← phi( main::@1/(byte) x#9 )
  (byte) x#1 ← ++ (byte) x#5
  (byte) row#1 ← (number) 0
  to:main::@4
main::@4: scope:[main]  from main::@2 main::@5
  (byte) line#9 ← phi( main::@2/(byte) line#11 main::@5/(byte) line#12 )
  (byte) x#10 ← phi( main::@2/(byte) x#1 main::@5/(byte) x#2 )
  (byte) y#8 ← phi( main::@2/(byte) y#12 main::@5/(byte) y#4 )
  (byte) idx#7 ← phi( main::@2/(byte) idx#12 main::@5/(byte) idx#1 )
  (byte) row#5 ← phi( main::@2/(byte) row#1 main::@5/(byte) row#2 )
  (bool~) main::$1 ← (byte) row#5 < (number) 8
  if((bool~) main::$1) goto main::@5
  to:main::@6
main::@5: scope:[main]  from main::@4
  (byte) line#12 ← phi( main::@4/(byte) line#9 )
  (byte) row#6 ← phi( main::@4/(byte) row#5 )
  (byte) x#6 ← phi( main::@4/(byte) x#10 )
  (byte) y#4 ← phi( main::@4/(byte) y#8 )
  (byte) idx#4 ← phi( main::@4/(byte) idx#7 )
  (byte~) main::$2 ← (byte) idx#4 * (const byte) SIZEOF_STRUCT_POS
  (byte*) main::$4 ← (byte*)(struct pos[$40]) p#0 + (const byte) OFFSET_STRUCT_POS_Y
  *((byte*) main::$4 + (byte~) main::$2) ← (byte) y#4
  (byte~) main::$3 ← (byte) idx#4 * (const byte) SIZEOF_STRUCT_POS
  (byte*) main::$5 ← (byte*)(struct pos[$40]) p#0 + (const byte) OFFSET_STRUCT_POS_X
  *((byte*) main::$5 + (byte~) main::$3) ← (byte) x#6
  (byte) idx#1 ← ++ (byte) idx#4
  (byte) x#2 ← (byte) x#6 + (byte) XSPACE#0
  (byte) row#2 ← ++ (byte) row#6
  to:main::@4
main::@6: scope:[main]  from main::@4
  (byte) idx#11 ← phi( main::@4/(byte) idx#7 )
  (byte) row#12 ← phi( main::@4/(byte) row#5 )
  (byte) x#13 ← phi( main::@4/(byte) x#10 )
  (byte) line#6 ← phi( main::@4/(byte) line#9 )
  (byte) y#5 ← phi( main::@4/(byte) y#8 )
  (byte) y#1 ← (byte) y#5 + (byte) YSPACE#0
  (byte) line#2 ← ++ (byte) line#6
  to:main::@1
main::@return: scope:[main]  from main::@1
  (byte) y#6 ← phi( main::@1/(byte) y#9 )
  (byte) idx#5 ← phi( main::@1/(byte) idx#8 )
  (byte) row#7 ← phi( main::@1/(byte) row#9 )
  (byte) x#7 ← phi( main::@1/(byte) x#9 )
  (byte) line#7 ← phi( main::@1/(byte) line#5 )
  (byte) line#3 ← (byte) line#7
  (byte) x#3 ← (byte) x#7
  (byte) row#3 ← (byte) row#7
  (byte) idx#2 ← (byte) idx#5
  (byte) y#2 ← (byte) y#6
  return 
  to:@return
@1: scope:[]  from @begin
  (byte) y#10 ← phi( @begin/(byte) y#0 )
  (byte) idx#9 ← phi( @begin/(byte) idx#0 )
  (byte) row#10 ← phi( @begin/(byte) row#0 )
  (byte) x#11 ← phi( @begin/(byte) x#0 )
  (byte) line#10 ← phi( @begin/(byte) line#0 )
  call main 
  to:@2
@2: scope:[]  from @1
  (byte) y#7 ← phi( @1/(byte) y#2 )
  (byte) idx#6 ← phi( @1/(byte) idx#2 )
  (byte) row#8 ← phi( @1/(byte) row#3 )
  (byte) x#8 ← phi( @1/(byte) x#3 )
  (byte) line#8 ← phi( @1/(byte) line#3 )
  (byte) line#4 ← (byte) line#8
  (byte) x#4 ← (byte) x#8
  (byte) row#4 ← (byte) row#8
  (byte) idx#3 ← (byte) idx#6
  (byte) y#3 ← (byte) y#7
  to:@end
@end: scope:[]  from @2

SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_POS_X = (byte) 0
(const byte) OFFSET_STRUCT_POS_Y = (byte) 1
(const byte) SIZEOF_STRUCT_POS = (byte) 2
(byte) XSPACE
(byte) XSPACE#0
(byte) YSPACE
(byte) YSPACE#0
(byte) idx
(byte) idx#0
(byte) idx#1
(byte) idx#10
(byte) idx#11
(byte) idx#12
(byte) idx#2
(byte) idx#3
(byte) idx#4
(byte) idx#5
(byte) idx#6
(byte) idx#7
(byte) idx#8
(byte) idx#9
(byte) line
(byte) line#0
(byte) line#1
(byte) line#10
(byte) line#11
(byte) line#12
(byte) line#2
(byte) line#3
(byte) line#4
(byte) line#5
(byte) line#6
(byte) line#7
(byte) line#8
(byte) line#9
(void()) main()
(bool~) main::$0
(bool~) main::$1
(byte~) main::$2
(byte~) main::$3
(byte*) main::$4
(byte*) main::$5
(label) main::@1
(label) main::@2
(label) main::@4
(label) main::@5
(label) main::@6
(label) main::@return
(struct pos[$40]) p
(struct pos[$40]) p#0
(byte) pos::x
(byte) pos::y
(byte) row
(byte) row#0
(byte) row#1
(byte) row#10
(byte) row#11
(byte) row#12
(byte) row#2
(byte) row#3
(byte) row#4
(byte) row#5
(byte) row#6
(byte) row#7
(byte) row#8
(byte) row#9
(byte) x
(byte) x#0
(byte) x#1
(byte) x#10
(byte) x#11
(byte) x#12
(byte) x#13
(byte) x#2
(byte) x#3
(byte) x#4
(byte) x#5
(byte) x#6
(byte) x#7
(byte) x#8
(byte) x#9
(byte) y
(byte) y#0
(byte) y#1
(byte) y#10
(byte) y#11
(byte) y#12
(byte) y#2
(byte) y#3
(byte) y#4
(byte) y#5
(byte) y#6
(byte) y#7
(byte) y#8
(byte) y#9

Adding number conversion cast (unumber) $14 in (byte) XSPACE#0 ← (number) $14
Adding number conversion cast (unumber) $14 in (byte) YSPACE#0 ← (number) $14
Adding number conversion cast (unumber) 0 in (byte) line#1 ← (number) 0
Adding number conversion cast (unumber) 8 in (bool~) main::$0 ← (byte) line#5 < (number) 8
Adding number conversion cast (unumber) 0 in (byte) row#1 ← (number) 0
Adding number conversion cast (unumber) 8 in (bool~) main::$1 ← (byte) row#5 < (number) 8
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte) XSPACE#0 ← (unumber)(number) $14
Inlining cast (byte) YSPACE#0 ← (unumber)(number) $14
Inlining cast (byte) line#1 ← (unumber)(number) 0
Inlining cast (byte) row#1 ← (unumber)(number) 0
Successful SSA optimization Pass2InlineCast
Simplifying constant integer cast $14
Simplifying constant integer cast $14
Simplifying constant integer cast 0
Simplifying constant integer cast 8
Simplifying constant integer cast 0
Simplifying constant integer cast 8
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) $14
Finalized unsigned number type (byte) $14
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 8
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 8
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte) x#3 = (byte) x#5 (byte) x#9 (byte) x#7 
Alias (byte) idx#12 = (byte) idx#8 (byte) idx#5 (byte) idx#2 
Alias (byte) y#12 = (byte) y#9 (byte) y#6 (byte) y#2 
Alias (byte) line#11 = (byte) line#5 (byte) line#7 (byte) line#3 
Alias (byte) idx#11 = (byte) idx#4 (byte) idx#7 
Alias (byte) y#4 = (byte) y#8 (byte) y#5 
Alias (byte) x#10 = (byte) x#6 (byte) x#13 
Alias (byte) row#12 = (byte) row#6 (byte) row#5 
Alias (byte) line#12 = (byte) line#9 (byte) line#6 
Alias (byte) row#3 = (byte) row#7 (byte) row#9 
Alias (byte) line#0 = (byte) line#10 
Alias (byte) x#0 = (byte) x#11 
Alias (byte) row#0 = (byte) row#10 
Alias (byte) idx#0 = (byte) idx#9 
Alias (byte) y#0 = (byte) y#10 
Alias (byte) line#4 = (byte) line#8 
Alias (byte) x#4 = (byte) x#8 
Alias (byte) row#4 = (byte) row#8 
Alias (byte) idx#3 = (byte) idx#6 
Alias (byte) y#3 = (byte) y#7 
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) x#12 (byte) x#0
Identical Phi Values (byte) row#11 (byte) row#0
Identical Phi Values (byte) idx#10 (byte) idx#0
Identical Phi Values (byte) y#11 (byte) y#0
Identical Phi Values (byte) y#4 (byte) y#12
Identical Phi Values (byte) line#12 (byte) line#11
Identical Phi Values (byte) line#4 (byte) line#11
Identical Phi Values (byte) x#4 (byte) x#3
Identical Phi Values (byte) row#4 (byte) row#3
Identical Phi Values (byte) idx#3 (byte) idx#12
Identical Phi Values (byte) y#3 (byte) y#12
Successful SSA optimization Pass2IdenticalPhiElimination
Identified duplicate assignment right side [23] (byte~) main::$3 ← (byte) idx#11 * (const byte) SIZEOF_STRUCT_POS
Successful SSA optimization Pass2DuplicateRValueIdentification
Simple Condition (bool~) main::$0 [12] if((byte) line#11<(byte) 8) goto main::@2
Simple Condition (bool~) main::$1 [18] if((byte) row#12<(byte) 8) goto main::@5
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant right-side identified [2] (struct pos[$40]) p#0 ← { fill( $40, 0) }
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte) XSPACE#0 = $14
Constant (const byte) YSPACE#0 = $14
Constant (const struct pos[$40]) p#0 = { fill( $40, 0) }
Constant (const byte) idx#0 = 0
Constant (const byte) line#0 = 0
Constant (const byte) row#0 = 0
Constant (const byte) x#0 = 0
Constant (const byte) y#0 = 0
Constant (const byte) line#1 = 0
Constant (const byte) row#1 = 0
Successful SSA optimization Pass2ConstantIdentification
Constant value identified (byte*)p#0 in [21] (byte*) main::$4 ← (byte*)(const struct pos[$40]) p#0 + (const byte) OFFSET_STRUCT_POS_Y
Constant value identified (byte*)p#0 in [24] (byte*) main::$5 ← (byte*)(const struct pos[$40]) p#0 + (const byte) OFFSET_STRUCT_POS_X
Successful SSA optimization Pass2ConstantValues
Simplifying expression containing zero (byte*)p#0 in [24] (byte*) main::$5 ← (byte*)(const struct pos[$40]) p#0 + (const byte) OFFSET_STRUCT_POS_X
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable - keeping the phi block (byte) row#3
Eliminating unused constant (const byte) OFFSET_STRUCT_POS_X
Eliminating unused constant (const byte) line#0
Successful SSA optimization PassNEliminateUnusedVars
Eliminating unused constant (const byte) row#0
Successful SSA optimization PassNEliminateUnusedVars
Successful SSA optimization Pass2LoopHeadConstantIdentification
Successful SSA optimization Pass2LoopHeadConstantIdentification
Alias (byte) line#11 = (byte) line#2 
Alias (byte) x#14 = (byte) x#3 
Alias (byte) idx#12 = (byte) idx#13 
Alias (byte) y#1 = (byte) y#12 
Alias (byte) row#12 = (byte) row#2 
Alias (byte) idx#1 = (byte) idx#11 
Alias (byte) x#10 = (byte) x#2 
Alias (byte) line#14 = (byte) line#16 
Alias (byte) y#13 = (byte) y#15 
Alias (byte~) main::$3 = (byte~) main::$2 
Alias (byte) idx#15 = (byte) idx#16 
Alias (byte) x#1 = (byte) x#16 
Alias (byte) line#15 = (byte) line#17 
Alias (byte) y#16 = (byte) y#17 
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) line#14 (byte) line#15
Identical Phi Values (byte) y#13 (byte) y#16
Identical Phi Values (byte) row#14 (const byte) row#1
Identical Phi Values (byte) line#18 (const byte) line#1
Identical Phi Values (byte) x#18 (const byte) x#0
Identical Phi Values (byte) idx#17 (const byte) idx#0
Identical Phi Values (byte) y#18 (const byte) y#0
Successful SSA optimization Pass2IdenticalPhiElimination
Identical Phi Values (byte) line#13 (byte) line#15
Identical Phi Values (byte) y#14 (byte) y#16
Successful SSA optimization Pass2IdenticalPhiElimination
Constant right-side identified [8] (byte*) main::$4 ← (byte*)(const struct pos[$40]) p#0 + (const byte) OFFSET_STRUCT_POS_Y
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) main::$4 = (byte*)p#0+OFFSET_STRUCT_POS_Y
Constant (const byte*) main::$5 = (byte*)p#0
Successful SSA optimization Pass2ConstantIdentification
Removing PHI-reference to removed block (main::@4_1) in block main::@6
Removing PHI-reference to removed block (main::@4_1) in block main::@6
if() condition always true - replacing block destination [23] if((const byte) row#1<(byte) 8) goto main::@5
if() condition always true - replacing block destination [25] if((const byte) line#1<(byte) 8) goto main::@2
Successful SSA optimization Pass2ConstantIfs
Alias (byte) idx#1 = (byte) idx#12 
Alias (byte) x#10 = (byte) x#14 
Successful SSA optimization Pass2AliasElimination
Rewriting multiplication to use shift [5] (byte~) main::$3 ← (byte) idx#14 * (const byte) SIZEOF_STRUCT_POS
Successful SSA optimization Pass2MultiplyToShiftRewriting
Inlining constant with var siblings (const byte) idx#0
Inlining constant with var siblings (const byte) x#0
Inlining constant with var siblings (const byte) y#0
Inlining constant with var siblings (const byte) line#1
Inlining constant with var siblings (const byte) row#1
Constant inlined row#1 = (byte) 0
Constant inlined x#0 = (byte) 0
Constant inlined line#1 = (byte) 0
Constant inlined y#0 = (byte) 0
Constant inlined main::$5 = (byte*)(const struct pos[$40]) p#0
Constant inlined main::$4 = (byte*)(const struct pos[$40]) p#0+(const byte) OFFSET_STRUCT_POS_Y
Constant inlined idx#0 = (byte) 0
Successful SSA optimization Pass2ConstantInlining
Eliminating unused constant (const byte) SIZEOF_STRUCT_POS
Successful SSA optimization PassNEliminateUnusedVars
Added new block during phi lifting main::@13(between main::@1 and main::@2)
Added new block during phi lifting main::@14(between main::@4 and main::@5)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1_1
CALL GRAPH
Calls in [] to main:2 

Created 7 initial phi equivalence classes
Coalesced [9] idx#20 ← idx#15
Coalesced [10] x#21 ← x#1
Coalesced [23] line#19 ← line#11
Coalesced [24] x#19 ← x#10
Coalesced [25] idx#18 ← idx#1
Coalesced [26] y#19 ← y#1
Coalesced [27] row#15 ← row#12
Coalesced (already) [28] idx#19 ← idx#1
Coalesced [29] x#20 ← x#10
Coalesced down to 5 phi equivalence classes
Culled Empty Block (label) @2
Culled Empty Block (label) main::@1_1
Culled Empty Block (label) main::@4_1
Culled Empty Block (label) main::@13
Culled Empty Block (label) main::@14
Renumbering block main::@4 to main::@3
Renumbering block main::@5 to main::@4
Renumbering block main::@6 to main::@5
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

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()
main: scope:[main]  from @1
  [4] phi()
  to:main::@2
main::@2: scope:[main]  from main main::@1
  [5] (byte) y#16 ← phi( main::@1/(byte) y#1 main/(byte) 0 )
  [5] (byte) idx#15 ← phi( main::@1/(byte) idx#1 main/(byte) 0 )
  [5] (byte) x#17 ← phi( main::@1/(byte) x#10 main/(byte) 0 )
  [5] (byte) line#15 ← phi( main::@1/(byte) line#11 main/(byte) 0 )
  [6] (byte) x#1 ← ++ (byte) x#17
  to:main::@4
main::@4: scope:[main]  from main::@2 main::@3
  [7] (byte) x#15 ← phi( main::@3/(byte) x#10 main::@2/(byte) x#1 )
  [7] (byte) idx#14 ← phi( main::@3/(byte) idx#1 main::@2/(byte) idx#15 )
  [7] (byte) row#13 ← phi( main::@3/(byte) row#12 main::@2/(byte) 0 )
  [8] (byte~) main::$3 ← (byte) idx#14 << (byte) 1
  [9] *((byte*)(const struct pos[$40]) p#0+(const byte) OFFSET_STRUCT_POS_Y + (byte~) main::$3) ← (byte) y#16
  [10] *((byte*)(const struct pos[$40]) p#0 + (byte~) main::$3) ← (byte) x#15
  [11] (byte) idx#1 ← ++ (byte) idx#14
  [12] (byte) x#10 ← (byte) x#15 + (const byte) XSPACE#0
  [13] (byte) row#12 ← ++ (byte) row#13
  to:main::@3
main::@3: scope:[main]  from main::@4
  [14] if((byte) row#12<(byte) 8) goto main::@4
  to:main::@5
main::@5: scope:[main]  from main::@3
  [15] (byte) y#1 ← (byte) y#16 + (const byte) YSPACE#0
  [16] (byte) line#11 ← ++ (byte) line#15
  to:main::@1
main::@1: scope:[main]  from main::@5
  [17] if((byte) line#11<(byte) 8) goto main::@2
  to:main::@return
main::@return: scope:[main]  from main::@1
  [18] return 
  to:@return


VARIABLE REGISTER WEIGHTS
(byte) XSPACE
(byte) YSPACE
(byte) idx
(byte) idx#1 30.42857142857143
(byte) idx#14 78.5
(byte) idx#15 11.0
(byte) line
(byte) line#11 16.5
(byte) line#15 2.0
(void()) main()
(byte~) main::$3 151.5
(struct pos[$40]) p
(byte) pos::x
(byte) pos::y
(byte) row
(byte) row#12 151.5
(byte) row#13 33.666666666666664
(byte) x
(byte) x#1 22.0
(byte) x#10 35.5
(byte) x#15 62.8
(byte) x#17 22.0
(byte) y
(byte) y#1 7.333333333333333
(byte) y#16 12.299999999999999

Initial phi equivalence classes
[ line#15 line#11 ]
[ y#16 y#1 ]
[ row#13 row#12 ]
[ idx#14 idx#15 idx#1 ]
[ x#15 x#17 x#10 x#1 ]
Added variable main::$3 to zero page equivalence class [ main::$3 ]
Complete equivalence classes
[ line#15 line#11 ]
[ y#16 y#1 ]
[ row#13 row#12 ]
[ idx#14 idx#15 idx#1 ]
[ x#15 x#17 x#10 x#1 ]
[ main::$3 ]
Allocated zp ZP_BYTE:2 [ line#15 line#11 ]
Allocated zp ZP_BYTE:3 [ y#16 y#1 ]
Allocated zp ZP_BYTE:4 [ row#13 row#12 ]
Allocated zp ZP_BYTE:5 [ idx#14 idx#15 idx#1 ]
Allocated zp ZP_BYTE:6 [ x#15 x#17 x#10 x#1 ]
Allocated zp ZP_BYTE:7 [ main::$3 ]

INITIAL ASM
Target platform is c64basic
  // File Comments
// Example of structs that can be optimized by going planar
// https://cc65.github.io/mailarchive/2010-09/8593.html?fbclid=IwAR1IF_cTdyWcFeKU93VfL2Un1EuLjkGh7O7dQ4EVj4kpJzJAj01dbmEFQt8
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .const OFFSET_STRUCT_POS_Y = 1
  .const XSPACE = $14
  .const YSPACE = $14
  .label x = 6
  .label idx = 5
  .label y = 3
  .label row = 4
  .label line = 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: {
    .label _3 = 7
    // [5] phi from main to main::@2 [phi:main->main::@2]
  b2_from_main:
    // [5] phi (byte) y#16 = (byte) 0 [phi:main->main::@2#0] -- vbuz1=vbuc1 
    lda #0
    sta.z y
    // [5] phi (byte) idx#15 = (byte) 0 [phi:main->main::@2#1] -- vbuz1=vbuc1 
    lda #0
    sta.z idx
    // [5] phi (byte) x#17 = (byte) 0 [phi:main->main::@2#2] -- vbuz1=vbuc1 
    lda #0
    sta.z x
    // [5] phi (byte) line#15 = (byte) 0 [phi:main->main::@2#3] -- vbuz1=vbuc1 
    lda #0
    sta.z line
    jmp b2
    // [5] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
  b2_from_b1:
    // [5] phi (byte) y#16 = (byte) y#1 [phi:main::@1->main::@2#0] -- register_copy 
    // [5] phi (byte) idx#15 = (byte) idx#1 [phi:main::@1->main::@2#1] -- register_copy 
    // [5] phi (byte) x#17 = (byte) x#10 [phi:main::@1->main::@2#2] -- register_copy 
    // [5] phi (byte) line#15 = (byte) line#11 [phi:main::@1->main::@2#3] -- register_copy 
    jmp b2
    // main::@2
  b2:
    // [6] (byte) x#1 ← ++ (byte) x#17 -- vbuz1=_inc_vbuz1 
    inc.z x
    // [7] phi from main::@2 to main::@4 [phi:main::@2->main::@4]
  b4_from_b2:
    // [7] phi (byte) x#15 = (byte) x#1 [phi:main::@2->main::@4#0] -- register_copy 
    // [7] phi (byte) idx#14 = (byte) idx#15 [phi:main::@2->main::@4#1] -- register_copy 
    // [7] phi (byte) row#13 = (byte) 0 [phi:main::@2->main::@4#2] -- vbuz1=vbuc1 
    lda #0
    sta.z row
    jmp b4
    // [7] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
  b4_from_b3:
    // [7] phi (byte) x#15 = (byte) x#10 [phi:main::@3->main::@4#0] -- register_copy 
    // [7] phi (byte) idx#14 = (byte) idx#1 [phi:main::@3->main::@4#1] -- register_copy 
    // [7] phi (byte) row#13 = (byte) row#12 [phi:main::@3->main::@4#2] -- register_copy 
    jmp b4
    // main::@4
  b4:
    // [8] (byte~) main::$3 ← (byte) idx#14 << (byte) 1 -- vbuz1=vbuz2_rol_1 
    lda.z idx
    asl
    sta.z _3
    // [9] *((byte*)(const struct pos[$40]) p#0+(const byte) OFFSET_STRUCT_POS_Y + (byte~) main::$3) ← (byte) y#16 -- pbuc1_derefidx_vbuz1=vbuz2 
    lda.z y
    ldy.z _3
    sta p+OFFSET_STRUCT_POS_Y,y
    // [10] *((byte*)(const struct pos[$40]) p#0 + (byte~) main::$3) ← (byte) x#15 -- pbuc1_derefidx_vbuz1=vbuz2 
    lda.z x
    ldy.z _3
    sta p,y
    // [11] (byte) idx#1 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuz1 
    inc.z idx
    // [12] (byte) x#10 ← (byte) x#15 + (const byte) XSPACE#0 -- vbuz1=vbuz1_plus_vbuc1 
    lax.z x
    axs #-[XSPACE]
    stx.z x
    // [13] (byte) row#12 ← ++ (byte) row#13 -- vbuz1=_inc_vbuz1 
    inc.z row
    jmp b3
    // main::@3
  b3:
    // [14] if((byte) row#12<(byte) 8) goto main::@4 -- vbuz1_lt_vbuc1_then_la1 
    lda.z row
    cmp #8
    bcc b4_from_b3
    jmp b5
    // main::@5
  b5:
    // [15] (byte) y#1 ← (byte) y#16 + (const byte) YSPACE#0 -- vbuz1=vbuz1_plus_vbuc1 
    lax.z y
    axs #-[YSPACE]
    stx.z y
    // [16] (byte) line#11 ← ++ (byte) line#15 -- vbuz1=_inc_vbuz1 
    inc.z line
    jmp b1
    // main::@1
  b1:
    // [17] if((byte) line#11<(byte) 8) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 
    lda.z line
    cmp #8
    bcc b2_from_b1
    jmp breturn
    // main::@return
  breturn:
    // [18] return 
    rts
}
  // File Data
  p: .fill 2*$40, 0

REGISTER UPLIFT POTENTIAL REGISTERS
Statement [8] (byte~) main::$3 ← (byte) idx#14 << (byte) 1 [ line#15 y#16 row#13 idx#14 x#15 main::$3 ] ( main:2 [ line#15 y#16 row#13 idx#14 x#15 main::$3 ] ) always clobbers reg byte a 
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ line#15 line#11 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ y#16 y#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ row#13 row#12 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ idx#14 idx#15 idx#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:6 [ x#15 x#17 x#10 x#1 ]
Statement [9] *((byte*)(const struct pos[$40]) p#0+(const byte) OFFSET_STRUCT_POS_Y + (byte~) main::$3) ← (byte) y#16 [ line#15 y#16 row#13 idx#14 x#15 main::$3 ] ( main:2 [ line#15 y#16 row#13 idx#14 x#15 main::$3 ] ) always clobbers reg byte a 
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:7 [ main::$3 ]
Statement [10] *((byte*)(const struct pos[$40]) p#0 + (byte~) main::$3) ← (byte) x#15 [ line#15 y#16 row#13 idx#14 x#15 ] ( main:2 [ line#15 y#16 row#13 idx#14 x#15 ] ) always clobbers reg byte a 
Statement [12] (byte) x#10 ← (byte) x#15 + (const byte) XSPACE#0 [ line#15 y#16 x#10 idx#1 row#13 ] ( main:2 [ line#15 y#16 x#10 idx#1 row#13 ] ) always clobbers reg byte a 
Statement [15] (byte) y#1 ← (byte) y#16 + (const byte) YSPACE#0 [ line#15 x#10 idx#1 y#1 ] ( main:2 [ line#15 x#10 idx#1 y#1 ] ) always clobbers reg byte a 
Statement [8] (byte~) main::$3 ← (byte) idx#14 << (byte) 1 [ line#15 y#16 row#13 idx#14 x#15 main::$3 ] ( main:2 [ line#15 y#16 row#13 idx#14 x#15 main::$3 ] ) always clobbers reg byte a 
Statement [9] *((byte*)(const struct pos[$40]) p#0+(const byte) OFFSET_STRUCT_POS_Y + (byte~) main::$3) ← (byte) y#16 [ line#15 y#16 row#13 idx#14 x#15 main::$3 ] ( main:2 [ line#15 y#16 row#13 idx#14 x#15 main::$3 ] ) always clobbers reg byte a 
Statement [10] *((byte*)(const struct pos[$40]) p#0 + (byte~) main::$3) ← (byte) x#15 [ line#15 y#16 row#13 idx#14 x#15 ] ( main:2 [ line#15 y#16 row#13 idx#14 x#15 ] ) always clobbers reg byte a 
Statement [12] (byte) x#10 ← (byte) x#15 + (const byte) XSPACE#0 [ line#15 y#16 x#10 idx#1 row#13 ] ( main:2 [ line#15 y#16 x#10 idx#1 row#13 ] ) always clobbers reg byte a 
Statement [15] (byte) y#1 ← (byte) y#16 + (const byte) YSPACE#0 [ line#15 x#10 idx#1 y#1 ] ( main:2 [ line#15 x#10 idx#1 y#1 ] ) always clobbers reg byte a 
Potential registers zp ZP_BYTE:2 [ line#15 line#11 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , 
Potential registers zp ZP_BYTE:3 [ y#16 y#1 ] : zp ZP_BYTE:3 , reg byte x , reg byte y , 
Potential registers zp ZP_BYTE:4 [ row#13 row#12 ] : zp ZP_BYTE:4 , reg byte x , reg byte y , 
Potential registers zp ZP_BYTE:5 [ idx#14 idx#15 idx#1 ] : zp ZP_BYTE:5 , reg byte x , reg byte y , 
Potential registers zp ZP_BYTE:6 [ x#15 x#17 x#10 x#1 ] : zp ZP_BYTE:6 , reg byte x , reg byte y , 
Potential registers zp ZP_BYTE:7 [ main::$3 ] : zp ZP_BYTE:7 , reg byte x , reg byte y , 

REGISTER UPLIFT SCOPES
Uplift Scope [] 185.17: zp ZP_BYTE:4 [ row#13 row#12 ] 142.3: zp ZP_BYTE:6 [ x#15 x#17 x#10 x#1 ] 119.93: zp ZP_BYTE:5 [ idx#14 idx#15 idx#1 ] 19.63: zp ZP_BYTE:3 [ y#16 y#1 ] 18.5: zp ZP_BYTE:2 [ line#15 line#11 ] 
Uplift Scope [main] 151.5: zp ZP_BYTE:7 [ main::$3 ] 
Uplift Scope [pos] 

Uplifting [] best 7843 combination zp ZP_BYTE:4 [ row#13 row#12 ] zp ZP_BYTE:6 [ x#15 x#17 x#10 x#1 ] zp ZP_BYTE:5 [ idx#14 idx#15 idx#1 ] zp ZP_BYTE:3 [ y#16 y#1 ] zp ZP_BYTE:2 [ line#15 line#11 ] 
Limited combination testing to 100 combinations of 243 possible.
Uplifting [main] best 7143 combination reg byte x [ main::$3 ] 
Uplifting [pos] best 7143 combination 
Attempting to uplift remaining variables inzp ZP_BYTE:4 [ row#13 row#12 ]
Uplifting [] best 6243 combination reg byte y [ row#13 row#12 ] 
Attempting to uplift remaining variables inzp ZP_BYTE:6 [ x#15 x#17 x#10 x#1 ]
Uplifting [] best 6243 combination zp ZP_BYTE:6 [ x#15 x#17 x#10 x#1 ] 
Attempting to uplift remaining variables inzp ZP_BYTE:5 [ idx#14 idx#15 idx#1 ]
Uplifting [] best 6243 combination zp ZP_BYTE:5 [ idx#14 idx#15 idx#1 ] 
Attempting to uplift remaining variables inzp ZP_BYTE:3 [ y#16 y#1 ]
Uplifting [] best 6243 combination zp ZP_BYTE:3 [ y#16 y#1 ] 
Attempting to uplift remaining variables inzp ZP_BYTE:2 [ line#15 line#11 ]
Uplifting [] best 6243 combination zp ZP_BYTE:2 [ line#15 line#11 ] 
Allocated (was zp ZP_BYTE:5) zp ZP_BYTE:4 [ idx#14 idx#15 idx#1 ]
Allocated (was zp ZP_BYTE:6) zp ZP_BYTE:5 [ x#15 x#17 x#10 x#1 ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Example of structs that can be optimized by going planar
// https://cc65.github.io/mailarchive/2010-09/8593.html?fbclid=IwAR1IF_cTdyWcFeKU93VfL2Un1EuLjkGh7O7dQ4EVj4kpJzJAj01dbmEFQt8
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
  // Global Constants & labels
  .const OFFSET_STRUCT_POS_Y = 1
  .const XSPACE = $14
  .const YSPACE = $14
  .label x = 5
  .label idx = 4
  .label y = 3
  .label line = 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] phi from main to main::@2 [phi:main->main::@2]
  b2_from_main:
    // [5] phi (byte) y#16 = (byte) 0 [phi:main->main::@2#0] -- vbuz1=vbuc1 
    lda #0
    sta.z y
    // [5] phi (byte) idx#15 = (byte) 0 [phi:main->main::@2#1] -- vbuz1=vbuc1 
    lda #0
    sta.z idx
    // [5] phi (byte) x#17 = (byte) 0 [phi:main->main::@2#2] -- vbuz1=vbuc1 
    lda #0
    sta.z x
    // [5] phi (byte) line#15 = (byte) 0 [phi:main->main::@2#3] -- vbuz1=vbuc1 
    lda #0
    sta.z line
    jmp b2
    // [5] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
  b2_from_b1:
    // [5] phi (byte) y#16 = (byte) y#1 [phi:main::@1->main::@2#0] -- register_copy 
    // [5] phi (byte) idx#15 = (byte) idx#1 [phi:main::@1->main::@2#1] -- register_copy 
    // [5] phi (byte) x#17 = (byte) x#10 [phi:main::@1->main::@2#2] -- register_copy 
    // [5] phi (byte) line#15 = (byte) line#11 [phi:main::@1->main::@2#3] -- register_copy 
    jmp b2
    // main::@2
  b2:
    // [6] (byte) x#1 ← ++ (byte) x#17 -- vbuz1=_inc_vbuz1 
    inc.z x
    // [7] phi from main::@2 to main::@4 [phi:main::@2->main::@4]
  b4_from_b2:
    // [7] phi (byte) x#15 = (byte) x#1 [phi:main::@2->main::@4#0] -- register_copy 
    // [7] phi (byte) idx#14 = (byte) idx#15 [phi:main::@2->main::@4#1] -- register_copy 
    // [7] phi (byte) row#13 = (byte) 0 [phi:main::@2->main::@4#2] -- vbuyy=vbuc1 
    ldy #0
    jmp b4
    // [7] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
  b4_from_b3:
    // [7] phi (byte) x#15 = (byte) x#10 [phi:main::@3->main::@4#0] -- register_copy 
    // [7] phi (byte) idx#14 = (byte) idx#1 [phi:main::@3->main::@4#1] -- register_copy 
    // [7] phi (byte) row#13 = (byte) row#12 [phi:main::@3->main::@4#2] -- register_copy 
    jmp b4
    // main::@4
  b4:
    // [8] (byte~) main::$3 ← (byte) idx#14 << (byte) 1 -- vbuxx=vbuz1_rol_1 
    lda.z idx
    asl
    tax
    // [9] *((byte*)(const struct pos[$40]) p#0+(const byte) OFFSET_STRUCT_POS_Y + (byte~) main::$3) ← (byte) y#16 -- pbuc1_derefidx_vbuxx=vbuz1 
    lda.z y
    sta p+OFFSET_STRUCT_POS_Y,x
    // [10] *((byte*)(const struct pos[$40]) p#0 + (byte~) main::$3) ← (byte) x#15 -- pbuc1_derefidx_vbuxx=vbuz1 
    lda.z x
    sta p,x
    // [11] (byte) idx#1 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuz1 
    inc.z idx
    // [12] (byte) x#10 ← (byte) x#15 + (const byte) XSPACE#0 -- vbuz1=vbuz1_plus_vbuc1 
    lax.z x
    axs #-[XSPACE]
    stx.z x
    // [13] (byte) row#12 ← ++ (byte) row#13 -- vbuyy=_inc_vbuyy 
    iny
    jmp b3
    // main::@3
  b3:
    // [14] if((byte) row#12<(byte) 8) goto main::@4 -- vbuyy_lt_vbuc1_then_la1 
    cpy #8
    bcc b4_from_b3
    jmp b5
    // main::@5
  b5:
    // [15] (byte) y#1 ← (byte) y#16 + (const byte) YSPACE#0 -- vbuz1=vbuz1_plus_vbuc1 
    lax.z y
    axs #-[YSPACE]
    stx.z y
    // [16] (byte) line#11 ← ++ (byte) line#15 -- vbuz1=_inc_vbuz1 
    inc.z line
    jmp b1
    // main::@1
  b1:
    // [17] if((byte) line#11<(byte) 8) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 
    lda.z line
    cmp #8
    bcc b2_from_b1
    jmp breturn
    // main::@return
  breturn:
    // [18] return 
    rts
}
  // File Data
  p: .fill 2*$40, 0

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b2
Removing instruction jmp b4
Removing instruction jmp b3
Removing instruction jmp b5
Removing instruction jmp b1
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Removing instruction lda #0
Removing instruction lda #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label b4_from_b3 with b4
Replacing label b2_from_b1 with b2
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction main_from_b1:
Removing instruction bend_from_b1:
Removing instruction b2_from_b1:
Removing instruction b4_from_b3:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction b2_from_main:
Removing instruction b4_from_b2:
Removing instruction b3:
Removing instruction b5:
Removing instruction b1:
Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction jmp b2
Removing instruction jmp b4
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_POS_Y OFFSET_STRUCT_POS_Y = (byte) 1
(byte) XSPACE
(const byte) XSPACE#0 XSPACE = (byte) $14
(byte) YSPACE
(const byte) YSPACE#0 YSPACE = (byte) $14
(byte) idx
(byte) idx#1 idx zp ZP_BYTE:4 30.42857142857143
(byte) idx#14 idx zp ZP_BYTE:4 78.5
(byte) idx#15 idx zp ZP_BYTE:4 11.0
(byte) line
(byte) line#11 line zp ZP_BYTE:2 16.5
(byte) line#15 line zp ZP_BYTE:2 2.0
(void()) main()
(byte~) main::$3 reg byte x 151.5
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::@5
(label) main::@return
(struct pos[$40]) p
(const struct pos[$40]) p#0 p = { fill( $40, 0) }
(byte) pos::x
(byte) pos::y
(byte) row
(byte) row#12 reg byte y 151.5
(byte) row#13 reg byte y 33.666666666666664
(byte) x
(byte) x#1 x zp ZP_BYTE:5 22.0
(byte) x#10 x zp ZP_BYTE:5 35.5
(byte) x#15 x zp ZP_BYTE:5 62.8
(byte) x#17 x zp ZP_BYTE:5 22.0
(byte) y
(byte) y#1 y zp ZP_BYTE:3 7.333333333333333
(byte) y#16 y zp ZP_BYTE:3 12.299999999999999

zp ZP_BYTE:2 [ line#15 line#11 ]
zp ZP_BYTE:3 [ y#16 y#1 ]
reg byte y [ row#13 row#12 ]
zp ZP_BYTE:4 [ idx#14 idx#15 idx#1 ]
zp ZP_BYTE:5 [ x#15 x#17 x#10 x#1 ]
reg byte x [ main::$3 ]


FINAL ASSEMBLER
Score: 4851

  // File Comments
// Example of structs that can be optimized by going planar
// https://cc65.github.io/mailarchive/2010-09/8593.html?fbclid=IwAR1IF_cTdyWcFeKU93VfL2Un1EuLjkGh7O7dQ4EVj4kpJzJAj01dbmEFQt8
  // Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
  // Global Constants & labels
  .const OFFSET_STRUCT_POS_Y = 1
  .const XSPACE = $14
  .const YSPACE = $14
  .label x = 5
  .label idx = 4
  .label y = 3
  .label line = 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: {
    // [5] phi from main to main::@2 [phi:main->main::@2]
    // [5] phi (byte) y#16 = (byte) 0 [phi:main->main::@2#0] -- vbuz1=vbuc1 
    lda #0
    sta.z y
    // [5] phi (byte) idx#15 = (byte) 0 [phi:main->main::@2#1] -- vbuz1=vbuc1 
    sta.z idx
    // [5] phi (byte) x#17 = (byte) 0 [phi:main->main::@2#2] -- vbuz1=vbuc1 
    sta.z x
    // [5] phi (byte) line#15 = (byte) 0 [phi:main->main::@2#3] -- vbuz1=vbuc1 
    sta.z line
    // [5] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
    // [5] phi (byte) y#16 = (byte) y#1 [phi:main::@1->main::@2#0] -- register_copy 
    // [5] phi (byte) idx#15 = (byte) idx#1 [phi:main::@1->main::@2#1] -- register_copy 
    // [5] phi (byte) x#17 = (byte) x#10 [phi:main::@1->main::@2#2] -- register_copy 
    // [5] phi (byte) line#15 = (byte) line#11 [phi:main::@1->main::@2#3] -- register_copy 
    // main::@2
  b2:
    // ++x;
    // [6] (byte) x#1 ← ++ (byte) x#17 -- vbuz1=_inc_vbuz1 
    inc.z x
    // [7] phi from main::@2 to main::@4 [phi:main::@2->main::@4]
    // [7] phi (byte) x#15 = (byte) x#1 [phi:main::@2->main::@4#0] -- register_copy 
    // [7] phi (byte) idx#14 = (byte) idx#15 [phi:main::@2->main::@4#1] -- register_copy 
    // [7] phi (byte) row#13 = (byte) 0 [phi:main::@2->main::@4#2] -- vbuyy=vbuc1 
    ldy #0
    // [7] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
    // [7] phi (byte) x#15 = (byte) x#10 [phi:main::@3->main::@4#0] -- register_copy 
    // [7] phi (byte) idx#14 = (byte) idx#1 [phi:main::@3->main::@4#1] -- register_copy 
    // [7] phi (byte) row#13 = (byte) row#12 [phi:main::@3->main::@4#2] -- register_copy 
    // main::@4
  b4:
    // p[idx].y=y
    // [8] (byte~) main::$3 ← (byte) idx#14 << (byte) 1 -- vbuxx=vbuz1_rol_1 
    lda.z idx
    asl
    tax
    // [9] *((byte*)(const struct pos[$40]) p#0+(const byte) OFFSET_STRUCT_POS_Y + (byte~) main::$3) ← (byte) y#16 -- pbuc1_derefidx_vbuxx=vbuz1 
    lda.z y
    sta p+OFFSET_STRUCT_POS_Y,x
    // p[idx].x=x
    // [10] *((byte*)(const struct pos[$40]) p#0 + (byte~) main::$3) ← (byte) x#15 -- pbuc1_derefidx_vbuxx=vbuz1 
    lda.z x
    sta p,x
    // ++idx;
    // [11] (byte) idx#1 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuz1 
    inc.z idx
    // x+=XSPACE
    // [12] (byte) x#10 ← (byte) x#15 + (const byte) XSPACE#0 -- vbuz1=vbuz1_plus_vbuc1 
    lax.z x
    axs #-[XSPACE]
    stx.z x
    // for (row=0;row<8;++row)
    // [13] (byte) row#12 ← ++ (byte) row#13 -- vbuyy=_inc_vbuyy 
    iny
    // main::@3
    // [14] if((byte) row#12<(byte) 8) goto main::@4 -- vbuyy_lt_vbuc1_then_la1 
    cpy #8
    bcc b4
    // main::@5
    // y+=YSPACE
    // [15] (byte) y#1 ← (byte) y#16 + (const byte) YSPACE#0 -- vbuz1=vbuz1_plus_vbuc1 
    lax.z y
    axs #-[YSPACE]
    stx.z y
    // for (line=0;line<8;++line)
    // [16] (byte) line#11 ← ++ (byte) line#15 -- vbuz1=_inc_vbuz1 
    inc.z line
    // main::@1
    // [17] if((byte) line#11<(byte) 8) goto main::@2 -- vbuz1_lt_vbuc1_then_la1 
    lda.z line
    cmp #8
    bcc b2
    // main::@return
    // }
    // [18] return 
    rts
}
  // File Data
  p: .fill 2*$40, 0

