1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-02 00:41:42 +00:00
kickc/src/test/ref/plus-0.log
2019-04-20 22:12:56 +02:00

768 lines
30 KiB
Plaintext

CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@2
main: scope:[main] from @2
(byte*~) main::$0 ← ((byte*)) (word/signed word/dword/signed dword) $400
(byte*) fill::screen#0 ← (byte*~) main::$0
(byte) fill::ch#0 ← (byte) 'a'
call fill
to:main::@1
main::@1: scope:[main] from main
(byte*~) main::$2 ← ((byte*)) (word/signed word/dword/signed dword) $2000
(byte*) fill::screen#1 ← (byte*~) main::$2
(byte) fill::ch#1 ← (byte) 'b'
call fill
to:main::@2
main::@2: scope:[main] from main::@1
to:main::@return
main::@return: scope:[main] from main::@2
return
to:@return
fill: scope:[fill] from main main::@1
(byte) fill::ch#4 ← phi( main/(byte) fill::ch#0 main::@1/(byte) fill::ch#1 )
(byte*) fill::screen#4 ← phi( main/(byte*) fill::screen#0 main::@1/(byte*) fill::screen#1 )
(byte) fill::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:fill::@1
fill::@1: scope:[fill] from fill fill::@3
(byte) fill::i#4 ← phi( fill/(byte) fill::i#0 fill::@3/(byte) fill::i#1 )
(byte) fill::ch#3 ← phi( fill/(byte) fill::ch#4 fill::@3/(byte) fill::ch#5 )
(byte*) fill::screen#3 ← phi( fill/(byte*) fill::screen#4 fill::@3/(byte*) fill::screen#5 )
(byte) fill::j#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
to:fill::@2
fill::@2: scope:[fill] from fill::@1 fill::@2
(byte) fill::i#2 ← phi( fill::@1/(byte) fill::i#4 fill::@2/(byte) fill::i#2 )
(byte) fill::ch#2 ← phi( fill::@1/(byte) fill::ch#3 fill::@2/(byte) fill::ch#2 )
(byte*) fill::screen#2 ← phi( fill::@1/(byte*) fill::screen#3 fill::@2/(byte*) fill::screen#2 )
(byte) fill::j#2 ← phi( fill::@1/(byte) fill::j#0 fill::@2/(byte) fill::j#1 )
(byte/signed word/word/dword/signed dword~) fill::$0 ← (byte) fill::j#2 * (byte/signed byte/word/signed word/dword/signed dword) $28
(byte*~) fill::$1 ← (byte*) fill::screen#2 + (byte/signed word/word/dword/signed dword~) fill::$0
*((byte*~) fill::$1 + (byte) fill::i#2) ← (byte) fill::ch#2
(byte) fill::j#1 ← (byte) fill::j#2 + rangenext(0,2)
(bool~) fill::$2 ← (byte) fill::j#1 != rangelast(0,2)
unroll if((bool~) fill::$2) goto fill::@2
to:fill::@3
fill::@3: scope:[fill] from fill::@2
(byte) fill::ch#5 ← phi( fill::@2/(byte) fill::ch#2 )
(byte*) fill::screen#5 ← phi( fill::@2/(byte*) fill::screen#2 )
(byte) fill::i#3 ← phi( fill::@2/(byte) fill::i#2 )
(byte) fill::i#1 ← (byte) fill::i#3 + rangenext(0,$27)
(bool~) fill::$3 ← (byte) fill::i#1 != rangelast(0,$27)
if((bool~) fill::$3) goto fill::@1
to:fill::@return
fill::@return: scope:[fill] from fill::@3
return
to:@return
@2: scope:[] from @begin
call main
to:@3
@3: scope:[] from @2
to:@end
@end: scope:[] from @3
SYMBOL TABLE SSA
(label) @2
(label) @3
(label) @begin
(label) @end
(void()) fill((byte*) fill::screen , (byte) fill::ch)
(byte/signed word/word/dword/signed dword~) fill::$0
(byte*~) fill::$1
(bool~) fill::$2
(bool~) fill::$3
(label) fill::@1
(label) fill::@2
(label) fill::@3
(label) fill::@return
(byte) fill::ch
(byte) fill::ch#0
(byte) fill::ch#1
(byte) fill::ch#2
(byte) fill::ch#3
(byte) fill::ch#4
(byte) fill::ch#5
(byte) fill::i
(byte) fill::i#0
(byte) fill::i#1
(byte) fill::i#2
(byte) fill::i#3
(byte) fill::i#4
(byte) fill::j
(byte) fill::j#0
(byte) fill::j#1
(byte) fill::j#2
(byte*) fill::screen
(byte*) fill::screen#0
(byte*) fill::screen#1
(byte*) fill::screen#2
(byte*) fill::screen#3
(byte*) fill::screen#4
(byte*) fill::screen#5
(void()) main()
(byte*~) main::$0
(byte*~) main::$2
(label) main::@1
(label) main::@2
(label) main::@return
Culled Empty Block (label) main::@2
Culled Empty Block (label) @3
Successful SSA optimization Pass2CullEmptyBlocks
Alias (byte*) fill::screen#0 = (byte*~) main::$0
Alias (byte*) fill::screen#1 = (byte*~) main::$2
Alias (byte) fill::i#2 = (byte) fill::i#3
Alias (byte*) fill::screen#2 = (byte*) fill::screen#5
Alias (byte) fill::ch#2 = (byte) fill::ch#5
Successful SSA optimization Pass2AliasElimination
Self Phi Eliminated (byte*) fill::screen#2
Self Phi Eliminated (byte) fill::ch#2
Self Phi Eliminated (byte) fill::i#2
Successful SSA optimization Pass2SelfPhiElimination
Redundant Phi (byte*) fill::screen#2 (byte*) fill::screen#3
Redundant Phi (byte) fill::ch#2 (byte) fill::ch#3
Redundant Phi (byte) fill::i#2 (byte) fill::i#4
Successful SSA optimization Pass2RedundantPhiElimination
Simple Condition (bool~) fill::$2 [19] unroll if((byte) fill::j#1!=rangelast(0,2)) goto fill::@2
Simple Condition (bool~) fill::$3 [23] if((byte) fill::i#1!=rangelast(0,$27)) goto fill::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) fill::screen#0 = ((byte*))$400
Constant (const byte) fill::ch#0 = 'a'
Constant (const byte*) fill::screen#1 = ((byte*))$2000
Constant (const byte) fill::ch#1 = 'b'
Constant (const byte) fill::i#0 = 0
Constant (const byte) fill::j#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value fill::j#1 ← ++ fill::j#2 to ++
Resolved ranged comparison value unroll if(fill::j#1!=rangelast(0,2)) goto fill::@2 to (byte/signed byte/word/signed word/dword/signed dword) 3
Resolved ranged next value fill::i#1 ← ++ fill::i#4 to ++
Resolved ranged comparison value if(fill::i#1!=rangelast(0,$27)) goto fill::@1 to (byte/signed byte/word/signed word/dword/signed dword) $28
Self Phi Eliminated (byte*) fill::screen#3
Self Phi Eliminated (byte) fill::ch#3
Successful SSA optimization Pass2SelfPhiElimination
Redundant Phi (byte*) fill::screen#3 (byte*) fill::screen#4
Redundant Phi (byte) fill::ch#3 (byte) fill::ch#4
Successful SSA optimization Pass2RedundantPhiElimination
Unrolling loop Loop head: fill::@2 tails: fill::@2 blocks: fill::@2
Successful SSA optimization Pass2LoopUnroll
Redundant Phi (byte) fill::j#2 (const byte) fill::j#0
Successful SSA optimization Pass2RedundantPhiElimination
Constant (const byte/signed word/word/dword/signed dword) fill::$0 = fill::j#0*$28
Constant (const byte) fill::j#1 = ++fill::j#0
Successful SSA optimization Pass2ConstantIdentification
Removed zero-constant in assignment fill::$1
if() condition always true - replacing block destination [7] if((const byte) fill::j#1!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto fill::@2_1
Successful SSA optimization Pass2ConstantIfs
Eliminating unused constant (const byte/signed word/word/dword/signed dword) fill::$0
Successful SSA optimization PassNEliminateUnusedVars
Alias (byte*) fill::screen#4 = (byte*~) fill::$1
Successful SSA optimization Pass2AliasElimination
Unrolling loop Loop head: fill::@2_1 tails: fill::@2_1 blocks: fill::@2_1
Successful SSA optimization Pass2LoopUnroll
Redundant Phi (byte) fill::j#3 (const byte) fill::j#1
Successful SSA optimization Pass2RedundantPhiElimination
Constant (const byte/signed word/word/dword/signed dword) fill::$4 = fill::j#1*$28
Constant (const byte) fill::j#4 = ++fill::j#1
Successful SSA optimization Pass2ConstantIdentification
if() condition always true - replacing block destination [9] if((const byte) fill::j#4!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto fill::@2_2
Successful SSA optimization Pass2ConstantIfs
Unrolling loop Loop head: fill::@2_2 tails: fill::@2_2 blocks: fill::@2_2
Successful SSA optimization Pass2LoopUnroll
Redundant Phi (byte) fill::j#5 (const byte) fill::j#4
Successful SSA optimization Pass2RedundantPhiElimination
Constant (const byte/signed word/word/dword/signed dword) fill::$6 = fill::j#4*$28
Constant (const byte) fill::j#6 = ++fill::j#4
Successful SSA optimization Pass2ConstantIdentification
Removing PHI-reference to removed block (fill::@2_2) in block fill::@2_3
if() condition always false - eliminating [11] if((const byte) fill::j#6!=(byte/signed byte/word/signed word/dword/signed dword) 3) goto fill::@2_3
Successful SSA optimization Pass2ConstantIfs
Eliminating unused constant (const byte) fill::j#6
Successful SSA optimization PassNEliminateUnusedVars
Eliminating variable (byte) fill::j#7 from unused block fill::@2_3
Eliminating variable (byte/signed word/word/dword/signed dword~) fill::$8 from unused block fill::@2_3
Eliminating variable (byte*~) fill::$9 from unused block fill::@2_3
Eliminating variable (byte) fill::j#8 from unused block fill::@2_3
Removing unused block fill::@2_3
Successful SSA optimization Pass2EliminateUnusedBlocks
Inlining constant with var siblings (const byte*) fill::screen#0
Inlining constant with var siblings (const byte) fill::ch#0
Inlining constant with var siblings (const byte*) fill::screen#1
Inlining constant with var siblings (const byte) fill::ch#1
Inlining constant with var siblings (const byte) fill::i#0
Inlining constant with different constant siblings (const byte) fill::j#0
Inlining constant with different constant siblings (const byte) fill::j#1
Inlining constant with different constant siblings (const byte) fill::j#4
Constant inlined fill::j#4 = ++++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined fill::ch#0 = (byte) 'a'
Constant inlined fill::screen#1 = ((byte*))(word/signed word/dword/signed dword) $2000
Constant inlined fill::screen#0 = ((byte*))(word/signed word/dword/signed dword) $400
Constant inlined fill::i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined fill::$6 = ++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) $28
Constant inlined fill::ch#1 = (byte) 'b'
Constant inlined fill::j#1 = ++(byte/signed byte/word/signed word/dword/signed dword) 0
Constant inlined fill::$4 = ++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) $28
Constant inlined fill::j#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
Successful SSA optimization Pass2ConstantInlining
Simplifying constant integer increment ++0
Simplifying constant integer increment ++0
Successful SSA optimization Pass2ConstantSimplification
Simplifying constant integer increment ++1
Successful SSA optimization Pass2ConstantSimplification
Added new block during phi lifting fill::@5(between fill::@3 and fill::@1)
Adding NOP phi() at start of @begin
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
CALL GRAPH
Calls in [] to main:2
Calls in [main] to fill:5 fill:7
Created 3 initial phi equivalence classes
Coalesced [19] fill::i#5 ← fill::i#1
Coalesced down to 3 phi equivalence classes
Culled Empty Block (label) fill::@5
Renumbering block @2 to @1
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
Adding NOP phi() at start of main::@1
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()
[5] call fill
to:main::@1
main::@1: scope:[main] from main
[6] phi()
[7] call fill
to:main::@return
main::@return: scope:[main] from main::@1
[8] return
to:@return
fill: scope:[fill] from main main::@1
[9] (byte) fill::ch#4 ← phi( main/(byte) 'a' main::@1/(byte) 'b' )
[9] (byte*) fill::screen#4 ← phi( main/((byte*))(word/signed word/dword/signed dword) $400 main::@1/((byte*))(word/signed word/dword/signed dword) $2000 )
to:fill::@1
fill::@1: scope:[fill] from fill fill::@3
[10] (byte) fill::i#4 ← phi( fill/(byte/signed byte/word/signed word/dword/signed dword) 0 fill::@3/(byte) fill::i#1 )
to:fill::@2
fill::@2: scope:[fill] from fill::@1
[11] *((byte*) fill::screen#4 + (byte) fill::i#4) ← (byte) fill::ch#4
to:fill::@2_1
fill::@2_1: scope:[fill] from fill::@2
[12] (byte*~) fill::$5 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28
[13] *((byte*~) fill::$5 + (byte) fill::i#4) ← (byte) fill::ch#4
to:fill::@2_2
fill::@2_2: scope:[fill] from fill::@2_1
[14] (byte*~) fill::$7 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28
[15] *((byte*~) fill::$7 + (byte) fill::i#4) ← (byte) fill::ch#4
to:fill::@3
fill::@3: scope:[fill] from fill::@2_2
[16] (byte) fill::i#1 ← ++ (byte) fill::i#4
[17] if((byte) fill::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $28) goto fill::@1
to:fill::@return
fill::@return: scope:[fill] from fill::@3
[18] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) fill((byte*) fill::screen , (byte) fill::ch)
(byte*~) fill::$5 22.0
(byte*~) fill::$7 22.0
(byte) fill::ch
(byte) fill::ch#4 3.666666666666667
(byte) fill::i
(byte) fill::i#1 16.5
(byte) fill::i#4 9.166666666666666
(byte) fill::j
(byte*) fill::screen
(byte*) fill::screen#4 3.666666666666667
(void()) main()
Initial phi equivalence classes
[ fill::screen#4 ]
[ fill::ch#4 ]
[ fill::i#4 fill::i#1 ]
Added variable fill::$5 to zero page equivalence class [ fill::$5 ]
Added variable fill::$7 to zero page equivalence class [ fill::$7 ]
Complete equivalence classes
[ fill::screen#4 ]
[ fill::ch#4 ]
[ fill::i#4 fill::i#1 ]
[ fill::$5 ]
[ fill::$7 ]
Allocated zp ZP_WORD:2 [ fill::screen#4 ]
Allocated zp ZP_BYTE:4 [ fill::ch#4 ]
Allocated zp ZP_BYTE:5 [ fill::i#4 fill::i#1 ]
Allocated zp ZP_WORD:6 [ fill::$5 ]
Allocated zp ZP_WORD:8 [ fill::$7 ]
INITIAL ASM
//SEG0 File Comments
// Tests elimination of plus 0
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//SEG3 @begin
bbegin:
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
//SEG5 @1
b1:
//SEG6 [2] call main
//SEG7 [4] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG9 @end
bend:
//SEG10 main
main: {
//SEG11 [5] call fill
//SEG12 [9] phi from main to fill [phi:main->fill]
fill_from_main:
//SEG13 [9] phi (byte) fill::ch#4 = (byte) 'a' [phi:main->fill#0] -- vbuz1=vbuc1
lda #'a'
sta fill.ch
//SEG14 [9] phi (byte*) fill::screen#4 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:main->fill#1] -- pbuz1=pbuc1
lda #<$400
sta fill.screen
lda #>$400
sta fill.screen+1
jsr fill
//SEG15 [6] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
jmp b1
//SEG16 main::@1
b1:
//SEG17 [7] call fill
//SEG18 [9] phi from main::@1 to fill [phi:main::@1->fill]
fill_from_b1:
//SEG19 [9] phi (byte) fill::ch#4 = (byte) 'b' [phi:main::@1->fill#0] -- vbuz1=vbuc1
lda #'b'
sta fill.ch
//SEG20 [9] phi (byte*) fill::screen#4 = ((byte*))(word/signed word/dword/signed dword) $2000 [phi:main::@1->fill#1] -- pbuz1=pbuc1
lda #<$2000
sta fill.screen
lda #>$2000
sta fill.screen+1
jsr fill
jmp breturn
//SEG21 main::@return
breturn:
//SEG22 [8] return
rts
}
//SEG23 fill
// fill(byte* zeropage(2) screen, byte zeropage(4) ch)
fill: {
.label i = 5
.label screen = 2
.label ch = 4
.label _5 = 6
.label _7 = 8
//SEG24 [10] phi from fill to fill::@1 [phi:fill->fill::@1]
b1_from_fill:
//SEG25 [10] phi (byte) fill::i#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:fill->fill::@1#0] -- vbuz1=vbuc1
lda #0
sta i
jmp b1
//SEG26 [10] phi from fill::@3 to fill::@1 [phi:fill::@3->fill::@1]
b1_from_b3:
//SEG27 [10] phi (byte) fill::i#4 = (byte) fill::i#1 [phi:fill::@3->fill::@1#0] -- register_copy
jmp b1
//SEG28 fill::@1
b1:
jmp b2
//SEG29 fill::@2
b2:
//SEG30 [11] *((byte*) fill::screen#4 + (byte) fill::i#4) ← (byte) fill::ch#4 -- pbuz1_derefidx_vbuz2=vbuz3
lda ch
ldy i
sta (screen),y
jmp b2_1
//SEG31 fill::@2_1
b2_1:
//SEG32 [12] (byte*~) fill::$5 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 -- pbuz1=pbuz2_plus_vbuc1
lda #1*$28
clc
adc screen
sta _5
lda #0
adc screen+1
sta _5+1
//SEG33 [13] *((byte*~) fill::$5 + (byte) fill::i#4) ← (byte) fill::ch#4 -- pbuz1_derefidx_vbuz2=vbuz3
lda ch
ldy i
sta (_5),y
jmp b2_2
//SEG34 fill::@2_2
b2_2:
//SEG35 [14] (byte*~) fill::$7 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 -- pbuz1=pbuz2_plus_vbuc1
lda #2*$28
clc
adc screen
sta _7
lda #0
adc screen+1
sta _7+1
//SEG36 [15] *((byte*~) fill::$7 + (byte) fill::i#4) ← (byte) fill::ch#4 -- pbuz1_derefidx_vbuz2=vbuz3
lda ch
ldy i
sta (_7),y
jmp b3
//SEG37 fill::@3
b3:
//SEG38 [16] (byte) fill::i#1 ← ++ (byte) fill::i#4 -- vbuz1=_inc_vbuz1
inc i
//SEG39 [17] if((byte) fill::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $28) goto fill::@1 -- vbuz1_neq_vbuc1_then_la1
lda #$28
cmp i
bne b1_from_b3
jmp breturn
//SEG40 fill::@return
breturn:
//SEG41 [18] return
rts
}
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [12] (byte*~) fill::$5 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$5 ] ( main:2::fill:5 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$5 ] main:2::fill:7 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$5 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:4 [ fill::ch#4 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:5 [ fill::i#4 fill::i#1 ]
Statement [13] *((byte*~) fill::$5 + (byte) fill::i#4) ← (byte) fill::ch#4 [ fill::screen#4 fill::ch#4 fill::i#4 ] ( main:2::fill:5 [ fill::screen#4 fill::ch#4 fill::i#4 ] main:2::fill:7 [ fill::screen#4 fill::ch#4 fill::i#4 ] ) always clobbers reg byte a
Statement [14] (byte*~) fill::$7 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$7 ] ( main:2::fill:5 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$7 ] main:2::fill:7 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$7 ] ) always clobbers reg byte a
Statement [15] *((byte*~) fill::$7 + (byte) fill::i#4) ← (byte) fill::ch#4 [ fill::screen#4 fill::ch#4 fill::i#4 ] ( main:2::fill:5 [ fill::screen#4 fill::ch#4 fill::i#4 ] main:2::fill:7 [ fill::screen#4 fill::ch#4 fill::i#4 ] ) always clobbers reg byte a
Statement [11] *((byte*) fill::screen#4 + (byte) fill::i#4) ← (byte) fill::ch#4 [ fill::screen#4 fill::ch#4 fill::i#4 ] ( main:2::fill:5 [ fill::screen#4 fill::ch#4 fill::i#4 ] main:2::fill:7 [ fill::screen#4 fill::ch#4 fill::i#4 ] ) always clobbers reg byte a
Statement [12] (byte*~) fill::$5 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$5 ] ( main:2::fill:5 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$5 ] main:2::fill:7 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$5 ] ) always clobbers reg byte a
Statement [13] *((byte*~) fill::$5 + (byte) fill::i#4) ← (byte) fill::ch#4 [ fill::screen#4 fill::ch#4 fill::i#4 ] ( main:2::fill:5 [ fill::screen#4 fill::ch#4 fill::i#4 ] main:2::fill:7 [ fill::screen#4 fill::ch#4 fill::i#4 ] ) always clobbers reg byte a
Statement [14] (byte*~) fill::$7 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$7 ] ( main:2::fill:5 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$7 ] main:2::fill:7 [ fill::screen#4 fill::ch#4 fill::i#4 fill::$7 ] ) always clobbers reg byte a
Statement [15] *((byte*~) fill::$7 + (byte) fill::i#4) ← (byte) fill::ch#4 [ fill::screen#4 fill::ch#4 fill::i#4 ] ( main:2::fill:5 [ fill::screen#4 fill::ch#4 fill::i#4 ] main:2::fill:7 [ fill::screen#4 fill::ch#4 fill::i#4 ] ) always clobbers reg byte a
Potential registers zp ZP_WORD:2 [ fill::screen#4 ] : zp ZP_WORD:2 ,
Potential registers zp ZP_BYTE:4 [ fill::ch#4 ] : zp ZP_BYTE:4 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:5 [ fill::i#4 fill::i#1 ] : zp ZP_BYTE:5 , reg byte x , reg byte y ,
Potential registers zp ZP_WORD:6 [ fill::$5 ] : zp ZP_WORD:6 ,
Potential registers zp ZP_WORD:8 [ fill::$7 ] : zp ZP_WORD:8 ,
REGISTER UPLIFT SCOPES
Uplift Scope [fill] 25.67: zp ZP_BYTE:5 [ fill::i#4 fill::i#1 ] 22: zp ZP_WORD:6 [ fill::$5 ] 22: zp ZP_WORD:8 [ fill::$7 ] 3.67: zp ZP_WORD:2 [ fill::screen#4 ] 3.67: zp ZP_BYTE:4 [ fill::ch#4 ]
Uplift Scope [main]
Uplift Scope []
Uplifting [fill] best 961 combination reg byte y [ fill::i#4 fill::i#1 ] zp ZP_WORD:6 [ fill::$5 ] zp ZP_WORD:8 [ fill::$7 ] zp ZP_WORD:2 [ fill::screen#4 ] reg byte x [ fill::ch#4 ]
Uplifting [main] best 961 combination
Uplifting [] best 961 combination
Coalescing zero page register [ zp ZP_WORD:6 [ fill::$5 ] ] with [ zp ZP_WORD:8 [ fill::$7 ] ]
Allocated (was zp ZP_WORD:6) zp ZP_WORD:4 [ fill::$5 fill::$7 ]
ASSEMBLER BEFORE OPTIMIZATION
//SEG0 File Comments
// Tests elimination of plus 0
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//SEG3 @begin
bbegin:
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
//SEG5 @1
b1:
//SEG6 [2] call main
//SEG7 [4] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
//SEG9 @end
bend:
//SEG10 main
main: {
//SEG11 [5] call fill
//SEG12 [9] phi from main to fill [phi:main->fill]
fill_from_main:
//SEG13 [9] phi (byte) fill::ch#4 = (byte) 'a' [phi:main->fill#0] -- vbuxx=vbuc1
ldx #'a'
//SEG14 [9] phi (byte*) fill::screen#4 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:main->fill#1] -- pbuz1=pbuc1
lda #<$400
sta fill.screen
lda #>$400
sta fill.screen+1
jsr fill
//SEG15 [6] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
jmp b1
//SEG16 main::@1
b1:
//SEG17 [7] call fill
//SEG18 [9] phi from main::@1 to fill [phi:main::@1->fill]
fill_from_b1:
//SEG19 [9] phi (byte) fill::ch#4 = (byte) 'b' [phi:main::@1->fill#0] -- vbuxx=vbuc1
ldx #'b'
//SEG20 [9] phi (byte*) fill::screen#4 = ((byte*))(word/signed word/dword/signed dword) $2000 [phi:main::@1->fill#1] -- pbuz1=pbuc1
lda #<$2000
sta fill.screen
lda #>$2000
sta fill.screen+1
jsr fill
jmp breturn
//SEG21 main::@return
breturn:
//SEG22 [8] return
rts
}
//SEG23 fill
// fill(byte* zeropage(2) screen, byte register(X) ch)
fill: {
.label screen = 2
.label _5 = 4
.label _7 = 4
//SEG24 [10] phi from fill to fill::@1 [phi:fill->fill::@1]
b1_from_fill:
//SEG25 [10] phi (byte) fill::i#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:fill->fill::@1#0] -- vbuyy=vbuc1
ldy #0
jmp b1
//SEG26 [10] phi from fill::@3 to fill::@1 [phi:fill::@3->fill::@1]
b1_from_b3:
//SEG27 [10] phi (byte) fill::i#4 = (byte) fill::i#1 [phi:fill::@3->fill::@1#0] -- register_copy
jmp b1
//SEG28 fill::@1
b1:
jmp b2
//SEG29 fill::@2
b2:
//SEG30 [11] *((byte*) fill::screen#4 + (byte) fill::i#4) ← (byte) fill::ch#4 -- pbuz1_derefidx_vbuyy=vbuxx
txa
sta (screen),y
jmp b2_1
//SEG31 fill::@2_1
b2_1:
//SEG32 [12] (byte*~) fill::$5 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 -- pbuz1=pbuz2_plus_vbuc1
lda #1*$28
clc
adc screen
sta _5
lda #0
adc screen+1
sta _5+1
//SEG33 [13] *((byte*~) fill::$5 + (byte) fill::i#4) ← (byte) fill::ch#4 -- pbuz1_derefidx_vbuyy=vbuxx
txa
sta (_5),y
jmp b2_2
//SEG34 fill::@2_2
b2_2:
//SEG35 [14] (byte*~) fill::$7 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 -- pbuz1=pbuz2_plus_vbuc1
lda #2*$28
clc
adc screen
sta _7
lda #0
adc screen+1
sta _7+1
//SEG36 [15] *((byte*~) fill::$7 + (byte) fill::i#4) ← (byte) fill::ch#4 -- pbuz1_derefidx_vbuyy=vbuxx
txa
sta (_7),y
jmp b3
//SEG37 fill::@3
b3:
//SEG38 [16] (byte) fill::i#1 ← ++ (byte) fill::i#4 -- vbuyy=_inc_vbuyy
iny
//SEG39 [17] if((byte) fill::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $28) goto fill::@1 -- vbuyy_neq_vbuc1_then_la1
cpy #$28
bne b1_from_b3
jmp breturn
//SEG40 fill::@return
breturn:
//SEG41 [18] return
rts
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp breturn
Removing instruction jmp b1
Removing instruction jmp b2
Removing instruction jmp b2_1
Removing instruction jmp b2_2
Removing instruction jmp b3
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label b1 with b2
Replacing label b1_from_b3 with b2
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction main_from_b1:
Removing instruction bend_from_b1:
Removing instruction b1_from_main:
Removing instruction fill_from_b1:
Removing instruction b1_from_b3:
Removing instruction b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction fill_from_main:
Removing instruction b1:
Removing instruction breturn:
Removing instruction b1_from_fill:
Removing instruction b2_1:
Removing instruction b2_2:
Removing instruction b3:
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
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(void()) fill((byte*) fill::screen , (byte) fill::ch)
(byte*~) fill::$5 $5 zp ZP_WORD:4 22.0
(byte*~) fill::$7 $7 zp ZP_WORD:4 22.0
(label) fill::@1
(label) fill::@2
(label) fill::@2_1
(label) fill::@2_2
(label) fill::@3
(label) fill::@return
(byte) fill::ch
(byte) fill::ch#4 reg byte x 3.666666666666667
(byte) fill::i
(byte) fill::i#1 reg byte y 16.5
(byte) fill::i#4 reg byte y 9.166666666666666
(byte) fill::j
(byte*) fill::screen
(byte*) fill::screen#4 screen zp ZP_WORD:2 3.666666666666667
(void()) main()
(label) main::@1
(label) main::@return
zp ZP_WORD:2 [ fill::screen#4 ]
reg byte x [ fill::ch#4 ]
reg byte y [ fill::i#4 fill::i#1 ]
zp ZP_WORD:4 [ fill::$5 fill::$7 ]
FINAL ASSEMBLER
Score: 733
//SEG0 File Comments
// Tests elimination of plus 0
//SEG1 Basic Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
//SEG2 Global Constants & labels
//SEG3 @begin
//SEG4 [1] phi from @begin to @1 [phi:@begin->@1]
//SEG5 @1
//SEG6 [2] call main
//SEG7 [4] phi from @1 to main [phi:@1->main]
//SEG8 [3] phi from @1 to @end [phi:@1->@end]
//SEG9 @end
//SEG10 main
main: {
//SEG11 [5] call fill
//SEG12 [9] phi from main to fill [phi:main->fill]
//SEG13 [9] phi (byte) fill::ch#4 = (byte) 'a' [phi:main->fill#0] -- vbuxx=vbuc1
ldx #'a'
//SEG14 [9] phi (byte*) fill::screen#4 = ((byte*))(word/signed word/dword/signed dword) $400 [phi:main->fill#1] -- pbuz1=pbuc1
lda #<$400
sta fill.screen
lda #>$400
sta fill.screen+1
jsr fill
//SEG15 [6] phi from main to main::@1 [phi:main->main::@1]
//SEG16 main::@1
//SEG17 [7] call fill
//SEG18 [9] phi from main::@1 to fill [phi:main::@1->fill]
//SEG19 [9] phi (byte) fill::ch#4 = (byte) 'b' [phi:main::@1->fill#0] -- vbuxx=vbuc1
ldx #'b'
//SEG20 [9] phi (byte*) fill::screen#4 = ((byte*))(word/signed word/dword/signed dword) $2000 [phi:main::@1->fill#1] -- pbuz1=pbuc1
lda #<$2000
sta fill.screen
lda #>$2000
sta fill.screen+1
jsr fill
//SEG21 main::@return
//SEG22 [8] return
rts
}
//SEG23 fill
// fill(byte* zeropage(2) screen, byte register(X) ch)
fill: {
.label screen = 2
.label _5 = 4
.label _7 = 4
//SEG24 [10] phi from fill to fill::@1 [phi:fill->fill::@1]
//SEG25 [10] phi (byte) fill::i#4 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:fill->fill::@1#0] -- vbuyy=vbuc1
ldy #0
//SEG26 [10] phi from fill::@3 to fill::@1 [phi:fill::@3->fill::@1]
//SEG27 [10] phi (byte) fill::i#4 = (byte) fill::i#1 [phi:fill::@3->fill::@1#0] -- register_copy
//SEG28 fill::@1
//SEG29 fill::@2
b2:
//SEG30 [11] *((byte*) fill::screen#4 + (byte) fill::i#4) ← (byte) fill::ch#4 -- pbuz1_derefidx_vbuyy=vbuxx
txa
sta (screen),y
//SEG31 fill::@2_1
//SEG32 [12] (byte*~) fill::$5 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 -- pbuz1=pbuz2_plus_vbuc1
lda #1*$28
clc
adc screen
sta _5
lda #0
adc screen+1
sta _5+1
//SEG33 [13] *((byte*~) fill::$5 + (byte) fill::i#4) ← (byte) fill::ch#4 -- pbuz1_derefidx_vbuyy=vbuxx
txa
sta (_5),y
//SEG34 fill::@2_2
//SEG35 [14] (byte*~) fill::$7 ← (byte*) fill::screen#4 + (byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 -- pbuz1=pbuz2_plus_vbuc1
lda #2*$28
clc
adc screen
sta _7
lda #0
adc screen+1
sta _7+1
//SEG36 [15] *((byte*~) fill::$7 + (byte) fill::i#4) ← (byte) fill::ch#4 -- pbuz1_derefidx_vbuyy=vbuxx
txa
sta (_7),y
//SEG37 fill::@3
//SEG38 [16] (byte) fill::i#1 ← ++ (byte) fill::i#4 -- vbuyy=_inc_vbuyy
iny
//SEG39 [17] if((byte) fill::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $28) goto fill::@1 -- vbuyy_neq_vbuc1_then_la1
cpy #$28
bne b2
//SEG40 fill::@return
//SEG41 [18] return
rts
}