Eliminating unused variable with no statement main::$0
Eliminating unused variable with no statement main::$1
Eliminating unused variable with no statement fct::$0

CONTROL FLOW GRAPH SSA

void main()
main: scope:[main]  from __start
  main::z#0 = (char *)$450
  main::z#0[2] = $f0
  main::z#0[3] = $f
  main::x#0 = $aa
  fct::x#0 = main::x#0
  fct::z#0 = main::z#0
  call fct
  fct::return#0 = fct::return#3
  to:main::@1
main::@1: scope:[main]  from main
  main::z#2 = phi( main/main::z#0 )
  fct::return#4 = phi( main/fct::return#0 )
  main::a1#0 = fct::return#4
  main::screen[0] = main::a1#0
  main::z#1 = ++ main::z#2
  main::x#1 = $55
  fct::x#1 = main::x#1
  fct::z#1 = main::z#1
  call fct
  fct::return#1 = fct::return#3
  to:main::@2
main::@2: scope:[main]  from main::@1
  fct::return#5 = phi( main::@1/fct::return#1 )
  main::a2#0 = fct::return#5
  main::screen[1] = main::a2#0
  to:main::@return
main::@return: scope:[main]  from main::@2
  return 
  to:@return

char fct(char x , char *z)
fct: scope:[fct]  from main main::@1
  fct::z#2 = phi( main/fct::z#0, main::@1/fct::z#1 )
  fct::x#2 = phi( main/fct::x#0, main::@1/fct::x#1 )
  fct::a#0 = fct::x#2 & fct::z#2[2]
  fct::return#2 = fct::a#0
  to:fct::@return
fct::@return: scope:[fct]  from fct
  fct::return#6 = phi( fct/fct::return#2 )
  fct::return#3 = fct::return#6
  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
void __start()
char fct(char x , char *z)
char fct::a // !reg byte a
char fct::a#0 // !reg byte a
char fct::return
char fct::return#0
char fct::return#1
char fct::return#2
char fct::return#3
char fct::return#4
char fct::return#5
char fct::return#6
char fct::x
char fct::x#0
char fct::x#1
char fct::x#2
char *fct::z
char *fct::z#0
char *fct::z#1
char *fct::z#2
void main()
char main::a1
char main::a1#0
char main::a2
char main::a2#0
__constant char *main::screen = (char *)$400
char main::x
char main::x#0
char main::x#1
char *main::z
char *main::z#0
char *main::z#1
char *main::z#2

Adding number conversion cast (unumber) $f0 in main::z#0[2] = $f0
Adding number conversion cast (unumber) 2 in main::z#0[2] = ((unumber)) $f0
Adding number conversion cast (unumber) $f in main::z#0[3] = $f
Adding number conversion cast (unumber) 3 in main::z#0[3] = ((unumber)) $f
Adding number conversion cast (unumber) 0 in main::screen[0] = main::a1#0
Adding number conversion cast (unumber) $55 in main::x#1 = $55
Adding number conversion cast (unumber) 1 in main::screen[1] = main::a2#0
Adding number conversion cast (unumber) 2 in fct::a#0 = fct::x#2 & fct::z#2[2]
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast main::z#0[(unumber)2] = (unumber)$f0
Inlining cast main::z#0[(unumber)3] = (unumber)$f
Inlining cast main::x#1 = (unumber)$55
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant pointer cast (char *) 1104
Simplifying constant integer cast $f0
Simplifying constant integer cast 2
Simplifying constant integer cast $f
Simplifying constant integer cast 3
Simplifying constant integer cast 0
Simplifying constant integer cast $55
Simplifying constant integer cast 1
Simplifying constant integer cast 2
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) $f0
Finalized unsigned number type (char) 2
Finalized unsigned number type (char) $f
Finalized unsigned number type (char) 3
Finalized unsigned number type (char) 0
Finalized unsigned number type (char) $55
Finalized unsigned number type (char) 1
Finalized unsigned number type (char) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias fct::return#0 = fct::return#4 
Alias main::z#0 = main::z#2 
Alias fct::return#1 = fct::return#5 
Alias fct::return#2 = fct::a#0 fct::return#6 fct::return#3 
Successful SSA optimization Pass2AliasElimination
Constant main::z#0 = (char *) 1104
Constant main::x#0 = $aa
Constant main::x#1 = $55
Successful SSA optimization Pass2ConstantIdentification
Constant fct::x#0 = main::x#0
Constant fct::z#0 = main::z#0
Constant fct::x#1 = main::x#1
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero main::screen in [9] main::screen[0] = main::a1#0
Successful SSA optimization PassNSimplifyExpressionWithZero
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
Constant right-side identified [6] main::z#1 = ++ main::z#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant main::z#1 = ++main::z#0
Successful SSA optimization Pass2ConstantIdentification
Constant fct::z#1 = main::z#1
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings main::z#0
Inlining constant with different constant siblings main::x#0
Inlining constant with different constant siblings main::x#1
Inlining constant with different constant siblings main::z#1
Inlining constant with var siblings fct::x#0
Inlining constant with var siblings fct::z#0
Inlining constant with var siblings fct::x#1
Inlining constant with var siblings fct::z#1
Constant inlined fct::z#0 = (char *) 1104
Constant inlined fct::z#1 = ++(char *) 1104
Constant inlined main::z#0 = (char *) 1104
Constant inlined main::z#1 = ++(char *) 1104
Constant inlined main::x#0 = $aa
Constant inlined main::x#1 = $55
Constant inlined fct::x#0 = $aa
Constant inlined fct::x#1 = $55
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *((char *) 1104+2)
Consolidated array index constant in *((char *) 1104+3)
Consolidated array index constant in *(main::screen+1)
Successful SSA optimization Pass2ConstantAdditionElimination
CALL GRAPH
Calls in [main] to fct:2 fct:6 

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

