From 607f740f8b1ce2e95bca4a0dc54609708f2576e1 Mon Sep 17 00:00:00 2001 From: Jesper Gravgaard Date: Mon, 30 Mar 2020 13:25:52 +0200 Subject: [PATCH] Added support for typedefs with const/volatile directives. Closes #375 --- .../Pass0GenerateStatementSequence.java | 34 ++- .../dk/camelot64/kickc/test/TestPrograms.java | 34 ++- src/test/kc/number-ternary-fail-3.kc | 13 + src/test/kc/typedef-4.kc | 10 +- src/test/kc/typedef-5.kc | 5 +- src/test/kc/typedef-6.kc | 14 + src/test/kc/typedef-7.kc | 14 + src/test/ref/pointer-const-typedef.asm | 2 +- src/test/ref/pointer-const-typedef.cfg | 10 +- src/test/ref/pointer-const-typedef.log | 91 +++--- src/test/ref/pointer-const-typedef.sym | 10 +- src/test/ref/typedef-4.asm | 23 ++ src/test/ref/typedef-4.cfg | 18 ++ src/test/ref/typedef-4.log | 263 ++++++++++++++++++ src/test/ref/typedef-4.sym | 10 + src/test/ref/typedef-5.asm | 17 ++ src/test/ref/typedef-5.cfg | 18 ++ src/test/ref/typedef-5.log | 250 +++++++++++++++++ src/test/ref/typedef-5.sym | 9 + src/test/ref/typedef-6.asm | 17 ++ src/test/ref/typedef-6.cfg | 18 ++ src/test/ref/typedef-6.log | 250 +++++++++++++++++ src/test/ref/typedef-6.sym | 9 + src/test/ref/typedef-7.asm | 17 ++ src/test/ref/typedef-7.cfg | 18 ++ src/test/ref/typedef-7.log | 248 +++++++++++++++++ src/test/ref/typedef-7.sym | 9 + 27 files changed, 1352 insertions(+), 79 deletions(-) create mode 100644 src/test/kc/number-ternary-fail-3.kc create mode 100644 src/test/kc/typedef-6.kc create mode 100644 src/test/kc/typedef-7.kc create mode 100644 src/test/ref/typedef-4.asm create mode 100644 src/test/ref/typedef-4.cfg create mode 100644 src/test/ref/typedef-4.log create mode 100644 src/test/ref/typedef-4.sym create mode 100644 src/test/ref/typedef-5.asm create mode 100644 src/test/ref/typedef-5.cfg create mode 100644 src/test/ref/typedef-5.log create mode 100644 src/test/ref/typedef-5.sym create mode 100644 src/test/ref/typedef-6.asm create mode 100644 src/test/ref/typedef-6.cfg create mode 100644 src/test/ref/typedef-6.log create mode 100644 src/test/ref/typedef-6.sym create mode 100644 src/test/ref/typedef-7.asm create mode 100644 src/test/ref/typedef-7.cfg create mode 100644 src/test/ref/typedef-7.log create mode 100644 src/test/ref/typedef-7.sym diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java index 8f93c2186..837505889 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass0GenerateStatementSequence.java @@ -640,10 +640,12 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor@1] @@ -449,11 +448,11 @@ main: { lda pc0 sta SCREEN // SCREEN[idx++] = *pc1 - // [5] *((const byte*) SCREEN+(byte) 1) ← *((const byte*) pc1) -- _deref_pbuc1=_deref_pbuc2 + // [5] *((const byte*) SCREEN+(byte) 1) ← *((const to_nomodify byte*) pc1) -- _deref_pbuc1=_deref_pbuc2 lda pc1 sta SCREEN+1 // SCREEN[idx++] = *pc2 - // [6] *((const byte*) SCREEN+(byte) 2) ← *((const byte*) pc2) -- _deref_pbuc1=_deref_pbuc2 + // [6] *((const byte*) SCREEN+(byte) 2) ← *((const to_nomodify byte*) pc2) -- _deref_pbuc1=_deref_pbuc2 lda pc2 sta SCREEN+2 // SCREEN[idx++] = *cp0 @@ -461,7 +460,7 @@ main: { lda cp0 sta SCREEN+3 // SCREEN[idx++] = *cp1 - // [8] *((const byte*) SCREEN+(byte) 4) ← *((const byte*) cp1) -- _deref_pbuc1=_deref_pbuc2 + // [8] *((const byte*) SCREEN+(byte) 4) ← *((const nomodify byte*) cp1) -- _deref_pbuc1=_deref_pbuc2 lda cp1 sta SCREEN+4 // SCREEN[idx++] = *cp2 @@ -473,11 +472,11 @@ main: { lda cpc0 sta SCREEN+6 // SCREEN[idx++] = *cpc1 - // [11] *((const byte*) SCREEN+(byte) 7) ← *((const nomodify byte*) cpc1) -- _deref_pbuc1=_deref_pbuc2 + // [11] *((const byte*) SCREEN+(byte) 7) ← *((const nomodify to_nomodify byte*) cpc1) -- _deref_pbuc1=_deref_pbuc2 lda cpc1 sta SCREEN+7 // SCREEN[idx++] = *cpc2 - // [12] *((const byte*) SCREEN+(byte) 8) ← *((const nomodify byte*) cpc2) -- _deref_pbuc1=_deref_pbuc2 + // [12] *((const byte*) SCREEN+(byte) 8) ← *((const nomodify to_nomodify byte*) cpc2) -- _deref_pbuc1=_deref_pbuc2 lda cpc2 sta SCREEN+8 // main::@return diff --git a/src/test/ref/pointer-const-typedef.sym b/src/test/ref/pointer-const-typedef.sym index ee3b7dfd2..944b3ec38 100644 --- a/src/test/ref/pointer-const-typedef.sym +++ b/src/test/ref/pointer-const-typedef.sym @@ -3,15 +3,15 @@ (label) @end (const byte*) SCREEN = (byte*) 1024 (const nomodify byte*) cp0 = (byte*) 1024 -(const byte*) cp1 = (byte*) 1024 +(const nomodify byte*) cp1 = (byte*) 1024 (const nomodify byte*) cp2 = (byte*) 1024 (const nomodify to_nomodify byte*) cpc0 = (byte*) 1024 -(const nomodify byte*) cpc1 = (byte*) 1024 -(const nomodify byte*) cpc2 = (byte*) 1024 +(const nomodify to_nomodify byte*) cpc1 = (byte*) 1024 +(const nomodify to_nomodify byte*) cpc2 = (byte*) 1024 (void()) main() (label) main::@return (byte) main::idx (const to_nomodify byte*) pc0 = (byte*) 1024 -(const byte*) pc1 = (byte*) 1024 -(const byte*) pc2 = (byte*) 1024 +(const to_nomodify byte*) pc1 = (byte*) 1024 +(const to_nomodify byte*) pc2 = (byte*) 1024 diff --git a/src/test/ref/typedef-4.asm b/src/test/ref/typedef-4.asm new file mode 100644 index 000000000..768dfb760 --- /dev/null +++ b/src/test/ref/typedef-4.asm @@ -0,0 +1,23 @@ +// Typedef const/volatile type +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + .label SCREEN = $400 + .const c = 'c' + .label v = 2 +__bbegin: + // v = 'v' + lda #'v' + sta.z v + jsr main + rts +main: { + // SCREEN[0] = c + lda #c + sta SCREEN + // SCREEN[0] = v + lda.z v + sta SCREEN + // } + rts +} diff --git a/src/test/ref/typedef-4.cfg b/src/test/ref/typedef-4.cfg new file mode 100644 index 000000000..e80abdfbe --- /dev/null +++ b/src/test/ref/typedef-4.cfg @@ -0,0 +1,18 @@ +@begin: scope:[] from + [0] (volatile byte) v ← (byte) 'v' + 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) ← (const nomodify byte) c + [5] *((const nomodify byte*) SCREEN) ← (volatile byte) v + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return diff --git a/src/test/ref/typedef-4.log b/src/test/ref/typedef-4.log new file mode 100644 index 000000000..22611a27b --- /dev/null +++ b/src/test/ref/typedef-4.log @@ -0,0 +1,263 @@ + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + (volatile byte) v ← (byte) 'v' + to:@1 + +(void()) main() +main: scope:[main] from @1 + *((const nomodify byte*) SCREEN + (number) 0) ← (const nomodify byte) c + *((const nomodify byte*) SCREEN + (number) 0) ← (volatile byte) v + 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 +(const nomodify byte) c = (byte) 'c' +(void()) main() +(label) main::@return +(volatile byte) v loadstore + +Adding number conversion cast (unumber) 0 in *((const nomodify byte*) SCREEN + (number) 0) ← (const nomodify byte) c +Adding number conversion cast (unumber) 0 in *((const nomodify byte*) SCREEN + (number) 0) ← (volatile byte) v +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant integer cast 0 +Simplifying constant integer cast 0 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 0 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Simplifying expression containing zero SCREEN in [1] *((const nomodify byte*) SCREEN + (byte) 0) ← (const nomodify byte) c +Simplifying expression containing zero SCREEN in [2] *((const nomodify byte*) SCREEN + (byte) 0) ← (volatile byte) v +Successful SSA optimization PassNSimplifyExpressionWithZero +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 @1 +Adding NOP phi() at start of @end + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] (volatile byte) v ← (byte) 'v' + 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) ← (const nomodify byte) c + [5] *((const nomodify byte*) SCREEN) ← (volatile byte) v + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() +(volatile byte) v loadstore 4.333333333333333 + +Initial phi equivalence classes +Added variable v to live range equivalence class [ v ] +Complete equivalence classes +[ v ] +Allocated zp[1]:2 [ v ] + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// Typedef const/volatile type + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const c = 'c' + .label v = 2 + // @begin +__bbegin: + // [0] (volatile byte) v ← (byte) 'v' -- vbuz1=vbuc1 + lda #'v' + sta.z v + // [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) ← (const nomodify byte) c -- _deref_pbuc1=vbuc2 + lda #c + sta SCREEN + // [5] *((const nomodify byte*) SCREEN) ← (volatile byte) v -- _deref_pbuc1=vbuz1 + lda.z v + sta SCREEN + jmp __breturn + // main::@return + __breturn: + // [6] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [0] (volatile byte) v ← (byte) 'v' [ v ] ( [ v ] { } ) always clobbers reg byte a +Statement [4] *((const nomodify byte*) SCREEN) ← (const nomodify byte) c [ v ] ( main:2 [ v ] { } ) always clobbers reg byte a +Statement [5] *((const nomodify byte*) SCREEN) ← (volatile byte) v [ ] ( main:2 [ ] { } ) always clobbers reg byte a +Potential registers zp[1]:2 [ v ] : zp[1]:2 , + +REGISTER UPLIFT SCOPES +Uplift Scope [] 4.33: zp[1]:2 [ v ] +Uplift Scope [main] + +Uplifting [] best 39 combination zp[1]:2 [ v ] +Uplifting [main] best 39 combination +Attempting to uplift remaining variables inzp[1]:2 [ v ] +Uplifting [] best 39 combination zp[1]:2 [ v ] + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Typedef const/volatile type + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const c = 'c' + .label v = 2 + // @begin +__bbegin: + // [0] (volatile byte) v ← (byte) 'v' -- vbuz1=vbuc1 + lda #'v' + sta.z v + // [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) ← (const nomodify byte) c -- _deref_pbuc1=vbuc2 + lda #c + sta SCREEN + // [5] *((const nomodify byte*) SCREEN) ← (volatile byte) v -- _deref_pbuc1=vbuz1 + lda.z v + 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 __breturn +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction __b1_from___bbegin: +Removing instruction __bend_from___b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __b1: +Removing instruction __bend: +Removing instruction __breturn: +Succesful ASM optimization Pass5UnusedLabelElimination +Adding RTS to root block +Succesful ASM optimization Pass5AddMainRts + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(const nomodify byte*) SCREEN = (byte*) 1024 +(const nomodify byte) c = (byte) 'c' +(void()) main() +(label) main::@return +(volatile byte) v loadstore zp[1]:2 4.333333333333333 + +zp[1]:2 [ v ] + + +FINAL ASSEMBLER +Score: 36 + + // File Comments +// Typedef const/volatile type + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .const c = 'c' + .label v = 2 + // @begin +__bbegin: + // v = 'v' + // [0] (volatile byte) v ← (byte) 'v' -- vbuz1=vbuc1 + lda #'v' + sta.z v + // [1] phi from @begin to @1 [phi:@begin->@1] + // @1 + // [2] call main + jsr main + rts + // [3] phi from @1 to @end [phi:@1->@end] + // @end + // main +main: { + // SCREEN[0] = c + // [4] *((const nomodify byte*) SCREEN) ← (const nomodify byte) c -- _deref_pbuc1=vbuc2 + lda #c + sta SCREEN + // SCREEN[0] = v + // [5] *((const nomodify byte*) SCREEN) ← (volatile byte) v -- _deref_pbuc1=vbuz1 + lda.z v + sta SCREEN + // main::@return + // } + // [6] return + rts +} + // File Data + diff --git a/src/test/ref/typedef-4.sym b/src/test/ref/typedef-4.sym new file mode 100644 index 000000000..012ce9c24 --- /dev/null +++ b/src/test/ref/typedef-4.sym @@ -0,0 +1,10 @@ +(label) @1 +(label) @begin +(label) @end +(const nomodify byte*) SCREEN = (byte*) 1024 +(const nomodify byte) c = (byte) 'c' +(void()) main() +(label) main::@return +(volatile byte) v loadstore zp[1]:2 4.333333333333333 + +zp[1]:2 [ v ] diff --git a/src/test/ref/typedef-5.asm b/src/test/ref/typedef-5.asm new file mode 100644 index 000000000..9349c673c --- /dev/null +++ b/src/test/ref/typedef-5.asm @@ -0,0 +1,17 @@ +// Typedef a const/volatile type and instantiate a pointer to it +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 +main: { + // SCREEN[0] = *cp + lda cp + sta SCREEN + // SCREEN[1] = *vp + lda vp + sta SCREEN+1 + // } + rts +} diff --git a/src/test/ref/typedef-5.cfg b/src/test/ref/typedef-5.cfg new file mode 100644 index 000000000..293a5a228 --- /dev/null +++ b/src/test/ref/typedef-5.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() + +(void()) main() +main: scope:[main] from @1 + [4] *((const nomodify byte*) SCREEN) ← *((const to_nomodify byte*) cp) + [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return diff --git a/src/test/ref/typedef-5.log b/src/test/ref/typedef-5.log new file mode 100644 index 000000000..f635744c7 --- /dev/null +++ b/src/test/ref/typedef-5.log @@ -0,0 +1,250 @@ +Identified constant variable (to_nomodify byte*) cp +Identified constant variable (to_volatile byte*) vp + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 + +(void()) main() +main: scope:[main] from @1 + *((const nomodify byte*) SCREEN + (number) 0) ← *((const to_nomodify byte*) cp) + *((const nomodify byte*) SCREEN + (number) 1) ← *((const to_volatile byte*) vp) + 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 +(const to_nomodify byte*) cp = (byte*)(number) $a003 +(void()) main() +(label) main::@return +(const to_volatile byte*) vp = (byte*)(number) $a004 + +Adding number conversion cast (unumber) 0 in *((const nomodify byte*) SCREEN + (number) 0) ← *((const to_nomodify byte*) cp) +Adding number conversion cast (unumber) 1 in *((const nomodify byte*) SCREEN + (number) 1) ← *((const to_volatile byte*) vp) +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant pointer cast (byte*) 40963 +Simplifying constant pointer cast (byte*) 40964 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Simplifying expression containing zero SCREEN in [0] *((const nomodify byte*) SCREEN + (byte) 0) ← *((const to_nomodify byte*) cp) +Successful SSA optimization PassNSimplifyExpressionWithZero +Consolidated array index constant in *(SCREEN+1) +Successful SSA optimization Pass2ConstantAdditionElimination +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) ← *((const to_nomodify byte*) cp) + [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// Typedef a const/volatile type and instantiate a pointer to it + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 + // @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) ← *((const to_nomodify byte*) cp) -- _deref_pbuc1=_deref_pbuc2 + lda cp + sta SCREEN + // [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) -- _deref_pbuc1=_deref_pbuc2 + lda vp + sta SCREEN+1 + jmp __breturn + // main::@return + __breturn: + // [6] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const nomodify byte*) SCREEN) ← *((const to_nomodify byte*) cp) [ ] ( main:2 [ ] { } ) always clobbers reg byte a +Statement [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) [ ] ( main:2 [ ] { } ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 37 combination +Uplifting [] best 37 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Typedef a const/volatile type and instantiate a pointer to it + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 + // @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) ← *((const to_nomodify byte*) cp) -- _deref_pbuc1=_deref_pbuc2 + lda cp + sta SCREEN + // [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) -- _deref_pbuc1=_deref_pbuc2 + lda vp + sta SCREEN+1 + jmp __breturn + // main::@return + __breturn: + // [6] 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 +(const to_nomodify byte*) cp = (byte*) 40963 +(void()) main() +(label) main::@return +(const to_volatile byte*) vp = (byte*) 40964 + + + +FINAL ASSEMBLER +Score: 22 + + // File Comments +// Typedef a const/volatile type and instantiate a pointer to it + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 + // @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[0] = *cp + // [4] *((const nomodify byte*) SCREEN) ← *((const to_nomodify byte*) cp) -- _deref_pbuc1=_deref_pbuc2 + lda cp + sta SCREEN + // SCREEN[1] = *vp + // [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) -- _deref_pbuc1=_deref_pbuc2 + lda vp + sta SCREEN+1 + // main::@return + // } + // [6] return + rts +} + // File Data + diff --git a/src/test/ref/typedef-5.sym b/src/test/ref/typedef-5.sym new file mode 100644 index 000000000..a0aa70b79 --- /dev/null +++ b/src/test/ref/typedef-5.sym @@ -0,0 +1,9 @@ +(label) @1 +(label) @begin +(label) @end +(const nomodify byte*) SCREEN = (byte*) 1024 +(const to_nomodify byte*) cp = (byte*) 40963 +(void()) main() +(label) main::@return +(const to_volatile byte*) vp = (byte*) 40964 + diff --git a/src/test/ref/typedef-6.asm b/src/test/ref/typedef-6.asm new file mode 100644 index 000000000..52125c8a8 --- /dev/null +++ b/src/test/ref/typedef-6.asm @@ -0,0 +1,17 @@ +// Typedef pointer to const/volatile type and instantiate it +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 +main: { + // SCREEN[0] = *cp + lda cp + sta SCREEN + // SCREEN[1] = *vp + lda vp + sta SCREEN+1 + // } + rts +} diff --git a/src/test/ref/typedef-6.cfg b/src/test/ref/typedef-6.cfg new file mode 100644 index 000000000..293a5a228 --- /dev/null +++ b/src/test/ref/typedef-6.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() + +(void()) main() +main: scope:[main] from @1 + [4] *((const nomodify byte*) SCREEN) ← *((const to_nomodify byte*) cp) + [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return diff --git a/src/test/ref/typedef-6.log b/src/test/ref/typedef-6.log new file mode 100644 index 000000000..f5a7c18b8 --- /dev/null +++ b/src/test/ref/typedef-6.log @@ -0,0 +1,250 @@ +Identified constant variable (to_nomodify byte*) cp +Identified constant variable (to_volatile byte*) vp + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 + +(void()) main() +main: scope:[main] from @1 + *((const nomodify byte*) SCREEN + (number) 0) ← *((const to_nomodify byte*) cp) + *((const nomodify byte*) SCREEN + (number) 1) ← *((const to_volatile byte*) vp) + 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 +(const to_nomodify byte*) cp = (byte*)(number) $a003 +(void()) main() +(label) main::@return +(const to_volatile byte*) vp = (byte*)(number) $a004 + +Adding number conversion cast (unumber) 0 in *((const nomodify byte*) SCREEN + (number) 0) ← *((const to_nomodify byte*) cp) +Adding number conversion cast (unumber) 1 in *((const nomodify byte*) SCREEN + (number) 1) ← *((const to_volatile byte*) vp) +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant pointer cast (byte*) 40963 +Simplifying constant pointer cast (byte*) 40964 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Simplifying expression containing zero SCREEN in [0] *((const nomodify byte*) SCREEN + (byte) 0) ← *((const to_nomodify byte*) cp) +Successful SSA optimization PassNSimplifyExpressionWithZero +Consolidated array index constant in *(SCREEN+1) +Successful SSA optimization Pass2ConstantAdditionElimination +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) ← *((const to_nomodify byte*) cp) + [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// Typedef pointer to const/volatile type and instantiate it + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 + // @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) ← *((const to_nomodify byte*) cp) -- _deref_pbuc1=_deref_pbuc2 + lda cp + sta SCREEN + // [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) -- _deref_pbuc1=_deref_pbuc2 + lda vp + sta SCREEN+1 + jmp __breturn + // main::@return + __breturn: + // [6] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const nomodify byte*) SCREEN) ← *((const to_nomodify byte*) cp) [ ] ( main:2 [ ] { } ) always clobbers reg byte a +Statement [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) [ ] ( main:2 [ ] { } ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 37 combination +Uplifting [] best 37 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Typedef pointer to const/volatile type and instantiate it + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 + // @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) ← *((const to_nomodify byte*) cp) -- _deref_pbuc1=_deref_pbuc2 + lda cp + sta SCREEN + // [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) -- _deref_pbuc1=_deref_pbuc2 + lda vp + sta SCREEN+1 + jmp __breturn + // main::@return + __breturn: + // [6] 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 +(const to_nomodify byte*) cp = (byte*) 40963 +(void()) main() +(label) main::@return +(const to_volatile byte*) vp = (byte*) 40964 + + + +FINAL ASSEMBLER +Score: 22 + + // File Comments +// Typedef pointer to const/volatile type and instantiate it + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 + // @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[0] = *cp + // [4] *((const nomodify byte*) SCREEN) ← *((const to_nomodify byte*) cp) -- _deref_pbuc1=_deref_pbuc2 + lda cp + sta SCREEN + // SCREEN[1] = *vp + // [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const to_volatile byte*) vp) -- _deref_pbuc1=_deref_pbuc2 + lda vp + sta SCREEN+1 + // main::@return + // } + // [6] return + rts +} + // File Data + diff --git a/src/test/ref/typedef-6.sym b/src/test/ref/typedef-6.sym new file mode 100644 index 000000000..a0aa70b79 --- /dev/null +++ b/src/test/ref/typedef-6.sym @@ -0,0 +1,9 @@ +(label) @1 +(label) @begin +(label) @end +(const nomodify byte*) SCREEN = (byte*) 1024 +(const to_nomodify byte*) cp = (byte*) 40963 +(void()) main() +(label) main::@return +(const to_volatile byte*) vp = (byte*) 40964 + diff --git a/src/test/ref/typedef-7.asm b/src/test/ref/typedef-7.asm new file mode 100644 index 000000000..19b8edf19 --- /dev/null +++ b/src/test/ref/typedef-7.asm @@ -0,0 +1,17 @@ +// Typedef pointer to const/volatile type and instantiate it to const variable +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 +main: { + // SCREEN[0] = *cp + lda cp + sta SCREEN + // SCREEN[1] = *vp + lda vp + sta SCREEN+1 + // } + rts +} diff --git a/src/test/ref/typedef-7.cfg b/src/test/ref/typedef-7.cfg new file mode 100644 index 000000000..0d0ea7423 --- /dev/null +++ b/src/test/ref/typedef-7.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() + +(void()) main() +main: scope:[main] from @1 + [4] *((const nomodify byte*) SCREEN) ← *((const nomodify to_nomodify byte*) cp) + [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const nomodify to_volatile byte*) vp) + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return diff --git a/src/test/ref/typedef-7.log b/src/test/ref/typedef-7.log new file mode 100644 index 000000000..3812e0d26 --- /dev/null +++ b/src/test/ref/typedef-7.log @@ -0,0 +1,248 @@ + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 + +(void()) main() +main: scope:[main] from @1 + *((const nomodify byte*) SCREEN + (number) 0) ← *((const nomodify to_nomodify byte*) cp) + *((const nomodify byte*) SCREEN + (number) 1) ← *((const nomodify to_volatile byte*) vp) + 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 +(const nomodify to_nomodify byte*) cp = (byte*)(number) $a003 +(void()) main() +(label) main::@return +(const nomodify to_volatile byte*) vp = (byte*)(number) $a004 + +Adding number conversion cast (unumber) 0 in *((const nomodify byte*) SCREEN + (number) 0) ← *((const nomodify to_nomodify byte*) cp) +Adding number conversion cast (unumber) 1 in *((const nomodify byte*) SCREEN + (number) 1) ← *((const nomodify to_volatile byte*) vp) +Successful SSA optimization PassNAddNumberTypeConversions +Simplifying constant pointer cast (byte*) 1024 +Simplifying constant pointer cast (byte*) 40963 +Simplifying constant pointer cast (byte*) 40964 +Simplifying constant integer cast 0 +Simplifying constant integer cast 1 +Successful SSA optimization PassNCastSimplification +Finalized unsigned number type (byte) 0 +Finalized unsigned number type (byte) 1 +Successful SSA optimization PassNFinalizeNumberTypeConversions +Simplifying expression containing zero SCREEN in [0] *((const nomodify byte*) SCREEN + (byte) 0) ← *((const nomodify to_nomodify byte*) cp) +Successful SSA optimization PassNSimplifyExpressionWithZero +Consolidated array index constant in *(SCREEN+1) +Successful SSA optimization Pass2ConstantAdditionElimination +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) ← *((const nomodify to_nomodify byte*) cp) + [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const nomodify to_volatile byte*) vp) + to:main::@return +main::@return: scope:[main] from main + [6] return + to:@return + + +VARIABLE REGISTER WEIGHTS +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +Target platform is c64basic / MOS6502X + // File Comments +// Typedef pointer to const/volatile type and instantiate it to const variable + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 + // @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) ← *((const nomodify to_nomodify byte*) cp) -- _deref_pbuc1=_deref_pbuc2 + lda cp + sta SCREEN + // [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const nomodify to_volatile byte*) vp) -- _deref_pbuc1=_deref_pbuc2 + lda vp + sta SCREEN+1 + jmp __breturn + // main::@return + __breturn: + // [6] return + rts +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [4] *((const nomodify byte*) SCREEN) ← *((const nomodify to_nomodify byte*) cp) [ ] ( main:2 [ ] { } ) always clobbers reg byte a +Statement [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const nomodify to_volatile byte*) vp) [ ] ( main:2 [ ] { } ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [main] +Uplift Scope [] + +Uplifting [main] best 37 combination +Uplifting [] best 37 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// Typedef pointer to const/volatile type and instantiate it to const variable + // Upstart +.pc = $801 "Basic" +:BasicUpstart(__bbegin) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 + // @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) ← *((const nomodify to_nomodify byte*) cp) -- _deref_pbuc1=_deref_pbuc2 + lda cp + sta SCREEN + // [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const nomodify to_volatile byte*) vp) -- _deref_pbuc1=_deref_pbuc2 + lda vp + sta SCREEN+1 + jmp __breturn + // main::@return + __breturn: + // [6] 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 +(const nomodify to_nomodify byte*) cp = (byte*) 40963 +(void()) main() +(label) main::@return +(const nomodify to_volatile byte*) vp = (byte*) 40964 + + + +FINAL ASSEMBLER +Score: 22 + + // File Comments +// Typedef pointer to const/volatile type and instantiate it to const variable + // Upstart +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Global Constants & labels + .label SCREEN = $400 + .label cp = $a003 + .label vp = $a004 + // @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[0] = *cp + // [4] *((const nomodify byte*) SCREEN) ← *((const nomodify to_nomodify byte*) cp) -- _deref_pbuc1=_deref_pbuc2 + lda cp + sta SCREEN + // SCREEN[1] = *vp + // [5] *((const nomodify byte*) SCREEN+(byte) 1) ← *((const nomodify to_volatile byte*) vp) -- _deref_pbuc1=_deref_pbuc2 + lda vp + sta SCREEN+1 + // main::@return + // } + // [6] return + rts +} + // File Data + diff --git a/src/test/ref/typedef-7.sym b/src/test/ref/typedef-7.sym new file mode 100644 index 000000000..345901f31 --- /dev/null +++ b/src/test/ref/typedef-7.sym @@ -0,0 +1,9 @@ +(label) @1 +(label) @begin +(label) @end +(const nomodify byte*) SCREEN = (byte*) 1024 +(const nomodify to_nomodify byte*) cp = (byte*) 40963 +(void()) main() +(label) main::@return +(const nomodify to_volatile byte*) vp = (byte*) 40964 +