1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-29 09:29:31 +00:00
kickc/src/test/ref/printf-10.log
2021-04-30 17:26:46 +02:00

631 lines
20 KiB
Plaintext

Added struct type cast to parameter value list call printf_string main::name (struct printf_format_string){ 0, 0 }
Inlined call call __init
Eliminating unused variable with no statement main::$0
CONTROL FLOW GRAPH SSA
void cputs(byte* cputs::str)
cputs: scope:[cputs] from main main::@2 printf_string
screen#25 = phi( main/screen#23, main::@2/screen#5, printf_string/screen#22 )
cputs::str#6 = phi( main/cputs::str#2, main::@2/cputs::str#3, printf_string/cputs::str#1 )
to:cputs::@1
cputs::@1: scope:[cputs] from cputs cputs::@2
screen#21 = phi( cputs/screen#25, cputs::@2/screen#0 )
cputs::str#4 = phi( cputs/cputs::str#6, cputs::@2/cputs::str#0 )
cputs::$0 = 0 != *cputs::str#4
if(cputs::$0) goto cputs::@2
to:cputs::@return
cputs::@2: scope:[cputs] from cputs::@1
screen#11 = phi( cputs::@1/screen#21 )
cputs::str#5 = phi( cputs::@1/cputs::str#4 )
*screen#11 = *cputs::str#5
screen#0 = ++ screen#11
cputs::str#0 = ++ cputs::str#5
to:cputs::@1
cputs::@return: scope:[cputs] from cputs::@1
screen#12 = phi( cputs::@1/screen#21 )
screen#1 = screen#12
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
screen#22 = phi( main::@1/screen#4 )
printf_string::str#1 = phi( main::@1/printf_string::str#0 )
cputs::str#1 = printf_string::str#1
call cputs
to:printf_string::@1
printf_string::@1: scope:[printf_string] from printf_string
screen#13 = phi( printf_string/screen#1 )
screen#2 = screen#13
to:printf_string::@return
printf_string::@return: scope:[printf_string] from printf_string::@1
screen#14 = phi( printf_string::@1/screen#2 )
screen#3 = screen#14
return
to:@return
void main()
main: scope:[main] from __start::@1
screen#23 = phi( __start::@1/screen#24 )
cputs::str#2 = main::str
call cputs
to:main::@1
main::@1: scope:[main] from main
screen#15 = phi( main/screen#1 )
screen#4 = screen#15
printf_string::str#0 = main::name
printf_string::format_min_length#0 = 0
printf_string::format_justify_left#0 = 0
call printf_string
to:main::@2
main::@2: scope:[main] from main::@1
screen#16 = phi( main::@1/screen#3 )
screen#5 = screen#16
cputs::str#3 = main::str1
call cputs
to:main::@3
main::@3: scope:[main] from main::@2
screen#17 = phi( main::@2/screen#1 )
screen#6 = screen#17
to:main::@return
main::@return: scope:[main] from main::@3
screen#18 = phi( main::@3/screen#6 )
screen#7 = screen#18
return
to:@return
void __start()
__start: scope:[__start] from
to:__start::__init1
__start::__init1: scope:[__start] from __start
screen#8 = (byte*)$400
to:__start::@1
__start::@1: scope:[__start] from __start::__init1
screen#24 = phi( __start::__init1/screen#8 )
call main
to:__start::@2
__start::@2: scope:[__start] from __start::@1
screen#19 = phi( __start::@1/screen#7 )
screen#9 = screen#19
to:__start::@return
__start::@return: scope:[__start] from __start::@2
screen#20 = phi( __start::@2/screen#9 )
screen#10 = screen#20
return
to:@return
SYMBOL TABLE SSA
void __start()
void cputs(byte* cputs::str)
bool~ cputs::$0
byte* cputs::str
byte* cputs::str#0
byte* cputs::str#1
byte* cputs::str#2
byte* cputs::str#3
byte* cputs::str#4
byte* cputs::str#5
byte* cputs::str#6
void main()
constant byte* main::name = "Jesper"
constant byte* main::str[$d] = "Hello, I am "
constant byte* main::str1[$f] = ". who are you?"
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_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
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#3
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 cputs::$0 = 0 != *cputs::str#4
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 0
Simplifying constant pointer cast (byte*) 1024
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias cputs::str#4 = cputs::str#5
Alias screen#1 = screen#11 screen#21 screen#12
Alias screen#13 = screen#2 screen#14 screen#3
Alias screen#15 = screen#4
Alias screen#16 = screen#5
Alias screen#17 = screen#6 screen#18 screen#7
Alias screen#24 = screen#8
Alias screen#10 = screen#9 screen#19 screen#20
Successful SSA optimization Pass2AliasElimination
Identical Phi Values printf_string::str#1 printf_string::str#0
Identical Phi Values screen#22 screen#15
Identical Phi Values screen#13 screen#1
Identical Phi Values screen#23 screen#24
Identical Phi Values screen#15 screen#1
Identical Phi Values screen#16 screen#13
Identical Phi Values screen#17 screen#1
Identical Phi Values screen#10 screen#17
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition cputs::$0 [3] if(0!=*cputs::str#4) goto cputs::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant cputs::str#2 = main::str
Constant printf_string::str#0 = main::name
Constant printf_string::format_min_length#0 = 0
Constant printf_string::format_justify_left#0 = 0
Constant cputs::str#3 = main::str1
Constant screen#24 = (byte*) 1024
Successful SSA optimization Pass2ConstantIdentification
Constant cputs::str#1 = printf_string::str#0
Successful SSA optimization Pass2ConstantIdentification
Eliminating unused constant printf_string::format_min_length#0
Eliminating unused constant printf_string::format_justify_left#0
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
Inlining constant with var siblings cputs::str#2
Inlining constant with var siblings cputs::str#3
Inlining constant with var siblings cputs::str#1
Inlining constant with var siblings screen#24
Constant inlined cputs::str#1 = main::name
Constant inlined cputs::str#2 = main::str
Constant inlined cputs::str#3 = main::str1
Constant inlined screen#24 = (byte*) 1024
Constant inlined printf_string::str#0 = main::name
Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
Adding NOP phi() at start of main::@3
Adding NOP phi() at start of printf_string::@1
CALL GRAPH
Calls in [main] to cputs:1 printf_string:3 cputs:5
Calls in [printf_string] to cputs:20
Created 4 initial phi equivalence classes
Coalesced [4] screen#26 = screen#1
Coalesced [9] cputs::str#7 = cputs::str#6
Coalesced (already) [10] screen#28 = screen#25
Coalesced [17] cputs::str#8 = cputs::str#0
Coalesced [18] screen#29 = screen#0
Coalesced (already) [19] screen#27 = screen#1
Coalesced down to 2 phi equivalence classes
Culled Empty Block label main::@3
Culled Empty Block label printf_string::@1
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 printf_string
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] phi()
[1] call cputs
to:main::@1
main::@1: scope:[main] from main
[2] phi()
[3] call printf_string
to:main::@2
main::@2: scope:[main] from main::@1
[4] phi()
[5] call cputs
to:main::@return
main::@return: scope:[main] from main::@2
[6] return
to:@return
void cputs(byte* cputs::str)
cputs: scope:[cputs] from main main::@2 printf_string
[7] screen#25 = phi( main/(byte*) 1024, main::@2/screen#1, printf_string/screen#1 )
[7] cputs::str#6 = phi( main/main::str, main::@2/main::str1, printf_string/main::name )
to:cputs::@1
cputs::@1: scope:[cputs] from cputs cputs::@2
[8] screen#1 = phi( cputs/screen#25, cputs::@2/screen#0 )
[8] cputs::str#4 = phi( cputs/cputs::str#6, cputs::@2/cputs::str#0 )
[9] if(0!=*cputs::str#4) goto cputs::@2
to:cputs::@return
cputs::@return: scope:[cputs] from cputs::@1
[10] return
to:@return
cputs::@2: scope:[cputs] from cputs::@1
[11] *screen#1 = *cputs::str#4
[12] screen#0 = ++ screen#1
[13] cputs::str#0 = ++ cputs::str#4
to:cputs::@1
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
[14] phi()
[15] call cputs
to:printf_string::@return
printf_string::@return: scope:[printf_string] from printf_string
[16] return
to:@return
VARIABLE REGISTER WEIGHTS
void cputs(byte* cputs::str)
byte* cputs::str
byte* cputs::str#0 2002.0
byte* cputs::str#4 1026.25
byte* cputs::str#6 101.0
void main()
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
byte* screen
byte* screen#0 1001.0
byte* screen#1 283.3636363636364
byte* screen#25 114.0
Initial phi equivalence classes
[ screen#25 screen#1 screen#0 ]
[ cputs::str#4 cputs::str#6 cputs::str#0 ]
Complete equivalence classes
[ screen#25 screen#1 screen#0 ]
[ cputs::str#4 cputs::str#6 cputs::str#0 ]
Allocated zp[2]:2 [ screen#25 screen#1 screen#0 ]
Allocated zp[2]:4 [ cputs::str#4 cputs::str#6 cputs::str#0 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [9] if(0!=*cputs::str#4) goto cputs::@2 [ screen#1 cputs::str#4 ] ( cputs:1 [ screen#1 cputs::str#4 ] { } cputs:5 [ screen#1 cputs::str#4 ] { { screen#1 = screen#25 } } printf_string:3::cputs:15 [ screen#1 cputs::str#4 ] { { screen#1 = screen#25 } } ) always clobbers reg byte a reg byte y
Statement [11] *screen#1 = *cputs::str#4 [ screen#1 cputs::str#4 ] ( cputs:1 [ screen#1 cputs::str#4 ] { } cputs:5 [ screen#1 cputs::str#4 ] { { screen#1 = screen#25 } } printf_string:3::cputs:15 [ screen#1 cputs::str#4 ] { { screen#1 = screen#25 } } ) always clobbers reg byte a reg byte y
Potential registers zp[2]:2 [ screen#25 screen#1 screen#0 ] : zp[2]:2 ,
Potential registers zp[2]:4 [ cputs::str#4 cputs::str#6 cputs::str#0 ] : zp[2]:4 ,
REGISTER UPLIFT SCOPES
Uplift Scope [cputs] 3,129.25: zp[2]:4 [ cputs::str#4 cputs::str#6 cputs::str#0 ]
Uplift Scope [] 1,398.36: zp[2]:2 [ screen#25 screen#1 screen#0 ]
Uplift Scope [printf_format_string]
Uplift Scope [printf_string]
Uplift Scope [main]
Uplifting [cputs] best 709 combination zp[2]:4 [ cputs::str#4 cputs::str#6 cputs::str#0 ]
Uplifting [] best 709 combination zp[2]:2 [ screen#25 screen#1 screen#0 ]
Uplifting [printf_format_string] best 709 combination
Uplifting [printf_string] best 709 combination
Uplifting [main] best 709 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Tests printf function call rewriting
// A simple string - with the printf-sub cuntions in the same file.
// Upstart
// Commodore 64 PRG executable file
.file [name="printf-10.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 = 2
.segment Code
// main
main: {
// [1] call cputs
// [7] phi from main to cputs [phi:main->cputs]
cputs_from_main:
// [7] phi screen#25 = (byte*) 1024 [phi:main->cputs#0] -- pbuz1=pbuc1
lda #<$400
sta.z screen
lda #>$400
sta.z screen+1
// [7] phi cputs::str#6 = main::str [phi:main->cputs#1] -- pbuz1=pbuc1
lda #<str
sta.z cputs.str
lda #>str
sta.z cputs.str+1
jsr cputs
// [2] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
jmp __b1
// main::@1
__b1:
// [3] call printf_string
// [14] phi from main::@1 to printf_string [phi:main::@1->printf_string]
printf_string_from___b1:
jsr printf_string
// [4] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
__b2_from___b1:
jmp __b2
// main::@2
__b2:
// [5] call cputs
// [7] phi from main::@2 to cputs [phi:main::@2->cputs]
cputs_from___b2:
// [7] phi screen#25 = screen#1 [phi:main::@2->cputs#0] -- register_copy
// [7] phi cputs::str#6 = main::str1 [phi:main::@2->cputs#1] -- pbuz1=pbuc1
lda #<str1
sta.z cputs.str
lda #>str1
sta.z cputs.str+1
jsr cputs
jmp __breturn
// main::@return
__breturn:
// [6] return
rts
.segment Data
name: .text "Jesper"
.byte 0
str: .text "Hello, I am "
.byte 0
str1: .text ". who are you?"
.byte 0
}
.segment Code
// cputs
// cputs(byte* zp(4) str)
cputs: {
.label str = 4
// [8] phi from cputs cputs::@2 to cputs::@1 [phi:cputs/cputs::@2->cputs::@1]
__b1_from_cputs:
__b1_from___b2:
// [8] phi screen#1 = screen#25 [phi:cputs/cputs::@2->cputs::@1#0] -- register_copy
// [8] phi cputs::str#4 = cputs::str#6 [phi:cputs/cputs::@2->cputs::@1#1] -- register_copy
jmp __b1
// cputs::@1
__b1:
// [9] if(0!=*cputs::str#4) goto cputs::@2 -- 0_neq__deref_pbuz1_then_la1
ldy #0
lda (str),y
cmp #0
bne __b2
jmp __breturn
// cputs::@return
__breturn:
// [10] return
rts
// cputs::@2
__b2:
// [11] *screen#1 = *cputs::str#4 -- _deref_pbuz1=_deref_pbuz2
ldy #0
lda (str),y
ldy #0
sta (screen),y
// [12] screen#0 = ++ screen#1 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// [13] cputs::str#0 = ++ cputs::str#4 -- pbuz1=_inc_pbuz1
inc.z str
bne !+
inc.z str+1
!:
jmp __b1_from___b2
}
// printf_string
// Print a string value using a specific format
// Handles justification and min length
printf_string: {
// [15] call cputs
// [7] phi from printf_string to cputs [phi:printf_string->cputs]
cputs_from_printf_string:
// [7] phi screen#25 = screen#1 [phi:printf_string->cputs#0] -- register_copy
// [7] phi cputs::str#6 = main::name [phi:printf_string->cputs#1] -- pbuz1=pbuc1
lda #<main.name
sta.z cputs.str
lda #>main.name
sta.z cputs.str+1
jsr cputs
jmp __breturn
// printf_string::@return
__breturn:
// [16] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn
Removing instruction jmp __b1
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_main:
Removing instruction printf_string_from___b1:
Removing instruction __b2_from___b1:
Removing instruction cputs_from___b2:
Removing instruction __b1_from_cputs:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction cputs_from_main:
Removing instruction __b1:
Removing instruction __b2:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction cputs_from_printf_string:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
void cputs(byte* cputs::str)
byte* cputs::str
byte* cputs::str#0 str zp[2]:4 2002.0
byte* cputs::str#4 str zp[2]:4 1026.25
byte* cputs::str#6 str zp[2]:4 101.0
void main()
constant byte* main::name = "Jesper"
constant byte* main::str[$d] = "Hello, I am "
constant byte* main::str1[$f] = ". who are you?"
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
byte* screen
byte* screen#0 screen zp[2]:2 1001.0
byte* screen#1 screen zp[2]:2 283.3636363636364
byte* screen#25 screen zp[2]:2 114.0
zp[2]:2 [ screen#25 screen#1 screen#0 ]
zp[2]:4 [ cputs::str#4 cputs::str#6 cputs::str#0 ]
FINAL ASSEMBLER
Score: 617
// File Comments
// Tests printf function call rewriting
// A simple string - with the printf-sub cuntions in the same file.
// Upstart
// Commodore 64 PRG executable file
.file [name="printf-10.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 = 2
.segment Code
// main
main: {
// printf("Hello, I am %s. who are you?", name)
// [1] call cputs
// [7] phi from main to cputs [phi:main->cputs]
// [7] phi screen#25 = (byte*) 1024 [phi:main->cputs#0] -- pbuz1=pbuc1
lda #<$400
sta.z screen
lda #>$400
sta.z screen+1
// [7] phi cputs::str#6 = main::str [phi:main->cputs#1] -- pbuz1=pbuc1
lda #<str
sta.z cputs.str
lda #>str
sta.z cputs.str+1
jsr cputs
// [2] phi from main to main::@1 [phi:main->main::@1]
// main::@1
// printf("Hello, I am %s. who are you?", name)
// [3] call printf_string
// [14] phi from main::@1 to printf_string [phi:main::@1->printf_string]
jsr printf_string
// [4] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
// main::@2
// printf("Hello, I am %s. who are you?", name)
// [5] call cputs
// [7] phi from main::@2 to cputs [phi:main::@2->cputs]
// [7] phi screen#25 = screen#1 [phi:main::@2->cputs#0] -- register_copy
// [7] phi cputs::str#6 = main::str1 [phi:main::@2->cputs#1] -- pbuz1=pbuc1
lda #<str1
sta.z cputs.str
lda #>str1
sta.z cputs.str+1
jsr cputs
// main::@return
// }
// [6] return
rts
.segment Data
name: .text "Jesper"
.byte 0
str: .text "Hello, I am "
.byte 0
str1: .text ". who are you?"
.byte 0
}
.segment Code
// cputs
// cputs(byte* zp(4) str)
cputs: {
.label str = 4
// [8] phi from cputs cputs::@2 to cputs::@1 [phi:cputs/cputs::@2->cputs::@1]
// [8] phi screen#1 = screen#25 [phi:cputs/cputs::@2->cputs::@1#0] -- register_copy
// [8] phi cputs::str#4 = cputs::str#6 [phi:cputs/cputs::@2->cputs::@1#1] -- register_copy
// cputs::@1
__b1:
// while(*str)
// [9] if(0!=*cputs::str#4) goto cputs::@2 -- 0_neq__deref_pbuz1_then_la1
ldy #0
lda (str),y
cmp #0
bne __b2
// cputs::@return
// }
// [10] return
rts
// cputs::@2
__b2:
// *screen++ = *str++
// [11] *screen#1 = *cputs::str#4 -- _deref_pbuz1=_deref_pbuz2
ldy #0
lda (str),y
sta (screen),y
// *screen++ = *str++;
// [12] screen#0 = ++ screen#1 -- pbuz1=_inc_pbuz1
inc.z screen
bne !+
inc.z screen+1
!:
// [13] cputs::str#0 = ++ cputs::str#4 -- pbuz1=_inc_pbuz1
inc.z str
bne !+
inc.z str+1
!:
jmp __b1
}
// printf_string
// Print a string value using a specific format
// Handles justification and min length
printf_string: {
// cputs(str)
// [15] call cputs
// [7] phi from printf_string to cputs [phi:printf_string->cputs]
// [7] phi screen#25 = screen#1 [phi:printf_string->cputs#0] -- register_copy
// [7] phi cputs::str#6 = main::name [phi:printf_string->cputs#1] -- pbuz1=pbuc1
lda #<main.name
sta.z cputs.str
lda #>main.name
sta.z cputs.str+1
jsr cputs
// printf_string::@return
// }
// [16] return
rts
}
// File Data