FINAL CONTROL FLOW GRAPH

void main()
main: scope:[main]  from
  [0] *((char *) 1104+2) = $f0
  [1] *((char *) 1104+3) = $f
  [2] call fct
  [3] fct::return#0 = fct::return#2
  to:main::@1
main::@1: scope:[main]  from main
  [4] main::a1#0 = fct::return#0
  [5] *main::screen = main::a1#0
  [6] call fct
  [7] fct::return#1 = fct::return#2
  to:main::@2
main::@2: scope:[main]  from main::@1
  [8] main::a2#0 = fct::return#1
  [9] *(main::screen+1) = main::a2#0
  to:main::@return
main::@return: scope:[main]  from main::@2
  [10] return 
  to:@return

char fct(char x , char *z)
fct: scope:[fct]  from main main::@1
  [11] fct::z#2 = phi( main/(char *) 1104, main::@1/++(char *) 1104 )
  [11] fct::x#2 = phi( main/$aa, main::@1/$55 )
  [12] fct::return#2 = fct::x#2 & fct::z#2[2]
  to:fct::@return
fct::@return: scope:[fct]  from fct
  [13] return 
  to:@return


VARIABLE REGISTER WEIGHTS
char fct(char x , char *z)
char fct::a // !reg byte a
char fct::return
char fct::return#0 // 4.0
char fct::return#1 // 4.0
char fct::return#2 // 3.75
char fct::x
char fct::x#2 // 11.0
char *fct::z
char *fct::z#2 // 11.0
void main()
char main::a1
char main::a1#0 // 4.0
char main::a2
char main::a2#0 // 4.0
char main::x
char *main::z

