diff --git a/src/test/kc/switch-2.kc b/src/test/kc/switch-2.kc index de5572402..0c1adf9b5 100644 --- a/src/test/kc/switch-2.kc +++ b/src/test/kc/switch-2.kc @@ -1,12 +1,11 @@ -// Tests simple switch()-statement - including a continue statement for the enclosing loop +// Tests simple switch()-statement - not inside a loop void main() { char* SCREEN = 0x0400; char b=0; char v64 = 0; switch(v64){ - case 0: b = 1; break; - default: + case 0: b = 1; } SCREEN[0] = b; } \ No newline at end of file diff --git a/src/test/ref/switch-2.asm b/src/test/ref/switch-2.asm new file mode 100644 index 000000000..18e6e02b7 --- /dev/null +++ b/src/test/ref/switch-2.asm @@ -0,0 +1,11 @@ +// Tests simple switch()-statement - not inside a loop +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" +main: { + .label SCREEN = $400 + .const b = 1 + lda #b + sta SCREEN + rts +} diff --git a/src/test/ref/switch-2.cfg b/src/test/ref/switch-2.cfg new file mode 100644 index 000000000..877a43ab7 --- /dev/null +++ b/src/test/ref/switch-2.cfg @@ -0,0 +1,18 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() +main: scope:[main] from @1 + [4] phi() + to:main::@1 +main::@1: scope:[main] from main + [5] *((const byte*) main::SCREEN#0) ← (const byte) main::b#1 + to:main::@return +main::@return: scope:[main] from main::@1 + [6] return + to:@return diff --git a/src/test/ref/switch-2.log b/src/test/ref/switch-2.log new file mode 100644 index 000000000..b74a908a9 --- /dev/null +++ b/src/test/ref/switch-2.log @@ -0,0 +1,303 @@ +Identified constant variable (byte*) main::SCREEN +Identified constant variable (byte) main::v64 +Culled Empty Block (label) main::@1 +Culled Empty Block (label) main::@2 + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 +main: scope:[main] from @1 + (byte*) main::SCREEN#0 ← ((byte*)) (number) $400 + (byte) main::b#0 ← (number) 0 + (byte) main::v64#0 ← (number) 0 + if((byte) main::v64#0==(number) 0) goto main::@3 + to:main::@4 +main::@3: scope:[main] from main + (byte) main::b#1 ← (number) 1 + to:main::@4 +main::@4: scope:[main] from main main::@3 + (byte) main::b#2 ← phi( main/(byte) main::b#0 main::@3/(byte) main::b#1 ) + *((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::b#2 + to:main::@return +main::@return: scope:[main] from main::@4 + return + to:@return +@1: scope:[] from @begin + call main + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(label) @1 +(label) @2 +(label) @begin +(label) @end +(void()) main() +(label) main::@3 +(label) main::@4 +(label) main::@return +(byte*) main::SCREEN +(byte*) main::SCREEN#0 +(byte) main::b +(byte) main::b#0 +(byte) main::b#1 +(byte) main::b#2 +(byte) main::v64 +(byte) main::v64#0 + +Adding number conversion cast (unumber) 0 in (byte) main::b#0 ← (number) 0 +Adding number conversion cast (unumber) 0 in (byte) main::v64#0 ← (number) 0 +Adding number conversion cast (unumber) 0 in if((byte) main::v64#0==(number) 0) goto main::@3 +Adding number conversion cast (unumber) 1 in (byte) main::b#1 ← (number) 1 +Adding number conversion cast (unumber) 0 in *((byte*) main::SCREEN#0 + (number) 0) ← (byte) main::b#2 +Successful SSA optimization PassNAddNumberTypeConversions +Inlining cast (byte*) main::SCREEN#0 ← (byte*)(number) $400 +Inlining cast (byte) main::b#0 ← (unumber)(number) 0 +Inlining cast (byte) main::v64#0 ← (unumber)(number) 0 +Inlining cast (byte) main::b#1 ← (unumber)(number) 1 +Successful SSA optimization Pass2InlineCast +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Simplifying constant integer cast 0 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Finalized unsigned number type (byte) 0 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Negating conditional jump and destination [3] if((byte) main::v64#0!=(byte) 0) goto main::@4 +Successful SSA optimization Pass2ConditionalJumpSequenceImprovement +Constant (const byte*) main::SCREEN#0 = (byte*) 1024 +Constant (const byte) main::b#0 = 0 +Constant (const byte) main::v64#0 = 0 +Constant (const byte) main::b#1 = 1 +Successful SSA optimization Pass2ConstantIdentification +Removing PHI-reference to removed block (main) in block main::@4 +if() condition always false - eliminating [3] if((const byte) main::v64#0!=(byte) 0) goto main::@4 +Successful SSA optimization Pass2ConstantIfs +Simplifying expression containing zero main::SCREEN#0 in [6] *((const byte*) main::SCREEN#0 + (byte) 0) ← (byte) main::b#2 +Successful SSA optimization PassNSimplifyExpressionWithZero +Eliminating unused constant (const byte) main::b#0 +Eliminating unused constant (const byte) main::v64#0 +Successful SSA optimization PassNEliminateUnusedVars +Identical Phi Values (byte) main::b#2 (const byte) main::b#1 +Successful SSA optimization Pass2IdenticalPhiElimination +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main +Adding NOP phi() at start of main::@3 +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block (label) @2 +Culled Empty Block (label) main::@3 +Renumbering block main::@4 to main::@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 + +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() +main: scope:[main] from @1 + [4] phi() + to:main::@1 +main::@1: scope:[main] from main + [5] *((const byte*) main::SCREEN#0) ← (const byte) main::b#1 + to:main::@return +main::@return: scope:[main] from main::@1 + [6] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(byte*) main::SCREEN +(byte) main::b +(byte) main::v64 + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +Target platform is c64basic + // File Comments +// Tests simple switch()-statement - not inside a loop + // Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" + // Global Constants & labels + // @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 SCREEN = $400 + .const b = 1 + jmp b1 + // main::@1 + b1: + // [5] *((const byte*) main::SCREEN#0) ← (const byte) main::b#1 -- _deref_pbuc1=vbuc2 + lda #b + sta SCREEN + jmp breturn + // main::@return + breturn: + // [6] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [5] *((const byte*) main::SCREEN#0) ← (const byte) main::b#1 [ ] ( main:2 [ ] ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 57 combination +Uplifting [] best 57 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Tests simple switch()-statement - not inside a loop + // Upstart +.pc = $801 "Basic" +:BasicUpstart(bbegin) +.pc = $80d "Program" + // Global Constants & labels + // @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 SCREEN = $400 + .const b = 1 + jmp b1 + // main::@1 + b1: + // [5] *((const byte*) main::SCREEN#0) ← (const byte) main::b#1 -- _deref_pbuc1=vbuc2 + lda #b + sta SCREEN + jmp breturn + // main::@return + breturn: + // [6] return + rts +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp b1 +Removing instruction jmp bend +Removing instruction jmp b1 +Removing instruction jmp breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction b1_from_bbegin: +Removing instruction b1: +Removing instruction main_from_b1: +Removing instruction bend_from_b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction bend: +Removing instruction b1: +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 +(void()) main() +(label) main::@1 +(label) main::@return +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::b +(const byte) main::b#1 b = (byte) 1 +(byte) main::v64 + + + +FINAL ASSEMBLER +Score: 12 + + // File Comments +// Tests simple switch()-statement - not inside a loop + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + // @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 SCREEN = $400 + .const b = 1 + // main::@1 + // SCREEN[0] = b + // [5] *((const byte*) main::SCREEN#0) ← (const byte) main::b#1 -- _deref_pbuc1=vbuc2 + lda #b + sta SCREEN + // main::@return + // } + // [6] return + rts +} + // File Data + diff --git a/src/test/ref/switch-2.sym b/src/test/ref/switch-2.sym new file mode 100644 index 000000000..dc7971eb1 --- /dev/null +++ b/src/test/ref/switch-2.sym @@ -0,0 +1,12 @@ +(label) @1 +(label) @begin +(label) @end +(void()) main() +(label) main::@1 +(label) main::@return +(byte*) main::SCREEN +(const byte*) main::SCREEN#0 SCREEN = (byte*) 1024 +(byte) main::b +(const byte) main::b#1 b = (byte) 1 +(byte) main::v64 +