kickc/src/test/ref/euclid-problem-2.log

821 lines
29 KiB
Plaintext

Inlined call call __init
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start::@1
idx#15 = phi( __start::@1/idx#16 )
euclid::a#0 = $80
euclid::b#0 = 2
call euclid
euclid::return#0 = euclid::return#5
to:main::@1
main::@1: scope:[main] from main
idx#8 = phi( main/idx#15 )
euclid::return#6 = phi( main/euclid::return#0 )
main::$0 = euclid::return#6
SCREEN[idx#8] = main::$0
idx#0 = ++ idx#8
euclid::a#1 = $a9
euclid::b#1 = $45
call euclid
euclid::return#1 = euclid::return#5
to:main::@2
main::@2: scope:[main] from main::@1
idx#9 = phi( main::@1/idx#0 )
euclid::return#7 = phi( main::@1/euclid::return#1 )
main::$1 = euclid::return#7
SCREEN[idx#9] = main::$1
idx#1 = ++ idx#9
euclid::a#2 = $ff
euclid::b#2 = $9b
call euclid
euclid::return#2 = euclid::return#5
to:main::@3
main::@3: scope:[main] from main::@2
idx#10 = phi( main::@2/idx#1 )
euclid::return#8 = phi( main::@2/euclid::return#2 )
main::$2 = euclid::return#8
SCREEN[idx#10] = main::$2
idx#2 = ++ idx#10
euclid::a#3 = $63
euclid::b#3 = 3
call euclid
euclid::return#3 = euclid::return#5
to:main::@4
main::@4: scope:[main] from main::@3
idx#11 = phi( main::@3/idx#2 )
euclid::return#9 = phi( main::@3/euclid::return#3 )
main::$3 = euclid::return#9
SCREEN[idx#11] = main::$3
idx#3 = ++ idx#11
to:main::@return
main::@return: scope:[main] from main::@4
idx#12 = phi( main::@4/idx#3 )
idx#4 = idx#12
return
to:@return
char euclid(char a , char b)
euclid: scope:[euclid] from main main::@1 main::@2 main::@3
euclid::b#9 = phi( main/euclid::b#0, main::@1/euclid::b#1, main::@2/euclid::b#2, main::@3/euclid::b#3 )
euclid::a#10 = phi( main/euclid::a#0, main::@1/euclid::a#1, main::@2/euclid::a#2, main::@3/euclid::a#3 )
to:euclid::@1
euclid::@1: scope:[euclid] from euclid euclid::@4 euclid::@5
euclid::b#5 = phi( euclid/euclid::b#9, euclid::@4/euclid::b#7, euclid::@5/euclid::b#4 )
euclid::a#5 = phi( euclid/euclid::a#10, euclid::@4/euclid::a#4, euclid::@5/euclid::a#9 )
euclid::$0 = euclid::a#5 != euclid::b#5
if(euclid::$0) goto euclid::@2
to:euclid::@3
euclid::@2: scope:[euclid] from euclid::@1
euclid::b#6 = phi( euclid::@1/euclid::b#5 )
euclid::a#6 = phi( euclid::@1/euclid::a#5 )
euclid::$1 = euclid::a#6 > euclid::b#6
if(euclid::$1) goto euclid::@4
to:euclid::@5
euclid::@3: scope:[euclid] from euclid::@1
euclid::a#7 = phi( euclid::@1/euclid::a#5 )
euclid::return#4 = euclid::a#7
to:euclid::@return
euclid::@4: scope:[euclid] from euclid::@2
euclid::b#7 = phi( euclid::@2/euclid::b#6 )
euclid::a#8 = phi( euclid::@2/euclid::a#6 )
euclid::$3 = euclid::a#8 - euclid::b#7
euclid::a#4 = euclid::$3
to:euclid::@1
euclid::@5: scope:[euclid] from euclid::@2
euclid::a#9 = phi( euclid::@2/euclid::a#6 )
euclid::b#8 = phi( euclid::@2/euclid::b#6 )
euclid::$2 = euclid::b#8 - euclid::a#9
euclid::b#4 = euclid::$2
to:euclid::@1
euclid::@return: scope:[euclid] from euclid::@3
euclid::return#10 = phi( euclid::@3/euclid::return#4 )
euclid::return#5 = euclid::return#10
return
to:@return
void __start()
__start: scope:[__start] from
to:__start::__init1
__start::__init1: scope:[__start] from __start
idx#5 = 0
to:__start::@1
__start::@1: scope:[__start] from __start::__init1
idx#16 = phi( __start::__init1/idx#5 )
call main
to:__start::@2
__start::@2: scope:[__start] from __start::@1
idx#13 = phi( __start::@1/idx#4 )
idx#6 = idx#13
to:__start::@return
__start::@return: scope:[__start] from __start::@2
idx#14 = phi( __start::@2/idx#6 )
idx#7 = idx#14
return
to:@return
SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400
void __start()
char euclid(char a , char b)
bool euclid::$0
bool euclid::$1
char euclid::$2
char euclid::$3
char euclid::a
char euclid::a#0
char euclid::a#1
char euclid::a#10
char euclid::a#2
char euclid::a#3
char euclid::a#4
char euclid::a#5
char euclid::a#6
char euclid::a#7
char euclid::a#8
char euclid::a#9
char euclid::b
char euclid::b#0
char euclid::b#1
char euclid::b#2
char euclid::b#3
char euclid::b#4
char euclid::b#5
char euclid::b#6
char euclid::b#7
char euclid::b#8
char euclid::b#9
char euclid::return
char euclid::return#0
char euclid::return#1
char euclid::return#10
char euclid::return#2
char euclid::return#3
char euclid::return#4
char euclid::return#5
char euclid::return#6
char euclid::return#7
char euclid::return#8
char euclid::return#9
char idx
char idx#0
char idx#1
char idx#10
char idx#11
char idx#12
char idx#13
char idx#14
char idx#15
char idx#16
char idx#2
char idx#3
char idx#4
char idx#5
char idx#6
char idx#7
char idx#8
char idx#9
void main()
char main::$0
char main::$1
char main::$2
char main::$3
Adding number conversion cast (unumber) $80 in euclid::a#0 = $80
Adding number conversion cast (unumber) 2 in euclid::b#0 = 2
Adding number conversion cast (unumber) $a9 in euclid::a#1 = $a9
Adding number conversion cast (unumber) $45 in euclid::b#1 = $45
Adding number conversion cast (unumber) $ff in euclid::a#2 = $ff
Adding number conversion cast (unumber) $9b in euclid::b#2 = $9b
Adding number conversion cast (unumber) $63 in euclid::a#3 = $63
Adding number conversion cast (unumber) 3 in euclid::b#3 = 3
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast euclid::a#0 = (unumber)$80
Inlining cast euclid::b#0 = (unumber)2
Inlining cast euclid::a#1 = (unumber)$a9
Inlining cast euclid::b#1 = (unumber)$45
Inlining cast euclid::a#2 = (unumber)$ff
Inlining cast euclid::b#2 = (unumber)$9b
Inlining cast euclid::a#3 = (unumber)$63
Inlining cast euclid::b#3 = (unumber)3
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast $80
Simplifying constant integer cast 2
Simplifying constant integer cast $a9
Simplifying constant integer cast $45
Simplifying constant integer cast $ff
Simplifying constant integer cast $9b
Simplifying constant integer cast $63
Simplifying constant integer cast 3
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) $80
Finalized unsigned number type (char) 2
Finalized unsigned number type (char) $a9
Finalized unsigned number type (char) $45
Finalized unsigned number type (char) $ff
Finalized unsigned number type (char) $9b
Finalized unsigned number type (char) $63
Finalized unsigned number type (char) 3
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias euclid::return#0 = euclid::return#6
Alias idx#15 = idx#8
Alias euclid::return#1 = euclid::return#7
Alias idx#0 = idx#9
Alias euclid::return#2 = euclid::return#8
Alias idx#1 = idx#10
Alias euclid::return#3 = euclid::return#9
Alias idx#11 = idx#2
Alias idx#12 = idx#3 idx#4
Alias euclid::a#5 = euclid::a#6 euclid::a#7 euclid::return#4 euclid::a#8 euclid::a#9 euclid::return#10 euclid::return#5
Alias euclid::b#5 = euclid::b#6 euclid::b#7 euclid::b#8
Alias euclid::a#4 = euclid::$3
Alias euclid::b#4 = euclid::$2
Alias idx#16 = idx#5
Alias idx#13 = idx#6 idx#14 idx#7
Successful SSA optimization Pass2AliasElimination
Identical Phi Values idx#15 idx#16
Identical Phi Values idx#13 idx#12
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition euclid::$0 [33] if(euclid::a#5!=euclid::b#5) goto euclid::@2
Simple Condition euclid::$1 [35] if(euclid::a#5>euclid::b#5) goto euclid::@4
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant euclid::a#0 = $80
Constant euclid::b#0 = 2
Constant euclid::a#1 = $a9
Constant euclid::b#1 = $45
Constant euclid::a#2 = $ff
Constant euclid::b#2 = $9b
Constant euclid::a#3 = $63
Constant euclid::b#3 = 3
Constant idx#16 = 0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [6] SCREEN[idx#16] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable idx#12 and assignment [19] idx#12 = ++ idx#11
Successful SSA optimization PassNEliminateUnusedVars
Removing unused procedure __start
Removing unused procedure block __start
Removing unused procedure block __start::__init1
Removing unused procedure block __start::@1
Removing unused procedure block __start::@2
Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [4] idx#0 = ++ idx#16
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant idx#0 = ++idx#16
Successful SSA optimization Pass2ConstantIdentification
Constant right-side identified [8] idx#1 = ++ idx#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant idx#1 = ++idx#0
Successful SSA optimization Pass2ConstantIdentification
Constant right-side identified [12] idx#11 = ++ idx#1
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant idx#11 = ++idx#1
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with var siblings euclid::a#0
Inlining constant with var siblings euclid::b#0
Inlining constant with var siblings euclid::a#1
Inlining constant with var siblings euclid::b#1
Inlining constant with var siblings euclid::a#2
Inlining constant with var siblings euclid::b#2
Inlining constant with var siblings euclid::a#3
Inlining constant with var siblings euclid::b#3
Inlining constant with different constant siblings idx#16
Inlining constant with different constant siblings idx#0
Inlining constant with different constant siblings idx#1
Inlining constant with different constant siblings idx#11
Constant inlined idx#11 = ++++++0
Constant inlined euclid::b#0 = 2
Constant inlined euclid::a#1 = $a9
Constant inlined euclid::a#0 = $80
Constant inlined euclid::b#2 = $9b
Constant inlined euclid::a#3 = $63
Constant inlined idx#0 = ++0
Constant inlined euclid::b#1 = $45
Constant inlined euclid::a#2 = $ff
Constant inlined idx#1 = ++++0
Constant inlined idx#16 = 0
Constant inlined euclid::b#3 = 3
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+++0)
Consolidated array index constant in *(SCREEN+++++0)
Consolidated array index constant in *(SCREEN+++++++0)
Successful SSA optimization Pass2ConstantAdditionElimination
Simplifying constant integer increment ++0
Simplifying constant integer increment ++0
Simplifying constant integer increment ++1
Successful SSA optimization Pass2ConstantSimplification
Simplifying constant integer increment ++1
Simplifying constant integer increment ++2
Successful SSA optimization Pass2ConstantSimplification
Adding NOP phi() at start of main
Adding NOP phi() at start of euclid::@3
CALL GRAPH
Calls in [main] to euclid:1 euclid:5 euclid:9 euclid:13
Created 4 initial phi equivalence classes
Coalesced [19] euclid::a#11 = euclid::a#10
Coalesced [20] euclid::b#10 = euclid::b#9
Coalesced (already) [27] euclid::a#13 = euclid::a#5
Coalesced [28] euclid::b#12 = euclid::b#4
Coalesced [30] euclid::a#12 = euclid::a#4
Coalesced (already) [31] euclid::b#11 = euclid::b#5
Coalesced down to 2 phi equivalence classes
Culled Empty Block label euclid::@3
Renumbering block euclid::@4 to euclid::@3
Renumbering block euclid::@5 to euclid::@4
Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call euclid
[2] euclid::return#0 = euclid::a#5
to:main::@1
main::@1: scope:[main] from main
[3] main::$0 = euclid::return#0
[4] *SCREEN = main::$0
[5] call euclid
[6] euclid::return#1 = euclid::a#5
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = euclid::return#1
[8] *(SCREEN+1) = main::$1
[9] call euclid
[10] euclid::return#2 = euclid::a#5
to:main::@3
main::@3: scope:[main] from main::@2
[11] main::$2 = euclid::return#2
[12] *(SCREEN+2) = main::$2
[13] call euclid
[14] euclid::return#3 = euclid::a#5
to:main::@4
main::@4: scope:[main] from main::@3
[15] main::$3 = euclid::return#3
[16] *(SCREEN+3) = main::$3
to:main::@return
main::@return: scope:[main] from main::@4
[17] return
to:@return
char euclid(char a , char b)
euclid: scope:[euclid] from main main::@1 main::@2 main::@3
[18] euclid::b#9 = phi( main/2, main::@1/$45, main::@2/$9b, main::@3/3 )
[18] euclid::a#10 = phi( main/$80, main::@1/$a9, main::@2/$ff, main::@3/$63 )
to:euclid::@1
euclid::@1: scope:[euclid] from euclid euclid::@3 euclid::@4
[19] euclid::b#5 = phi( euclid/euclid::b#9, euclid::@3/euclid::b#5, euclid::@4/euclid::b#4 )
[19] euclid::a#5 = phi( euclid/euclid::a#10, euclid::@3/euclid::a#4, euclid::@4/euclid::a#5 )
[20] if(euclid::a#5!=euclid::b#5) goto euclid::@2
to:euclid::@return
euclid::@return: scope:[euclid] from euclid::@1
[21] return
to:@return
euclid::@2: scope:[euclid] from euclid::@1
[22] if(euclid::a#5>euclid::b#5) goto euclid::@3
to:euclid::@4
euclid::@4: scope:[euclid] from euclid::@2
[23] euclid::b#4 = euclid::b#5 - euclid::a#5
to:euclid::@1
euclid::@3: scope:[euclid] from euclid::@2
[24] euclid::a#4 = euclid::a#5 - euclid::b#5
to:euclid::@1
VARIABLE REGISTER WEIGHTS
char euclid(char a , char b)
char euclid::a
char euclid::a#10 // 11.0
char euclid::a#4 // 202.0
char euclid::a#5 // 80.66666666666666
char euclid::b
char euclid::b#4 // 202.0
char euclid::b#5 // 179.5
char euclid::b#9 // 11.0
char euclid::return
char euclid::return#0 // 4.0
char euclid::return#1 // 4.0
char euclid::return#2 // 4.0
char euclid::return#3 // 4.0
char idx
void main()
char main::$0 // 4.0
char main::$1 // 4.0
char main::$2 // 4.0
char main::$3 // 4.0
Initial phi equivalence classes
[ euclid::a#5 euclid::a#10 euclid::a#4 ]
[ euclid::b#5 euclid::b#9 euclid::b#4 ]
Added variable euclid::return#0 to live range equivalence class [ euclid::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable euclid::return#1 to live range equivalence class [ euclid::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable euclid::return#2 to live range equivalence class [ euclid::return#2 ]
Added variable main::$2 to live range equivalence class [ main::$2 ]
Added variable euclid::return#3 to live range equivalence class [ euclid::return#3 ]
Added variable main::$3 to live range equivalence class [ main::$3 ]
Complete equivalence classes
[ euclid::a#5 euclid::a#10 euclid::a#4 ]
[ euclid::b#5 euclid::b#9 euclid::b#4 ]
[ euclid::return#0 ]
[ main::$0 ]
[ euclid::return#1 ]
[ main::$1 ]
[ euclid::return#2 ]
[ main::$2 ]
[ euclid::return#3 ]
[ main::$3 ]
Allocated zp[1]:2 [ euclid::b#5 euclid::b#9 euclid::b#4 ]
Allocated zp[1]:3 [ euclid::a#5 euclid::a#10 euclid::a#4 ]
Allocated zp[1]:4 [ euclid::return#0 ]
Allocated zp[1]:5 [ main::$0 ]
Allocated zp[1]:6 [ euclid::return#1 ]
Allocated zp[1]:7 [ main::$1 ]
Allocated zp[1]:8 [ euclid::return#2 ]
Allocated zp[1]:9 [ main::$2 ]
Allocated zp[1]:10 [ euclid::return#3 ]
Allocated zp[1]:11 [ main::$3 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [23] euclid::b#4 = euclid::b#5 - euclid::a#5 [ euclid::a#5 euclid::b#4 ] ( euclid:1 [ euclid::a#5 euclid::b#4 ] { { euclid::return#0 = euclid::a#5 } } euclid:5 [ euclid::a#5 euclid::b#4 ] { { euclid::return#1 = euclid::a#5 } } euclid:9 [ euclid::a#5 euclid::b#4 ] { { euclid::return#2 = euclid::a#5 } } euclid:13 [ euclid::a#5 euclid::b#4 ] { { euclid::return#3 = euclid::a#5 } } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:3 [ euclid::a#5 euclid::a#10 euclid::a#4 ]
Statement [24] euclid::a#4 = euclid::a#5 - euclid::b#5 [ euclid::b#5 euclid::a#4 ] ( euclid:1 [ euclid::b#5 euclid::a#4 ] { { euclid::return#0 = euclid::a#5 } } euclid:5 [ euclid::b#5 euclid::a#4 ] { { euclid::return#1 = euclid::a#5 } } euclid:9 [ euclid::b#5 euclid::a#4 ] { { euclid::return#2 = euclid::a#5 } } euclid:13 [ euclid::b#5 euclid::a#4 ] { { euclid::return#3 = euclid::a#5 } } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ euclid::b#5 euclid::b#9 euclid::b#4 ]
Statement [23] euclid::b#4 = euclid::b#5 - euclid::a#5 [ euclid::a#5 euclid::b#4 ] ( euclid:1 [ euclid::a#5 euclid::b#4 ] { { euclid::return#0 = euclid::a#5 } } euclid:5 [ euclid::a#5 euclid::b#4 ] { { euclid::return#1 = euclid::a#5 } } euclid:9 [ euclid::a#5 euclid::b#4 ] { { euclid::return#2 = euclid::a#5 } } euclid:13 [ euclid::a#5 euclid::b#4 ] { { euclid::return#3 = euclid::a#5 } } ) always clobbers reg byte a
Statement [24] euclid::a#4 = euclid::a#5 - euclid::b#5 [ euclid::b#5 euclid::a#4 ] ( euclid:1 [ euclid::b#5 euclid::a#4 ] { { euclid::return#0 = euclid::a#5 } } euclid:5 [ euclid::b#5 euclid::a#4 ] { { euclid::return#1 = euclid::a#5 } } euclid:9 [ euclid::b#5 euclid::a#4 ] { { euclid::return#2 = euclid::a#5 } } euclid:13 [ euclid::b#5 euclid::a#4 ] { { euclid::return#3 = euclid::a#5 } } ) always clobbers reg byte a
Potential registers zp[1]:3 [ euclid::a#5 euclid::a#10 euclid::a#4 ] : zp[1]:3 , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ euclid::b#5 euclid::b#9 euclid::b#4 ] : zp[1]:2 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ euclid::return#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ main::$0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:6 [ euclid::return#1 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ main::$1 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ euclid::return#2 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ main::$2 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ euclid::return#3 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:11 [ main::$3 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [euclid] 392.5: zp[1]:2 [ euclid::b#5 euclid::b#9 euclid::b#4 ] 293.67: zp[1]:3 [ euclid::a#5 euclid::a#10 euclid::a#4 ] 4: zp[1]:4 [ euclid::return#0 ] 4: zp[1]:6 [ euclid::return#1 ] 4: zp[1]:8 [ euclid::return#2 ] 4: zp[1]:10 [ euclid::return#3 ]
Uplift Scope [main] 4: zp[1]:5 [ main::$0 ] 4: zp[1]:7 [ main::$1 ] 4: zp[1]:9 [ main::$2 ] 4: zp[1]:11 [ main::$3 ]
Uplift Scope []
Uplifting [euclid] best 613 combination reg byte x [ euclid::b#5 euclid::b#9 euclid::b#4 ] zp[1]:3 [ euclid::a#5 euclid::a#10 euclid::a#4 ] reg byte a [ euclid::return#0 ] reg byte a [ euclid::return#1 ] zp[1]:8 [ euclid::return#2 ] zp[1]:10 [ euclid::return#3 ]
Limited combination testing to 100 combinations of 2304 possible.
Uplifting [main] best 589 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ] reg byte a [ main::$2 ] reg byte a [ main::$3 ]
Limited combination testing to 100 combinations of 256 possible.
Uplifting [] best 589 combination
Attempting to uplift remaining variables inzp[1]:3 [ euclid::a#5 euclid::a#10 euclid::a#4 ]
Uplifting [euclid] best 589 combination zp[1]:3 [ euclid::a#5 euclid::a#10 euclid::a#4 ]
Attempting to uplift remaining variables inzp[1]:8 [ euclid::return#2 ]
Uplifting [euclid] best 583 combination reg byte a [ euclid::return#2 ]
Attempting to uplift remaining variables inzp[1]:10 [ euclid::return#3 ]
Uplifting [euclid] best 577 combination reg byte a [ euclid::return#3 ]
Allocated (was zp[1]:3) zp[1]:2 [ euclid::a#5 euclid::a#10 euclid::a#4 ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Demonstrates a problem where wrong alive ranges result in clobbering an alive variable
// The compiler does not realize that A is alive in the statement b=b-a - and thus can clobber it.
// Upstart
// Commodore 64 PRG executable file
.file [name="euclid-problem-2.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// [1] call euclid
// [18] phi from main to euclid [phi:main->euclid]
euclid_from_main:
// [18] phi euclid::b#9 = 2 [phi:main->euclid#0] -- vbuxx=vbuc1
ldx #2
// [18] phi euclid::a#10 = $80 [phi:main->euclid#1] -- vbuz1=vbuc1
lda #$80
sta.z euclid.a
jsr euclid
// [2] euclid::return#0 = euclid::a#5 -- vbuaa=vbuz1
lda.z euclid.a
jmp __b1
// main::@1
__b1:
// [3] main::$0 = euclid::return#0
// [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN
// [5] call euclid
// [18] phi from main::@1 to euclid [phi:main::@1->euclid]
euclid_from___b1:
// [18] phi euclid::b#9 = $45 [phi:main::@1->euclid#0] -- vbuxx=vbuc1
ldx #$45
// [18] phi euclid::a#10 = $a9 [phi:main::@1->euclid#1] -- vbuz1=vbuc1
lda #$a9
sta.z euclid.a
jsr euclid
// [6] euclid::return#1 = euclid::a#5 -- vbuaa=vbuz1
lda.z euclid.a
jmp __b2
// main::@2
__b2:
// [7] main::$1 = euclid::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
sta SCREEN+1
// [9] call euclid
// [18] phi from main::@2 to euclid [phi:main::@2->euclid]
euclid_from___b2:
// [18] phi euclid::b#9 = $9b [phi:main::@2->euclid#0] -- vbuxx=vbuc1
ldx #$9b
// [18] phi euclid::a#10 = $ff [phi:main::@2->euclid#1] -- vbuz1=vbuc1
lda #$ff
sta.z euclid.a
jsr euclid
// [10] euclid::return#2 = euclid::a#5 -- vbuaa=vbuz1
lda.z euclid.a
jmp __b3
// main::@3
__b3:
// [11] main::$2 = euclid::return#2
// [12] *(SCREEN+2) = main::$2 -- _deref_pbuc1=vbuaa
sta SCREEN+2
// [13] call euclid
// [18] phi from main::@3 to euclid [phi:main::@3->euclid]
euclid_from___b3:
// [18] phi euclid::b#9 = 3 [phi:main::@3->euclid#0] -- vbuxx=vbuc1
ldx #3
// [18] phi euclid::a#10 = $63 [phi:main::@3->euclid#1] -- vbuz1=vbuc1
lda #$63
sta.z euclid.a
jsr euclid
// [14] euclid::return#3 = euclid::a#5 -- vbuaa=vbuz1
lda.z euclid.a
jmp __b4
// main::@4
__b4:
// [15] main::$3 = euclid::return#3
// [16] *(SCREEN+3) = main::$3 -- _deref_pbuc1=vbuaa
sta SCREEN+3
jmp __breturn
// main::@return
__breturn:
// [17] return
rts
}
// euclid
// Calculate least common denominator using euclids subtraction method
// __register(A) char euclid(__zp(2) char a, __register(X) char b)
euclid: {
.label a = 2
// [19] phi from euclid euclid::@3 euclid::@4 to euclid::@1 [phi:euclid/euclid::@3/euclid::@4->euclid::@1]
__b1_from_euclid:
__b1_from___b3:
__b1_from___b4:
// [19] phi euclid::b#5 = euclid::b#9 [phi:euclid/euclid::@3/euclid::@4->euclid::@1#0] -- register_copy
// [19] phi euclid::a#5 = euclid::a#10 [phi:euclid/euclid::@3/euclid::@4->euclid::@1#1] -- register_copy
jmp __b1
// euclid::@1
__b1:
// [20] if(euclid::a#5!=euclid::b#5) goto euclid::@2 -- vbuz1_neq_vbuxx_then_la1
cpx.z a
bne __b2
jmp __breturn
// euclid::@return
__breturn:
// [21] return
rts
// euclid::@2
__b2:
// [22] if(euclid::a#5>euclid::b#5) goto euclid::@3 -- vbuz1_gt_vbuxx_then_la1
cpx.z a
bcc __b3
jmp __b4
// euclid::@4
__b4:
// [23] euclid::b#4 = euclid::b#5 - euclid::a#5 -- vbuxx=vbuxx_minus_vbuz1
txa
sec
sbc.z a
tax
jmp __b1_from___b4
// euclid::@3
__b3:
// [24] euclid::a#4 = euclid::a#5 - euclid::b#5 -- vbuz1=vbuz1_minus_vbuxx
txa
eor #$ff
sec
adc.z a
sta.z a
jmp __b1_from___b3
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __b3
Removing instruction jmp __b4
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b4
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __b1_from___b4 with __b1
Replacing label __b1_from___b3 with __b1
Removing instruction __b1_from_euclid:
Removing instruction __b1_from___b3:
Removing instruction __b1_from___b4:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction euclid_from_main:
Removing instruction __b1:
Removing instruction euclid_from___b1:
Removing instruction __b2:
Removing instruction euclid_from___b2:
Removing instruction __b3:
Removing instruction euclid_from___b3:
Removing instruction __b4:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __b4:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024
char euclid(char a , char b)
char euclid::a
char euclid::a#10 // a zp[1]:2 11.0
char euclid::a#4 // a zp[1]:2 202.0
char euclid::a#5 // a zp[1]:2 80.66666666666666
char euclid::b
char euclid::b#4 // reg byte x 202.0
char euclid::b#5 // reg byte x 179.5
char euclid::b#9 // reg byte x 11.0
char euclid::return
char euclid::return#0 // reg byte a 4.0
char euclid::return#1 // reg byte a 4.0
char euclid::return#2 // reg byte a 4.0
char euclid::return#3 // reg byte a 4.0
char idx
void main()
char main::$0 // reg byte a 4.0
char main::$1 // reg byte a 4.0
char main::$2 // reg byte a 4.0
char main::$3 // reg byte a 4.0
zp[1]:2 [ euclid::a#5 euclid::a#10 euclid::a#4 ]
reg byte x [ euclid::b#5 euclid::b#9 euclid::b#4 ]
reg byte a [ euclid::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ euclid::return#1 ]
reg byte a [ main::$1 ]
reg byte a [ euclid::return#2 ]
reg byte a [ main::$2 ]
reg byte a [ euclid::return#3 ]
reg byte a [ main::$3 ]
FINAL ASSEMBLER
Score: 472
// File Comments
// Demonstrates a problem where wrong alive ranges result in clobbering an alive variable
// The compiler does not realize that A is alive in the statement b=b-a - and thus can clobber it.
// Upstart
// Commodore 64 PRG executable file
.file [name="euclid-problem-2.prg", type="prg", segments="Program"]
.segmentdef Program [segments="Basic, Code, Data"]
.segmentdef Basic [start=$0801]
.segmentdef Code [start=$80d]
.segmentdef Data [startAfter="Code"]
.segment Basic
:BasicUpstart(main)
// Global Constants & labels
.label SCREEN = $400
.segment Code
// main
main: {
// euclid(128,2)
// [1] call euclid
// [18] phi from main to euclid [phi:main->euclid]
// [18] phi euclid::b#9 = 2 [phi:main->euclid#0] -- vbuxx=vbuc1
ldx #2
// [18] phi euclid::a#10 = $80 [phi:main->euclid#1] -- vbuz1=vbuc1
lda #$80
sta.z euclid.a
jsr euclid
// euclid(128,2)
// [2] euclid::return#0 = euclid::a#5 -- vbuaa=vbuz1
lda.z euclid.a
// main::@1
// [3] main::$0 = euclid::return#0
// SCREEN[idx++] = euclid(128,2)
// [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN
// euclid(169,69)
// [5] call euclid
// [18] phi from main::@1 to euclid [phi:main::@1->euclid]
// [18] phi euclid::b#9 = $45 [phi:main::@1->euclid#0] -- vbuxx=vbuc1
ldx #$45
// [18] phi euclid::a#10 = $a9 [phi:main::@1->euclid#1] -- vbuz1=vbuc1
lda #$a9
sta.z euclid.a
jsr euclid
// euclid(169,69)
// [6] euclid::return#1 = euclid::a#5 -- vbuaa=vbuz1
lda.z euclid.a
// main::@2
// [7] main::$1 = euclid::return#1
// SCREEN[idx++] = euclid(169,69)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
sta SCREEN+1
// euclid(255,155)
// [9] call euclid
// [18] phi from main::@2 to euclid [phi:main::@2->euclid]
// [18] phi euclid::b#9 = $9b [phi:main::@2->euclid#0] -- vbuxx=vbuc1
ldx #$9b
// [18] phi euclid::a#10 = $ff [phi:main::@2->euclid#1] -- vbuz1=vbuc1
lda #$ff
sta.z euclid.a
jsr euclid
// euclid(255,155)
// [10] euclid::return#2 = euclid::a#5 -- vbuaa=vbuz1
lda.z euclid.a
// main::@3
// [11] main::$2 = euclid::return#2
// SCREEN[idx++] = euclid(255,155)
// [12] *(SCREEN+2) = main::$2 -- _deref_pbuc1=vbuaa
sta SCREEN+2
// euclid(99,3)
// [13] call euclid
// [18] phi from main::@3 to euclid [phi:main::@3->euclid]
// [18] phi euclid::b#9 = 3 [phi:main::@3->euclid#0] -- vbuxx=vbuc1
ldx #3
// [18] phi euclid::a#10 = $63 [phi:main::@3->euclid#1] -- vbuz1=vbuc1
lda #$63
sta.z euclid.a
jsr euclid
// euclid(99,3)
// [14] euclid::return#3 = euclid::a#5 -- vbuaa=vbuz1
lda.z euclid.a
// main::@4
// [15] main::$3 = euclid::return#3
// SCREEN[idx++] = euclid(99,3)
// [16] *(SCREEN+3) = main::$3 -- _deref_pbuc1=vbuaa
sta SCREEN+3
// main::@return
// }
// [17] return
rts
}
// euclid
// Calculate least common denominator using euclids subtraction method
// __register(A) char euclid(__zp(2) char a, __register(X) char b)
euclid: {
.label a = 2
// [19] phi from euclid euclid::@3 euclid::@4 to euclid::@1 [phi:euclid/euclid::@3/euclid::@4->euclid::@1]
// [19] phi euclid::b#5 = euclid::b#9 [phi:euclid/euclid::@3/euclid::@4->euclid::@1#0] -- register_copy
// [19] phi euclid::a#5 = euclid::a#10 [phi:euclid/euclid::@3/euclid::@4->euclid::@1#1] -- register_copy
// euclid::@1
__b1:
// while (a!=b)
// [20] if(euclid::a#5!=euclid::b#5) goto euclid::@2 -- vbuz1_neq_vbuxx_then_la1
cpx.z a
bne __b2
// euclid::@return
// }
// [21] return
rts
// euclid::@2
__b2:
// if(a>b)
// [22] if(euclid::a#5>euclid::b#5) goto euclid::@3 -- vbuz1_gt_vbuxx_then_la1
cpx.z a
bcc __b3
// euclid::@4
// b = b-a
// [23] euclid::b#4 = euclid::b#5 - euclid::a#5 -- vbuxx=vbuxx_minus_vbuz1
txa
sec
sbc.z a
tax
jmp __b1
// euclid::@3
__b3:
// a = a-b
// [24] euclid::a#4 = euclid::a#5 - euclid::b#5 -- vbuz1=vbuz1_minus_vbuxx
txa
eor #$ff
sec
adc.z a
sta.z a
jmp __b1
}
// File Data