Initial phi equivalence classes
[ fct::x#2 ]
[ fct::z#2 ]
Added variable fct::return#0 to live range equivalence class [ fct::return#0 ]
Added variable main::a1#0 to live range equivalence class [ main::a1#0 ]
Added variable fct::return#1 to live range equivalence class [ fct::return#1 ]
Added variable main::a2#0 to live range equivalence class [ main::a2#0 ]
Added variable fct::return#2 to live range equivalence class [ fct::return#2 ]
Complete equivalence classes
[ fct::x#2 ]
[ fct::z#2 ]
[ fct::return#0 ]
[ main::a1#0 ]
[ fct::return#1 ]
[ main::a2#0 ]
[ fct::return#2 ]
Allocated zp[1]:2 [ fct::x#2 ]
Allocated zp[2]:3 [ fct::z#2 ]
Allocated zp[1]:5 [ fct::return#0 ]
Allocated zp[1]:6 [ main::a1#0 ]
Allocated zp[1]:7 [ fct::return#1 ]
Allocated zp[1]:8 [ main::a2#0 ]
Allocated zp[1]:9 [ fct::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((char *) 1104+2) = $f0 [ ] (  [ ] { { fct::return#0 = fct::return#2 } }  ) always clobbers reg byte a 
Statement [1] *((char *) 1104+3) = $f [ ] (  [ ] { { fct::return#0 = fct::return#2 } }  ) always clobbers reg byte a 
Statement [12] fct::return#2 = fct::x#2 & fct::z#2[2] [ fct::return#2 ] ( fct:2 [ fct::return#2 ] { { fct::return#0 = fct::return#2 } }  fct:6 [ fct::return#2 ] { { fct::return#1 = fct::return#2 } }  ) always clobbers reg byte a reg byte y 
Potential registers zp[1]:2 [ fct::x#2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , 
Potential registers zp[2]:3 [ fct::z#2 ] : zp[2]:3 , 
Potential registers zp[1]:5 [ fct::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , 
Potential registers zp[1]:6 [ main::a1#0 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y , 
Potential registers zp[1]:7 [ fct::return#1 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y , 
Potential registers zp[1]:8 [ main::a2#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y , 
Potential registers zp[1]:9 [ fct::return#2 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y , 

REGISTER UPLIFT SCOPES
Uplift Scope [fct] 11: zp[1]:2 [ fct::x#2 ] 11: zp[2]:3 [ fct::z#2 ] 4: zp[1]:5 [ fct::return#0 ] 4: zp[1]:7 [ fct::return#1 ] 3.75: zp[1]:9 [ fct::return#2 ] 
Uplift Scope [main] 4: zp[1]:6 [ main::a1#0 ] 4: zp[1]:8 [ main::a2#0 ] 
Uplift Scope [] 

Uplifting [fct] best 101 combination reg byte x [ fct::x#2 ] zp[2]:3 [ fct::z#2 ] reg byte a [ fct::return#0 ] reg byte a [ fct::return#1 ] reg byte a [ fct::return#2 ] 
Limited combination testing to 100 combinations of 256 possible.
Uplifting [main] best 89 combination reg byte a [ main::a1#0 ] reg byte a [ main::a2#0 ] 
Uplifting [] best 89 combination 
Allocated (was zp[2]:3) zp[2]:2 [ fct::z#2 ]

ASSEMBLER BEFORE OPTIMIZATION
  // File Comments
// Tests a sub-optimal fragment synthesis
// vbuaa=vbuxx_band_pbuz1_derefidx_vbuc1 < vbuaa=pbuz1_derefidx_vbuc1_band_vbuxx < vbuaa=pbuz1_derefidx_vbuaa_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuaa < vbuaa=vbuaa_band_pbuz1_derefidx_vbuyy - clobber:A Y  cycles:11.5
  // Upstart
  // Commodore 64 PRG executable file
.file [name="fragment-synth.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
.segment Code
  // main
main: {
    .label screen = $400
    // [0] *((char *) 1104+2) = $f0 -- _deref_pbuc1=vbuc2 
    lda #$f0
    sta $450+2
    // [1] *((char *) 1104+3) = $f -- _deref_pbuc1=vbuc2 
    lda #$f
    sta $450+3
    // [2] call fct
    // [11] phi from main to fct [phi:main->fct]
  fct_from_main:
    // [11] phi fct::z#2 = (char *) 1104 [phi:main->fct#0] -- pbuz1=pbuc1 
    lda #<$450
    sta.z fct.z
    lda #>$450
    sta.z fct.z+1
    // [11] phi fct::x#2 = $aa [phi:main->fct#1] -- vbuxx=vbuc1 
    ldx #$aa
    jsr fct
    // [3] fct::return#0 = fct::return#2
    jmp __b1
    // main::@1
  __b1:
    // [4] main::a1#0 = fct::return#0
    // [5] *main::screen = main::a1#0 -- _deref_pbuc1=vbuaa 
    sta screen
    // [6] call fct
    // [11] phi from main::@1 to fct [phi:main::@1->fct]
  fct_from___b1:
    // [11] phi fct::z#2 = ++(char *) 1104 [phi:main::@1->fct#0] -- pbuz1=pbuc1 
    lda #<$450+1
    sta.z fct.z
    lda #>$450+1
    sta.z fct.z+1
    // [11] phi fct::x#2 = $55 [phi:main::@1->fct#1] -- vbuxx=vbuc1 
    ldx #$55
    jsr fct
    // [7] fct::return#1 = fct::return#2
    jmp __b2
    // main::@2
  __b2:
    // [8] main::a2#0 = fct::return#1
    // [9] *(main::screen+1) = main::a2#0 -- _deref_pbuc1=vbuaa 
    sta screen+1
    jmp __breturn
    // main::@return
  __breturn:
    // [10] return 
    rts
}
  // fct
// __register(A) char fct(__register(X) char x, __zp(2) char *z)
fct: {
    .label z = 2
    // [12] fct::return#2 = fct::x#2 & fct::z#2[2] -- vbuaa=vbuxx_band_pbuz1_derefidx_vbuc1 
    ldy #2
    txa
    and (z),y
    jmp __breturn
    // fct::@return
  __breturn:
    // [13] return 
    rts
}
  // File Data

ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction fct_from_main:
Removing instruction __b1:
Removing instruction fct_from___b1:
Removing instruction __b2:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination

FINAL SYMBOL TABLE
char fct(char x , char *z)
char fct::a // !reg byte a
char fct::return
char fct::return#0 // reg byte a 4.0
char fct::return#1 // reg byte a 4.0
char fct::return#2 // reg byte a 3.75
char fct::x
char fct::x#2 // reg byte x 11.0
char *fct::z
char *fct::z#2 // z zp[2]:2 11.0
void main()
char main::a1
char main::a1#0 // reg byte a 4.0
char main::a2
char main::a2#0 // reg byte a 4.0
__constant char *main::screen = (char *) 1024
char main::x
char *main::z

reg byte x [ fct::x#2 ]
zp[2]:2 [ fct::z#2 ]
reg byte a [ fct::return#0 ]
reg byte a [ main::a1#0 ]
reg byte a [ fct::return#1 ]
reg byte a [ main::a2#0 ]
reg byte a [ fct::return#2 ]


FINAL ASSEMBLER
Score: 77

  // File Comments
// Tests a sub-optimal fragment synthesis
// vbuaa=vbuxx_band_pbuz1_derefidx_vbuc1 < vbuaa=pbuz1_derefidx_vbuc1_band_vbuxx < vbuaa=pbuz1_derefidx_vbuaa_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuxx < vbuaa=pbuz1_derefidx_vbuyy_band_vbuaa < vbuaa=vbuaa_band_pbuz1_derefidx_vbuyy - clobber:A Y  cycles:11.5
  // Upstart
  // Commodore 64 PRG executable file
.file [name="fragment-synth.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
.segment Code
  // main
main: {
    .label screen = $400
    // z[2] = $f0
    // [0] *((char *) 1104+2) = $f0 -- _deref_pbuc1=vbuc2 
    lda #$f0
    sta $450+2
    // z[3] = $0f
    // [1] *((char *) 1104+3) = $f -- _deref_pbuc1=vbuc2 
    lda #$f
    sta $450+3
    // byte a1 = fct(x, z)
    // [2] call fct
    // [11] phi from main to fct [phi:main->fct]
    // [11] phi fct::z#2 = (char *) 1104 [phi:main->fct#0] -- pbuz1=pbuc1 
    lda #<$450
    sta.z fct.z
    lda #>$450
    sta.z fct.z+1
    // [11] phi fct::x#2 = $aa [phi:main->fct#1] -- vbuxx=vbuc1 
    ldx #$aa
    jsr fct
    // byte a1 = fct(x, z)
    // [3] fct::return#0 = fct::return#2
    // main::@1
    // [4] main::a1#0 = fct::return#0
    // screen[0] = a1
    // [5] *main::screen = main::a1#0 -- _deref_pbuc1=vbuaa 
    sta screen
    // byte a2 = fct(x, z)
    // [6] call fct
    // [11] phi from main::@1 to fct [phi:main::@1->fct]
    // [11] phi fct::z#2 = ++(char *) 1104 [phi:main::@1->fct#0] -- pbuz1=pbuc1 
    lda #<$450+1
    sta.z fct.z
    lda #>$450+1
    sta.z fct.z+1
    // [11] phi fct::x#2 = $55 [phi:main::@1->fct#1] -- vbuxx=vbuc1 
    ldx #$55
    jsr fct
    // byte a2 = fct(x, z)
    // [7] fct::return#1 = fct::return#2
    // main::@2
    // [8] main::a2#0 = fct::return#1
    // screen[1] = a2
    // [9] *(main::screen+1) = main::a2#0 -- _deref_pbuc1=vbuaa 
    sta screen+1
    // main::@return
    // }
    // [10] return 
    rts
}
  // fct
// __register(A) char fct(__register(X) char x, __zp(2) char *z)
fct: {
    .label z = 2
    // byte register(A) a = x & z[2]
    // [12] fct::return#2 = fct::x#2 & fct::z#2[2] -- vbuaa=vbuxx_band_pbuz1_derefidx_vbuc1 
    ldy #2
    txa
    and (z),y
    // fct::@return
    // }
    // [13] return 
    rts
}
  // File Data

