mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-23 13:31:12 +00:00
Added missing test and fragments.
This commit is contained in:
parent
a74a36df35
commit
040c915d0c
@ -9,6 +9,11 @@ import java.io.IOException;
|
||||
*/
|
||||
public class TestProgramsFast extends TestPrograms {
|
||||
|
||||
@Test
|
||||
public void testConstBoolReturnProblem() throws IOException {
|
||||
compileAndCompare("const-bool-return-problem.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStructFunction() throws IOException {
|
||||
compileAndCompare("struct-function.c");
|
||||
|
22
src/test/kc/const-bool-return-problem.c
Normal file
22
src/test/kc/const-bool-return-problem.c
Normal file
@ -0,0 +1,22 @@
|
||||
// A function that returns a constant boolean crashes the compiler because it produces illegal ASM
|
||||
|
||||
char * const SCREEN = (char*)0x0400;
|
||||
|
||||
void main() {
|
||||
for(char ox=0;ox<5;ox++)
|
||||
for(char oy=0;oy<5;oy++)
|
||||
if(OBJ_is_solid(ox,oy))
|
||||
SCREEN[ox] = oy;
|
||||
|
||||
}
|
||||
|
||||
bool OBJ_is_solid(char ox, char oy) {
|
||||
if (oy==oy) {
|
||||
return true;
|
||||
}
|
||||
return tile_flag_at();
|
||||
}
|
||||
|
||||
bool tile_flag_at() {
|
||||
return false;
|
||||
}
|
73
src/test/ref/const-bool-return-problem.asm
Normal file
73
src/test/ref/const-bool-return-problem.asm
Normal file
@ -0,0 +1,73 @@
|
||||
// A function that returns a constant boolean crashes the compiler because it produces illegal ASM
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="const-bool-return-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)
|
||||
.label SCREEN = $400
|
||||
.segment Code
|
||||
main: {
|
||||
.label ox = 3
|
||||
.label oy = 2
|
||||
lda #0
|
||||
sta.z ox
|
||||
__b1:
|
||||
// for(char ox=0;ox<5;ox++)
|
||||
lda.z ox
|
||||
cmp #5
|
||||
bcc __b4
|
||||
// }
|
||||
rts
|
||||
__b4:
|
||||
lda #0
|
||||
sta.z oy
|
||||
__b2:
|
||||
// for(char oy=0;oy<5;oy++)
|
||||
lda.z oy
|
||||
cmp #5
|
||||
bcc __b3
|
||||
// for(char ox=0;ox<5;ox++)
|
||||
inc.z ox
|
||||
jmp __b1
|
||||
__b3:
|
||||
// OBJ_is_solid(ox,oy)
|
||||
lda.z oy
|
||||
jsr OBJ_is_solid
|
||||
// if(OBJ_is_solid(ox,oy))
|
||||
cmp #0
|
||||
bne __b6
|
||||
jmp __b5
|
||||
__b6:
|
||||
// SCREEN[ox] = oy
|
||||
lda.z oy
|
||||
ldy.z ox
|
||||
sta SCREEN,y
|
||||
__b5:
|
||||
// for(char oy=0;oy<5;oy++)
|
||||
inc.z oy
|
||||
jmp __b2
|
||||
}
|
||||
// __register(A) bool OBJ_is_solid(char ox, __register(A) char oy)
|
||||
OBJ_is_solid: {
|
||||
// if (oy==oy)
|
||||
tax
|
||||
tay
|
||||
stx.z $ff
|
||||
cpy.z $ff
|
||||
bne __b1
|
||||
lda #1
|
||||
rts
|
||||
__b1:
|
||||
// tile_flag_at()
|
||||
jsr tile_flag_at
|
||||
lda #tile_flag_at.return
|
||||
// }
|
||||
rts
|
||||
}
|
||||
tile_flag_at: {
|
||||
.label return = 0
|
||||
rts
|
||||
}
|
55
src/test/ref/const-bool-return-problem.cfg
Normal file
55
src/test/ref/const-bool-return-problem.cfg
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
[0] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
[1] main::ox#2 = phi( main/0, main::@4/main::ox#1 )
|
||||
[2] if(main::ox#2<5) goto main::@2
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[3] return
|
||||
to:@return
|
||||
main::@2: scope:[main] from main::@1 main::@5
|
||||
[4] main::oy#2 = phi( main::@1/0, main::@5/main::oy#1 )
|
||||
[5] if(main::oy#2<5) goto main::@3
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2
|
||||
[6] main::ox#1 = ++ main::ox#2
|
||||
to:main::@1
|
||||
main::@3: scope:[main] from main::@2
|
||||
[7] OBJ_is_solid::oy#0 = main::oy#2
|
||||
[8] call OBJ_is_solid
|
||||
[9] OBJ_is_solid::return#0 = OBJ_is_solid::return#3
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@3
|
||||
[10] main::$2 = OBJ_is_solid::return#0
|
||||
[11] if(main::$2) goto main::@6
|
||||
to:main::@5
|
||||
main::@6: scope:[main] from main::@7
|
||||
[12] SCREEN[main::ox#2] = main::oy#2
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@6 main::@7
|
||||
[13] main::oy#1 = ++ main::oy#2
|
||||
to:main::@2
|
||||
|
||||
bool OBJ_is_solid(char ox , char oy)
|
||||
OBJ_is_solid: scope:[OBJ_is_solid] from main::@3
|
||||
[14] if(OBJ_is_solid::oy#0!=OBJ_is_solid::oy#0) goto OBJ_is_solid::@1
|
||||
to:OBJ_is_solid::@return
|
||||
OBJ_is_solid::@1: scope:[OBJ_is_solid] from OBJ_is_solid
|
||||
[15] phi()
|
||||
[16] call tile_flag_at
|
||||
to:OBJ_is_solid::@return
|
||||
OBJ_is_solid::@return: scope:[OBJ_is_solid] from OBJ_is_solid OBJ_is_solid::@1
|
||||
[17] OBJ_is_solid::return#3 = phi( OBJ_is_solid/true, OBJ_is_solid::@1/tile_flag_at::return#1 )
|
||||
[18] return
|
||||
to:@return
|
||||
|
||||
bool tile_flag_at()
|
||||
tile_flag_at: scope:[tile_flag_at] from OBJ_is_solid::@1
|
||||
[19] phi()
|
||||
to:tile_flag_at::@return
|
||||
tile_flag_at::@return: scope:[tile_flag_at] from tile_flag_at
|
||||
[20] return
|
||||
to:@return
|
678
src/test/ref/const-bool-return-problem.log
Normal file
678
src/test/ref/const-bool-return-problem.log
Normal file
@ -0,0 +1,678 @@
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
|
||||
void main()
|
||||
main: scope:[main] from __start
|
||||
main::ox#0 = 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@5
|
||||
main::ox#2 = phi( main/main::ox#0, main::@5/main::ox#1 )
|
||||
main::$0 = main::ox#2 < 5
|
||||
if(main::$0) goto main::@2
|
||||
to:main::@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
main::ox#8 = phi( main::@1/main::ox#2 )
|
||||
main::oy#0 = 0
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2 main::@6
|
||||
main::ox#6 = phi( main::@2/main::ox#8, main::@6/main::ox#9 )
|
||||
main::oy#2 = phi( main::@2/main::oy#0, main::@6/main::oy#1 )
|
||||
main::$1 = main::oy#2 < 5
|
||||
if(main::$1) goto main::@4
|
||||
to:main::@5
|
||||
main::@4: scope:[main] from main::@3
|
||||
main::oy#3 = phi( main::@3/main::oy#2 )
|
||||
main::ox#3 = phi( main::@3/main::ox#6 )
|
||||
OBJ_is_solid::ox#0 = main::ox#3
|
||||
OBJ_is_solid::oy#0 = main::oy#3
|
||||
call OBJ_is_solid
|
||||
OBJ_is_solid::return#0 = OBJ_is_solid::return#3
|
||||
to:main::@8
|
||||
main::@8: scope:[main] from main::@4
|
||||
main::ox#7 = phi( main::@4/main::ox#3 )
|
||||
main::oy#6 = phi( main::@4/main::oy#3 )
|
||||
OBJ_is_solid::return#4 = phi( main::@4/OBJ_is_solid::return#0 )
|
||||
main::$2 = OBJ_is_solid::return#4
|
||||
main::$3 = ! main::$2
|
||||
if(main::$3) goto main::@6
|
||||
to:main::@7
|
||||
main::@5: scope:[main] from main::@3
|
||||
main::ox#4 = phi( main::@3/main::ox#6 )
|
||||
main::ox#1 = ++ main::ox#4
|
||||
to:main::@1
|
||||
main::@6: scope:[main] from main::@7 main::@8
|
||||
main::ox#9 = phi( main::@7/main::ox#5, main::@8/main::ox#7 )
|
||||
main::oy#4 = phi( main::@7/main::oy#5, main::@8/main::oy#6 )
|
||||
main::oy#1 = ++ main::oy#4
|
||||
to:main::@3
|
||||
main::@7: scope:[main] from main::@8
|
||||
main::ox#5 = phi( main::@8/main::ox#7 )
|
||||
main::oy#5 = phi( main::@8/main::oy#6 )
|
||||
SCREEN[main::ox#5] = main::oy#5
|
||||
to:main::@6
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
|
||||
bool OBJ_is_solid(char ox , char oy)
|
||||
OBJ_is_solid: scope:[OBJ_is_solid] from main::@4
|
||||
OBJ_is_solid::oy#1 = phi( main::@4/OBJ_is_solid::oy#0 )
|
||||
OBJ_is_solid::$0 = OBJ_is_solid::oy#1 == OBJ_is_solid::oy#1
|
||||
OBJ_is_solid::$1 = ! OBJ_is_solid::$0
|
||||
if(OBJ_is_solid::$1) goto OBJ_is_solid::@1
|
||||
to:OBJ_is_solid::@2
|
||||
OBJ_is_solid::@1: scope:[OBJ_is_solid] from OBJ_is_solid
|
||||
call tile_flag_at
|
||||
tile_flag_at::return#0 = tile_flag_at::return#2
|
||||
to:OBJ_is_solid::@3
|
||||
OBJ_is_solid::@3: scope:[OBJ_is_solid] from OBJ_is_solid::@1
|
||||
tile_flag_at::return#3 = phi( OBJ_is_solid::@1/tile_flag_at::return#0 )
|
||||
OBJ_is_solid::$2 = tile_flag_at::return#3
|
||||
OBJ_is_solid::return#1 = OBJ_is_solid::$2
|
||||
to:OBJ_is_solid::@return
|
||||
OBJ_is_solid::@2: scope:[OBJ_is_solid] from OBJ_is_solid
|
||||
OBJ_is_solid::return#2 = true
|
||||
to:OBJ_is_solid::@return
|
||||
OBJ_is_solid::@return: scope:[OBJ_is_solid] from OBJ_is_solid::@2 OBJ_is_solid::@3
|
||||
OBJ_is_solid::return#5 = phi( OBJ_is_solid::@2/OBJ_is_solid::return#2, OBJ_is_solid::@3/OBJ_is_solid::return#1 )
|
||||
OBJ_is_solid::return#3 = OBJ_is_solid::return#5
|
||||
return
|
||||
to:@return
|
||||
|
||||
bool tile_flag_at()
|
||||
tile_flag_at: scope:[tile_flag_at] from OBJ_is_solid::@1
|
||||
tile_flag_at::return#1 = false
|
||||
to:tile_flag_at::@return
|
||||
tile_flag_at::@return: scope:[tile_flag_at] from tile_flag_at
|
||||
tile_flag_at::return#4 = phi( tile_flag_at/tile_flag_at::return#1 )
|
||||
tile_flag_at::return#2 = tile_flag_at::return#4
|
||||
return
|
||||
to:@return
|
||||
|
||||
void __start()
|
||||
__start: scope:[__start] from
|
||||
call main
|
||||
to:__start::@1
|
||||
__start::@1: scope:[__start] from __start
|
||||
to:__start::@return
|
||||
__start::@return: scope:[__start] from __start::@1
|
||||
return
|
||||
to:@return
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
bool OBJ_is_solid(char ox , char oy)
|
||||
bool OBJ_is_solid::$0
|
||||
bool OBJ_is_solid::$1
|
||||
bool OBJ_is_solid::$2
|
||||
char OBJ_is_solid::ox
|
||||
char OBJ_is_solid::ox#0
|
||||
char OBJ_is_solid::oy
|
||||
char OBJ_is_solid::oy#0
|
||||
char OBJ_is_solid::oy#1
|
||||
bool OBJ_is_solid::return
|
||||
bool OBJ_is_solid::return#0
|
||||
bool OBJ_is_solid::return#1
|
||||
bool OBJ_is_solid::return#2
|
||||
bool OBJ_is_solid::return#3
|
||||
bool OBJ_is_solid::return#4
|
||||
bool OBJ_is_solid::return#5
|
||||
__constant char * const SCREEN = (char *)$400
|
||||
void __start()
|
||||
void main()
|
||||
bool main::$0
|
||||
bool main::$1
|
||||
bool main::$2
|
||||
bool main::$3
|
||||
char main::ox
|
||||
char main::ox#0
|
||||
char main::ox#1
|
||||
char main::ox#2
|
||||
char main::ox#3
|
||||
char main::ox#4
|
||||
char main::ox#5
|
||||
char main::ox#6
|
||||
char main::ox#7
|
||||
char main::ox#8
|
||||
char main::ox#9
|
||||
char main::oy
|
||||
char main::oy#0
|
||||
char main::oy#1
|
||||
char main::oy#2
|
||||
char main::oy#3
|
||||
char main::oy#4
|
||||
char main::oy#5
|
||||
char main::oy#6
|
||||
bool tile_flag_at()
|
||||
bool tile_flag_at::return
|
||||
bool tile_flag_at::return#0
|
||||
bool tile_flag_at::return#1
|
||||
bool tile_flag_at::return#2
|
||||
bool tile_flag_at::return#3
|
||||
bool tile_flag_at::return#4
|
||||
|
||||
Adding number conversion cast (unumber) 5 in main::$0 = main::ox#2 < 5
|
||||
Adding number conversion cast (unumber) 5 in main::$1 = main::oy#2 < 5
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Simplifying constant pointer cast (char *) 1024
|
||||
Simplifying constant integer cast 5
|
||||
Simplifying constant integer cast 5
|
||||
Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (char) 5
|
||||
Finalized unsigned number type (char) 5
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Inversing boolean not [27] OBJ_is_solid::$1 = OBJ_is_solid::oy#1 != OBJ_is_solid::oy#1 from [26] OBJ_is_solid::$0 = OBJ_is_solid::oy#1 == OBJ_is_solid::oy#1
|
||||
Successful SSA optimization Pass2UnaryNotSimplification
|
||||
Alias main::ox#2 = main::ox#8
|
||||
Alias main::ox#3 = main::ox#6 main::ox#7 main::ox#4 main::ox#5
|
||||
Alias main::oy#2 = main::oy#3 main::oy#6 main::oy#5
|
||||
Alias OBJ_is_solid::return#0 = OBJ_is_solid::return#4
|
||||
Alias tile_flag_at::return#0 = tile_flag_at::return#3
|
||||
Alias OBJ_is_solid::return#1 = OBJ_is_solid::$2
|
||||
Alias OBJ_is_solid::return#3 = OBJ_is_solid::return#5
|
||||
Alias tile_flag_at::return#1 = tile_flag_at::return#4 tile_flag_at::return#2
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Alias main::oy#2 = main::oy#4
|
||||
Alias main::ox#3 = main::ox#9
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Identical Phi Values main::ox#3 main::ox#2
|
||||
Identical Phi Values OBJ_is_solid::oy#1 OBJ_is_solid::oy#0
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Simple Condition main::$0 [3] if(main::ox#2<5) goto main::@2
|
||||
Simple Condition main::$1 [7] if(main::oy#2<5) goto main::@4
|
||||
Simple Condition OBJ_is_solid::$1 [21] if(OBJ_is_solid::oy#0!=OBJ_is_solid::oy#0) goto OBJ_is_solid::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Rewriting ! if()-condition to reversed if() [13] main::$3 = ! main::$2
|
||||
Successful SSA optimization Pass2ConditionalAndOrRewriting
|
||||
Constant main::ox#0 = 0
|
||||
Constant main::oy#0 = 0
|
||||
Constant OBJ_is_solid::return#2 = true
|
||||
Constant tile_flag_at::return#1 = false
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant tile_flag_at::return#0 = tile_flag_at::return#1
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Constant OBJ_is_solid::return#1 = tile_flag_at::return#0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Eliminating unused variable OBJ_is_solid::ox#0 and assignment [4] OBJ_is_solid::ox#0 = main::ox#2
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Removing unused procedure __start
|
||||
Removing unused procedure block __start
|
||||
Removing unused procedure block __start::@1
|
||||
Removing unused procedure block __start::@return
|
||||
Successful SSA optimization PassNEliminateEmptyStart
|
||||
Inlining constant with var siblings main::ox#0
|
||||
Inlining constant with var siblings main::oy#0
|
||||
Inlining constant with var siblings OBJ_is_solid::return#2
|
||||
Inlining constant with var siblings OBJ_is_solid::return#1
|
||||
Inlining constant with different constant siblings tile_flag_at::return#0
|
||||
Constant inlined main::oy#0 = 0
|
||||
Constant inlined OBJ_is_solid::return#1 = tile_flag_at::return#1
|
||||
Constant inlined tile_flag_at::return#0 = tile_flag_at::return#1
|
||||
Constant inlined main::ox#0 = 0
|
||||
Constant inlined OBJ_is_solid::return#2 = true
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Adding NOP phi() at start of main
|
||||
Adding NOP phi() at start of main::@2
|
||||
Adding NOP phi() at start of OBJ_is_solid::@2
|
||||
Adding NOP phi() at start of OBJ_is_solid::@1
|
||||
Adding NOP phi() at start of OBJ_is_solid::@3
|
||||
Adding NOP phi() at start of tile_flag_at
|
||||
CALL GRAPH
|
||||
Calls in [main] to OBJ_is_solid:10
|
||||
Calls in [OBJ_is_solid] to tile_flag_at:22
|
||||
|
||||
Created 3 initial phi equivalence classes
|
||||
Coalesced [8] main::ox#10 = main::ox#1
|
||||
Coalesced [16] main::oy#7 = main::oy#1
|
||||
Coalesced down to 3 phi equivalence classes
|
||||
Culled Empty Block label main::@2
|
||||
Culled Empty Block label OBJ_is_solid::@2
|
||||
Culled Empty Block label OBJ_is_solid::@3
|
||||
Renumbering block main::@3 to main::@2
|
||||
Renumbering block main::@4 to main::@3
|
||||
Renumbering block main::@5 to main::@4
|
||||
Renumbering block main::@6 to main::@5
|
||||
Renumbering block main::@7 to main::@6
|
||||
Renumbering block main::@8 to main::@7
|
||||
Adding NOP phi() at start of main
|
||||
Adding NOP phi() at start of OBJ_is_solid::@1
|
||||
Adding NOP phi() at start of tile_flag_at
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
|
||||
void main()
|
||||
main: scope:[main] from
|
||||
[0] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
[1] main::ox#2 = phi( main/0, main::@4/main::ox#1 )
|
||||
[2] if(main::ox#2<5) goto main::@2
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[3] return
|
||||
to:@return
|
||||
main::@2: scope:[main] from main::@1 main::@5
|
||||
[4] main::oy#2 = phi( main::@1/0, main::@5/main::oy#1 )
|
||||
[5] if(main::oy#2<5) goto main::@3
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@2
|
||||
[6] main::ox#1 = ++ main::ox#2
|
||||
to:main::@1
|
||||
main::@3: scope:[main] from main::@2
|
||||
[7] OBJ_is_solid::oy#0 = main::oy#2
|
||||
[8] call OBJ_is_solid
|
||||
[9] OBJ_is_solid::return#0 = OBJ_is_solid::return#3
|
||||
to:main::@7
|
||||
main::@7: scope:[main] from main::@3
|
||||
[10] main::$2 = OBJ_is_solid::return#0
|
||||
[11] if(main::$2) goto main::@6
|
||||
to:main::@5
|
||||
main::@6: scope:[main] from main::@7
|
||||
[12] SCREEN[main::ox#2] = main::oy#2
|
||||
to:main::@5
|
||||
main::@5: scope:[main] from main::@6 main::@7
|
||||
[13] main::oy#1 = ++ main::oy#2
|
||||
to:main::@2
|
||||
|
||||
bool OBJ_is_solid(char ox , char oy)
|
||||
OBJ_is_solid: scope:[OBJ_is_solid] from main::@3
|
||||
[14] if(OBJ_is_solid::oy#0!=OBJ_is_solid::oy#0) goto OBJ_is_solid::@1
|
||||
to:OBJ_is_solid::@return
|
||||
OBJ_is_solid::@1: scope:[OBJ_is_solid] from OBJ_is_solid
|
||||
[15] phi()
|
||||
[16] call tile_flag_at
|
||||
to:OBJ_is_solid::@return
|
||||
OBJ_is_solid::@return: scope:[OBJ_is_solid] from OBJ_is_solid OBJ_is_solid::@1
|
||||
[17] OBJ_is_solid::return#3 = phi( OBJ_is_solid/true, OBJ_is_solid::@1/tile_flag_at::return#1 )
|
||||
[18] return
|
||||
to:@return
|
||||
|
||||
bool tile_flag_at()
|
||||
tile_flag_at: scope:[tile_flag_at] from OBJ_is_solid::@1
|
||||
[19] phi()
|
||||
to:tile_flag_at::@return
|
||||
tile_flag_at::@return: scope:[tile_flag_at] from tile_flag_at
|
||||
[20] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
bool OBJ_is_solid(char ox , char oy)
|
||||
char OBJ_is_solid::ox
|
||||
char OBJ_is_solid::oy
|
||||
char OBJ_is_solid::oy#0 // 2103.0
|
||||
bool OBJ_is_solid::return
|
||||
bool OBJ_is_solid::return#0 // 202.0
|
||||
bool OBJ_is_solid::return#3 // 33.666666666666664
|
||||
void main()
|
||||
bool main::$2 // 202.0
|
||||
char main::ox
|
||||
char main::ox#1 // 22.0
|
||||
char main::ox#2 // 12.181818181818182
|
||||
char main::oy
|
||||
char main::oy#1 // 202.0
|
||||
char main::oy#2 // 63.125
|
||||
bool tile_flag_at()
|
||||
bool tile_flag_at::return
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::ox#2 main::ox#1 ]
|
||||
[ main::oy#2 main::oy#1 ]
|
||||
[ OBJ_is_solid::return#3 ]
|
||||
Added variable OBJ_is_solid::oy#0 to live range equivalence class [ OBJ_is_solid::oy#0 ]
|
||||
Added variable OBJ_is_solid::return#0 to live range equivalence class [ OBJ_is_solid::return#0 ]
|
||||
Added variable main::$2 to live range equivalence class [ main::$2 ]
|
||||
Complete equivalence classes
|
||||
[ main::ox#2 main::ox#1 ]
|
||||
[ main::oy#2 main::oy#1 ]
|
||||
[ OBJ_is_solid::return#3 ]
|
||||
[ OBJ_is_solid::oy#0 ]
|
||||
[ OBJ_is_solid::return#0 ]
|
||||
[ main::$2 ]
|
||||
Allocated zp[1]:2 [ OBJ_is_solid::oy#0 ]
|
||||
Allocated zp[1]:3 [ main::oy#2 main::oy#1 ]
|
||||
Allocated zp[1]:4 [ OBJ_is_solid::return#0 ]
|
||||
Allocated zp[1]:5 [ main::$2 ]
|
||||
Allocated zp[1]:6 [ main::ox#2 main::ox#1 ]
|
||||
Allocated zp[1]:7 [ OBJ_is_solid::return#3 ]
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Potential registers zp[1]:6 [ main::ox#2 main::ox#1 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:3 [ main::oy#2 main::oy#1 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:7 [ OBJ_is_solid::return#3 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:2 [ OBJ_is_solid::oy#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:4 [ OBJ_is_solid::return#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:5 [ main::$2 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [OBJ_is_solid] 2,103: zp[1]:2 [ OBJ_is_solid::oy#0 ] 202: zp[1]:4 [ OBJ_is_solid::return#0 ] 33.67: zp[1]:7 [ OBJ_is_solid::return#3 ]
|
||||
Uplift Scope [main] 265.12: zp[1]:3 [ main::oy#2 main::oy#1 ] 202: zp[1]:5 [ main::$2 ] 34.18: zp[1]:6 [ main::ox#2 main::ox#1 ]
|
||||
Uplift Scope [tile_flag_at]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [OBJ_is_solid] best 6944 combination reg byte a [ OBJ_is_solid::oy#0 ] reg byte a [ OBJ_is_solid::return#0 ] reg byte a [ OBJ_is_solid::return#3 ]
|
||||
Uplifting [main] best 6344 combination zp[1]:3 [ main::oy#2 main::oy#1 ] reg byte a [ main::$2 ] zp[1]:6 [ main::ox#2 main::ox#1 ]
|
||||
Uplifting [tile_flag_at] best 6344 combination
|
||||
Uplifting [] best 6344 combination
|
||||
Attempting to uplift remaining variables inzp[1]:3 [ main::oy#2 main::oy#1 ]
|
||||
Uplifting [main] best 6344 combination zp[1]:3 [ main::oy#2 main::oy#1 ]
|
||||
Attempting to uplift remaining variables inzp[1]:6 [ main::ox#2 main::ox#1 ]
|
||||
Uplifting [main] best 6344 combination zp[1]:6 [ main::ox#2 main::ox#1 ]
|
||||
Allocated (was zp[1]:3) zp[1]:2 [ main::oy#2 main::oy#1 ]
|
||||
Allocated (was zp[1]:6) zp[1]:3 [ main::ox#2 main::ox#1 ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
// A function that returns a constant boolean crashes the compiler because it produces illegal ASM
|
||||
// Upstart
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="const-bool-return-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
|
||||
main: {
|
||||
.label ox = 3
|
||||
.label oy = 2
|
||||
// [1] phi from main to main::@1 [phi:main->main::@1]
|
||||
__b1_from_main:
|
||||
// [1] phi main::ox#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z ox
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [2] if(main::ox#2<5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z ox
|
||||
cmp #5
|
||||
bcc __b2_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [3] return
|
||||
rts
|
||||
// [4] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
|
||||
__b2_from___b1:
|
||||
// [4] phi main::oy#2 = 0 [phi:main::@1->main::@2#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z oy
|
||||
jmp __b2
|
||||
// main::@2
|
||||
__b2:
|
||||
// [5] if(main::oy#2<5) goto main::@3 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z oy
|
||||
cmp #5
|
||||
bcc __b3
|
||||
jmp __b4
|
||||
// main::@4
|
||||
__b4:
|
||||
// [6] main::ox#1 = ++ main::ox#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z ox
|
||||
// [1] phi from main::@4 to main::@1 [phi:main::@4->main::@1]
|
||||
__b1_from___b4:
|
||||
// [1] phi main::ox#2 = main::ox#1 [phi:main::@4->main::@1#0] -- register_copy
|
||||
jmp __b1
|
||||
// main::@3
|
||||
__b3:
|
||||
// [7] OBJ_is_solid::oy#0 = main::oy#2 -- vbuaa=vbuz1
|
||||
lda.z oy
|
||||
// [8] call OBJ_is_solid
|
||||
jsr OBJ_is_solid
|
||||
// [9] OBJ_is_solid::return#0 = OBJ_is_solid::return#3
|
||||
jmp __b7
|
||||
// main::@7
|
||||
__b7:
|
||||
// [10] main::$2 = OBJ_is_solid::return#0
|
||||
// [11] if(main::$2) goto main::@6 -- vboaa_then_la1
|
||||
cmp #0
|
||||
bne __b6
|
||||
jmp __b5
|
||||
// main::@6
|
||||
__b6:
|
||||
// [12] SCREEN[main::ox#2] = main::oy#2 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
lda.z oy
|
||||
ldy.z ox
|
||||
sta SCREEN,y
|
||||
jmp __b5
|
||||
// main::@5
|
||||
__b5:
|
||||
// [13] main::oy#1 = ++ main::oy#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z oy
|
||||
// [4] phi from main::@5 to main::@2 [phi:main::@5->main::@2]
|
||||
__b2_from___b5:
|
||||
// [4] phi main::oy#2 = main::oy#1 [phi:main::@5->main::@2#0] -- register_copy
|
||||
jmp __b2
|
||||
}
|
||||
// OBJ_is_solid
|
||||
// __register(A) bool OBJ_is_solid(char ox, __register(A) char oy)
|
||||
OBJ_is_solid: {
|
||||
// [14] if(OBJ_is_solid::oy#0!=OBJ_is_solid::oy#0) goto OBJ_is_solid::@1 -- vbuaa_neq_vbuaa_then_la1
|
||||
tax
|
||||
tay
|
||||
stx.z $ff
|
||||
cpy.z $ff
|
||||
bne __b1_from_OBJ_is_solid
|
||||
// [17] phi from OBJ_is_solid to OBJ_is_solid::@return [phi:OBJ_is_solid->OBJ_is_solid::@return]
|
||||
__breturn_from_OBJ_is_solid:
|
||||
// [17] phi OBJ_is_solid::return#3 = true [phi:OBJ_is_solid->OBJ_is_solid::@return#0] -- vboaa=vboc1
|
||||
lda #1
|
||||
jmp __breturn
|
||||
// [15] phi from OBJ_is_solid to OBJ_is_solid::@1 [phi:OBJ_is_solid->OBJ_is_solid::@1]
|
||||
__b1_from_OBJ_is_solid:
|
||||
jmp __b1
|
||||
// OBJ_is_solid::@1
|
||||
__b1:
|
||||
// [16] call tile_flag_at
|
||||
// [19] phi from OBJ_is_solid::@1 to tile_flag_at [phi:OBJ_is_solid::@1->tile_flag_at]
|
||||
tile_flag_at_from___b1:
|
||||
jsr tile_flag_at
|
||||
// [17] phi from OBJ_is_solid::@1 to OBJ_is_solid::@return [phi:OBJ_is_solid::@1->OBJ_is_solid::@return]
|
||||
__breturn_from___b1:
|
||||
// [17] phi OBJ_is_solid::return#3 = tile_flag_at::return#1 [phi:OBJ_is_solid::@1->OBJ_is_solid::@return#0] -- vboaa=vboc1
|
||||
lda #tile_flag_at.return
|
||||
jmp __breturn
|
||||
// OBJ_is_solid::@return
|
||||
__breturn:
|
||||
// [18] return
|
||||
rts
|
||||
}
|
||||
// tile_flag_at
|
||||
tile_flag_at: {
|
||||
.label return = 0
|
||||
jmp __breturn
|
||||
// tile_flag_at::@return
|
||||
__breturn:
|
||||
// [20] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __breturn
|
||||
Removing instruction jmp __b2
|
||||
Removing instruction jmp __b4
|
||||
Removing instruction jmp __b7
|
||||
Removing instruction jmp __b5
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __breturn
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Replacing label __b1_from_OBJ_is_solid with __b1
|
||||
Removing instruction __b1_from_OBJ_is_solid:
|
||||
Removing instruction tile_flag_at_from___b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __b1_from_main:
|
||||
Removing instruction __breturn:
|
||||
Removing instruction __b4:
|
||||
Removing instruction __b1_from___b4:
|
||||
Removing instruction __b7:
|
||||
Removing instruction __b2_from___b5:
|
||||
Removing instruction __breturn_from_OBJ_is_solid:
|
||||
Removing instruction __breturn_from___b1:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Replacing jump to rts with rts in jmp __breturn
|
||||
Succesful ASM optimization Pass5DoubleJumpElimination
|
||||
Relabelling long label __b2_from___b1 to __b4
|
||||
Succesful ASM optimization Pass5RelabelLongLabels
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
bool OBJ_is_solid(char ox , char oy)
|
||||
char OBJ_is_solid::ox
|
||||
char OBJ_is_solid::oy
|
||||
char OBJ_is_solid::oy#0 // reg byte a 2103.0
|
||||
bool OBJ_is_solid::return
|
||||
bool OBJ_is_solid::return#0 // reg byte a 202.0
|
||||
bool OBJ_is_solid::return#3 // reg byte a 33.666666666666664
|
||||
__constant char * const SCREEN = (char *) 1024
|
||||
void main()
|
||||
bool main::$2 // reg byte a 202.0
|
||||
char main::ox
|
||||
char main::ox#1 // ox zp[1]:3 22.0
|
||||
char main::ox#2 // ox zp[1]:3 12.181818181818182
|
||||
char main::oy
|
||||
char main::oy#1 // oy zp[1]:2 202.0
|
||||
char main::oy#2 // oy zp[1]:2 63.125
|
||||
bool tile_flag_at()
|
||||
bool tile_flag_at::return
|
||||
__constant bool tile_flag_at::return#1 = false // return
|
||||
|
||||
zp[1]:3 [ main::ox#2 main::ox#1 ]
|
||||
zp[1]:2 [ main::oy#2 main::oy#1 ]
|
||||
reg byte a [ OBJ_is_solid::return#3 ]
|
||||
reg byte a [ OBJ_is_solid::oy#0 ]
|
||||
reg byte a [ OBJ_is_solid::return#0 ]
|
||||
reg byte a [ main::$2 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 5051
|
||||
|
||||
// File Comments
|
||||
// A function that returns a constant boolean crashes the compiler because it produces illegal ASM
|
||||
// Upstart
|
||||
// Commodore 64 PRG executable file
|
||||
.file [name="const-bool-return-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
|
||||
main: {
|
||||
.label ox = 3
|
||||
.label oy = 2
|
||||
// [1] phi from main to main::@1 [phi:main->main::@1]
|
||||
// [1] phi main::ox#2 = 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z ox
|
||||
// main::@1
|
||||
__b1:
|
||||
// for(char ox=0;ox<5;ox++)
|
||||
// [2] if(main::ox#2<5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z ox
|
||||
cmp #5
|
||||
bcc __b4
|
||||
// main::@return
|
||||
// }
|
||||
// [3] return
|
||||
rts
|
||||
// [4] phi from main::@1 to main::@2 [phi:main::@1->main::@2]
|
||||
__b4:
|
||||
// [4] phi main::oy#2 = 0 [phi:main::@1->main::@2#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z oy
|
||||
// main::@2
|
||||
__b2:
|
||||
// for(char oy=0;oy<5;oy++)
|
||||
// [5] if(main::oy#2<5) goto main::@3 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z oy
|
||||
cmp #5
|
||||
bcc __b3
|
||||
// main::@4
|
||||
// for(char ox=0;ox<5;ox++)
|
||||
// [6] main::ox#1 = ++ main::ox#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z ox
|
||||
// [1] phi from main::@4 to main::@1 [phi:main::@4->main::@1]
|
||||
// [1] phi main::ox#2 = main::ox#1 [phi:main::@4->main::@1#0] -- register_copy
|
||||
jmp __b1
|
||||
// main::@3
|
||||
__b3:
|
||||
// OBJ_is_solid(ox,oy)
|
||||
// [7] OBJ_is_solid::oy#0 = main::oy#2 -- vbuaa=vbuz1
|
||||
lda.z oy
|
||||
// [8] call OBJ_is_solid
|
||||
jsr OBJ_is_solid
|
||||
// [9] OBJ_is_solid::return#0 = OBJ_is_solid::return#3
|
||||
// main::@7
|
||||
// [10] main::$2 = OBJ_is_solid::return#0
|
||||
// if(OBJ_is_solid(ox,oy))
|
||||
// [11] if(main::$2) goto main::@6 -- vboaa_then_la1
|
||||
cmp #0
|
||||
bne __b6
|
||||
jmp __b5
|
||||
// main::@6
|
||||
__b6:
|
||||
// SCREEN[ox] = oy
|
||||
// [12] SCREEN[main::ox#2] = main::oy#2 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
lda.z oy
|
||||
ldy.z ox
|
||||
sta SCREEN,y
|
||||
// main::@5
|
||||
__b5:
|
||||
// for(char oy=0;oy<5;oy++)
|
||||
// [13] main::oy#1 = ++ main::oy#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z oy
|
||||
// [4] phi from main::@5 to main::@2 [phi:main::@5->main::@2]
|
||||
// [4] phi main::oy#2 = main::oy#1 [phi:main::@5->main::@2#0] -- register_copy
|
||||
jmp __b2
|
||||
}
|
||||
// OBJ_is_solid
|
||||
// __register(A) bool OBJ_is_solid(char ox, __register(A) char oy)
|
||||
OBJ_is_solid: {
|
||||
// if (oy==oy)
|
||||
// [14] if(OBJ_is_solid::oy#0!=OBJ_is_solid::oy#0) goto OBJ_is_solid::@1 -- vbuaa_neq_vbuaa_then_la1
|
||||
tax
|
||||
tay
|
||||
stx.z $ff
|
||||
cpy.z $ff
|
||||
bne __b1
|
||||
// [17] phi from OBJ_is_solid to OBJ_is_solid::@return [phi:OBJ_is_solid->OBJ_is_solid::@return]
|
||||
// [17] phi OBJ_is_solid::return#3 = true [phi:OBJ_is_solid->OBJ_is_solid::@return#0] -- vboaa=vboc1
|
||||
lda #1
|
||||
rts
|
||||
// [15] phi from OBJ_is_solid to OBJ_is_solid::@1 [phi:OBJ_is_solid->OBJ_is_solid::@1]
|
||||
// OBJ_is_solid::@1
|
||||
__b1:
|
||||
// tile_flag_at()
|
||||
// [16] call tile_flag_at
|
||||
// [19] phi from OBJ_is_solid::@1 to tile_flag_at [phi:OBJ_is_solid::@1->tile_flag_at]
|
||||
jsr tile_flag_at
|
||||
// [17] phi from OBJ_is_solid::@1 to OBJ_is_solid::@return [phi:OBJ_is_solid::@1->OBJ_is_solid::@return]
|
||||
// [17] phi OBJ_is_solid::return#3 = tile_flag_at::return#1 [phi:OBJ_is_solid::@1->OBJ_is_solid::@return#0] -- vboaa=vboc1
|
||||
lda #tile_flag_at.return
|
||||
// OBJ_is_solid::@return
|
||||
// }
|
||||
// [18] return
|
||||
rts
|
||||
}
|
||||
// tile_flag_at
|
||||
tile_flag_at: {
|
||||
.label return = 0
|
||||
// tile_flag_at::@return
|
||||
// [20] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
26
src/test/ref/const-bool-return-problem.sym
Normal file
26
src/test/ref/const-bool-return-problem.sym
Normal file
@ -0,0 +1,26 @@
|
||||
bool OBJ_is_solid(char ox , char oy)
|
||||
char OBJ_is_solid::ox
|
||||
char OBJ_is_solid::oy
|
||||
char OBJ_is_solid::oy#0 // reg byte a 2103.0
|
||||
bool OBJ_is_solid::return
|
||||
bool OBJ_is_solid::return#0 // reg byte a 202.0
|
||||
bool OBJ_is_solid::return#3 // reg byte a 33.666666666666664
|
||||
__constant char * const SCREEN = (char *) 1024
|
||||
void main()
|
||||
bool main::$2 // reg byte a 202.0
|
||||
char main::ox
|
||||
char main::ox#1 // ox zp[1]:3 22.0
|
||||
char main::ox#2 // ox zp[1]:3 12.181818181818182
|
||||
char main::oy
|
||||
char main::oy#1 // oy zp[1]:2 202.0
|
||||
char main::oy#2 // oy zp[1]:2 63.125
|
||||
bool tile_flag_at()
|
||||
bool tile_flag_at::return
|
||||
__constant bool tile_flag_at::return#1 = false // return
|
||||
|
||||
zp[1]:3 [ main::ox#2 main::ox#1 ]
|
||||
zp[1]:2 [ main::oy#2 main::oy#1 ]
|
||||
reg byte a [ OBJ_is_solid::return#3 ]
|
||||
reg byte a [ OBJ_is_solid::oy#0 ]
|
||||
reg byte a [ OBJ_is_solid::return#0 ]
|
||||
reg byte a [ main::$2 ]
|
Loading…
Reference in New Issue
Block a user