From c4550b5aecad7700ba4ec86fceef5c04602284a7 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sun, 5 Apr 2020 14:45:32 +0200 Subject: [PATCH] Added test of defines with complex body. #169 --- .../Pass0GenerateStatementSequence.java | 5 +- .../dk/camelot64/kickc/test/TestPrograms.java | 5 + src/test/kc/preprocessor-1.kc | 12 + src/test/ref/preprocessor-1.asm | 11 + src/test/ref/preprocessor-1.cfg | 17 ++ src/test/ref/preprocessor-1.log | 208 ++++++++++++++++++ src/test/ref/preprocessor-1.sym | 7 + 7 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 src/test/kc/preprocessor-1.kc create mode 100644 src/test/ref/preprocessor-1.asm create mode 100644 src/test/ref/preprocessor-1.cfg create mode 100644 src/test/ref/preprocessor-1.log create mode 100644 src/test/ref/preprocessor-1.sym diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 3a043c633..99047353c 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -2370,7 +2370,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor> commentBlocks = new ArrayList<>(); List comments = new ArrayList<>(); BufferedTokenStream tokenStream = cParser.getTokenStream(); - List hiddenTokens = tokenStream.getHiddenTokensToLeft(ctx.start.getTokenIndex()); + final int startTokenIndex = ctx.start.getTokenIndex(); + if(startTokenIndex<0) + return commentBlocks; + List hiddenTokens = tokenStream.getHiddenTokensToLeft(startTokenIndex); if(hiddenTokens != null) { for(Token hiddenToken : hiddenTokens) { if(hiddenToken.getChannel() == CParser.CHANNEL_WHITESPACE) { diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 19275a8ff..7c09207ab 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -42,6 +42,11 @@ public class TestPrograms { compileAndCompare("preprocessor-0"); } + @Test + public void testPreprocessor1() throws IOException, URISyntaxException { + compileAndCompare("preprocessor-1"); + } + @Test public void testMaCoalesceProblem() throws IOException, URISyntaxException { compileAndCompare("ma_coalesce_problem"); diff --git a/src/test/kc/preprocessor-1.kc b/src/test/kc/preprocessor-1.kc new file mode 100644 index 000000000..6de16e04a --- /dev/null +++ b/src/test/kc/preprocessor-1.kc @@ -0,0 +1,12 @@ +// Test the preprocessor +// #define's with complex token bodies + +#define USE_SCREEN_DEFAULT char * const SCREEN = 0x0400; +#define START_MAIN void main() { +#define END_MAIN } + +USE_SCREEN_DEFAULT + +START_MAIN + *SCREEN = 'a'; +END_MAIN diff --git a/src/test/ref/preprocessor-1.asm b/src/test/ref/preprocessor-1.asm new file mode 100644 index 000000000..dcaa01a06 --- /dev/null +++ b/src/test/ref/preprocessor-1.asm @@ -0,0 +1,11 @@ +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 +main: { + // *SCREEN = 'a' + lda #'a' + sta SCREEN + // END_MAIN + rts +} diff --git a/src/test/ref/preprocessor-1.cfg b/src/test/ref/preprocessor-1.cfg new file mode 100644 index 000000000..6a5142472 --- /dev/null +++ b/src/test/ref/preprocessor-1.cfg @@ -0,0 +1,17 @@ +@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] *((const nomodify byte*) SCREEN) ← (byte) 'a' + to:main::@return +main::@return: scope:[main] from main + [5] return + to:@return diff --git a/src/test/ref/preprocessor-1.log b/src/test/ref/preprocessor-1.log new file mode 100644 index 000000000..407d55ca6 --- /dev/null +++ b/src/test/ref/preprocessor-1.log @@ -0,0 +1,208 @@ + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 + +(void()) main() +main: scope:[main] from @1 + *((const nomodify byte*) SCREEN) ← (byte) 'a' + to:main::@return +main::@return: scope:[main] from main + 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 +(const nomodify byte*) SCREEN = (byte*)(number) $400 +(void()) main() +(label) main::@return + +Simplifying constant pointer cast (byte*) 1024 +Successful SSA optimization PassNCastSimplification +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 +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 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +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] *((const nomodify byte*) SCREEN) ← (byte) 'a' + to:main::@return +main::@return: scope:[main] from main + [5] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @begin +__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + // [4] *((const nomodify byte*) SCREEN) ← (byte) 'a' -- _deref_pbuc1=vbuc2 + lda #'a' + sta SCREEN + jmp __breturn + // main::@return + __breturn: + // [5] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const nomodify byte*) SCREEN) ← (byte) 'a' [ ] ( main:2 [ ] { } ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 27 combination +Uplifting [] best 27 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @begin +__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + // [4] *((const nomodify byte*) SCREEN) ← (byte) 'a' -- _deref_pbuc1=vbuc2 + lda #'a' + sta SCREEN + jmp __breturn + // main::@return + __breturn: + // [5] return + rts +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __b1 +Removing instruction jmp __bend +Removing instruction jmp __breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction __b1_from___bbegin: +Removing instruction __b1: +Removing instruction __bend_from___b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __bend: +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 nomodify byte*) SCREEN = (byte*) 1024 +(void()) main() +(label) main::@return + + + +FINAL ASSEMBLER +Score: 12 + + // File Comments + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + // @begin + // [1] phi from @begin to @1 [phi:@begin->@1] + // @1 + // [2] call main + // [3] phi from @1 to @end [phi:@1->@end] + // @end + // main +main: { + // *SCREEN = 'a' + // [4] *((const nomodify byte*) SCREEN) ← (byte) 'a' -- _deref_pbuc1=vbuc2 + lda #'a' + sta SCREEN + // main::@return + // END_MAIN + // [5] return + rts +} + // File Data + diff --git a/src/test/ref/preprocessor-1.sym b/src/test/ref/preprocessor-1.sym new file mode 100644 index 000000000..17d516eda --- /dev/null +++ b/src/test/ref/preprocessor-1.sym @@ -0,0 +1,7 @@ +(label) @1 +(label) @begin +(label) @end +(const nomodify byte*) SCREEN = (byte*) 1024 +(void()) main() +(label) main::@return +