1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-07-03 20:29:34 +00:00
kickc/src/test/ref/printf-10.log

1440 lines
57 KiB
Plaintext
Raw Normal View History

Added struct type cast to parameter value list call printf_string (byte*) "Jesper" (struct printf_format_string){ (byte) 0, (byte) 0 }
Added struct type cast to parameter value list call printf_uint (word) main::age (struct printf_format_number){ (byte) 0, (byte) 0, (byte) 0, (byte) 0, (const byte) HEXADECIMAL }
Created struct value member variable (byte) printf_string::format_min_length
Created struct value member variable (byte) printf_string::format_justify_left
Converted struct value to member variables (struct printf_format_string) printf_string::format
Created struct value member variable (byte) printf_uint::format_min_length
Created struct value member variable (byte) printf_uint::format_justify_left
Created struct value member variable (byte) printf_uint::format_sign_always
Created struct value member variable (byte) printf_uint::format_zero_padding
Created struct value member variable (byte) printf_uint::format_radix
Converted struct value to member variables (struct printf_format_number) printf_uint::format
Converted procedure struct value parameter to member unwinding (void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left)
Converted procedure struct value parameter to member unwinding (void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix)
Converted call struct value parameter to member unwinding call printf_string (byte*) "Jesper" (byte) 0 (byte) 0
Converted call struct value parameter to member unwinding call printf_uint (word) main::age (byte) 0 (byte) 0 (byte) 0 (byte) 0 (const byte) HEXADECIMAL
Warning! Adding boolean cast to non-boolean condition *((byte*) printf_str::str)
Identified constant variable (byte) idx
Identified constant variable (word) main::age
Eliminating unused variable with no statement (void~) main::$0
Eliminating unused variable with no statement (void~) main::$1
Culled Empty Block (label) printf_str::@4
Culled Empty Block (label) printf_str::@3
Culled Empty Block (label) printf_str::@5
Culled Empty Block (label) printf_str::@6
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte*) screen#0 ← (byte*)(number) $400
to:@4
(void()) printf_str((byte*) printf_str::str)
printf_str: scope:[printf_str] from main main::@2 main::@3 main::@5 printf_string
(byte*) screen#36 ← phi( main/(byte*) screen#34 main::@2/(byte*) screen#11 main::@3/(byte*) screen#12 main::@5/(byte*) screen#14 printf_string/(byte*) screen#33 )
(byte*) printf_str::str#8 ← phi( main/(byte*) printf_str::str#2 main::@2/(byte*) printf_str::str#3 main::@3/(byte*) printf_str::str#4 main::@5/(byte*) printf_str::str#5 printf_string/(byte*) printf_str::str#1 )
to:printf_str::@1
printf_str::@1: scope:[printf_str] from printf_str printf_str::@2
(byte*) screen#32 ← phi( printf_str/(byte*) screen#36 printf_str::@2/(byte*) screen#1 )
(byte*) printf_str::str#6 ← phi( printf_str/(byte*) printf_str::str#8 printf_str::@2/(byte*) printf_str::str#0 )
(bool~) printf_str::$0 ← (number) 0 != *((byte*) printf_str::str#6)
if((bool~) printf_str::$0) goto printf_str::@2
to:printf_str::@return
printf_str::@2: scope:[printf_str] from printf_str::@1
(byte*) screen#18 ← phi( printf_str::@1/(byte*) screen#32 )
(byte*) printf_str::str#7 ← phi( printf_str::@1/(byte*) printf_str::str#6 )
*((byte*) screen#18) ← *((byte*) printf_str::str#7)
(byte*) screen#1 ← ++ (byte*) screen#18
(byte*) printf_str::str#0 ← ++ (byte*) printf_str::str#7
to:printf_str::@1
printf_str::@return: scope:[printf_str] from printf_str::@1
(byte*) screen#19 ← phi( printf_str::@1/(byte*) screen#32 )
(byte*) screen#2 ← (byte*) screen#19
return
to:@return
(void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left)
printf_string: scope:[printf_string] from main::@1
(byte*) screen#33 ← phi( main::@1/(byte*) screen#10 )
(byte*) printf_string::str#1 ← phi( main::@1/(byte*) printf_string::str#0 )
(byte*) printf_str::str#1 ← (byte*) printf_string::str#1
call printf_str
to:printf_string::@1
printf_string::@1: scope:[printf_string] from printf_string
(byte*) screen#20 ← phi( printf_string/(byte*) screen#2 )
(byte*) screen#3 ← (byte*) screen#20
to:printf_string::@return
printf_string::@return: scope:[printf_string] from printf_string::@1
(byte*) screen#21 ← phi( printf_string::@1/(byte*) screen#3 )
(byte*) screen#4 ← (byte*) screen#21
return
to:@return
(void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix)
printf_uint: scope:[printf_uint] from main::@4
(byte*) screen#22 ← phi( main::@4/(byte*) screen#13 )
(word) printf_uint::uvalue#1 ← phi( main::@4/(word) printf_uint::uvalue#0 )
(byte~) printf_uint::$0 ← > (word) printf_uint::uvalue#1
(byte~) printf_uint::$1 ← (byte~) printf_uint::$0 >> (number) 4
*((byte*) screen#22) ← *((const to_nomodify byte*) printf_hextab + (byte~) printf_uint::$1)
(byte*) screen#5 ← ++ (byte*) screen#22
(byte~) printf_uint::$2 ← > (word) printf_uint::uvalue#1
(number~) printf_uint::$3 ← (byte~) printf_uint::$2 & (number) $f
*((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab + (number~) printf_uint::$3)
(byte*) screen#6 ← ++ (byte*) screen#5
(byte~) printf_uint::$4 ← < (word) printf_uint::uvalue#1
(byte~) printf_uint::$5 ← (byte~) printf_uint::$4 >> (number) 4
*((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab + (byte~) printf_uint::$5)
(byte*) screen#7 ← ++ (byte*) screen#6
(byte~) printf_uint::$6 ← < (word) printf_uint::uvalue#1
(number~) printf_uint::$7 ← (byte~) printf_uint::$6 & (number) $f
*((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab + (number~) printf_uint::$7)
(byte*) screen#8 ← ++ (byte*) screen#7
to:printf_uint::@return
printf_uint::@return: scope:[printf_uint] from printf_uint
(byte*) screen#23 ← phi( printf_uint/(byte*) screen#8 )
(byte*) screen#9 ← (byte*) screen#23
return
to:@return
(void()) main()
main: scope:[main] from @4
(byte*) screen#34 ← phi( @4/(byte*) screen#35 )
(byte*) printf_str::str#2 ← (const byte*) main::str
call printf_str
to:main::@1
main::@1: scope:[main] from main
(byte*) screen#24 ← phi( main/(byte*) screen#2 )
(byte*) screen#10 ← (byte*) screen#24
(byte*) printf_string::str#0 ← (const byte*) main::str1
(byte) printf_string::format_min_length#0 ← (byte) 0
(byte) printf_string::format_justify_left#0 ← (byte) 0
call printf_string
to:main::@2
main::@2: scope:[main] from main::@1
(byte*) screen#25 ← phi( main::@1/(byte*) screen#4 )
(byte*) screen#11 ← (byte*) screen#25
(byte*) printf_str::str#3 ← (const byte*) main::str2
call printf_str
to:main::@3
main::@3: scope:[main] from main::@2
(byte*) screen#26 ← phi( main::@2/(byte*) screen#2 )
(byte*) screen#12 ← (byte*) screen#26
(byte*) printf_str::str#4 ← (const byte*) main::str3
call printf_str
to:main::@4
main::@4: scope:[main] from main::@3
(byte*) screen#27 ← phi( main::@3/(byte*) screen#2 )
(byte*) screen#13 ← (byte*) screen#27
(word) printf_uint::uvalue#0 ← (const word) main::age
(byte) printf_uint::format_min_length#0 ← (byte) 0
(byte) printf_uint::format_justify_left#0 ← (byte) 0
(byte) printf_uint::format_sign_always#0 ← (byte) 0
(byte) printf_uint::format_zero_padding#0 ← (byte) 0
(byte) printf_uint::format_radix#0 ← (const byte) HEXADECIMAL
call printf_uint
to:main::@5
main::@5: scope:[main] from main::@4
(byte*) screen#28 ← phi( main::@4/(byte*) screen#9 )
(byte*) screen#14 ← (byte*) screen#28
(byte*) printf_str::str#5 ← (const byte*) main::str4
call printf_str
to:main::@6
main::@6: scope:[main] from main::@5
(byte*) screen#29 ← phi( main::@5/(byte*) screen#2 )
(byte*) screen#15 ← (byte*) screen#29
to:main::@return
main::@return: scope:[main] from main::@6
(byte*) screen#30 ← phi( main::@6/(byte*) screen#15 )
(byte*) screen#16 ← (byte*) screen#30
return
to:@return
@4: scope:[] from @begin
(byte*) screen#35 ← phi( @begin/(byte*) screen#0 )
call main
to:@5
@5: scope:[] from @4
(byte*) screen#31 ← phi( @4/(byte*) screen#16 )
(byte*) screen#17 ← (byte*) screen#31
to:@end
@end: scope:[] from @5
SYMBOL TABLE SSA
(label) @4
(label) @5
(label) @begin
(label) @end
(const byte) HEXADECIMAL = (number) $10
(const byte) RADIX::BINARY = (number) 2
(const byte) RADIX::DECIMAL = (number) $a
(const byte) RADIX::HEXADECIMAL = (number) $10
(const byte) RADIX::OCTAL = (number) 8
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::@5
(label) main::@6
(label) main::@return
(const word) main::age = (word) $2e
(const byte*) main::str[(byte) $d] = (byte*) "Hello, I am "
(const byte*) main::str1[(byte) 7] = (byte*) "Jesper"
(const byte*) main::str2[(byte) $f] = (byte*) ". who are you?"
(const byte*) main::str3[(byte) 6] = (byte*) "I am "
(const byte*) main::str4[(byte) $b] = (byte*) " years old"
(byte) printf_format_number::justify_left
(byte) printf_format_number::min_length
(byte) printf_format_number::radix
(byte) printf_format_number::sign_always
(byte) printf_format_number::zero_padding
(byte) printf_format_string::justify_left
(byte) printf_format_string::min_length
(const to_nomodify byte*) printf_hextab[] = (byte*) "0123456789abcdef"z
(void()) printf_str((byte*) printf_str::str)
(bool~) printf_str::$0
(label) printf_str::@1
(label) printf_str::@2
(label) printf_str::@return
(byte*) printf_str::str
(byte*) printf_str::str#0
(byte*) printf_str::str#1
(byte*) printf_str::str#2
(byte*) printf_str::str#3
(byte*) printf_str::str#4
(byte*) printf_str::str#5
(byte*) printf_str::str#6
(byte*) printf_str::str#7
(byte*) printf_str::str#8
(void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left)
(label) printf_string::@1
(label) printf_string::@return
(struct printf_format_string) printf_string::format
(byte) printf_string::format_justify_left
(byte) printf_string::format_justify_left#0
(byte) printf_string::format_min_length
(byte) printf_string::format_min_length#0
(byte*) printf_string::str
(byte*) printf_string::str#0
(byte*) printf_string::str#1
(void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix)
(byte~) printf_uint::$0
(byte~) printf_uint::$1
(byte~) printf_uint::$2
(number~) printf_uint::$3
(byte~) printf_uint::$4
(byte~) printf_uint::$5
(byte~) printf_uint::$6
(number~) printf_uint::$7
(label) printf_uint::@return
(struct printf_format_number) printf_uint::format
(byte) printf_uint::format_justify_left
(byte) printf_uint::format_justify_left#0
(byte) printf_uint::format_min_length
(byte) printf_uint::format_min_length#0
(byte) printf_uint::format_radix
(byte) printf_uint::format_radix#0
(byte) printf_uint::format_sign_always
(byte) printf_uint::format_sign_always#0
(byte) printf_uint::format_zero_padding
(byte) printf_uint::format_zero_padding#0
(word) printf_uint::uvalue
(word) printf_uint::uvalue#0
(word) printf_uint::uvalue#1
(byte*) screen
(byte*) screen#0
(byte*) screen#1
(byte*) screen#10
(byte*) screen#11
(byte*) screen#12
(byte*) screen#13
(byte*) screen#14
(byte*) screen#15
(byte*) screen#16
(byte*) screen#17
(byte*) screen#18
(byte*) screen#19
(byte*) screen#2
(byte*) screen#20
(byte*) screen#21
(byte*) screen#22
(byte*) screen#23
(byte*) screen#24
(byte*) screen#25
(byte*) screen#26
(byte*) screen#27
(byte*) screen#28
(byte*) screen#29
(byte*) screen#3
(byte*) screen#30
(byte*) screen#31
(byte*) screen#32
(byte*) screen#33
(byte*) screen#34
(byte*) screen#35
(byte*) screen#36
(byte*) screen#4
(byte*) screen#5
(byte*) screen#6
(byte*) screen#7
(byte*) screen#8
(byte*) screen#9
Adding number conversion cast (unumber) 0 in (bool~) printf_str::$0 ← (number) 0 != *((byte*) printf_str::str#6)
Adding number conversion cast (unumber) 4 in (byte~) printf_uint::$1 ← (byte~) printf_uint::$0 >> (number) 4
Adding number conversion cast (unumber) $f in (number~) printf_uint::$3 ← (byte~) printf_uint::$2 & (number) $f
Adding number conversion cast (unumber) printf_uint::$3 in (number~) printf_uint::$3 ← (byte~) printf_uint::$2 & (unumber)(number) $f
Adding number conversion cast (unumber) 4 in (byte~) printf_uint::$5 ← (byte~) printf_uint::$4 >> (number) 4
Adding number conversion cast (unumber) $f in (number~) printf_uint::$7 ← (byte~) printf_uint::$6 & (number) $f
Adding number conversion cast (unumber) printf_uint::$7 in (number~) printf_uint::$7 ← (byte~) printf_uint::$6 & (unumber)(number) $f
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 4
Simplifying constant integer cast $f
Simplifying constant integer cast 4
Simplifying constant integer cast $f
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 4
Finalized unsigned number type (byte) $f
Finalized unsigned number type (byte) 4
Finalized unsigned number type (byte) $f
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to byte in (unumber~) printf_uint::$3 ← (byte~) printf_uint::$2 & (byte) $f
Inferred type updated to byte in (unumber~) printf_uint::$7 ← (byte~) printf_uint::$6 & (byte) $f
Alias printf_str::str#6 = printf_str::str#7
Alias screen#18 = screen#32 screen#19 screen#2
Alias screen#20 = screen#3 screen#21 screen#4
Alias screen#23 = screen#8 screen#9
Alias screen#10 = screen#24
Alias screen#11 = screen#25
Alias screen#12 = screen#26
Alias screen#13 = screen#27
Alias screen#14 = screen#28
Alias screen#15 = screen#29 screen#30 screen#16
Alias screen#0 = screen#35
Alias screen#17 = screen#31
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte*) printf_string::str#1 (byte*) printf_string::str#0
Identical Phi Values (byte*) screen#33 (byte*) screen#10
Identical Phi Values (byte*) screen#20 (byte*) screen#18
Identical Phi Values (word) printf_uint::uvalue#1 (word) printf_uint::uvalue#0
Identical Phi Values (byte*) screen#22 (byte*) screen#13
Identical Phi Values (byte*) screen#34 (byte*) screen#0
Identical Phi Values (byte*) screen#10 (byte*) screen#18
Identical Phi Values (byte*) screen#11 (byte*) screen#20
Identical Phi Values (byte*) screen#12 (byte*) screen#18
Identical Phi Values (byte*) screen#13 (byte*) screen#18
Identical Phi Values (byte*) screen#14 (byte*) screen#23
Identical Phi Values (byte*) screen#15 (byte*) screen#18
Identical Phi Values (byte*) screen#17 (byte*) screen#15
Successful SSA optimization Pass2IdenticalPhiElimination
Identified duplicate assignment right side [25] (byte~) printf_uint::$2 ← > (word) printf_uint::uvalue#0
Identified duplicate assignment right side [33] (byte~) printf_uint::$6 ← < (word) printf_uint::uvalue#0
Successful SSA optimization Pass2DuplicateRValueIdentification
Simple Condition (bool~) printf_str::$0 [4] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte*) screen#0 = (byte*) 1024
Constant (const byte*) printf_str::str#2 = main::str
Constant (const byte*) printf_string::str#0 = main::str1
Constant (const byte) printf_string::format_min_length#0 = 0
Constant (const byte) printf_string::format_justify_left#0 = 0
Constant (const byte*) printf_str::str#3 = main::str2
Constant (const byte*) printf_str::str#4 = main::str3
Constant (const word) printf_uint::uvalue#0 = main::age
Constant (const byte) printf_uint::format_min_length#0 = 0
Constant (const byte) printf_uint::format_justify_left#0 = 0
Constant (const byte) printf_uint::format_sign_always#0 = 0
Constant (const byte) printf_uint::format_zero_padding#0 = 0
Constant (const byte) printf_uint::format_radix#0 = HEXADECIMAL
Constant (const byte*) printf_str::str#5 = main::str4
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte*) printf_str::str#1 = printf_string::str#0
Successful SSA optimization Pass2ConstantIdentification
Eliminating unused constant (const byte) printf_string::format_min_length#0
Eliminating unused constant (const byte) printf_string::format_justify_left#0
Eliminating unused constant (const byte) printf_uint::format_min_length#0
Eliminating unused constant (const byte) printf_uint::format_justify_left#0
Eliminating unused constant (const byte) printf_uint::format_sign_always#0
Eliminating unused constant (const byte) printf_uint::format_zero_padding#0
Eliminating unused constant (const byte) printf_uint::format_radix#0
Successful SSA optimization PassNEliminateUnusedVars
Eliminating unused constant (const byte) HEXADECIMAL
Successful SSA optimization PassNEliminateUnusedVars
Alias printf_uint::$2 = printf_uint::$0
Alias printf_uint::$6 = printf_uint::$4
Successful SSA optimization Pass2AliasElimination
Constant right-side identified [9] (byte~) printf_uint::$2 ← > (const word) printf_uint::uvalue#0
Constant right-side identified [16] (byte~) printf_uint::$6 ← < (const word) printf_uint::uvalue#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte) printf_uint::$2 = >printf_uint::uvalue#0
Constant (const byte) printf_uint::$6 = <printf_uint::uvalue#0
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero >(const word) printf_uint::uvalue#0 in
Successful SSA optimization PassNSimplifyConstantZero
Constant right-side identified [9] (byte~) printf_uint::$1 ← (const byte) printf_uint::$2 >> (byte) 4
Constant right-side identified [12] (byte~) printf_uint::$3 ← (const byte) printf_uint::$2 & (byte) $f
Constant right-side identified [15] (byte~) printf_uint::$5 ← (const byte) printf_uint::$6 >> (byte) 4
Constant right-side identified [18] (byte~) printf_uint::$7 ← (const byte) printf_uint::$6 & (byte) $f
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte) printf_uint::$1 = printf_uint::$2>>4
Constant (const byte) printf_uint::$3 = printf_uint::$2&$f
Constant (const byte) printf_uint::$5 = printf_uint::$6>>4
Constant (const byte) printf_uint::$7 = printf_uint::$6&$f
Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero (const byte) printf_uint::$2>>(byte) 4 in
Simplifying constant evaluating to zero (const byte) printf_uint::$2&(byte) $f in
Successful SSA optimization PassNSimplifyConstantZero
Simplifying expression containing zero printf_hextab in [10] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab + (const byte) printf_uint::$1)
Simplifying expression containing zero printf_hextab in [13] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab + (const byte) printf_uint::$3)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) printf_uint::$2
Eliminating unused constant (const byte) printf_uint::$1
Eliminating unused constant (const byte) printf_uint::$3
Successful SSA optimization PassNEliminateUnusedVars
Inlining constant with var siblings (const byte*) printf_str::str#2
Inlining constant with var siblings (const byte*) printf_str::str#3
Inlining constant with var siblings (const byte*) printf_str::str#4
Inlining constant with var siblings (const byte*) printf_str::str#5
Inlining constant with var siblings (const byte*) printf_str::str#1
Inlining constant with var siblings (const byte*) screen#0
Constant inlined printf_str::str#5 = (const byte*) main::str4
Constant inlined printf_string::str#0 = (const byte*) main::str1
Constant inlined printf_uint::uvalue#0 = (const word) main::age
Constant inlined printf_uint::$5 = <(const word) main::age>>(byte) 4
Constant inlined printf_uint::$7 = <(const word) main::age&(byte) $f
Constant inlined printf_uint::$6 = <(const word) main::age
Constant inlined printf_str::str#2 = (const byte*) main::str
Constant inlined printf_str::str#1 = (const byte*) main::str1
Constant inlined printf_str::str#4 = (const byte*) main::str3
Constant inlined screen#0 = (byte*) 1024
Constant inlined printf_str::str#3 = (const byte*) main::str2
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(printf_hextab+<main::age>>4)
Consolidated array index constant in *(printf_hextab+<main::age&$f)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @4
Adding NOP phi() at start of @5
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@4
Adding NOP phi() at start of main::@6
Adding NOP phi() at start of printf_string::@1
CALL GRAPH
Calls in [] to main:2
Calls in [main] to printf_str:6 printf_string:8 printf_str:10 printf_str:12 printf_uint:14 printf_str:16
Calls in [printf_string] to printf_str:40
Created 4 initial phi equivalence classes
Coalesced [9] screen#37 ← screen#18
Coalesced (already) [11] screen#38 ← screen#18
Coalesced [15] screen#39 ← screen#23
Coalesced [20] printf_str::str#9 ← printf_str::str#8
Coalesced (already) [21] screen#41 ← screen#36
Coalesced [28] printf_str::str#10 ← printf_str::str#0
Coalesced [29] screen#42 ← screen#1
Coalesced (already) [39] screen#40 ← screen#18
Coalesced down to 2 phi equivalence classes
Culled Empty Block (label) @5
Culled Empty Block (label) main::@6
Culled Empty Block (label) printf_string::@1
Renumbering block @4 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
Adding NOP phi() at start of main::@2
Adding NOP phi() at start of main::@3
Adding NOP phi() at start of main::@4
Adding NOP phi() at start of main::@5
Adding NOP phi() at start of printf_string
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()
(void()) main()
main: scope:[main] from @1
[4] phi()
[5] call printf_str
to:main::@1
main::@1: scope:[main] from main
[6] phi()
[7] call printf_string
to:main::@2
main::@2: scope:[main] from main::@1
[8] phi()
[9] call printf_str
to:main::@3
main::@3: scope:[main] from main::@2
[10] phi()
[11] call printf_str
to:main::@4
main::@4: scope:[main] from main::@3
[12] phi()
[13] call printf_uint
to:main::@5
main::@5: scope:[main] from main::@4
[14] phi()
[15] call printf_str
to:main::@return
main::@return: scope:[main] from main::@5
[16] return
to:@return
(void()) printf_str((byte*) printf_str::str)
printf_str: scope:[printf_str] from main main::@2 main::@3 main::@5 printf_string
[17] (byte*) screen#36 ← phi( main/(byte*) 1024 main::@2/(byte*) screen#18 main::@3/(byte*) screen#18 main::@5/(byte*) screen#23 printf_string/(byte*) screen#18 )
[17] (byte*) printf_str::str#8 ← phi( main/(const byte*) main::str main::@2/(const byte*) main::str2 main::@3/(const byte*) main::str3 main::@5/(const byte*) main::str4 printf_string/(const byte*) main::str1 )
to:printf_str::@1
printf_str::@1: scope:[printf_str] from printf_str printf_str::@2
[18] (byte*) screen#18 ← phi( printf_str/(byte*) screen#36 printf_str::@2/(byte*) screen#1 )
[18] (byte*) printf_str::str#6 ← phi( printf_str/(byte*) printf_str::str#8 printf_str::@2/(byte*) printf_str::str#0 )
[19] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2
to:printf_str::@return
printf_str::@return: scope:[printf_str] from printf_str::@1
[20] return
to:@return
printf_str::@2: scope:[printf_str] from printf_str::@1
[21] *((byte*) screen#18) ← *((byte*) printf_str::str#6)
[22] (byte*) screen#1 ← ++ (byte*) screen#18
[23] (byte*) printf_str::str#0 ← ++ (byte*) printf_str::str#6
to:printf_str::@1
(void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix)
printf_uint: scope:[printf_uint] from main::@4
[24] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab)
[25] (byte*) screen#5 ← ++ (byte*) screen#18
[26] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab)
[27] (byte*) screen#6 ← ++ (byte*) screen#5
[28] *((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age>>(byte) 4)
[29] (byte*) screen#7 ← ++ (byte*) screen#6
[30] *((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age&(byte) $f)
[31] (byte*) screen#23 ← ++ (byte*) screen#7
to:printf_uint::@return
printf_uint::@return: scope:[printf_uint] from printf_uint
[32] return
to:@return
(void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left)
printf_string: scope:[printf_string] from main::@1
[33] phi()
[34] call printf_str
to:printf_string::@return
printf_string::@return: scope:[printf_string] from printf_string
[35] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) main()
(byte) printf_format_number::justify_left
(byte) printf_format_number::min_length
(byte) printf_format_number::radix
(byte) printf_format_number::sign_always
(byte) printf_format_number::zero_padding
(byte) printf_format_string::justify_left
(byte) printf_format_string::min_length
(void()) printf_str((byte*) printf_str::str)
(byte*) printf_str::str
(byte*) printf_str::str#0 20002.0
(byte*) printf_str::str#6 10251.25
(byte*) printf_str::str#8 1001.0
(void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left)
(struct printf_format_string) printf_string::format
(byte) printf_string::format_justify_left
(byte) printf_string::format_min_length
(byte*) printf_string::str
(void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix)
(struct printf_format_number) printf_uint::format
(byte) printf_uint::format_justify_left
(byte) printf_uint::format_min_length
(byte) printf_uint::format_radix
(byte) printf_uint::format_sign_always
(byte) printf_uint::format_zero_padding
(word) printf_uint::uvalue
(byte*) screen
(byte*) screen#1 10001.0
(byte*) screen#18 1958.0625
(byte*) screen#23 28.0
(byte*) screen#36 1135.0
(byte*) screen#5 151.5
(byte*) screen#6 151.5
(byte*) screen#7 151.5
Initial phi equivalence classes
[ screen#36 screen#18 screen#23 screen#1 ]
[ printf_str::str#6 printf_str::str#8 printf_str::str#0 ]
Added variable screen#5 to live range equivalence class [ screen#5 ]
Added variable screen#6 to live range equivalence class [ screen#6 ]
Added variable screen#7 to live range equivalence class [ screen#7 ]
Complete equivalence classes
[ screen#36 screen#18 screen#23 screen#1 ]
[ printf_str::str#6 printf_str::str#8 printf_str::str#0 ]
[ screen#5 ]
[ screen#6 ]
[ screen#7 ]
Allocated zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 ]
Allocated zp[2]:4 [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ]
Allocated zp[2]:6 [ screen#5 ]
Allocated zp[2]:8 [ screen#6 ]
Allocated zp[2]:10 [ screen#7 ]
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Tests printf function call rewriting
// A simple string - with the printf-sub cuntions in the same file.
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.label screen = 2
.label screen_1 = 6
.label screen_2 = 8
.label screen_3 = $a
// @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 age = $2e
// [5] call printf_str
// [17] phi from main to printf_str [phi:main->printf_str]
printf_str_from_main:
// [17] phi (byte*) screen#36 = (byte*) 1024 [phi:main->printf_str#0] -- pbuz1=pbuc1
lda #<$400
sta.z screen
lda #>$400
sta.z screen+1
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str [phi:main->printf_str#1] -- pbuz1=pbuc1
lda #<str
sta.z printf_str.str
lda #>str
sta.z printf_str.str+1
jsr printf_str
// [6] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
jmp __b1
// main::@1
__b1:
// [7] call printf_string
// [33] phi from main::@1 to printf_string [phi:main::@1->printf_string]
printf_string_from___b1:
jsr printf_string
// [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
__b2_from___b1:
jmp __b2
// main::@2
__b2:
// [9] call printf_str
// [17] phi from main::@2 to printf_str [phi:main::@2->printf_str]
printf_str_from___b2:
// [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@2->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str2 [phi:main::@2->printf_str#1] -- pbuz1=pbuc1
lda #<str2
sta.z printf_str.str
lda #>str2
sta.z printf_str.str+1
jsr printf_str
// [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
__b3_from___b2:
jmp __b3
// main::@3
__b3:
// [11] call printf_str
// [17] phi from main::@3 to printf_str [phi:main::@3->printf_str]
printf_str_from___b3:
// [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@3->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str3 [phi:main::@3->printf_str#1] -- pbuz1=pbuc1
lda #<str3
sta.z printf_str.str
lda #>str3
sta.z printf_str.str+1
jsr printf_str
// [12] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
__b4_from___b3:
jmp __b4
// main::@4
__b4:
// [13] call printf_uint
jsr printf_uint
// [14] phi from main::@4 to main::@5 [phi:main::@4->main::@5]
__b5_from___b4:
jmp __b5
// main::@5
__b5:
// [15] call printf_str
// [17] phi from main::@5 to printf_str [phi:main::@5->printf_str]
printf_str_from___b5:
// [17] phi (byte*) screen#36 = (byte*) screen#23 [phi:main::@5->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str4 [phi:main::@5->printf_str#1] -- pbuz1=pbuc1
lda #<str4
sta.z printf_str.str
lda #>str4
sta.z printf_str.str+1
jsr printf_str
jmp __breturn
// main::@return
__breturn:
// [16] return
rts
str: .text "Hello, I am "
.byte 0
str1: .text "Jesper"
.byte 0
str2: .text ". who are you?"
.byte 0
str3: .text "I am "
.byte 0
str4: .text " years old"
.byte 0
}
// printf_str
// printf_str(byte* zp(4) str)
printf_str: {
.label str = 4
// [18] phi from printf_str printf_str::@2 to printf_str::@1 [phi:printf_str/printf_str::@2->printf_str::@1]
__b1_from_printf_str:
__b1_from___b2:
// [18] phi (byte*) screen#18 = (byte*) screen#36 [phi:printf_str/printf_str::@2->printf_str::@1#0] -- register_copy
// [18] phi (byte*) printf_str::str#6 = (byte*) printf_str::str#8 [phi:printf_str/printf_str::@2->printf_str::@1#1] -- register_copy
jmp __b1
// printf_str::@1
__b1:
// [19] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1
ldy #0
lda (str),y
cmp #0
bne __b2
jmp __breturn
// printf_str::@return
__breturn:
// [20] return
rts
// printf_str::@2
__b2:
// [21] *((byte*) screen#18) ← *((byte*) printf_str::str#6) -- _deref_pbuz1=_deref_pbuz2
ldy #0
lda (str),y
ldy #0
sta (screen),y
// [22] (byte*) screen#1 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// [23] (byte*) printf_str::str#0 ← ++ (byte*) printf_str::str#6 -- pbuz1=_inc_pbuz1
inc.z str
bne !+
inc.z str+1
!:
jmp __b1_from___b2
}
// printf_uint
// Print an unsigned int using a specific format
// Always prints hexadecimals - ignores min_length and flags
printf_uint: {
// [24] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab
ldy #0
sta (screen),y
// [25] (byte*) screen#5 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz2
lda.z screen
clc
adc #1
sta.z screen_1
lda.z screen+1
adc #0
sta.z screen_1+1
// [26] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab
ldy #0
sta (screen_1),y
// [27] (byte*) screen#6 ← ++ (byte*) screen#5 -- pbuz1=_inc_pbuz2
lda.z screen_1
clc
adc #1
sta.z screen_2
lda.z screen_1+1
adc #0
sta.z screen_2+1
// [28] *((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age>>(byte) 4) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab+((<main.age)>>4)
ldy #0
sta (screen_2),y
// [29] (byte*) screen#7 ← ++ (byte*) screen#6 -- pbuz1=_inc_pbuz2
lda.z screen_2
clc
adc #1
sta.z screen_3
lda.z screen_2+1
adc #0
sta.z screen_3+1
// [30] *((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age&(byte) $f) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab+((<main.age)&$f)
ldy #0
sta (screen_3),y
// [31] (byte*) screen#23 ← ++ (byte*) screen#7 -- pbuz1=_inc_pbuz2
lda.z screen_3
clc
adc #1
sta.z screen
lda.z screen_3+1
adc #0
sta.z screen+1
jmp __breturn
// printf_uint::@return
__breturn:
// [32] return
rts
}
// printf_string
// Print a string value using a specific format
// Handles justification and min length
printf_string: {
// [34] call printf_str
// [17] phi from printf_string to printf_str [phi:printf_string->printf_str]
printf_str_from_printf_string:
// [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:printf_string->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str1 [phi:printf_string->printf_str#1] -- pbuz1=pbuc1
lda #<main.str1
sta.z printf_str.str
lda #>main.str1
sta.z printf_str.str+1
jsr printf_str
jmp __breturn
// printf_string::@return
__breturn:
// [35] return
rts
}
// File Data
printf_hextab: .text "0123456789abcdef"
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [19] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2 [ screen#18 printf_str::str#6 ] ( main:2::printf_str:5 [ screen#18 printf_str::str#6 ] { } main:2::printf_str:9 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } main:2::printf_str:11 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } main:2::printf_str:15 [ screen#18 printf_str::str#6 ] { { screen#23 = screen#36 } } main:2::printf_string:7::printf_str:34 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } ) always clobbers reg byte a reg byte y
Statement [21] *((byte*) screen#18) ← *((byte*) printf_str::str#6) [ screen#18 printf_str::str#6 ] ( main:2::printf_str:5 [ screen#18 printf_str::str#6 ] { } main:2::printf_str:9 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } main:2::printf_str:11 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } main:2::printf_str:15 [ screen#18 printf_str::str#6 ] { { screen#23 = screen#36 } } main:2::printf_string:7::printf_str:34 [ screen#18 printf_str::str#6 ] { { screen#18 = screen#36 } } ) always clobbers reg byte a reg byte y
Statement [24] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab) [ screen#18 ] ( main:2::printf_uint:13 [ screen#18 ] { } ) always clobbers reg byte a reg byte y
Statement [25] (byte*) screen#5 ← ++ (byte*) screen#18 [ screen#5 ] ( main:2::printf_uint:13 [ screen#5 ] { } ) always clobbers reg byte a
Statement [26] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab) [ screen#5 ] ( main:2::printf_uint:13 [ screen#5 ] { } ) always clobbers reg byte a reg byte y
Statement [27] (byte*) screen#6 ← ++ (byte*) screen#5 [ screen#6 ] ( main:2::printf_uint:13 [ screen#6 ] { } ) always clobbers reg byte a
Statement [28] *((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age>>(byte) 4) [ screen#6 ] ( main:2::printf_uint:13 [ screen#6 ] { } ) always clobbers reg byte a reg byte y
Statement [29] (byte*) screen#7 ← ++ (byte*) screen#6 [ screen#7 ] ( main:2::printf_uint:13 [ screen#7 ] { } ) always clobbers reg byte a
Statement [30] *((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age&(byte) $f) [ screen#7 ] ( main:2::printf_uint:13 [ screen#7 ] { } ) always clobbers reg byte a reg byte y
Statement [31] (byte*) screen#23 ← ++ (byte*) screen#7 [ screen#23 ] ( main:2::printf_uint:13 [ screen#23 ] { } ) always clobbers reg byte a
Potential registers zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 ] : zp[2]:2 ,
Potential registers zp[2]:4 [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ] : zp[2]:4 ,
Potential registers zp[2]:6 [ screen#5 ] : zp[2]:6 ,
Potential registers zp[2]:8 [ screen#6 ] : zp[2]:8 ,
Potential registers zp[2]:10 [ screen#7 ] : zp[2]:10 ,
REGISTER UPLIFT SCOPES
Uplift Scope [printf_str] 31,254.25: zp[2]:4 [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ]
Uplift Scope [] 13,122.06: zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 ] 151.5: zp[2]:6 [ screen#5 ] 151.5: zp[2]:8 [ screen#6 ] 151.5: zp[2]:10 [ screen#7 ]
Uplift Scope [printf_format_string]
Uplift Scope [printf_string]
Uplift Scope [RADIX]
Uplift Scope [printf_format_number]
Uplift Scope [printf_uint]
Uplift Scope [main]
Uplifting [printf_str] best 897 combination zp[2]:4 [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ]
Uplifting [] best 897 combination zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 ] zp[2]:6 [ screen#5 ] zp[2]:8 [ screen#6 ] zp[2]:10 [ screen#7 ]
Uplifting [printf_format_string] best 897 combination
Uplifting [printf_string] best 897 combination
Uplifting [RADIX] best 897 combination
Uplifting [printf_format_number] best 897 combination
Uplifting [printf_uint] best 897 combination
Uplifting [main] best 897 combination
Coalescing zero page register [ zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 ] ] with [ zp[2]:6 [ screen#5 ] ] - score: 1
Coalescing zero page register [ zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 screen#5 ] ] with [ zp[2]:10 [ screen#7 ] ] - score: 1
Coalescing zero page register [ zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 screen#5 screen#7 ] ] with [ zp[2]:8 [ screen#6 ] ] - score: 2
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Tests printf function call rewriting
// A simple string - with the printf-sub cuntions in the same file.
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.label screen = 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 age = $2e
// [5] call printf_str
// [17] phi from main to printf_str [phi:main->printf_str]
printf_str_from_main:
// [17] phi (byte*) screen#36 = (byte*) 1024 [phi:main->printf_str#0] -- pbuz1=pbuc1
lda #<$400
sta.z screen
lda #>$400
sta.z screen+1
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str [phi:main->printf_str#1] -- pbuz1=pbuc1
lda #<str
sta.z printf_str.str
lda #>str
sta.z printf_str.str+1
jsr printf_str
// [6] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
jmp __b1
// main::@1
__b1:
// [7] call printf_string
// [33] phi from main::@1 to printf_string [phi:main::@1->printf_string]
printf_string_from___b1:
jsr printf_string
// [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
__b2_from___b1:
jmp __b2
// main::@2
__b2:
// [9] call printf_str
// [17] phi from main::@2 to printf_str [phi:main::@2->printf_str]
printf_str_from___b2:
// [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@2->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str2 [phi:main::@2->printf_str#1] -- pbuz1=pbuc1
lda #<str2
sta.z printf_str.str
lda #>str2
sta.z printf_str.str+1
jsr printf_str
// [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
__b3_from___b2:
jmp __b3
// main::@3
__b3:
// [11] call printf_str
// [17] phi from main::@3 to printf_str [phi:main::@3->printf_str]
printf_str_from___b3:
// [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@3->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str3 [phi:main::@3->printf_str#1] -- pbuz1=pbuc1
lda #<str3
sta.z printf_str.str
lda #>str3
sta.z printf_str.str+1
jsr printf_str
// [12] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
__b4_from___b3:
jmp __b4
// main::@4
__b4:
// [13] call printf_uint
jsr printf_uint
// [14] phi from main::@4 to main::@5 [phi:main::@4->main::@5]
__b5_from___b4:
jmp __b5
// main::@5
__b5:
// [15] call printf_str
// [17] phi from main::@5 to printf_str [phi:main::@5->printf_str]
printf_str_from___b5:
// [17] phi (byte*) screen#36 = (byte*) screen#23 [phi:main::@5->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str4 [phi:main::@5->printf_str#1] -- pbuz1=pbuc1
lda #<str4
sta.z printf_str.str
lda #>str4
sta.z printf_str.str+1
jsr printf_str
jmp __breturn
// main::@return
__breturn:
// [16] return
rts
str: .text "Hello, I am "
.byte 0
str1: .text "Jesper"
.byte 0
str2: .text ". who are you?"
.byte 0
str3: .text "I am "
.byte 0
str4: .text " years old"
.byte 0
}
// printf_str
// printf_str(byte* zp(4) str)
printf_str: {
.label str = 4
// [18] phi from printf_str printf_str::@2 to printf_str::@1 [phi:printf_str/printf_str::@2->printf_str::@1]
__b1_from_printf_str:
__b1_from___b2:
// [18] phi (byte*) screen#18 = (byte*) screen#36 [phi:printf_str/printf_str::@2->printf_str::@1#0] -- register_copy
// [18] phi (byte*) printf_str::str#6 = (byte*) printf_str::str#8 [phi:printf_str/printf_str::@2->printf_str::@1#1] -- register_copy
jmp __b1
// printf_str::@1
__b1:
// [19] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1
ldy #0
lda (str),y
cmp #0
bne __b2
jmp __breturn
// printf_str::@return
__breturn:
// [20] return
rts
// printf_str::@2
__b2:
// [21] *((byte*) screen#18) ← *((byte*) printf_str::str#6) -- _deref_pbuz1=_deref_pbuz2
ldy #0
lda (str),y
ldy #0
sta (screen),y
// [22] (byte*) screen#1 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// [23] (byte*) printf_str::str#0 ← ++ (byte*) printf_str::str#6 -- pbuz1=_inc_pbuz1
inc.z str
bne !+
inc.z str+1
!:
jmp __b1_from___b2
}
// printf_uint
// Print an unsigned int using a specific format
// Always prints hexadecimals - ignores min_length and flags
printf_uint: {
// [24] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab
ldy #0
sta (screen),y
// [25] (byte*) screen#5 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// [26] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab
ldy #0
sta (screen),y
// [27] (byte*) screen#6 ← ++ (byte*) screen#5 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// [28] *((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age>>(byte) 4) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab+((<main.age)>>4)
ldy #0
sta (screen),y
// [29] (byte*) screen#7 ← ++ (byte*) screen#6 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// [30] *((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age&(byte) $f) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab+((<main.age)&$f)
ldy #0
sta (screen),y
// [31] (byte*) screen#23 ← ++ (byte*) screen#7 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
jmp __breturn
// printf_uint::@return
__breturn:
// [32] return
rts
}
// printf_string
// Print a string value using a specific format
// Handles justification and min length
printf_string: {
// [34] call printf_str
// [17] phi from printf_string to printf_str [phi:printf_string->printf_str]
printf_str_from_printf_string:
// [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:printf_string->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str1 [phi:printf_string->printf_str#1] -- pbuz1=pbuc1
lda #<main.str1
sta.z printf_str.str
lda #>main.str1
sta.z printf_str.str+1
jsr printf_str
jmp __breturn
// printf_string::@return
__breturn:
// [35] return
rts
}
// File Data
printf_hextab: .text "0123456789abcdef"
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __b3
Removing instruction jmp __b4
Removing instruction jmp __b5
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction ldy #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __b1_from___b2 with __b1
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 printf_string_from___b1:
Removing instruction __b2_from___b1:
Removing instruction printf_str_from___b2:
Removing instruction __b3_from___b2:
Removing instruction printf_str_from___b3:
Removing instruction __b4_from___b3:
Removing instruction __b5_from___b4:
Removing instruction printf_str_from___b5:
Removing instruction __b1_from_printf_str:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bend:
Removing instruction printf_str_from_main:
Removing instruction __b1:
Removing instruction __b2:
Removing instruction __b3:
Removing instruction __b4:
Removing instruction __b5:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction printf_str_from_printf_string:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction __bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(const byte) RADIX::BINARY = (number) 2
(const byte) RADIX::DECIMAL = (number) $a
(const byte) RADIX::HEXADECIMAL = (number) $10
(const byte) RADIX::OCTAL = (number) 8
(void()) main()
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::@5
(label) main::@return
(const word) main::age = (word) $2e
(const byte*) main::str[(byte) $d] = (byte*) "Hello, I am "
(const byte*) main::str1[(byte) 7] = (byte*) "Jesper"
(const byte*) main::str2[(byte) $f] = (byte*) ". who are you?"
(const byte*) main::str3[(byte) 6] = (byte*) "I am "
(const byte*) main::str4[(byte) $b] = (byte*) " years old"
(byte) printf_format_number::justify_left
(byte) printf_format_number::min_length
(byte) printf_format_number::radix
(byte) printf_format_number::sign_always
(byte) printf_format_number::zero_padding
(byte) printf_format_string::justify_left
(byte) printf_format_string::min_length
(const to_nomodify byte*) printf_hextab[] = (byte*) "0123456789abcdef"z
(void()) printf_str((byte*) printf_str::str)
(label) printf_str::@1
(label) printf_str::@2
(label) printf_str::@return
(byte*) printf_str::str
(byte*) printf_str::str#0 str zp[2]:4 20002.0
(byte*) printf_str::str#6 str zp[2]:4 10251.25
(byte*) printf_str::str#8 str zp[2]:4 1001.0
(void()) printf_string((byte*) printf_string::str , (byte) printf_string::format_min_length , (byte) printf_string::format_justify_left)
(label) printf_string::@return
(struct printf_format_string) printf_string::format
(byte) printf_string::format_justify_left
(byte) printf_string::format_min_length
(byte*) printf_string::str
(void()) printf_uint((word) printf_uint::uvalue , (byte) printf_uint::format_min_length , (byte) printf_uint::format_justify_left , (byte) printf_uint::format_sign_always , (byte) printf_uint::format_zero_padding , (byte) printf_uint::format_radix)
(label) printf_uint::@return
(struct printf_format_number) printf_uint::format
(byte) printf_uint::format_justify_left
(byte) printf_uint::format_min_length
(byte) printf_uint::format_radix
(byte) printf_uint::format_sign_always
(byte) printf_uint::format_zero_padding
(word) printf_uint::uvalue
(byte*) screen
(byte*) screen#1 screen zp[2]:2 10001.0
(byte*) screen#18 screen zp[2]:2 1958.0625
(byte*) screen#23 screen zp[2]:2 28.0
(byte*) screen#36 screen zp[2]:2 1135.0
(byte*) screen#5 screen zp[2]:2 151.5
(byte*) screen#6 screen zp[2]:2 151.5
(byte*) screen#7 screen zp[2]:2 151.5
zp[2]:2 [ screen#36 screen#18 screen#23 screen#1 screen#5 screen#7 screen#6 ]
zp[2]:4 [ printf_str::str#6 printf_str::str#8 printf_str::str#0 ]
FINAL ASSEMBLER
Score: 757
// File Comments
// Tests printf function call rewriting
// A simple string - with the printf-sub cuntions in the same file.
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.label screen = 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: {
.label age = $2e
// printf("Hello, I am %s. who are you?", "Jesper")
// [5] call printf_str
// [17] phi from main to printf_str [phi:main->printf_str]
// [17] phi (byte*) screen#36 = (byte*) 1024 [phi:main->printf_str#0] -- pbuz1=pbuc1
lda #<$400
sta.z screen
lda #>$400
sta.z screen+1
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str [phi:main->printf_str#1] -- pbuz1=pbuc1
lda #<str
sta.z printf_str.str
lda #>str
sta.z printf_str.str+1
jsr printf_str
// [6] phi from main to main::@1 [phi:main->main::@1]
// main::@1
// printf("Hello, I am %s. who are you?", "Jesper")
// [7] call printf_string
// [33] phi from main::@1 to printf_string [phi:main::@1->printf_string]
jsr printf_string
// [8] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
// main::@2
// printf("Hello, I am %s. who are you?", "Jesper")
// [9] call printf_str
// [17] phi from main::@2 to printf_str [phi:main::@2->printf_str]
// [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@2->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str2 [phi:main::@2->printf_str#1] -- pbuz1=pbuc1
lda #<str2
sta.z printf_str.str
lda #>str2
sta.z printf_str.str+1
jsr printf_str
// [10] phi from main::@2 to main::@3 [phi:main::@2->main::@3]
// main::@3
// printf("I am %x years old", age)
// [11] call printf_str
// [17] phi from main::@3 to printf_str [phi:main::@3->printf_str]
// [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:main::@3->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str3 [phi:main::@3->printf_str#1] -- pbuz1=pbuc1
lda #<str3
sta.z printf_str.str
lda #>str3
sta.z printf_str.str+1
jsr printf_str
// [12] phi from main::@3 to main::@4 [phi:main::@3->main::@4]
// main::@4
// printf("I am %x years old", age)
// [13] call printf_uint
jsr printf_uint
// [14] phi from main::@4 to main::@5 [phi:main::@4->main::@5]
// main::@5
// printf("I am %x years old", age)
// [15] call printf_str
// [17] phi from main::@5 to printf_str [phi:main::@5->printf_str]
// [17] phi (byte*) screen#36 = (byte*) screen#23 [phi:main::@5->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str4 [phi:main::@5->printf_str#1] -- pbuz1=pbuc1
lda #<str4
sta.z printf_str.str
lda #>str4
sta.z printf_str.str+1
jsr printf_str
// main::@return
// }
// [16] return
rts
str: .text "Hello, I am "
.byte 0
str1: .text "Jesper"
.byte 0
str2: .text ". who are you?"
.byte 0
str3: .text "I am "
.byte 0
str4: .text " years old"
.byte 0
}
// printf_str
// printf_str(byte* zp(4) str)
printf_str: {
.label str = 4
// [18] phi from printf_str printf_str::@2 to printf_str::@1 [phi:printf_str/printf_str::@2->printf_str::@1]
// [18] phi (byte*) screen#18 = (byte*) screen#36 [phi:printf_str/printf_str::@2->printf_str::@1#0] -- register_copy
// [18] phi (byte*) printf_str::str#6 = (byte*) printf_str::str#8 [phi:printf_str/printf_str::@2->printf_str::@1#1] -- register_copy
// printf_str::@1
__b1:
// while(*str)
// [19] if((byte) 0!=*((byte*) printf_str::str#6)) goto printf_str::@2 -- vbuc1_neq__deref_pbuz1_then_la1
ldy #0
lda (str),y
cmp #0
bne __b2
// printf_str::@return
// }
// [20] return
rts
// printf_str::@2
__b2:
// *screen++ = *str++
// [21] *((byte*) screen#18) ← *((byte*) printf_str::str#6) -- _deref_pbuz1=_deref_pbuz2
ldy #0
lda (str),y
sta (screen),y
// *screen++ = *str++;
// [22] (byte*) screen#1 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// [23] (byte*) printf_str::str#0 ← ++ (byte*) printf_str::str#6 -- pbuz1=_inc_pbuz1
inc.z str
bne !+
inc.z str+1
!:
jmp __b1
}
// printf_uint
// Print an unsigned int using a specific format
// Always prints hexadecimals - ignores min_length and flags
printf_uint: {
// *screen++ = printf_hextab[(>uvalue)>>4]
// [24] *((byte*) screen#18) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab
ldy #0
sta (screen),y
// *screen++ = printf_hextab[(>uvalue)>>4];
// [25] (byte*) screen#5 ← ++ (byte*) screen#18 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// *screen++ = printf_hextab[(>uvalue)&0xf]
// [26] *((byte*) screen#5) ← *((const to_nomodify byte*) printf_hextab) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab
ldy #0
sta (screen),y
// *screen++ = printf_hextab[(>uvalue)&0xf];
// [27] (byte*) screen#6 ← ++ (byte*) screen#5 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// *screen++ = printf_hextab[(<uvalue)>>4]
// [28] *((byte*) screen#6) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age>>(byte) 4) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab+((<main.age)>>4)
ldy #0
sta (screen),y
// *screen++ = printf_hextab[(<uvalue)>>4];
// [29] (byte*) screen#7 ← ++ (byte*) screen#6 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// *screen++ = printf_hextab[(<uvalue)&0xf]
// [30] *((byte*) screen#7) ← *((const to_nomodify byte*) printf_hextab+<(const word) main::age&(byte) $f) -- _deref_pbuz1=_deref_pbuc1
lda printf_hextab+((<main.age)&$f)
ldy #0
sta (screen),y
// *screen++ = printf_hextab[(<uvalue)&0xf];
// [31] (byte*) screen#23 ← ++ (byte*) screen#7 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// printf_uint::@return
// }
// [32] return
rts
}
// printf_string
// Print a string value using a specific format
// Handles justification and min length
printf_string: {
// printf_str(str)
// [34] call printf_str
// [17] phi from printf_string to printf_str [phi:printf_string->printf_str]
// [17] phi (byte*) screen#36 = (byte*) screen#18 [phi:printf_string->printf_str#0] -- register_copy
// [17] phi (byte*) printf_str::str#8 = (const byte*) main::str1 [phi:printf_string->printf_str#1] -- pbuz1=pbuc1
lda #<main.str1
sta.z printf_str.str
lda #>main.str1
sta.z printf_str.str+1
jsr printf_str
// printf_string::@return
// }
// [35] return
rts
}
// File Data
printf_hextab: .text "0123456789abcdef"