From 450fc1add02079cc38dcb29ade113d01078eec56 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sat, 12 Aug 2017 00:22:46 +0200 Subject: [PATCH] Added more minimal test for modifying globals --- .../kickc/asm/fragment/aby=_inc_xby.asm | 3 + .../kickc/asm/fragment/aby=_inc_yby.asm | 3 + .../kickc/asm/fragment/xby=_inc_yby.asm | 3 + .../kickc/asm/fragment/yby=_inc_xby.asm | 3 + .../kickc/asm/fragment/zpby1=_inc_xby.asm | 2 + .../kickc/asm/fragment/zpby1=_inc_yby.asm | 2 + .../kickc/test/TestCompilationOutput.java | 4 + .../dk/camelot64/kickc/test/modglobalmin.kc | 18 + .../camelot64/kickc/test/ref/modglobalmin.asm | 21 + .../camelot64/kickc/test/ref/modglobalmin.cfg | 26 + .../camelot64/kickc/test/ref/modglobalmin.log | 747 ++++++++++++++++++ .../camelot64/kickc/test/ref/modglobalmin.sym | 18 + 12 files changed, 850 insertions(+) create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/aby=_inc_xby.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/aby=_inc_yby.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/xby=_inc_yby.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/yby=_inc_xby.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=_inc_xby.asm create mode 100644 src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=_inc_yby.asm create mode 100644 src/main/java/dk/camelot64/kickc/test/modglobalmin.kc create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.asm create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.cfg create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.log create mode 100644 src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.sym diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/aby=_inc_xby.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/aby=_inc_xby.asm new file mode 100644 index 000000000..c046351b2 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/aby=_inc_xby.asm @@ -0,0 +1,3 @@ +txa +clc +adc #1 \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/aby=_inc_yby.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/aby=_inc_yby.asm new file mode 100644 index 000000000..d3d5744a3 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/aby=_inc_yby.asm @@ -0,0 +1,3 @@ +tya +clc +adc #1 \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/xby=_inc_yby.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/xby=_inc_yby.asm new file mode 100644 index 000000000..9fdb5068e --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/xby=_inc_yby.asm @@ -0,0 +1,3 @@ +sty $ff +ldx $ff +inx \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/yby=_inc_xby.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/yby=_inc_xby.asm new file mode 100644 index 000000000..6869f2271 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/yby=_inc_xby.asm @@ -0,0 +1,3 @@ +stx $ff +ldy $ff +iny \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=_inc_xby.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=_inc_xby.asm new file mode 100644 index 000000000..5df2acd30 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=_inc_xby.asm @@ -0,0 +1,2 @@ +stx {zpby1} +inc {zpby1} \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=_inc_yby.asm b/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=_inc_yby.asm new file mode 100644 index 000000000..6f0dcffd9 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/asm/fragment/zpby1=_inc_yby.asm @@ -0,0 +1,2 @@ +sty {zpby1} +inc {zpby1} \ No newline at end of file diff --git a/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java b/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java index e052af0f3..9befc64ad 100644 --- a/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java +++ b/src/main/java/dk/camelot64/kickc/test/TestCompilationOutput.java @@ -80,6 +80,10 @@ public class TestCompilationOutput extends TestCase { compileAndCompare("modglobal"); } + public void testModGlobalMin() throws IOException, URISyntaxException { + compileAndCompare("modglobalmin"); + } + public void testUseUninitialized() throws IOException, URISyntaxException { String filename = "useuninitialized"; compileAndCompare(filename); diff --git a/src/main/java/dk/camelot64/kickc/test/modglobalmin.kc b/src/main/java/dk/camelot64/kickc/test/modglobalmin.kc new file mode 100644 index 000000000..781c36c1b --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/modglobalmin.kc @@ -0,0 +1,18 @@ +byte cnt = 0; +byte[256] SCREEN=$0400; + +main(); + +void main() { + inccnt(); + SCREEN[0]=cnt++; + inccnt(); + SCREEN[1]=++cnt; +} + +void inccnt() { + ++cnt; +} + + + diff --git a/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.asm b/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.asm new file mode 100644 index 000000000..0e1783f19 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.asm @@ -0,0 +1,21 @@ +BBEGIN: + jsr main +BEND: +main: +inccnt_from_main: + ldx #0 + jsr inccnt +main__B1: + stx 1024 + inx +inccnt_from_B1: + jsr inccnt +main__B2: + inx + stx 1025 +main__Breturn: + rts +inccnt: + inx +inccnt__Breturn: + rts diff --git a/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.cfg b/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.cfg new file mode 100644 index 000000000..3d2e13159 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.cfg @@ -0,0 +1,26 @@ +@BEGIN: from + [0] call main param-assignment [ ] + to:@END +@END: from @BEGIN +main: from @BEGIN + [1] call inccnt param-assignment [ cnt#10 ] + to:main::@1 +main::@1: from main + [2] *((word) 1024) ← (byte) cnt#10 [ cnt#10 ] + [3] (byte) cnt#3 ← ++ (byte) cnt#10 [ cnt#3 ] + [4] call inccnt param-assignment [ cnt#10 ] + to:main::@2 +main::@2: from main::@1 + [5] (byte) cnt#1 ← ++ (byte) cnt#10 [ cnt#1 ] + [6] *((word) 1025) ← (byte) cnt#1 [ ] + to:main::@return +main::@return: from main::@2 + [7] return [ ] + to:@RETURN +inccnt: from main main::@1 + [8] (byte) cnt#13 ← phi( main/(byte) 0 main::@1/(byte) cnt#3 ) [ cnt#13 ] + [9] (byte) cnt#10 ← ++ (byte) cnt#13 [ cnt#10 ] + to:inccnt::@return +inccnt::@return: from inccnt + [10] return [ cnt#10 ] + to:@RETURN diff --git a/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.log b/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.log new file mode 100644 index 000000000..a9ae53a66 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.log @@ -0,0 +1,747 @@ +byte cnt = 0; +byte[256] SCREEN=$0400; + +main(); + +void main() { + inccnt(); + SCREEN[0]=cnt++; + inccnt(); + SCREEN[1]=++cnt; +} + +void inccnt() { + ++cnt; +} + + + + +Adding pre/post-modifier (byte) cnt ← ++ (byte) cnt +Adding pre/post-modifier (byte) cnt ← ++ (byte) cnt +Adding pre/post-modifier (byte) cnt ← ++ (byte) cnt +PROGRAM + (byte) cnt ← (byte) 0 + (byte[256]) SCREEN ← (word) 1024 + (void~) $0 ← call main + proc (void()) main() + (void~) main::$0 ← call inccnt + *((byte[256]) SCREEN + (byte) 0) ← (byte) cnt + (byte) cnt ← ++ (byte) cnt + (void~) main::$1 ← call inccnt + (byte) cnt ← ++ (byte) cnt + *((byte[256]) SCREEN + (byte) 1) ← (byte) cnt +main::@return: + return + endproc // main() + proc (void()) inccnt() + (byte) cnt ← ++ (byte) cnt +inccnt::@return: + return + endproc // inccnt() + +SYMBOLS +(void~) $0 +(byte[256]) SCREEN +(byte) cnt +(void()) inccnt() +(label) inccnt::@return +(void()) main() +(void~) main::$0 +(void~) main::$1 +(label) main::@return + +INITIAL CONTROL FLOW GRAPH +@BEGIN: from + (byte) cnt ← (byte) 0 + (byte[256]) SCREEN ← (word) 1024 + (void~) $0 ← call main + to:@1 +main: from + (void~) main::$0 ← call inccnt + *((byte[256]) SCREEN + (byte) 0) ← (byte) cnt + (byte) cnt ← ++ (byte) cnt + (void~) main::$1 ← call inccnt + (byte) cnt ← ++ (byte) cnt + *((byte[256]) SCREEN + (byte) 1) ← (byte) cnt + to:main::@return +main::@return: from main + return + to:@RETURN +@1: from @BEGIN + to:@2 +inccnt: from + (byte) cnt ← ++ (byte) cnt + to:inccnt::@return +inccnt::@return: from inccnt + return + to:@RETURN +@2: from @1 + to:@END +@END: from @2 + +Removing empty block @1 +Removing empty block @2 +CONTROL FLOW GRAPH +@BEGIN: from + (byte) cnt ← (byte) 0 + (byte[256]) SCREEN ← (word) 1024 + (void~) $0 ← call main + to:@END +main: from + (void~) main::$0 ← call inccnt + *((byte[256]) SCREEN + (byte) 0) ← (byte) cnt + (byte) cnt ← ++ (byte) cnt + (void~) main::$1 ← call inccnt + (byte) cnt ← ++ (byte) cnt + *((byte[256]) SCREEN + (byte) 1) ← (byte) cnt + to:main::@return +main::@return: from main + return + to:@RETURN +inccnt: from + (byte) cnt ← ++ (byte) cnt + to:inccnt::@return +inccnt::@return: from inccnt + return + to:@RETURN +@END: from @BEGIN + +PROCEDURE MODIFY VARIABLE ANALYSIS +main modifies cnt +inccnt modifies cnt + +CONTROL FLOW GRAPH WITH ASSIGNMENT CALL +@BEGIN: from + (byte) cnt ← (byte) 0 + (byte[256]) SCREEN ← (word) 1024 + call main param-assignment + to:@3 +@3: from @BEGIN + (byte) cnt ← (byte) cnt + to:@END +main: from @BEGIN + call inccnt param-assignment + to:main::@1 +main::@1: from main + (byte) cnt ← (byte) cnt + *((byte[256]) SCREEN + (byte) 0) ← (byte) cnt + (byte) cnt ← ++ (byte) cnt + call inccnt param-assignment + to:main::@2 +main::@2: from main::@1 + (byte) cnt ← (byte) cnt + (byte) cnt ← ++ (byte) cnt + *((byte[256]) SCREEN + (byte) 1) ← (byte) cnt + to:main::@return +main::@return: from main::@2 + (byte) cnt ← (byte) cnt + return + to:@RETURN +inccnt: from main main::@1 + (byte) cnt ← ++ (byte) cnt + to:inccnt::@return +inccnt::@return: from inccnt + (byte) cnt ← (byte) cnt + return + to:@RETURN +@END: from @3 + +Completing Phi functions... +Completing Phi functions... +CONTROL FLOW GRAPH SSA +@BEGIN: from + (byte) cnt#0 ← (byte) 0 + (byte[256]) SCREEN#0 ← (word) 1024 + call main param-assignment + to:@3 +@3: from @BEGIN + (byte) cnt#9 ← phi( @BEGIN/(byte) cnt#0 ) + (byte) cnt#1 ← (byte) cnt#9 + to:@END +main: from @BEGIN + (byte[256]) SCREEN#3 ← phi( @BEGIN/(byte[256]) SCREEN#0 ) + (byte) cnt#15 ← phi( @BEGIN/(byte) cnt#0 ) + call inccnt param-assignment + to:main::@1 +main::@1: from main + (byte[256]) SCREEN#1 ← phi( main/(byte[256]) SCREEN#3 ) + (byte) cnt#10 ← phi( main/(byte) cnt#15 ) + (byte) cnt#2 ← (byte) cnt#10 + *((byte[256]) SCREEN#1 + (byte) 0) ← (byte) cnt#2 + (byte) cnt#3 ← ++ (byte) cnt#2 + call inccnt param-assignment + to:main::@2 +main::@2: from main::@1 + (byte[256]) SCREEN#2 ← phi( main::@1/(byte[256]) SCREEN#1 ) + (byte) cnt#11 ← phi( main::@1/(byte) cnt#3 ) + (byte) cnt#4 ← (byte) cnt#11 + (byte) cnt#5 ← ++ (byte) cnt#4 + *((byte[256]) SCREEN#2 + (byte) 1) ← (byte) cnt#5 + to:main::@return +main::@return: from main::@2 + (byte) cnt#12 ← phi( main::@2/(byte) cnt#5 ) + (byte) cnt#6 ← (byte) cnt#12 + return + to:@RETURN +inccnt: from main main::@1 + (byte) cnt#13 ← phi( main/(byte) cnt#15 main::@1/(byte) cnt#3 ) + (byte) cnt#7 ← ++ (byte) cnt#13 + to:inccnt::@return +inccnt::@return: from inccnt + (byte) cnt#14 ← phi( inccnt/(byte) cnt#7 ) + (byte) cnt#8 ← (byte) cnt#14 + return + to:@RETURN +@END: from @3 + +CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN +@BEGIN: from + (byte) cnt#0 ← (byte) 0 + (byte[256]) SCREEN#0 ← (word) 1024 + call main param-assignment + to:@3 +@3: from @BEGIN + (byte) cnt#9 ← phi( @BEGIN/(byte) cnt#6 ) + (byte) cnt#1 ← (byte) cnt#9 + to:@END +main: from @BEGIN + (byte[256]) SCREEN#3 ← phi( @BEGIN/(byte[256]) SCREEN#0 ) + (byte) cnt#15 ← phi( @BEGIN/(byte) cnt#0 ) + call inccnt param-assignment + to:main::@1 +main::@1: from main + (byte[256]) SCREEN#1 ← phi( main/(byte[256]) SCREEN#3 ) + (byte) cnt#10 ← phi( main/(byte) cnt#8 ) + (byte) cnt#2 ← (byte) cnt#10 + *((byte[256]) SCREEN#1 + (byte) 0) ← (byte) cnt#2 + (byte) cnt#3 ← ++ (byte) cnt#2 + call inccnt param-assignment + to:main::@2 +main::@2: from main::@1 + (byte[256]) SCREEN#2 ← phi( main::@1/(byte[256]) SCREEN#1 ) + (byte) cnt#11 ← phi( main::@1/(byte) cnt#8 ) + (byte) cnt#4 ← (byte) cnt#11 + (byte) cnt#5 ← ++ (byte) cnt#4 + *((byte[256]) SCREEN#2 + (byte) 1) ← (byte) cnt#5 + to:main::@return +main::@return: from main::@2 + (byte) cnt#12 ← phi( main::@2/(byte) cnt#5 ) + (byte) cnt#6 ← (byte) cnt#12 + return + to:@RETURN +inccnt: from main main::@1 + (byte) cnt#13 ← phi( main/(byte) cnt#15 main::@1/(byte) cnt#3 ) + (byte) cnt#7 ← ++ (byte) cnt#13 + to:inccnt::@return +inccnt::@return: from inccnt + (byte) cnt#14 ← phi( inccnt/(byte) cnt#7 ) + (byte) cnt#8 ← (byte) cnt#14 + return + to:@RETURN +@END: from @3 + +Constant (byte) cnt#0 (byte) 0 +Constant (byte[256]) SCREEN#0 (word) 1024 +Succesful SSA optimization Pass2ConstantPropagation +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@3 +@3: from @BEGIN + (byte) cnt#9 ← phi( @BEGIN/(byte) cnt#6 ) + (byte) cnt#1 ← (byte) cnt#9 + to:@END +main: from @BEGIN + (byte[256]) SCREEN#3 ← phi( @BEGIN/(word) 1024 ) + (byte) cnt#15 ← phi( @BEGIN/(byte) 0 ) + call inccnt param-assignment + to:main::@1 +main::@1: from main + (byte[256]) SCREEN#1 ← phi( main/(byte[256]) SCREEN#3 ) + (byte) cnt#10 ← phi( main/(byte) cnt#8 ) + (byte) cnt#2 ← (byte) cnt#10 + *((byte[256]) SCREEN#1 + (byte) 0) ← (byte) cnt#2 + (byte) cnt#3 ← ++ (byte) cnt#2 + call inccnt param-assignment + to:main::@2 +main::@2: from main::@1 + (byte[256]) SCREEN#2 ← phi( main::@1/(byte[256]) SCREEN#1 ) + (byte) cnt#11 ← phi( main::@1/(byte) cnt#8 ) + (byte) cnt#4 ← (byte) cnt#11 + (byte) cnt#5 ← ++ (byte) cnt#4 + *((byte[256]) SCREEN#2 + (byte) 1) ← (byte) cnt#5 + to:main::@return +main::@return: from main::@2 + (byte) cnt#12 ← phi( main::@2/(byte) cnt#5 ) + (byte) cnt#6 ← (byte) cnt#12 + return + to:@RETURN +inccnt: from main main::@1 + (byte) cnt#13 ← phi( main/(byte) cnt#15 main::@1/(byte) cnt#3 ) + (byte) cnt#7 ← ++ (byte) cnt#13 + to:inccnt::@return +inccnt::@return: from inccnt + (byte) cnt#14 ← phi( inccnt/(byte) cnt#7 ) + (byte) cnt#8 ← (byte) cnt#14 + return + to:@RETURN +@END: from @3 + +Alias (byte) cnt#1 = (byte) cnt#9 (byte) cnt#6 (byte) cnt#12 (byte) cnt#5 +Alias (byte) cnt#10 = (byte) cnt#8 (byte) cnt#2 (byte) cnt#11 (byte) cnt#4 (byte) cnt#14 (byte) cnt#7 +Alias (byte[256]) SCREEN#1 = (byte[256]) SCREEN#3 (byte[256]) SCREEN#2 +Succesful SSA optimization Pass2AliasElimination +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@3 +@3: from @BEGIN + to:@END +main: from @BEGIN + (byte[256]) SCREEN#1 ← phi( @BEGIN/(word) 1024 ) + (byte) cnt#15 ← phi( @BEGIN/(byte) 0 ) + call inccnt param-assignment + to:main::@1 +main::@1: from main + *((byte[256]) SCREEN#1 + (byte) 0) ← (byte) cnt#10 + (byte) cnt#3 ← ++ (byte) cnt#10 + call inccnt param-assignment + to:main::@2 +main::@2: from main::@1 + (byte) cnt#1 ← ++ (byte) cnt#10 + *((byte[256]) SCREEN#1 + (byte) 1) ← (byte) cnt#1 + to:main::@return +main::@return: from main::@2 + return + to:@RETURN +inccnt: from main main::@1 + (byte) cnt#13 ← phi( main/(byte) cnt#15 main::@1/(byte) cnt#3 ) + (byte) cnt#10 ← ++ (byte) cnt#13 + to:inccnt::@return +inccnt::@return: from inccnt + return + to:@RETURN +@END: from @3 + +Redundant Phi (byte) cnt#15 (byte) 0 +Redundant Phi (byte[256]) SCREEN#1 (word) 1024 +Succesful SSA optimization Pass2RedundantPhiElimination +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@3 +@3: from @BEGIN + to:@END +main: from @BEGIN + call inccnt param-assignment + to:main::@1 +main::@1: from main + *((word) 1024 + (byte) 0) ← (byte) cnt#10 + (byte) cnt#3 ← ++ (byte) cnt#10 + call inccnt param-assignment + to:main::@2 +main::@2: from main::@1 + (byte) cnt#1 ← ++ (byte) cnt#10 + *((word) 1024 + (byte) 1) ← (byte) cnt#1 + to:main::@return +main::@return: from main::@2 + return + to:@RETURN +inccnt: from main main::@1 + (byte) cnt#13 ← phi( main/(byte) 0 main::@1/(byte) cnt#3 ) + (byte) cnt#10 ← ++ (byte) cnt#13 + to:inccnt::@return +inccnt::@return: from inccnt + return + to:@RETURN +@END: from @3 + +Culled Empty Block (label) @3 +Succesful SSA optimization Pass2CullEmptyBlocks +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + call inccnt param-assignment + to:main::@1 +main::@1: from main + *((word) 1024 + (byte) 0) ← (byte) cnt#10 + (byte) cnt#3 ← ++ (byte) cnt#10 + call inccnt param-assignment + to:main::@2 +main::@2: from main::@1 + (byte) cnt#1 ← ++ (byte) cnt#10 + *((word) 1024 + (byte) 1) ← (byte) cnt#1 + to:main::@return +main::@return: from main::@2 + return + to:@RETURN +inccnt: from main main::@1 + (byte) cnt#13 ← phi( main/(byte) 0 main::@1/(byte) cnt#3 ) + (byte) cnt#10 ← ++ (byte) cnt#13 + to:inccnt::@return +inccnt::@return: from inccnt + return + to:@RETURN +@END: from @BEGIN + +Consolidated assigned array index constant in assignment *(1024) +Consolidated assigned array index constant in assignment *(1025) +Succesful SSA optimization Pass2ConstantAdditionElimination +CONTROL FLOW GRAPH +@BEGIN: from + call main param-assignment + to:@END +main: from @BEGIN + call inccnt param-assignment + to:main::@1 +main::@1: from main + *((word) 1024) ← (byte) cnt#10 + (byte) cnt#3 ← ++ (byte) cnt#10 + call inccnt param-assignment + to:main::@2 +main::@2: from main::@1 + (byte) cnt#1 ← ++ (byte) cnt#10 + *((word) 1025) ← (byte) cnt#1 + to:main::@return +main::@return: from main::@2 + return + to:@RETURN +inccnt: from main main::@1 + (byte) cnt#13 ← phi( main/(byte) 0 main::@1/(byte) cnt#3 ) + (byte) cnt#10 ← ++ (byte) cnt#13 + to:inccnt::@return +inccnt::@return: from inccnt + return + to:@RETURN +@END: from @BEGIN + +Block Sequence Planned @BEGIN @END main main::@1 main::@2 main::@return inccnt inccnt::@return +Block Sequence Planned @BEGIN @END main main::@1 main::@2 main::@return inccnt inccnt::@return +CONTROL FLOW GRAPH - PHI LIFTED +@BEGIN: from + call main param-assignment + to:@END +@END: from @BEGIN +main: from @BEGIN + call inccnt param-assignment + to:main::@1 +main::@1: from main + *((word) 1024) ← (byte) cnt#10 + (byte) cnt#3 ← ++ (byte) cnt#10 + (byte~) cnt#16 ← (byte) cnt#3 + call inccnt param-assignment + to:main::@2 +main::@2: from main::@1 + (byte) cnt#1 ← ++ (byte) cnt#10 + *((word) 1025) ← (byte) cnt#1 + to:main::@return +main::@return: from main::@2 + return + to:@RETURN +inccnt: from main main::@1 + (byte) cnt#13 ← phi( main/(byte) 0 main::@1/(byte~) cnt#16 ) + (byte) cnt#10 ← ++ (byte) cnt#13 + to:inccnt::@return +inccnt::@return: from inccnt + return + to:@RETURN + +Propagating live ranges... +Propagating live ranges... +CONTROL FLOW GRAPH - LIVE RANGES +@BEGIN: from + [0] call main param-assignment [ ] + to:@END +@END: from @BEGIN +main: from @BEGIN + [1] call inccnt param-assignment [ cnt#10 ] + to:main::@1 +main::@1: from main + [2] *((word) 1024) ← (byte) cnt#10 [ cnt#10 ] + [3] (byte) cnt#3 ← ++ (byte) cnt#10 [ cnt#3 ] + [4] (byte~) cnt#16 ← (byte) cnt#3 [ cnt#16 ] + [5] call inccnt param-assignment [ cnt#10 ] + to:main::@2 +main::@2: from main::@1 + [6] (byte) cnt#1 ← ++ (byte) cnt#10 [ cnt#1 ] + [7] *((word) 1025) ← (byte) cnt#1 [ ] + to:main::@return +main::@return: from main::@2 + [8] return [ ] + to:@RETURN +inccnt: from main main::@1 + [9] (byte) cnt#13 ← phi( main/(byte) 0 main::@1/(byte~) cnt#16 ) [ cnt#13 ] + [10] (byte) cnt#10 ← ++ (byte) cnt#13 [ cnt#10 ] + to:inccnt::@return +inccnt::@return: from inccnt + [11] return [ cnt#10 ] + to:@RETURN + +Created 1 initial phi equivalence classes +Coalesced [4] cnt#16 ← cnt#3 +Coalesced down to 1 phi equivalence classes +Block Sequence Planned @BEGIN @END main main::@1 main::@2 main::@return inccnt inccnt::@return +Propagating live ranges... +Propagating live ranges... +CONTROL FLOW GRAPH - PHI MEM COALESCED +@BEGIN: from + [0] call main param-assignment [ ] + to:@END +@END: from @BEGIN +main: from @BEGIN + [1] call inccnt param-assignment [ cnt#10 ] + to:main::@1 +main::@1: from main + [2] *((word) 1024) ← (byte) cnt#10 [ cnt#10 ] + [3] (byte) cnt#3 ← ++ (byte) cnt#10 [ cnt#3 ] + [4] call inccnt param-assignment [ cnt#10 ] + to:main::@2 +main::@2: from main::@1 + [5] (byte) cnt#1 ← ++ (byte) cnt#10 [ cnt#1 ] + [6] *((word) 1025) ← (byte) cnt#1 [ ] + to:main::@return +main::@return: from main::@2 + [7] return [ ] + to:@RETURN +inccnt: from main main::@1 + [8] (byte) cnt#13 ← phi( main/(byte) 0 main::@1/(byte) cnt#3 ) [ cnt#13 ] + [9] (byte) cnt#10 ← ++ (byte) cnt#13 [ cnt#10 ] + to:inccnt::@return +inccnt::@return: from inccnt + [10] return [ cnt#10 ] + to:@RETURN + +CALL GRAPH +Calls in [] to 0:main +Calls in [main] to 1:inccnt 4:inccnt + +DOMINATORS +@BEGIN dominated by @BEGIN +@END dominated by @BEGIN @END +main dominated by @BEGIN main +main::@1 dominated by @BEGIN main::@1 main +main::@2 dominated by @BEGIN main::@2 main::@1 main +main::@return dominated by @BEGIN main::@return main::@2 main::@1 main +inccnt dominated by @BEGIN inccnt main +inccnt::@return dominated by inccnt::@return @BEGIN inccnt main + +NATURAL LOOPS + +Found 0 loops in scope [] +Found 0 loops in scope [main] +Found 0 loops in scope [inccnt] +NATURAL LOOPS WITH DEPTH + + +VARIABLE REGISTER WEIGHTS +(byte[256]) SCREEN +(byte) cnt +(byte) cnt#1 4.0 +(byte) cnt#10 1.6 +(byte) cnt#13 4.0 +(byte) cnt#3 4.0 +(void()) inccnt() +(void()) main() + +Initial phi equivalence classes +[ cnt#13 cnt#3 ] +Added variable cnt#1 to zero page equivalence class [ cnt#1 ] +Added variable cnt#10 to zero page equivalence class [ cnt#10 ] +Complete equivalence classes +[ cnt#13 cnt#3 ] +[ cnt#1 ] +[ cnt#10 ] +Allocated zp byte:2 to zp byte:2 [ cnt#13 cnt#3 ] +Allocated zp byte:3 to zp byte:3 [ cnt#1 ] +Allocated zp byte:4 to zp byte:4 [ cnt#10 ] +INITIAL ASM +//SEG0 @BEGIN +BBEGIN: +//SEG1 [0] call main param-assignment [ ] + jsr main + jmp BEND +//SEG2 @END +BEND: +//SEG3 main +main: +//SEG4 [1] call inccnt param-assignment [ cnt#10 ] +//SEG5 [8] phi from main to inccnt +inccnt_from_main: +//SEG6 [8] phi (byte) cnt#13 = (byte) 0 -- zpby1=coby1 + lda #0 + sta 2 + jsr inccnt + jmp main__B1 +//SEG7 main::@1 +main__B1: +//SEG8 [2] *((word) 1024) ← (byte) cnt#10 [ cnt#10 ] -- _star_cowo1=zpby1 + lda 4 + sta 1024 +//SEG9 [3] (byte) cnt#3 ← ++ (byte) cnt#10 [ cnt#3 ] -- zpby1=_inc_zpby2 + lda 4 + sta 2 + inc 2 +//SEG10 [4] call inccnt param-assignment [ cnt#10 ] +//SEG11 [8] phi from main::@1 to inccnt +inccnt_from_B1: +//SEG12 [8] phi (byte) cnt#13 = (byte) cnt#3 -- register_copy + jsr inccnt + jmp main__B2 +//SEG13 main::@2 +main__B2: +//SEG14 [5] (byte) cnt#1 ← ++ (byte) cnt#10 [ cnt#1 ] -- zpby1=_inc_zpby2 + lda 4 + sta 3 + inc 3 +//SEG15 [6] *((word) 1025) ← (byte) cnt#1 [ ] -- _star_cowo1=zpby1 + lda 3 + sta 1025 + jmp main__Breturn +//SEG16 main::@return +main__Breturn: +//SEG17 [7] return [ ] + rts +//SEG18 inccnt +inccnt: +//SEG19 [9] (byte) cnt#10 ← ++ (byte) cnt#13 [ cnt#10 ] -- zpby1=_inc_zpby2 + lda 2 + sta 4 + inc 4 + jmp inccnt__Breturn +//SEG20 inccnt::@return +inccnt__Breturn: +//SEG21 [10] return [ cnt#10 ] + rts + +REGISTER UPLIFT POTENTIAL REGISTERS +Potential registers zp byte:2 [ cnt#13 cnt#3 ] : zp byte:2 , reg byte a , reg byte x , reg byte y , +Potential registers zp byte:3 [ cnt#1 ] : zp byte:3 , reg byte a , reg byte x , reg byte y , +Potential registers zp byte:4 [ cnt#10 ] : zp byte:4 , reg byte a , reg byte x , reg byte y , + +REGISTER UPLIFT SCOPES +Uplift Scope [] 8: zp byte:2 [ cnt#13 cnt#3 ] 4: zp byte:3 [ cnt#1 ] 1.6: zp byte:4 [ cnt#10 ] +Uplift Scope [main] +Uplift Scope [inccnt] + +Uplifting [] best 61 combination reg byte x [ cnt#13 cnt#3 ] reg byte x [ cnt#1 ] reg byte x [ cnt#10 ] +Uplifting [main] best 61 combination +Uplifting [inccnt] best 61 combination +Removing instruction jmp BEND +Removing instruction jmp main__B1 +Removing instruction jmp main__B2 +Removing instruction jmp main__Breturn +Removing instruction jmp inccnt__Breturn +Succesful ASM optimization Pass5NextJumpElimination +ASSEMBLER +//SEG0 @BEGIN +BBEGIN: +//SEG1 [0] call main param-assignment [ ] + jsr main +//SEG2 @END +BEND: +//SEG3 main +main: +//SEG4 [1] call inccnt param-assignment [ cnt#10 ] +//SEG5 [8] phi from main to inccnt +inccnt_from_main: +//SEG6 [8] phi (byte) cnt#13 = (byte) 0 -- xby=coby1 + ldx #0 + jsr inccnt +//SEG7 main::@1 +main__B1: +//SEG8 [2] *((word) 1024) ← (byte) cnt#10 [ cnt#10 ] -- _star_cowo1=xby + stx 1024 +//SEG9 [3] (byte) cnt#3 ← ++ (byte) cnt#10 [ cnt#3 ] -- xby=_inc_xby + inx +//SEG10 [4] call inccnt param-assignment [ cnt#10 ] +//SEG11 [8] phi from main::@1 to inccnt +inccnt_from_B1: +//SEG12 [8] phi (byte) cnt#13 = (byte) cnt#3 -- register_copy + jsr inccnt +//SEG13 main::@2 +main__B2: +//SEG14 [5] (byte) cnt#1 ← ++ (byte) cnt#10 [ cnt#1 ] -- xby=_inc_xby + inx +//SEG15 [6] *((word) 1025) ← (byte) cnt#1 [ ] -- _star_cowo1=xby + stx 1025 +//SEG16 main::@return +main__Breturn: +//SEG17 [7] return [ ] + rts +//SEG18 inccnt +inccnt: +//SEG19 [9] (byte) cnt#10 ← ++ (byte) cnt#13 [ cnt#10 ] -- xby=_inc_xby + inx +//SEG20 inccnt::@return +inccnt__Breturn: +//SEG21 [10] return [ cnt#10 ] + rts + +FINAL SYMBOL TABLE +(label) @BEGIN +(label) @END +(byte[256]) SCREEN +(byte) cnt +(byte) cnt#1 reg byte x 4.0 +(byte) cnt#10 reg byte x 1.6 +(byte) cnt#13 reg byte x 4.0 +(byte) cnt#3 reg byte x 4.0 +(void()) inccnt() +(label) inccnt::@return +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@return + +reg byte x [ cnt#13 cnt#3 ] +reg byte x [ cnt#1 ] +reg byte x [ cnt#10 ] + +FINAL CODE +//SEG0 @BEGIN +BBEGIN: +//SEG1 [0] call main param-assignment [ ] + jsr main +//SEG2 @END +BEND: +//SEG3 main +main: +//SEG4 [1] call inccnt param-assignment [ cnt#10 ] +//SEG5 [8] phi from main to inccnt +inccnt_from_main: +//SEG6 [8] phi (byte) cnt#13 = (byte) 0 -- xby=coby1 + ldx #0 + jsr inccnt +//SEG7 main::@1 +main__B1: +//SEG8 [2] *((word) 1024) ← (byte) cnt#10 [ cnt#10 ] -- _star_cowo1=xby + stx 1024 +//SEG9 [3] (byte) cnt#3 ← ++ (byte) cnt#10 [ cnt#3 ] -- xby=_inc_xby + inx +//SEG10 [4] call inccnt param-assignment [ cnt#10 ] +//SEG11 [8] phi from main::@1 to inccnt +inccnt_from_B1: +//SEG12 [8] phi (byte) cnt#13 = (byte) cnt#3 -- register_copy + jsr inccnt +//SEG13 main::@2 +main__B2: +//SEG14 [5] (byte) cnt#1 ← ++ (byte) cnt#10 [ cnt#1 ] -- xby=_inc_xby + inx +//SEG15 [6] *((word) 1025) ← (byte) cnt#1 [ ] -- _star_cowo1=xby + stx 1025 +//SEG16 main::@return +main__Breturn: +//SEG17 [7] return [ ] + rts +//SEG18 inccnt +inccnt: +//SEG19 [9] (byte) cnt#10 ← ++ (byte) cnt#13 [ cnt#10 ] -- xby=_inc_xby + inx +//SEG20 inccnt::@return +inccnt__Breturn: +//SEG21 [10] return [ cnt#10 ] + rts + diff --git a/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.sym b/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.sym new file mode 100644 index 000000000..0ccd4a4be --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/test/ref/modglobalmin.sym @@ -0,0 +1,18 @@ +(label) @BEGIN +(label) @END +(byte[256]) SCREEN +(byte) cnt +(byte) cnt#1 reg byte x 4.0 +(byte) cnt#10 reg byte x 1.6 +(byte) cnt#13 reg byte x 4.0 +(byte) cnt#3 reg byte x 4.0 +(void()) inccnt() +(label) inccnt::@return +(void()) main() +(label) main::@1 +(label) main::@2 +(label) main::@return + +reg byte x [ cnt#13 cnt#3 ] +reg byte x [ cnt#1 ] +reg byte x [ cnt#10 ]