kickc/src/test/ref/loophead-problem.log

403 lines
14 KiB
Plaintext

Inlined call call __init
CONTROL FLOW GRAPH SSA
void main()
main: scope:[main] from __start::@1
opcode#7 = phi( __start::@1/opcode#13 )
screen[$28] = opcode#7
call popup_selector
to:main::@1
main::@1: scope:[main] from main
opcode#8 = phi( main/opcode#3 )
opcode#0 = opcode#8
screen[$29] = opcode#0
to:main::@return
main::@return: scope:[main] from main::@1
opcode#9 = phi( main::@1/opcode#0 )
opcode#1 = opcode#9
return
to:@return
void popup_selector()
popup_selector: scope:[popup_selector] from main
opcode#15 = phi( main/opcode#7 )
popup_selector::k#0 = 0
to:popup_selector::@1
popup_selector::@1: scope:[popup_selector] from popup_selector popup_selector::@2
opcode#14 = phi( popup_selector/opcode#15, popup_selector::@2/opcode#2 )
popup_selector::k#2 = phi( popup_selector/popup_selector::k#0, popup_selector::@2/popup_selector::k#1 )
popup_selector::$0 = popup_selector::k#2 <= 2
if(popup_selector::$0) goto popup_selector::@2
to:popup_selector::@return
popup_selector::@2: scope:[popup_selector] from popup_selector::@1
popup_selector::k#3 = phi( popup_selector::@1/popup_selector::k#2 )
opcode#2 = 'b'
screen[popup_selector::k#3] = opcode#2
popup_selector::k#1 = ++ popup_selector::k#3
to:popup_selector::@1
popup_selector::@return: scope:[popup_selector] from popup_selector::@1
opcode#10 = phi( popup_selector::@1/opcode#14 )
opcode#3 = opcode#10
return
to:@return
void __start()
__start: scope:[__start] from
to:__start::__init1
__start::__init1: scope:[__start] from __start
opcode#4 = 'a'
to:__start::@1
__start::@1: scope:[__start] from __start::__init1
opcode#13 = phi( __start::__init1/opcode#4 )
call main
to:__start::@2
__start::@2: scope:[__start] from __start::@1
opcode#11 = phi( __start::@1/opcode#1 )
opcode#5 = opcode#11
to:__start::@return
__start::@return: scope:[__start] from __start::@2
opcode#12 = phi( __start::@2/opcode#5 )
opcode#6 = opcode#12
return
to:@return
SYMBOL TABLE SSA
void __start()
void main()
char opcode
char opcode#0
char opcode#1
char opcode#10
char opcode#11
char opcode#12
char opcode#13
char opcode#14
char opcode#15
char opcode#2
char opcode#3
char opcode#4
char opcode#5
char opcode#6
char opcode#7
char opcode#8
char opcode#9
void popup_selector()
bool popup_selector::$0
char popup_selector::k
char popup_selector::k#0
char popup_selector::k#1
char popup_selector::k#2
char popup_selector::k#3
__constant char * const screen = (char *)$400
Adding number conversion cast (unumber) $28 in screen[$28] = opcode#7
Adding number conversion cast (unumber) $29 in screen[$29] = opcode#0
Adding number conversion cast (unumber) 2 in popup_selector::$0 = popup_selector::k#2 <= 2
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast $28
Simplifying constant integer cast $29
Simplifying constant integer cast 2
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) $28
Finalized unsigned number type (char) $29
Finalized unsigned number type (char) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias opcode#0 = opcode#8 opcode#9 opcode#1
Alias popup_selector::k#2 = popup_selector::k#3
Alias opcode#10 = opcode#14 opcode#3
Alias opcode#13 = opcode#4
Alias opcode#11 = opcode#5 opcode#12 opcode#6
Successful SSA optimization Pass2AliasElimination
Identical Phi Values opcode#7 opcode#13
Identical Phi Values opcode#0 opcode#10
Identical Phi Values opcode#15 opcode#7
Identical Phi Values opcode#11 opcode#0
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition popup_selector::$0 [10] if(popup_selector::k#2<=2) goto popup_selector::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant popup_selector::k#0 = 0
Constant opcode#2 = 'b'
Constant opcode#13 = 'a'
Successful SSA optimization Pass2ConstantIdentification
Rewriting conditional comparison [10] if(popup_selector::k#2<=2) goto popup_selector::@2
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
Adding number conversion cast (unumber) 2+1 in [5] if(popup_selector::k#2<2+1) goto popup_selector::@2
Adding number conversion cast (unumber) 1 in [5] if(popup_selector::k#2<(unumber)2+1) goto popup_selector::@2
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 2+(unumber)1
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Inlining constant with var siblings popup_selector::k#0
Inlining constant with var siblings opcode#2
Inlining constant with var siblings opcode#13
Constant inlined popup_selector::k#0 = 0
Constant inlined opcode#13 = 'a'
Constant inlined opcode#2 = 'b'
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(screen+$28)
Consolidated array index constant in *(screen+$29)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of popup_selector
CALL GRAPH
Calls in [main] to popup_selector:1
Created 2 initial phi equivalence classes
Coalesced [10] popup_selector::k#4 = popup_selector::k#1
Coalesced down to 2 phi equivalence classes
Adding NOP phi() at start of popup_selector
FINAL CONTROL FLOW GRAPH
void main()
main: scope:[main] from
[0] *(screen+$28) = 'a'
[1] call popup_selector
to:main::@1
main::@1: scope:[main] from main
[2] *(screen+$29) = opcode#10
to:main::@return
main::@return: scope:[main] from main::@1
[3] return
to:@return
void popup_selector()
popup_selector: scope:[popup_selector] from main
[4] phi()
to:popup_selector::@1
popup_selector::@1: scope:[popup_selector] from popup_selector popup_selector::@2
[5] opcode#10 = phi( popup_selector/'a', popup_selector::@2/'b' )
[5] popup_selector::k#2 = phi( popup_selector/0, popup_selector::@2/popup_selector::k#1 )
[6] if(popup_selector::k#2<2+1) goto popup_selector::@2
to:popup_selector::@return
popup_selector::@return: scope:[popup_selector] from popup_selector::@1
[7] return
to:@return
popup_selector::@2: scope:[popup_selector] from popup_selector::@1
[8] screen[popup_selector::k#2] = 'b'
[9] popup_selector::k#1 = ++ popup_selector::k#2
to:popup_selector::@1
VARIABLE REGISTER WEIGHTS
void main()
char opcode
char opcode#10 // 0.5
void popup_selector()
char popup_selector::k
char popup_selector::k#1 // 202.0
char popup_selector::k#2 // 134.66666666666666
Initial phi equivalence classes
[ popup_selector::k#2 popup_selector::k#1 ]
[ opcode#10 ]
Complete equivalence classes
[ popup_selector::k#2 popup_selector::k#1 ]
[ opcode#10 ]
Allocated zp[1]:2 [ popup_selector::k#2 popup_selector::k#1 ]
Allocated zp[1]:3 [ opcode#10 ]
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *(screen+$28) = 'a' [ ] ( [ ] { } ) always clobbers reg byte a
Statement [8] screen[popup_selector::k#2] = 'b' [ popup_selector::k#2 ] ( popup_selector:1 [ popup_selector::k#2 ] { } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ popup_selector::k#2 popup_selector::k#1 ]
Statement [0] *(screen+$28) = 'a' [ ] ( [ ] { } ) always clobbers reg byte a
Statement [8] screen[popup_selector::k#2] = 'b' [ popup_selector::k#2 ] ( popup_selector:1 [ popup_selector::k#2 ] { } ) always clobbers reg byte a
Potential registers zp[1]:2 [ popup_selector::k#2 popup_selector::k#1 ] : zp[1]:2 , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ opcode#10 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [popup_selector] 336.67: zp[1]:2 [ popup_selector::k#2 popup_selector::k#1 ]
Uplift Scope [] 0.5: zp[1]:3 [ opcode#10 ]
Uplift Scope [main]
Uplifting [popup_selector] best 382 combination reg byte x [ popup_selector::k#2 popup_selector::k#1 ]
Uplifting [] best 319 combination reg byte a [ opcode#10 ]
Uplifting [main] best 319 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Demonstrates a problem where constant loophead unrolling results in an error
// The result is a NullPointerException
// The cause is that the Unroller does not handle the variable opcode correctly.
// The Unroller gets the verwions for opcode wrong because it misses the fact that it is modified inside call to popup_selector()
// Upstart
// Commodore 64 PRG executable file
.file [name="loophead-problem.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
// Offending unroll variable
main: {
// [0] *(screen+$28) = 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta screen+$28
// [1] call popup_selector
// [4] phi from main to popup_selector [phi:main->popup_selector]
popup_selector_from_main:
jsr popup_selector
jmp __b1
// main::@1
__b1:
// [2] *(screen+$29) = opcode#10 -- _deref_pbuc1=vbuaa
sta screen+$29
jmp __breturn
// main::@return
__breturn:
// [3] return
rts
}
// popup_selector
popup_selector: {
// [5] phi from popup_selector to popup_selector::@1 [phi:popup_selector->popup_selector::@1]
__b1_from_popup_selector:
// [5] phi opcode#10 = 'a' [phi:popup_selector->popup_selector::@1#0] -- vbuaa=vbuc1
lda #'a'
// [5] phi popup_selector::k#2 = 0 [phi:popup_selector->popup_selector::@1#1] -- vbuxx=vbuc1
ldx #0
jmp __b1
// popup_selector::@1
__b1:
// [6] if(popup_selector::k#2<2+1) goto popup_selector::@2 -- vbuxx_lt_vbuc1_then_la1
cpx #2+1
bcc __b2
jmp __breturn
// popup_selector::@return
__breturn:
// [7] return
rts
// popup_selector::@2
__b2:
// [8] screen[popup_selector::k#2] = 'b' -- pbuc1_derefidx_vbuxx=vbuc2
lda #'b'
sta screen,x
// [9] popup_selector::k#1 = ++ popup_selector::k#2 -- vbuxx=_inc_vbuxx
inx
// [5] phi from popup_selector::@2 to popup_selector::@1 [phi:popup_selector::@2->popup_selector::@1]
__b1_from___b2:
// [5] phi opcode#10 = 'b' [phi:popup_selector::@2->popup_selector::@1#0] -- vbuaa=vbuc1
lda #'b'
// [5] phi popup_selector::k#2 = popup_selector::k#1 [phi:popup_selector::@2->popup_selector::@1#1] -- register_copy
jmp __b1
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction popup_selector_from_main:
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __b1_from_popup_selector:
Removing instruction __breturn:
Removing instruction __b1_from___b2:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction lda #'b'
Succesful ASM optimization Pass5UnnecesaryLoadElimination
FINAL SYMBOL TABLE
void main()
char opcode
char opcode#10 // reg byte a 0.5
void popup_selector()
char popup_selector::k
char popup_selector::k#1 // reg byte x 202.0
char popup_selector::k#2 // reg byte x 134.66666666666666
__constant char * const screen = (char *) 1024
reg byte x [ popup_selector::k#2 popup_selector::k#1 ]
reg byte a [ opcode#10 ]
FINAL ASSEMBLER
Score: 233
// File Comments
// Demonstrates a problem where constant loophead unrolling results in an error
// The result is a NullPointerException
// The cause is that the Unroller does not handle the variable opcode correctly.
// The Unroller gets the verwions for opcode wrong because it misses the fact that it is modified inside call to popup_selector()
// Upstart
// Commodore 64 PRG executable file
.file [name="loophead-problem.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
// Offending unroll variable
main: {
// screen[40] = opcode
// [0] *(screen+$28) = 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta screen+$28
// popup_selector()
// [1] call popup_selector
// [4] phi from main to popup_selector [phi:main->popup_selector]
jsr popup_selector
// main::@1
// screen[41] = opcode
// [2] *(screen+$29) = opcode#10 -- _deref_pbuc1=vbuaa
sta screen+$29
// main::@return
// }
// [3] return
rts
}
// popup_selector
popup_selector: {
// [5] phi from popup_selector to popup_selector::@1 [phi:popup_selector->popup_selector::@1]
// [5] phi opcode#10 = 'a' [phi:popup_selector->popup_selector::@1#0] -- vbuaa=vbuc1
lda #'a'
// [5] phi popup_selector::k#2 = 0 [phi:popup_selector->popup_selector::@1#1] -- vbuxx=vbuc1
ldx #0
// popup_selector::@1
__b1:
// for (byte k = 0; k <= 2; k++)
// [6] if(popup_selector::k#2<2+1) goto popup_selector::@2 -- vbuxx_lt_vbuc1_then_la1
cpx #2+1
bcc __b2
// popup_selector::@return
// }
// [7] return
rts
// popup_selector::@2
__b2:
// screen[k] = opcode
// [8] screen[popup_selector::k#2] = 'b' -- pbuc1_derefidx_vbuxx=vbuc2
lda #'b'
sta screen,x
// for (byte k = 0; k <= 2; k++)
// [9] popup_selector::k#1 = ++ popup_selector::k#2 -- vbuxx=_inc_vbuxx
inx
// [5] phi from popup_selector::@2 to popup_selector::@1 [phi:popup_selector::@2->popup_selector::@1]
// [5] phi opcode#10 = 'b' [phi:popup_selector::@2->popup_selector::@1#0] -- vbuaa=vbuc1
// [5] phi popup_selector::k#2 = popup_selector::k#1 [phi:popup_selector::@2->popup_selector::@1#1] -- register_copy
jmp __b1
}
// File Data