From 5fec69e3f182b746bdfb38fd400e102d7efd8f9b Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Mon, 26 Jul 2021 12:15:15 +0200 Subject: [PATCH] Working on classic structs. #197 --- .../cache/fragment-cache-mos6502x.asm | 201 ++++----- .../java/dk/camelot64/kickc/Compiler.java | 18 +- .../kickc/passes/Pass1UnwindStructValues.java | 2 + .../passes/unwinding/ValueSourceVariable.java | 13 + src/test/kc/intermediates-struct.c | 2 +- src/test/ref/intermediates-struct.asm | 44 +- src/test/ref/intermediates-struct.cfg | 17 +- src/test/ref/intermediates-struct.log | 395 +++++++++--------- src/test/ref/intermediates-struct.sym | 32 +- src/test/ref/struct-23.log | 52 ++- src/test/ref/struct-5.log | 34 +- src/test/ref/struct-ptr-16.cfg | 12 +- src/test/ref/struct-ptr-16.log | 130 +++--- src/test/ref/struct-ptr-16.sym | 8 +- src/test/ref/struct-ptr-17.log | 54 ++- src/test/ref/tod-1.cfg | 16 +- src/test/ref/tod-1.log | 222 +++++----- src/test/ref/tod-1.sym | 16 +- 18 files changed, 635 insertions(+), 633 deletions(-) diff --git a/src/main/fragment/cache/fragment-cache-mos6502x.asm b/src/main/fragment/cache/fragment-cache-mos6502x.asm index 4446c2212..ea5a2791c 100644 --- a/src/main/fragment/cache/fragment-cache-mos6502x.asm +++ b/src/main/fragment/cache/fragment-cache-mos6502x.asm @@ -3161,6 +3161,30 @@ iny inx cpx #{c3} bne !- +//FRAGMENT vwuz1=_deref_pwuc1 +lda {c1} +sta {z1} +lda {c1}+1 +sta {z1}+1 +//FRAGMENT vbuz1=_deref_pbuz2 +ldy #0 +lda ({z2}),y +sta {z1} +//FRAGMENT vbuaa=_deref_pbuz1 +ldy #0 +lda ({z1}),y +//FRAGMENT vbuxx=_deref_pbuz1 +ldy #0 +lda ({z1}),y +tax +//FRAGMENT vbuyy=_deref_pbuz1 +ldy #0 +lda ({z1}),y +tay +//FRAGMENT pbuz1_derefidx_vbuxx=vbuxx +txa +tay +sta ({z1}),y //FRAGMENT _deref_pbuc1=_byte_pprz1 lda {z1} sta {c1} @@ -3190,21 +3214,6 @@ lda {z1} sta {c1} lda {z1}+1 sta {c1}+1 -//FRAGMENT vbuz1=_deref_pbuz2 -ldy #0 -lda ({z2}),y -sta {z1} -//FRAGMENT vbuaa=_deref_pbuz1 -ldy #0 -lda ({z1}),y -//FRAGMENT vbuxx=_deref_pbuz1 -ldy #0 -lda ({z1}),y -tax -//FRAGMENT vbuyy=_deref_pbuz1 -ldy #0 -lda ({z1}),y -tay //FRAGMENT vbuz1=vbuz2_plus_vbuz2 lda {z2} asl @@ -3985,10 +3994,6 @@ sta ({z1}),y tay txa sta ({z1}),y -//FRAGMENT pbuz1_derefidx_vbuxx=vbuxx -txa -tay -sta ({z1}),y //FRAGMENT pbuz1_derefidx_vbuaa=vbuyy sta $ff tya @@ -8647,11 +8652,6 @@ bcs {la1} cpx #{c1} bcc {la1} beq {la1} -//FRAGMENT vwuz1=_deref_pwuc1 -lda {c1} -sta {z1} -lda {c1}+1 -sta {z1}+1 //FRAGMENT pbuc1_derefidx_vbuz1_eq_vbuz2_then_la1 ldy {z1} lda {c1},y @@ -11875,6 +11875,28 @@ iny lda #{c1} sty {z1}+1 sta {z1} +//FRAGMENT vduz1=vduc1_minus__deref_pduc2 +lda #<{c1} +sec +sbc {c2} +sta {z1} +lda #>{c1} +sbc {c2}+1 +sta {z1}+1 +lda #<{c1}>>$10 +sbc {c2}+2 +sta {z1}+2 +lda #>{c1}>>$10 +sbc {c2}+3 +sta {z1}+3 +//FRAGMENT pbuz1=pbuz2_plus_1 +clc +lda {z2} +adc #1 +sta {z1} +lda {z2}+1 +adc #0 +sta {z1}+1 //FRAGMENT vbuz1=_deref_pbuc1_ror_1 lda {c1} lsr @@ -12312,14 +12334,6 @@ sta {z1} //FRAGMENT vbsz1_lt_0_then_la1 lda {z1} bmi {la1} -//FRAGMENT pbuz1=pbuz2_plus_1 -clc -lda {z2} -adc #1 -sta {z1} -lda {z2}+1 -adc #0 -sta {z1}+1 //FRAGMENT vbsaa=pbsc1_derefidx_vbuz1 ldy {z1} lda {c1},y @@ -14943,6 +14957,20 @@ sta ($fe),y iny lda ({z1}),y sta ($fe),y +//FRAGMENT vduz1=vduz2_minus_vduc1 +lda {z2} +sec +sbc #<{c1} +sta {z1} +lda {z2}+1 +sbc #>{c1} +sta {z1}+1 +lda {z2}+2 +sbc #<{c1}>>$10 +sta {z1}+2 +lda {z2}+3 +sbc #>{c1}>>$10 +sta {z1}+3 //FRAGMENT vbsz1_le_vbsc1_then_la1 lda #{c1} sec @@ -14993,6 +15021,37 @@ sta {z1} lda {z2}+1 sbc #0 sta {z1}+1 +//FRAGMENT vwuz1=vwuc1_plus_vbuz2 +lda {z2} +clc +adc #<{c1} +sta {z1} +lda #>{c1} +adc #0 +sta {z1}+1 +//FRAGMENT vwuz1=vwuc1_plus_vbuaa +clc +adc #<{c1} +sta {z1} +lda #>{c1} +adc #0 +sta {z1}+1 +//FRAGMENT vwuz1=vwuc1_plus_vbuxx +txa +clc +adc #<{c1} +sta {z1} +lda #>{c1} +adc #0 +sta {z1}+1 +//FRAGMENT vwuz1=vwuc1_plus_vbuyy +tya +clc +adc #<{c1} +sta {z1} +lda #>{c1} +adc #0 +sta {z1}+1 //FRAGMENT pbuz1=pbuz1_plus_vbuz2 lda {z2} clc @@ -15206,81 +15265,3 @@ sta {c1},x lda #{c2} ora {c1},y sta {c1},y -//FRAGMENT vduz1=vduc1_minus__deref_pduc2 -lda #<{c1} -sec -sbc {c2} -sta {z1} -lda #>{c1} -sbc {c2}+1 -sta {z1}+1 -lda #<{c1}>>$10 -sbc {c2}+2 -sta {z1}+2 -lda #>{c1}>>$10 -sbc {c2}+3 -sta {z1}+3 -//FRAGMENT vduz1=vduz2_minus_vduc1 -lda {z2} -sec -sbc #<{c1} -sta {z1} -lda {z2}+1 -sbc #>{c1} -sta {z1}+1 -lda {z2}+2 -sbc #<{c1}>>$10 -sta {z1}+2 -lda {z2}+3 -sbc #>{c1}>>$10 -sta {z1}+3 -//FRAGMENT vwuz1=vwuc1_plus_vbuz2 -lda {z2} -clc -adc #<{c1} -sta {z1} -lda #>{c1} -adc #0 -sta {z1}+1 -//FRAGMENT vwuz1=vwuc1_plus_vbuaa -clc -adc #<{c1} -sta {z1} -lda #>{c1} -adc #0 -sta {z1}+1 -//FRAGMENT vwuz1=vwuc1_plus_vbuxx -txa -clc -adc #<{c1} -sta {z1} -lda #>{c1} -adc #0 -sta {z1}+1 -//FRAGMENT vwuz1=vwuc1_plus_vbuyy -tya -clc -adc #<{c1} -sta {z1} -lda #>{c1} -adc #0 -sta {z1}+1 -//FRAGMENT vbuz1=_deref_pbuc1_plus__deref_pbuc2 -lda {c1} -clc -adc {c2} -sta {z1} -//FRAGMENT vbuaa=_deref_pbuc1_plus__deref_pbuc2 -lda {c1} -clc -adc {c2} -//FRAGMENT vbuxx=_deref_pbuc1_plus__deref_pbuc2 -lda {c1} -clc -adc {c2} -tax -//FRAGMENT vbuyy=_deref_pbuc1_plus__deref_pbuc2 -lda {c1} -clc -adc {c2} -tay diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 754b511b5..379073f12 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -248,11 +248,9 @@ public class Compiler { new PassNAssertTypeMatch(program).check(); - if(!program.getTargetPlatform().getVariableBuilderConfig().isStructModelClassic()) { - new Pass1UnwindStructPrepare(program).execute(); - new Pass1UnwindStructVariables(program).execute(); - new Pass1UnwindStructValues(program).execute(); - } + new Pass1UnwindStructPrepare(program).execute(); + new Pass1UnwindStructVariables(program).execute(); + new Pass1UnwindStructValues(program).execute(); if(getLog().isVerbosePass1CreateSsa()) { getLog().append("CONTROL FLOW GRAPH AFTER UNWIND"); @@ -314,9 +312,7 @@ public class Compiler { new Pass1CallPhiReturn(program).execute(); new PassNUnwindLValueLists(program).execute(); - if(!program.getTargetPlatform().getVariableBuilderConfig().isStructModelClassic()) { - new PassNStructUnwoundPlaceholderRemoval(program).execute(); - } + new PassNStructUnwoundPlaceholderRemoval(program).execute(); getLog().append("\nCONTROL FLOW GRAPH SSA"); getLog().append(program.getGraph().toString(program)); @@ -552,10 +548,8 @@ public class Compiler { private void pass3Analysis() { - if(program.getTargetPlatform().getVariableBuilderConfig().isStructModelClassic()) { - new Pass1UnwindStructValues(program).execute(); - new PassNStructUnwoundPlaceholderRemoval(program).execute(); - } + new Pass1UnwindStructValues(program).execute(); + new PassNStructUnwoundPlaceholderRemoval(program).execute(); if(getLog().isVerboseSizeInfo()) { getLog().append(program.getSizeInfo()); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java index e7714e304..e3f5d6e5b 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1UnwindStructValues.java @@ -281,6 +281,8 @@ public class Pass1UnwindStructValues extends Pass1Base { public static boolean copyValues(ValueSource lValueSource, ValueSource rValueSource, List lValueUnwoundList, boolean initialAssignment, Statement currentStmt, ControlFlowBlock currentBlock, ListIterator stmtIt, Program program) { if(lValueSource == null || rValueSource == null) return false; + if(lValueSource.equals(rValueSource)) + return true; if(lValueSource.isSimple() && rValueSource.isSimple()) { stmtIt.previous(); LValue lValueRef = (LValue) lValueSource.getSimpleValue(program.getScope()); diff --git a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceVariable.java b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceVariable.java index fd52eaa13..d16fcb330 100644 --- a/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceVariable.java +++ b/src/main/java/dk/camelot64/kickc/passes/unwinding/ValueSourceVariable.java @@ -17,6 +17,7 @@ import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.passes.utils.SizeOfConstants; import java.util.ListIterator; +import java.util.Objects; /** Value Source for a variable */ public class ValueSourceVariable extends ValueSourceBase { @@ -107,4 +108,16 @@ public class ValueSourceVariable extends ValueSourceBase { } } + @Override + public boolean equals(Object o) { + if(this == o) return true; + if(o == null || getClass() != o.getClass()) return false; + ValueSourceVariable that = (ValueSourceVariable) o; + return variable.equals(that.variable); + } + + @Override + public int hashCode() { + return Objects.hash(variable); + } } \ No newline at end of file diff --git a/src/test/kc/intermediates-struct.c b/src/test/kc/intermediates-struct.c index f266ce744..cb821b878 100644 --- a/src/test/kc/intermediates-struct.c +++ b/src/test/kc/intermediates-struct.c @@ -1,6 +1,6 @@ // Test intermediate vars -// #pragma struct_model(classic) +#pragma struct_model(classic) char * const SCREEN = (char*)0x0400; char idx = 0; diff --git a/src/test/ref/intermediates-struct.asm b/src/test/ref/intermediates-struct.asm index a74e62574..9987243dd 100644 --- a/src/test/ref/intermediates-struct.asm +++ b/src/test/ref/intermediates-struct.asm @@ -7,34 +7,64 @@ .segmentdef Data [startAfter="Code"] .segment Basic :BasicUpstart(main) + .const SIZEOF_STRUCT_DATA = 2 .const OFFSET_STRUCT_DATA_D = 1 - // #pragma struct_model(classic) .label SCREEN = $400 .segment Code main: { + .label x = 2 + .label __0 = 4 + .label y = 6 + .label __1 = 8 // sum(1,2) ldx #2 lda #1 jsr sum // sum(1,2) - txa + ldy #SIZEOF_STRUCT_DATA + !: + lda sum.return-1,y + sta __0-1,y + dey + bne !- // struct Data x = sum(1,2) + ldy #SIZEOF_STRUCT_DATA + !: + lda __0-1,y + sta x-1,y + dey + bne !- // SCREEN[idx++] = x.c + lda.z x sta SCREEN // sum(3, 4) ldx #4 lda #3 jsr sum // sum(3, 4) + ldy #SIZEOF_STRUCT_DATA + !: + lda sum.return-1,y + sta __1-1,y + dey + bne !- // struct Data y = sum(3, 4) + ldy #SIZEOF_STRUCT_DATA + !: + lda __1-1,y + sta y-1,y + dey + bne !- // SCREEN[idx++] = y.d + lda y+OFFSET_STRUCT_DATA_D sta SCREEN+1 // } rts } // sum(byte register(A) a, byte register(X) b) sum: { - .label d = 2 + .label return = $a + .label d = $c // a+b stx.z $ff clc @@ -43,8 +73,12 @@ sum: { sta.z d stx d+OFFSET_STRUCT_DATA_D // return d; - tax - lda d+OFFSET_STRUCT_DATA_D + ldy #SIZEOF_STRUCT_DATA + !: + lda d-1,y + sta return-1,y + dey + bne !- // } rts } diff --git a/src/test/ref/intermediates-struct.cfg b/src/test/ref/intermediates-struct.cfg index 323d180d3..dc9a86280 100644 --- a/src/test/ref/intermediates-struct.cfg +++ b/src/test/ref/intermediates-struct.cfg @@ -3,17 +3,17 @@ void main() main: scope:[main] from [0] phi() [1] call sum - [2] sum::return_c#0 = sum::return_c#2 to:main::@1 main::@1: scope:[main] from main - [3] main::x_c#0 = sum::return_c#0 - [4] *SCREEN = main::x_c#0 + [2] *(&main::$0) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) + [3] *(&main::x) = memcpy(*(&main::$0), struct Data, SIZEOF_STRUCT_DATA) + [4] *SCREEN = *((byte*)&main::x) [5] call sum - [6] sum::return_d#1 = sum::return_d#2 to:main::@2 main::@2: scope:[main] from main::@1 - [7] main::y_d#0 = sum::return_d#1 - [8] *(SCREEN+1) = main::y_d#0 + [6] *(&main::$1) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) + [7] *(&main::y) = memcpy(*(&main::$1), struct Data, SIZEOF_STRUCT_DATA) + [8] *(SCREEN+1) = *((byte*)&main::y+OFFSET_STRUCT_DATA_D) to:main::@return main::@return: scope:[main] from main::@2 [9] return @@ -26,9 +26,8 @@ sum: scope:[sum] from main main::@1 [11] sum::$0 = sum::a#2 + sum::b#2 [12] *((byte*)&sum::d) = sum::$0 [13] *((byte*)&sum::d+OFFSET_STRUCT_DATA_D) = sum::b#2 - [14] sum::return_c#2 = *((byte*)&sum::d) - [15] sum::return_d#2 = *((byte*)&sum::d+OFFSET_STRUCT_DATA_D) + [14] *(&sum::return) = memcpy(*(&sum::d), struct Data, SIZEOF_STRUCT_DATA) to:sum::@return sum::@return: scope:[sum] from sum - [16] return + [15] return to:@return diff --git a/src/test/ref/intermediates-struct.log b/src/test/ref/intermediates-struct.log index 4e71d9860..534348701 100644 --- a/src/test/ref/intermediates-struct.log +++ b/src/test/ref/intermediates-struct.log @@ -1,11 +1,9 @@ Inlined call call __init -Eliminating unused variable with no statement main::$0 -Eliminating unused variable with no statement main::$1 -Unwinding list assignment { main::$0_c, main::$0_d } = { sum::return_c, sum::return_d } -Unwinding list assignment { main::$1_c, main::$1_d } = { sum::return_c, sum::return_d } -Unwinding list assignment { sum::return_c#0, sum::return_d#0 } = { sum::return_c#3, sum::return_d#3 } -Unwinding list assignment { sum::return_c#1, sum::return_d#1 } = { sum::return_c#3, sum::return_d#3 } +Removing C-classic struct-unwound assignment main::x = struct-unwound {*(&main::x)} +Removing C-classic struct-unwound assignment main::y = struct-unwound {*(&main::y)} Removing C-classic struct-unwound assignment sum::d = struct-unwound {*((byte*)&sum::d+OFFSET_STRUCT_DATA_C), *((byte*)&sum::d+OFFSET_STRUCT_DATA_D)} +Removing C-classic struct-unwound assignment sum::return = struct-unwound {*(&sum::return)} +Removing C-classic struct-unwound assignment sum::return = struct-unwound {} CONTROL FLOW GRAPH SSA @@ -15,32 +13,24 @@ main: scope:[main] from __start::@1 sum::a#0 = 1 sum::b#0 = 2 call sum - sum::return_c#0 = sum::return_c#3 - sum::return_d#0 = sum::return_d#3 + sum::return = sum::return to:main::@1 main::@1: scope:[main] from main idx#6 = phi( main/idx#11 ) - sum::return_d#4 = phi( main/sum::return_d#0 ) - sum::return_c#4 = phi( main/sum::return_c#0 ) - main::$0_c = sum::return_c#4 - main::$0_d = sum::return_d#4 - main::x_c#0 = main::$0_c - SCREEN[idx#6] = main::x_c#0 + main::$0 = sum::return + *(&main::x) = memcpy(*(&main::$0), struct Data, SIZEOF_STRUCT_DATA) + SCREEN[idx#6] = *((byte*)&main::x+OFFSET_STRUCT_DATA_C) idx#0 = ++ idx#6 sum::a#1 = 3 sum::b#1 = 4 call sum - sum::return_c#1 = sum::return_c#3 - sum::return_d#1 = sum::return_d#3 + sum::return = sum::return to:main::@2 main::@2: scope:[main] from main::@1 idx#7 = phi( main::@1/idx#0 ) - sum::return_d#5 = phi( main::@1/sum::return_d#1 ) - sum::return_c#5 = phi( main::@1/sum::return_c#1 ) - main::$1_c = sum::return_c#5 - main::$1_d = sum::return_d#5 - main::y_d#0 = main::$1_d - SCREEN[idx#7] = main::y_d#0 + main::$1 = sum::return + *(&main::y) = memcpy(*(&main::$1), struct Data, SIZEOF_STRUCT_DATA) + SCREEN[idx#7] = *((byte*)&main::y+OFFSET_STRUCT_DATA_D) idx#1 = ++ idx#7 to:main::@return main::@return: scope:[main] from main::@2 @@ -56,16 +46,9 @@ sum: scope:[sum] from main main::@1 sum::$0 = sum::a#2 + sum::b#2 *((byte*)&sum::d+OFFSET_STRUCT_DATA_C) = sum::$0 *((byte*)&sum::d+OFFSET_STRUCT_DATA_D) = sum::b#2 - sum::return_c#2 = *((byte*)&sum::d+OFFSET_STRUCT_DATA_C) - sum::return_d#2 = *((byte*)&sum::d+OFFSET_STRUCT_DATA_D) - sum::return#0 = struct-unwound {sum::return_c#2, sum::return_d#2} + *(&sum::return) = memcpy(*(&sum::d), struct Data, SIZEOF_STRUCT_DATA) to:sum::@return sum::@return: scope:[sum] from sum - sum::return_d#6 = phi( sum/sum::return_d#2 ) - sum::return_c#6 = phi( sum/sum::return_c#2 ) - sum::return_c#3 = sum::return_c#6 - sum::return_d#3 = sum::return_d#6 - sum::return#1 = struct-unwound {sum::return_c#3, sum::return_d#3} return to:@return @@ -93,6 +76,7 @@ SYMBOL TABLE SSA constant byte OFFSET_STRUCT_DATA_C = 0 constant byte OFFSET_STRUCT_DATA_D = 1 constant byte* const SCREEN = (byte*)$400 +constant byte SIZEOF_STRUCT_DATA = 2 void __start() byte idx byte idx#0 @@ -109,14 +93,10 @@ byte idx#7 byte idx#8 byte idx#9 void main() -byte~ main::$0_c -byte~ main::$0_d -byte~ main::$1_c -byte~ main::$1_d -byte main::x_c -byte main::x_c#0 -byte main::y_d -byte main::y_d#0 +struct Data~ main::$0 +struct Data~ main::$1 +struct Data main::x loadstore +struct Data main::y loadstore struct Data sum(byte sum::a , byte sum::b) byte~ sum::$0 byte sum::a @@ -128,25 +108,7 @@ byte sum::b#0 byte sum::b#1 byte sum::b#2 struct Data sum::d loadstore -struct Data sum::return -struct Data sum::return#0 -struct Data sum::return#1 -byte sum::return_c -byte sum::return_c#0 -byte sum::return_c#1 -byte sum::return_c#2 -byte sum::return_c#3 -byte sum::return_c#4 -byte sum::return_c#5 -byte sum::return_c#6 -byte sum::return_d -byte sum::return_d#0 -byte sum::return_d#1 -byte sum::return_d#2 -byte sum::return_d#3 -byte sum::return_d#4 -byte sum::return_d#5 -byte sum::return_d#6 +struct Data sum::return loadstore Adding number conversion cast (unumber) 1 in sum::a#0 = 1 Adding number conversion cast (unumber) 2 in sum::b#0 = 2 @@ -169,17 +131,9 @@ Finalized unsigned number type (byte) 2 Finalized unsigned number type (byte) 3 Finalized unsigned number type (byte) 4 Successful SSA optimization PassNFinalizeNumberTypeConversions -Alias sum::return_c#0 = sum::return_c#4 -Alias sum::return_d#0 = sum::return_d#4 Alias idx#11 = idx#6 -Alias main::x_c#0 = main::$0_c -Alias sum::return_c#1 = sum::return_c#5 -Alias sum::return_d#1 = sum::return_d#5 Alias idx#0 = idx#7 -Alias main::y_d#0 = main::$1_d Alias idx#1 = idx#8 idx#2 -Alias sum::return_c#2 = sum::return_c#6 sum::return_c#3 -Alias sum::return_d#2 = sum::return_d#6 sum::return_d#3 Alias idx#12 = idx#3 Alias idx#10 = idx#4 idx#9 idx#5 Successful SSA optimization Pass2AliasElimination @@ -192,20 +146,13 @@ Constant sum::a#1 = 3 Constant sum::b#1 = 4 Constant idx#12 = 0 Successful SSA optimization Pass2ConstantIdentification -Simplifying expression containing zero SCREEN in [8] SCREEN[idx#12] = main::x_c#0 -Simplifying expression containing zero (byte*)&sum::d in [22] *((byte*)&sum::d+OFFSET_STRUCT_DATA_C) = sum::$0 -Simplifying expression containing zero (byte*)&sum::d in [24] sum::return_c#2 = *((byte*)&sum::d+OFFSET_STRUCT_DATA_C) +Simplifying expression containing zero (byte*)&main::x in [7] SCREEN[idx#12] = *((byte*)&main::x+OFFSET_STRUCT_DATA_C) +Simplifying expression containing zero SCREEN in [7] SCREEN[idx#12] = *((byte*)&main::x) +Simplifying expression containing zero (byte*)&sum::d in [20] *((byte*)&sum::d+OFFSET_STRUCT_DATA_C) = sum::$0 Successful SSA optimization PassNSimplifyExpressionWithZero -Eliminating unused variable main::$0_d and assignment [4] main::$0_d = sum::return_d#0 -Eliminating unused variable main::$1_c and assignment [10] main::$1_c = sum::return_c#1 -Eliminating unused variable idx#1 and assignment [13] idx#1 = ++ idx#0 -Eliminating unused variable sum::return#0 and assignment [21] sum::return#0 = struct-unwound {sum::return_c#2, sum::return_d#2} -Eliminating unused variable sum::return#1 and assignment [22] sum::return#1 = struct-unwound {sum::return_c#2, sum::return_d#2} +Eliminating unused variable idx#1 and assignment [11] idx#1 = ++ idx#0 Eliminating unused constant OFFSET_STRUCT_DATA_C Successful SSA optimization PassNEliminateUnusedVars -Eliminating unused variable sum::return_d#0 and assignment [2] sum::return_d#0 = sum::return_d#2 -Eliminating unused variable sum::return_c#1 and assignment [7] sum::return_c#1 = sum::return_c#2 -Successful SSA optimization PassNEliminateUnusedVars Removing unused procedure __start Removing unused procedure block __start Removing unused procedure block __start::__init1 @@ -213,7 +160,7 @@ Removing unused procedure block __start::@1 Removing unused procedure block __start::@2 Removing unused procedure block __start::@return Successful SSA optimization PassNEliminateEmptyStart -Constant right-side identified [4] idx#0 = ++ idx#12 +Constant right-side identified [5] idx#0 = ++ idx#12 Successful SSA optimization Pass2ConstantRValueConsolidation Constant idx#0 = ++idx#12 Successful SSA optimization Pass2ConstantIdentification @@ -234,6 +181,10 @@ Consolidated array index constant in *(SCREEN+++0) Successful SSA optimization Pass2ConstantAdditionElimination Simplifying constant integer increment ++0 Successful SSA optimization Pass2ConstantSimplification +Removing C-classic struct-unwound assignment sum::return = struct-unwound {} +Removing C-classic struct-unwound assignment main::$0 = struct-unwound {*(&main::$0)} +Removing C-classic struct-unwound assignment sum::return = struct-unwound {} +Removing C-classic struct-unwound assignment main::$1 = struct-unwound {*(&main::$1)} Adding NOP phi() at start of main CALL GRAPH Calls in [main] to sum:1 sum:5 @@ -248,17 +199,17 @@ void main() main: scope:[main] from [0] phi() [1] call sum - [2] sum::return_c#0 = sum::return_c#2 to:main::@1 main::@1: scope:[main] from main - [3] main::x_c#0 = sum::return_c#0 - [4] *SCREEN = main::x_c#0 + [2] *(&main::$0) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) + [3] *(&main::x) = memcpy(*(&main::$0), struct Data, SIZEOF_STRUCT_DATA) + [4] *SCREEN = *((byte*)&main::x) [5] call sum - [6] sum::return_d#1 = sum::return_d#2 to:main::@2 main::@2: scope:[main] from main::@1 - [7] main::y_d#0 = sum::return_d#1 - [8] *(SCREEN+1) = main::y_d#0 + [6] *(&main::$1) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) + [7] *(&main::y) = memcpy(*(&main::$1), struct Data, SIZEOF_STRUCT_DATA) + [8] *(SCREEN+1) = *((byte*)&main::y+OFFSET_STRUCT_DATA_D) to:main::@return main::@return: scope:[main] from main::@2 [9] return @@ -271,21 +222,20 @@ sum: scope:[sum] from main main::@1 [11] sum::$0 = sum::a#2 + sum::b#2 [12] *((byte*)&sum::d) = sum::$0 [13] *((byte*)&sum::d+OFFSET_STRUCT_DATA_D) = sum::b#2 - [14] sum::return_c#2 = *((byte*)&sum::d) - [15] sum::return_d#2 = *((byte*)&sum::d+OFFSET_STRUCT_DATA_D) + [14] *(&sum::return) = memcpy(*(&sum::d), struct Data, SIZEOF_STRUCT_DATA) to:sum::@return sum::@return: scope:[sum] from sum - [16] return + [15] return to:@return VARIABLE REGISTER WEIGHTS byte idx void main() -byte main::x_c -byte main::x_c#0 4.0 -byte main::y_d -byte main::y_d#0 4.0 +struct Data~ main::$0 +struct Data~ main::$1 +struct Data main::x loadstore +struct Data main::y loadstore struct Data sum(byte sum::a , byte sum::b) byte~ sum::$0 22.0 byte sum::a @@ -293,79 +243,81 @@ byte sum::a#2 11.0 byte sum::b byte sum::b#2 7.333333333333333 struct Data sum::d loadstore -struct Data sum::return -byte sum::return_c -byte sum::return_c#0 4.0 -byte sum::return_c#2 3.25 -byte sum::return_d -byte sum::return_d#1 4.0 -byte sum::return_d#2 4.333333333333333 +struct Data sum::return loadstore Initial phi equivalence classes [ sum::a#2 ] [ sum::b#2 ] -Added variable sum::return_c#0 to live range equivalence class [ sum::return_c#0 ] -Added variable main::x_c#0 to live range equivalence class [ main::x_c#0 ] -Added variable sum::return_d#1 to live range equivalence class [ sum::return_d#1 ] -Added variable main::y_d#0 to live range equivalence class [ main::y_d#0 ] Added variable sum::$0 to live range equivalence class [ sum::$0 ] -Added variable sum::return_c#2 to live range equivalence class [ sum::return_c#2 ] -Added variable sum::return_d#2 to live range equivalence class [ sum::return_d#2 ] +Added variable main::x to live range equivalence class [ main::x ] +Added variable main::$0 to live range equivalence class [ main::$0 ] +Added variable main::y to live range equivalence class [ main::y ] +Added variable main::$1 to live range equivalence class [ main::$1 ] +Added variable sum::return to live range equivalence class [ sum::return ] Added variable sum::d to live range equivalence class [ sum::d ] Complete equivalence classes [ sum::a#2 ] [ sum::b#2 ] -[ sum::return_c#0 ] -[ main::x_c#0 ] -[ sum::return_d#1 ] -[ main::y_d#0 ] [ sum::$0 ] -[ sum::return_c#2 ] -[ sum::return_d#2 ] +[ main::x ] +[ main::$0 ] +[ main::y ] +[ main::$1 ] +[ sum::return ] [ sum::d ] Allocated zp[1]:2 [ sum::a#2 ] Allocated zp[1]:3 [ sum::b#2 ] -Allocated zp[1]:4 [ sum::return_c#0 ] -Allocated zp[1]:5 [ main::x_c#0 ] -Allocated zp[1]:6 [ sum::return_d#1 ] -Allocated zp[1]:7 [ main::y_d#0 ] -Allocated zp[1]:8 [ sum::$0 ] -Allocated zp[1]:9 [ sum::return_c#2 ] -Allocated zp[1]:10 [ sum::return_d#2 ] -Allocated zp[2]:11 [ sum::d ] +Allocated zp[1]:4 [ sum::$0 ] +Allocated zp[2]:5 [ main::x ] +Allocated zp[2]:7 [ main::$0 ] +Allocated zp[2]:9 [ main::y ] +Allocated zp[2]:11 [ main::$1 ] +Allocated zp[2]:13 [ sum::return ] +Allocated zp[2]:15 [ sum::d ] REGISTER UPLIFT POTENTIAL REGISTERS -Statement [11] sum::$0 = sum::a#2 + sum::b#2 [ sum::b#2 sum::$0 sum::d ] ( sum:1 [ sum::b#2 sum::$0 sum::d ] { { sum::return_c#0 = sum::return_c#2 } } sum:5 [ sum::b#2 sum::$0 sum::d ] { { sum::return_d#1 = sum::return_d#2 } } ) always clobbers reg byte a +Statement [2] *(&main::$0) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) [ main::$0 sum::return main::x main::$1 main::y sum::d ] ( [ main::$0 sum::return main::x main::$1 main::y sum::d ] { } ) always clobbers reg byte a reg byte y +Statement [3] *(&main::x) = memcpy(*(&main::$0), struct Data, SIZEOF_STRUCT_DATA) [ sum::return main::x main::$1 main::y sum::d ] ( [ sum::return main::x main::$1 main::y sum::d ] { } ) always clobbers reg byte a reg byte y +Statement [4] *SCREEN = *((byte*)&main::x) [ sum::return main::$1 main::y sum::d ] ( [ sum::return main::$1 main::y sum::d ] { } ) always clobbers reg byte a +Statement [6] *(&main::$1) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) [ main::$1 main::y ] ( [ main::$1 main::y ] { } ) always clobbers reg byte a reg byte y +Statement [7] *(&main::y) = memcpy(*(&main::$1), struct Data, SIZEOF_STRUCT_DATA) [ main::y ] ( [ main::y ] { } ) always clobbers reg byte a reg byte y +Statement [8] *(SCREEN+1) = *((byte*)&main::y+OFFSET_STRUCT_DATA_D) [ ] ( [ ] { } ) always clobbers reg byte a +Statement [11] sum::$0 = sum::a#2 + sum::b#2 [ sum::return sum::b#2 sum::$0 sum::d ] ( sum:1 [ main::$0 main::x main::$1 main::y sum::return sum::b#2 sum::$0 sum::d ] { } sum:5 [ main::$1 main::y sum::return sum::b#2 sum::$0 sum::d ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:3 [ sum::b#2 ] -Statement [11] sum::$0 = sum::a#2 + sum::b#2 [ sum::b#2 sum::$0 sum::d ] ( sum:1 [ sum::b#2 sum::$0 sum::d ] { { sum::return_c#0 = sum::return_c#2 } } sum:5 [ sum::b#2 sum::$0 sum::d ] { { sum::return_d#1 = sum::return_d#2 } } ) always clobbers reg byte a +Statement [14] *(&sum::return) = memcpy(*(&sum::d), struct Data, SIZEOF_STRUCT_DATA) [ sum::return sum::d ] ( sum:1 [ main::$0 main::x main::$1 main::y sum::return sum::d ] { } sum:5 [ main::$1 main::y sum::return sum::d ] { } ) always clobbers reg byte a reg byte y +Statement [2] *(&main::$0) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) [ main::$0 sum::return main::x main::$1 main::y sum::d ] ( [ main::$0 sum::return main::x main::$1 main::y sum::d ] { } ) always clobbers reg byte a reg byte y +Statement [3] *(&main::x) = memcpy(*(&main::$0), struct Data, SIZEOF_STRUCT_DATA) [ sum::return main::x main::$1 main::y sum::d ] ( [ sum::return main::x main::$1 main::y sum::d ] { } ) always clobbers reg byte a reg byte y +Statement [4] *SCREEN = *((byte*)&main::x) [ sum::return main::$1 main::y sum::d ] ( [ sum::return main::$1 main::y sum::d ] { } ) always clobbers reg byte a +Statement [6] *(&main::$1) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) [ main::$1 main::y ] ( [ main::$1 main::y ] { } ) always clobbers reg byte a reg byte y +Statement [7] *(&main::y) = memcpy(*(&main::$1), struct Data, SIZEOF_STRUCT_DATA) [ main::y ] ( [ main::y ] { } ) always clobbers reg byte a reg byte y +Statement [8] *(SCREEN+1) = *((byte*)&main::y+OFFSET_STRUCT_DATA_D) [ ] ( [ ] { } ) always clobbers reg byte a +Statement [11] sum::$0 = sum::a#2 + sum::b#2 [ sum::return sum::b#2 sum::$0 sum::d ] ( sum:1 [ main::$0 main::x main::$1 main::y sum::return sum::b#2 sum::$0 sum::d ] { } sum:5 [ main::$1 main::y sum::return sum::b#2 sum::$0 sum::d ] { } ) always clobbers reg byte a +Statement [14] *(&sum::return) = memcpy(*(&sum::d), struct Data, SIZEOF_STRUCT_DATA) [ sum::return sum::d ] ( sum:1 [ main::$0 main::x main::$1 main::y sum::return sum::d ] { } sum:5 [ main::$1 main::y sum::return sum::d ] { } ) always clobbers reg byte a reg byte y Potential registers zp[1]:2 [ sum::a#2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:3 [ sum::b#2 ] : zp[1]:3 , reg byte x , reg byte y , -Potential registers zp[1]:4 [ sum::return_c#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:5 [ main::x_c#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:6 [ sum::return_d#1 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:7 [ main::y_d#0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:8 [ sum::$0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:9 [ sum::return_c#2 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:10 [ sum::return_d#2 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y , -Potential registers zp[2]:11 [ sum::d ] : zp[2]:11 , +Potential registers zp[1]:4 [ sum::$0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y , +Potential registers zp[2]:5 [ main::x ] : zp[2]:5 , +Potential registers zp[2]:7 [ main::$0 ] : zp[2]:7 , +Potential registers zp[2]:9 [ main::y ] : zp[2]:9 , +Potential registers zp[2]:11 [ main::$1 ] : zp[2]:11 , +Potential registers zp[2]:13 [ sum::return ] : zp[2]:13 , +Potential registers zp[2]:15 [ sum::d ] : zp[2]:15 , REGISTER UPLIFT SCOPES -Uplift Scope [sum] 22: zp[1]:8 [ sum::$0 ] 11: zp[1]:2 [ sum::a#2 ] 7.33: zp[1]:3 [ sum::b#2 ] 4.33: zp[1]:10 [ sum::return_d#2 ] 4: zp[1]:4 [ sum::return_c#0 ] 4: zp[1]:6 [ sum::return_d#1 ] 3.25: zp[1]:9 [ sum::return_c#2 ] 0: zp[2]:11 [ sum::d ] -Uplift Scope [main] 4: zp[1]:5 [ main::x_c#0 ] 4: zp[1]:7 [ main::y_d#0 ] +Uplift Scope [sum] 22: zp[1]:4 [ sum::$0 ] 11: zp[1]:2 [ sum::a#2 ] 7.33: zp[1]:3 [ sum::b#2 ] 0: zp[2]:13 [ sum::return ] 0: zp[2]:15 [ sum::d ] Uplift Scope [Data] +Uplift Scope [main] 0: zp[2]:5 [ main::x ] 0: zp[2]:7 [ main::$0 ] 0: zp[2]:9 [ main::y ] 0: zp[2]:11 [ main::$1 ] Uplift Scope [] -Uplifting [sum] best 104 combination reg byte a [ sum::$0 ] reg byte a [ sum::a#2 ] reg byte x [ sum::b#2 ] reg byte a [ sum::return_d#2 ] zp[1]:4 [ sum::return_c#0 ] zp[1]:6 [ sum::return_d#1 ] zp[1]:9 [ sum::return_c#2 ] zp[2]:11 [ sum::d ] -Limited combination testing to 100 combinations of 12288 possible. -Uplifting [main] best 92 combination reg byte a [ main::x_c#0 ] reg byte a [ main::y_d#0 ] -Uplifting [Data] best 92 combination -Uplifting [] best 92 combination -Attempting to uplift remaining variables inzp[1]:4 [ sum::return_c#0 ] -Uplifting [sum] best 86 combination reg byte a [ sum::return_c#0 ] -Attempting to uplift remaining variables inzp[1]:6 [ sum::return_d#1 ] -Uplifting [sum] best 80 combination reg byte a [ sum::return_d#1 ] -Attempting to uplift remaining variables inzp[1]:9 [ sum::return_c#2 ] -Uplifting [sum] best 76 combination reg byte x [ sum::return_c#2 ] -Allocated (was zp[2]:11) zp[2]:2 [ sum::d ] +Uplifting [sum] best 154 combination reg byte a [ sum::$0 ] reg byte a [ sum::a#2 ] reg byte x [ sum::b#2 ] zp[2]:13 [ sum::return ] zp[2]:15 [ sum::d ] +Uplifting [Data] best 154 combination +Uplifting [main] best 154 combination zp[2]:5 [ main::x ] zp[2]:7 [ main::$0 ] zp[2]:9 [ main::y ] zp[2]:11 [ main::$1 ] +Uplifting [] best 154 combination +Allocated (was zp[2]:5) zp[2]:2 [ main::x ] +Allocated (was zp[2]:7) zp[2]:4 [ main::$0 ] +Allocated (was zp[2]:9) zp[2]:6 [ main::y ] +Allocated (was zp[2]:11) zp[2]:8 [ main::$1 ] +Allocated (was zp[2]:13) zp[2]:10 [ sum::return ] +Allocated (was zp[2]:15) zp[2]:12 [ sum::d ] ASSEMBLER BEFORE OPTIMIZATION // File Comments @@ -380,12 +332,16 @@ ASSEMBLER BEFORE OPTIMIZATION .segment Basic :BasicUpstart(main) // Global Constants & labels + .const SIZEOF_STRUCT_DATA = 2 .const OFFSET_STRUCT_DATA_D = 1 - // #pragma struct_model(classic) .label SCREEN = $400 .segment Code // main main: { + .label x = 2 + .label __0 = 4 + .label y = 6 + .label __1 = 8 // [1] call sum // [10] phi from main to sum [phi:main->sum] sum_from_main: @@ -394,13 +350,25 @@ main: { // [10] phi sum::a#2 = 1 [phi:main->sum#1] -- vbuaa=vbuc1 lda #1 jsr sum - // [2] sum::return_c#0 = sum::return_c#2 -- vbuaa=vbuxx - txa jmp __b1 // main::@1 __b1: - // [3] main::x_c#0 = sum::return_c#0 - // [4] *SCREEN = main::x_c#0 -- _deref_pbuc1=vbuaa + // [2] *(&main::$0) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_DATA + !: + lda sum.return-1,y + sta __0-1,y + dey + bne !- + // [3] *(&main::x) = memcpy(*(&main::$0), struct Data, SIZEOF_STRUCT_DATA) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_DATA + !: + lda __0-1,y + sta x-1,y + dey + bne !- + // [4] *SCREEN = *((byte*)&main::x) -- _deref_pbuc1=_deref_pbuc2 + lda.z x sta SCREEN // [5] call sum // [10] phi from main::@1 to sum [phi:main::@1->sum] @@ -410,12 +378,25 @@ main: { // [10] phi sum::a#2 = 3 [phi:main::@1->sum#1] -- vbuaa=vbuc1 lda #3 jsr sum - // [6] sum::return_d#1 = sum::return_d#2 jmp __b2 // main::@2 __b2: - // [7] main::y_d#0 = sum::return_d#1 - // [8] *(SCREEN+1) = main::y_d#0 -- _deref_pbuc1=vbuaa + // [6] *(&main::$1) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_DATA + !: + lda sum.return-1,y + sta __1-1,y + dey + bne !- + // [7] *(&main::y) = memcpy(*(&main::$1), struct Data, SIZEOF_STRUCT_DATA) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_DATA + !: + lda __1-1,y + sta y-1,y + dey + bne !- + // [8] *(SCREEN+1) = *((byte*)&main::y+OFFSET_STRUCT_DATA_D) -- _deref_pbuc1=_deref_pbuc2 + lda y+OFFSET_STRUCT_DATA_D sta SCREEN+1 jmp __breturn // main::@return @@ -426,7 +407,8 @@ main: { // sum // sum(byte register(A) a, byte register(X) b) sum: { - .label d = 2 + .label return = $a + .label d = $c // [11] sum::$0 = sum::a#2 + sum::b#2 -- vbuaa=vbuaa_plus_vbuxx stx.z $ff clc @@ -435,14 +417,17 @@ sum: { sta.z d // [13] *((byte*)&sum::d+OFFSET_STRUCT_DATA_D) = sum::b#2 -- _deref_pbuc1=vbuxx stx d+OFFSET_STRUCT_DATA_D - // [14] sum::return_c#2 = *((byte*)&sum::d) -- vbuxx=_deref_pbuc1 - ldx.z d - // [15] sum::return_d#2 = *((byte*)&sum::d+OFFSET_STRUCT_DATA_D) -- vbuaa=_deref_pbuc1 - lda d+OFFSET_STRUCT_DATA_D + // [14] *(&sum::return) = memcpy(*(&sum::d), struct Data, SIZEOF_STRUCT_DATA) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_DATA + !: + lda d-1,y + sta return-1,y + dey + bne !- jmp __breturn // sum::@return __breturn: - // [16] return + // [15] return rts } // File Data @@ -453,7 +438,6 @@ Removing instruction jmp __b2 Removing instruction jmp __breturn Removing instruction jmp __breturn Succesful ASM optimization Pass5NextJumpElimination -Replacing instruction ldx.z d with TAX Removing instruction sum_from_main: Removing instruction __b1: Removing instruction sum_from___b1: @@ -465,41 +449,35 @@ Succesful ASM optimization Pass5UnusedLabelElimination FINAL SYMBOL TABLE constant byte OFFSET_STRUCT_DATA_D = 1 constant byte* const SCREEN = (byte*) 1024 +constant byte SIZEOF_STRUCT_DATA = 2 byte idx void main() -byte main::x_c -byte main::x_c#0 reg byte a 4.0 -byte main::y_d -byte main::y_d#0 reg byte a 4.0 +struct Data~ main::$0 zp[2]:4 +struct Data~ main::$1 zp[2]:8 +struct Data main::x loadstore zp[2]:2 +struct Data main::y loadstore zp[2]:6 struct Data sum(byte sum::a , byte sum::b) byte~ sum::$0 reg byte a 22.0 byte sum::a byte sum::a#2 reg byte a 11.0 byte sum::b byte sum::b#2 reg byte x 7.333333333333333 -struct Data sum::d loadstore zp[2]:2 -struct Data sum::return -byte sum::return_c -byte sum::return_c#0 reg byte a 4.0 -byte sum::return_c#2 reg byte x 3.25 -byte sum::return_d -byte sum::return_d#1 reg byte a 4.0 -byte sum::return_d#2 reg byte a 4.333333333333333 +struct Data sum::d loadstore zp[2]:12 +struct Data sum::return loadstore zp[2]:10 reg byte a [ sum::a#2 ] reg byte x [ sum::b#2 ] -reg byte a [ sum::return_c#0 ] -reg byte a [ main::x_c#0 ] -reg byte a [ sum::return_d#1 ] -reg byte a [ main::y_d#0 ] reg byte a [ sum::$0 ] -reg byte x [ sum::return_c#2 ] -reg byte a [ sum::return_d#2 ] -zp[2]:2 [ sum::d ] +zp[2]:2 [ main::x ] +zp[2]:4 [ main::$0 ] +zp[2]:6 [ main::y ] +zp[2]:8 [ main::$1 ] +zp[2]:10 [ sum::return ] +zp[2]:12 [ sum::d ] FINAL ASSEMBLER -Score: 63 +Score: 142 // File Comments // Test intermediate vars @@ -513,12 +491,16 @@ Score: 63 .segment Basic :BasicUpstart(main) // Global Constants & labels + .const SIZEOF_STRUCT_DATA = 2 .const OFFSET_STRUCT_DATA_D = 1 - // #pragma struct_model(classic) .label SCREEN = $400 .segment Code // main main: { + .label x = 2 + .label __0 = 4 + .label y = 6 + .label __1 = 8 // sum(1,2) // [1] call sum // [10] phi from main to sum [phi:main->sum] @@ -527,14 +509,26 @@ main: { // [10] phi sum::a#2 = 1 [phi:main->sum#1] -- vbuaa=vbuc1 lda #1 jsr sum - // sum(1,2) - // [2] sum::return_c#0 = sum::return_c#2 -- vbuaa=vbuxx - txa // main::@1 + // sum(1,2) + // [2] *(&main::$0) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_DATA + !: + lda sum.return-1,y + sta __0-1,y + dey + bne !- // struct Data x = sum(1,2) - // [3] main::x_c#0 = sum::return_c#0 + // [3] *(&main::x) = memcpy(*(&main::$0), struct Data, SIZEOF_STRUCT_DATA) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_DATA + !: + lda __0-1,y + sta x-1,y + dey + bne !- // SCREEN[idx++] = x.c - // [4] *SCREEN = main::x_c#0 -- _deref_pbuc1=vbuaa + // [4] *SCREEN = *((byte*)&main::x) -- _deref_pbuc1=_deref_pbuc2 + lda.z x sta SCREEN // sum(3, 4) // [5] call sum @@ -544,13 +538,26 @@ main: { // [10] phi sum::a#2 = 3 [phi:main::@1->sum#1] -- vbuaa=vbuc1 lda #3 jsr sum - // sum(3, 4) - // [6] sum::return_d#1 = sum::return_d#2 // main::@2 + // sum(3, 4) + // [6] *(&main::$1) = memcpy(*(&sum::return), struct Data, SIZEOF_STRUCT_DATA) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_DATA + !: + lda sum.return-1,y + sta __1-1,y + dey + bne !- // struct Data y = sum(3, 4) - // [7] main::y_d#0 = sum::return_d#1 + // [7] *(&main::y) = memcpy(*(&main::$1), struct Data, SIZEOF_STRUCT_DATA) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_DATA + !: + lda __1-1,y + sta y-1,y + dey + bne !- // SCREEN[idx++] = y.d - // [8] *(SCREEN+1) = main::y_d#0 -- _deref_pbuc1=vbuaa + // [8] *(SCREEN+1) = *((byte*)&main::y+OFFSET_STRUCT_DATA_D) -- _deref_pbuc1=_deref_pbuc2 + lda y+OFFSET_STRUCT_DATA_D sta SCREEN+1 // main::@return // } @@ -560,7 +567,8 @@ main: { // sum // sum(byte register(A) a, byte register(X) b) sum: { - .label d = 2 + .label return = $a + .label d = $c // a+b // [11] sum::$0 = sum::a#2 + sum::b#2 -- vbuaa=vbuaa_plus_vbuxx stx.z $ff @@ -572,13 +580,16 @@ sum: { // [13] *((byte*)&sum::d+OFFSET_STRUCT_DATA_D) = sum::b#2 -- _deref_pbuc1=vbuxx stx d+OFFSET_STRUCT_DATA_D // return d; - // [14] sum::return_c#2 = *((byte*)&sum::d) -- vbuxx=_deref_pbuc1 - tax - // [15] sum::return_d#2 = *((byte*)&sum::d+OFFSET_STRUCT_DATA_D) -- vbuaa=_deref_pbuc1 - lda d+OFFSET_STRUCT_DATA_D + // [14] *(&sum::return) = memcpy(*(&sum::d), struct Data, SIZEOF_STRUCT_DATA) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3 + ldy #SIZEOF_STRUCT_DATA + !: + lda d-1,y + sta return-1,y + dey + bne !- // sum::@return // } - // [16] return + // [15] return rts } // File Data diff --git a/src/test/ref/intermediates-struct.sym b/src/test/ref/intermediates-struct.sym index 2ad8f8a91..519a089a5 100644 --- a/src/test/ref/intermediates-struct.sym +++ b/src/test/ref/intermediates-struct.sym @@ -1,33 +1,27 @@ constant byte OFFSET_STRUCT_DATA_D = 1 constant byte* const SCREEN = (byte*) 1024 +constant byte SIZEOF_STRUCT_DATA = 2 byte idx void main() -byte main::x_c -byte main::x_c#0 reg byte a 4.0 -byte main::y_d -byte main::y_d#0 reg byte a 4.0 +struct Data~ main::$0 zp[2]:4 +struct Data~ main::$1 zp[2]:8 +struct Data main::x loadstore zp[2]:2 +struct Data main::y loadstore zp[2]:6 struct Data sum(byte sum::a , byte sum::b) byte~ sum::$0 reg byte a 22.0 byte sum::a byte sum::a#2 reg byte a 11.0 byte sum::b byte sum::b#2 reg byte x 7.333333333333333 -struct Data sum::d loadstore zp[2]:2 -struct Data sum::return -byte sum::return_c -byte sum::return_c#0 reg byte a 4.0 -byte sum::return_c#2 reg byte x 3.25 -byte sum::return_d -byte sum::return_d#1 reg byte a 4.0 -byte sum::return_d#2 reg byte a 4.333333333333333 +struct Data sum::d loadstore zp[2]:12 +struct Data sum::return loadstore zp[2]:10 reg byte a [ sum::a#2 ] reg byte x [ sum::b#2 ] -reg byte a [ sum::return_c#0 ] -reg byte a [ main::x_c#0 ] -reg byte a [ sum::return_d#1 ] -reg byte a [ main::y_d#0 ] reg byte a [ sum::$0 ] -reg byte x [ sum::return_c#2 ] -reg byte a [ sum::return_d#2 ] -zp[2]:2 [ sum::d ] +zp[2]:2 [ main::x ] +zp[2]:4 [ main::$0 ] +zp[2]:6 [ main::y ] +zp[2]:8 [ main::$1 ] +zp[2]:10 [ sum::return ] +zp[2]:12 [ sum::d ] diff --git a/src/test/ref/struct-23.log b/src/test/ref/struct-23.log index 762e2caa3..586ce35c8 100644 --- a/src/test/ref/struct-23.log +++ b/src/test/ref/struct-23.log @@ -2,8 +2,8 @@ Eliminating unused variable with no statement main::$0 Eliminating unused variable with no statement main::$1 Unwinding list assignment { main::$0_x, main::$0_y } = { getPoint::return_x, getPoint::return_y } Unwinding list assignment { main::$1_x, main::$1_y } = { getPoint::return_x, getPoint::return_y } -Unwinding list assignment { getPoint::return_x#0, getPoint::return_y#0 } = { getPoint::return_x#3, getPoint::return_y#3 } -Unwinding list assignment { getPoint::return_x#1, getPoint::return_y#1 } = { getPoint::return_x#3, getPoint::return_y#3 } +Unwinding list assignment { getPoint::return_x#0, getPoint::return_y#0 } = { getPoint::return_x#5, getPoint::return_y#5 } +Unwinding list assignment { getPoint::return_x#1, getPoint::return_y#1 } = { getPoint::return_x#5, getPoint::return_y#5 } Removing C-classic struct-unwound assignment main::point1 = struct-unwound {*((byte*)&main::point1+OFFSET_STRUCT_POINT_X), *((byte*)&main::point1+OFFSET_STRUCT_POINT_Y)} Removing C-classic struct-unwound assignment main::point2 = struct-unwound {*((byte*)&main::point2+OFFSET_STRUCT_POINT_X), *((byte*)&main::point2+OFFSET_STRUCT_POINT_Y)} @@ -14,14 +14,14 @@ main: scope:[main] from __start getPoint::x#0 = 2 getPoint::y#0 = 3 call getPoint - getPoint::return_x#0 = getPoint::return_x#3 - getPoint::return_y#0 = getPoint::return_y#3 + getPoint::return_x#0 = getPoint::return_x#5 + getPoint::return_y#0 = getPoint::return_y#5 to:main::@1 main::@1: scope:[main] from main - getPoint::return_y#4 = phi( main/getPoint::return_y#0 ) - getPoint::return_x#4 = phi( main/getPoint::return_x#0 ) - main::$0_x = getPoint::return_x#4 - main::$0_y = getPoint::return_y#4 + getPoint::return_y#3 = phi( main/getPoint::return_y#0 ) + getPoint::return_x#3 = phi( main/getPoint::return_x#0 ) + main::$0_x = getPoint::return_x#3 + main::$0_y = getPoint::return_y#3 *((byte*)&main::point1+OFFSET_STRUCT_POINT_X) = main::$0_x *((byte*)&main::point1+OFFSET_STRUCT_POINT_Y) = main::$0_y SCREEN[0] = *((byte*)&main::point1+OFFSET_STRUCT_POINT_X) @@ -29,14 +29,14 @@ main::@1: scope:[main] from main getPoint::x#1 = 4 getPoint::y#1 = 5 call getPoint - getPoint::return_x#1 = getPoint::return_x#3 - getPoint::return_y#1 = getPoint::return_y#3 + getPoint::return_x#1 = getPoint::return_x#5 + getPoint::return_y#1 = getPoint::return_y#5 to:main::@2 main::@2: scope:[main] from main::@1 - getPoint::return_y#5 = phi( main::@1/getPoint::return_y#1 ) - getPoint::return_x#5 = phi( main::@1/getPoint::return_x#1 ) - main::$1_x = getPoint::return_x#5 - main::$1_y = getPoint::return_y#5 + getPoint::return_y#4 = phi( main::@1/getPoint::return_y#1 ) + getPoint::return_x#4 = phi( main::@1/getPoint::return_x#1 ) + main::$1_x = getPoint::return_x#4 + main::$1_y = getPoint::return_y#4 *((byte*)&main::point2+OFFSET_STRUCT_POINT_X) = main::$1_x *((byte*)&main::point2+OFFSET_STRUCT_POINT_Y) = main::$1_y SCREEN[2] = *((byte*)&main::point2+OFFSET_STRUCT_POINT_X) @@ -57,11 +57,9 @@ getPoint: scope:[getPoint] from main main::@1 getPoint::return#0 = struct-unwound {getPoint::return_x#2, getPoint::return_y#2} to:getPoint::@return getPoint::@return: scope:[getPoint] from getPoint - getPoint::return_y#6 = phi( getPoint/getPoint::return_y#2 ) - getPoint::return_x#6 = phi( getPoint/getPoint::return_x#2 ) - getPoint::return_x#3 = getPoint::return_x#6 - getPoint::return_y#3 = getPoint::return_y#6 - getPoint::return#1 = struct-unwound {getPoint::return_x#3, getPoint::return_y#3} + getPoint::return_y#5 = phi( getPoint/getPoint::return_y#2 ) + getPoint::return_x#5 = phi( getPoint/getPoint::return_x#2 ) + getPoint::return#1 = struct-unwound {} return to:@return @@ -95,7 +93,6 @@ byte getPoint::return_x#2 byte getPoint::return_x#3 byte getPoint::return_x#4 byte getPoint::return_x#5 -byte getPoint::return_x#6 byte getPoint::return_y byte getPoint::return_y#0 byte getPoint::return_y#1 @@ -103,7 +100,6 @@ byte getPoint::return_y#2 byte getPoint::return_y#3 byte getPoint::return_y#4 byte getPoint::return_y#5 -byte getPoint::return_y#6 byte getPoint::x byte getPoint::x#0 byte getPoint::x#1 @@ -153,12 +149,12 @@ Finalized unsigned number type (byte) 5 Finalized unsigned number type (byte) 2 Finalized unsigned number type (byte) 3 Successful SSA optimization PassNFinalizeNumberTypeConversions -Alias getPoint::return_x#0 = getPoint::return_x#4 -Alias getPoint::return_y#0 = getPoint::return_y#4 -Alias getPoint::return_x#1 = getPoint::return_x#5 -Alias getPoint::return_y#1 = getPoint::return_y#5 -Alias getPoint::return_x#2 = getPoint::p_x#0 getPoint::x#2 getPoint::return_x#6 getPoint::return_x#3 -Alias getPoint::return_y#2 = getPoint::p_y#0 getPoint::y#2 getPoint::return_y#6 getPoint::return_y#3 +Alias getPoint::return_x#0 = getPoint::return_x#3 +Alias getPoint::return_y#0 = getPoint::return_y#3 +Alias getPoint::return_x#1 = getPoint::return_x#4 +Alias getPoint::return_y#1 = getPoint::return_y#4 +Alias getPoint::return_x#2 = getPoint::p_x#0 getPoint::x#2 getPoint::return_x#5 +Alias getPoint::return_y#2 = getPoint::p_y#0 getPoint::y#2 getPoint::return_y#5 Successful SSA optimization Pass2AliasElimination Constant getPoint::x#0 = 2 Constant getPoint::y#0 = 3 @@ -172,7 +168,7 @@ Simplifying expression containing zero (byte*)&main::point2 in [18] *((byte*)&ma Simplifying expression containing zero (byte*)&main::point2 in [20] SCREEN[2] = *((byte*)&main::point2+OFFSET_STRUCT_POINT_X) Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused variable getPoint::return#0 and assignment [20] getPoint::return#0 = struct-unwound {getPoint::return_x#2, getPoint::return_y#2} -Eliminating unused variable getPoint::return#1 and assignment [21] getPoint::return#1 = struct-unwound {getPoint::return_x#2, getPoint::return_y#2} +Eliminating unused variable getPoint::return#1 and assignment [21] getPoint::return#1 = struct-unwound {} Eliminating unused constant OFFSET_STRUCT_POINT_X Successful SSA optimization PassNEliminateUnusedVars Removing unused procedure __start diff --git a/src/test/ref/struct-5.log b/src/test/ref/struct-5.log index 24fca842c..9608ce486 100644 --- a/src/test/ref/struct-5.log +++ b/src/test/ref/struct-5.log @@ -1,6 +1,6 @@ Eliminating unused variable with no statement main::$0 Unwinding list assignment { main::$0_x, main::$0_y } = { point::return_x, point::return_y } -Unwinding list assignment { point::return_x#0, point::return_y#0 } = { point::return_x#2, point::return_y#2 } +Unwinding list assignment { point::return_x#0, point::return_y#0 } = { point::return_x#3, point::return_y#3 } CONTROL FLOW GRAPH SSA @@ -9,14 +9,14 @@ main: scope:[main] from __start main::q_x#0 = 0 main::q_y#0 = 0 call point - point::return_x#0 = point::return_x#2 - point::return_y#0 = point::return_y#2 + point::return_x#0 = point::return_x#3 + point::return_y#0 = point::return_y#3 to:main::@1 main::@1: scope:[main] from main - point::return_y#3 = phi( main/point::return_y#0 ) - point::return_x#3 = phi( main/point::return_x#0 ) - main::$0_x = point::return_x#3 - main::$0_y = point::return_y#3 + point::return_y#2 = phi( main/point::return_y#0 ) + point::return_x#2 = phi( main/point::return_x#0 ) + main::$0_x = point::return_x#2 + main::$0_y = point::return_y#2 main::q_x#1 = main::$0_x main::q_y#1 = main::$0_y main::SCREEN[0] = main::q_x#1 @@ -33,11 +33,9 @@ point: scope:[point] from main point::return#0 = struct-unwound {point::return_x#1, point::return_y#1} to:point::@return point::@return: scope:[point] from point - point::return_y#4 = phi( point/point::return_y#1 ) - point::return_x#4 = phi( point/point::return_x#1 ) - point::return_x#2 = point::return_x#4 - point::return_y#2 = point::return_y#4 - point::return#1 = struct-unwound {point::return_x#2, point::return_y#2} + point::return_y#3 = phi( point/point::return_y#1 ) + point::return_x#3 = phi( point/point::return_x#1 ) + point::return#1 = struct-unwound {} return to:@return @@ -74,13 +72,11 @@ byte point::return_x#0 byte point::return_x#1 byte point::return_x#2 byte point::return_x#3 -byte point::return_x#4 byte point::return_y byte point::return_y#0 byte point::return_y#1 byte point::return_y#2 byte point::return_y#3 -byte point::return_y#4 Adding number conversion cast (unumber) 0 in main::SCREEN[0] = main::q_x#1 Adding number conversion cast (unumber) 1 in main::SCREEN[1] = main::q_y#1 @@ -92,12 +88,12 @@ Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 1 Successful SSA optimization PassNFinalizeNumberTypeConversions -Alias point::return_x#0 = point::return_x#3 -Alias point::return_y#0 = point::return_y#3 +Alias point::return_x#0 = point::return_x#2 +Alias point::return_y#0 = point::return_y#2 Alias main::q_x#1 = main::$0_x Alias main::q_y#1 = main::$0_y -Alias point::return_x#1 = point::return_x#4 point::return_x#2 -Alias point::return_y#1 = point::return_y#4 point::return_y#2 +Alias point::return_x#1 = point::return_x#3 +Alias point::return_y#1 = point::return_y#3 Successful SSA optimization Pass2AliasElimination Constant main::q_x#0 = 0 Constant main::q_y#0 = 0 @@ -113,7 +109,7 @@ Successful SSA optimization Pass2ConstantIdentification Simplifying expression containing zero main::SCREEN in [7] main::SCREEN[0] = main::q_x#1 Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused variable point::return#0 and assignment [4] point::return#0 = struct-unwound {point::return_x#1, point::return_y#1} -Eliminating unused variable point::return#1 and assignment [5] point::return#1 = struct-unwound {point::return_x#1, point::return_y#1} +Eliminating unused variable point::return#1 and assignment [5] point::return#1 = struct-unwound {} Eliminating unused constant main::q_x#0 Eliminating unused constant main::q_y#0 Successful SSA optimization PassNEliminateUnusedVars diff --git a/src/test/ref/struct-ptr-16.cfg b/src/test/ref/struct-ptr-16.cfg index 539f33e06..5864fb33b 100644 --- a/src/test/ref/struct-ptr-16.cfg +++ b/src/test/ref/struct-ptr-16.cfg @@ -3,8 +3,8 @@ void main() main: scope:[main] from [0] phi() [1] call get - [2] get::return_x#0 = get::return_x#5 - [3] get::return_y#0 = get::return_y#5 + [2] get::return_x#0 = get::return_x#7 + [3] get::return_y#0 = get::return_y#7 to:main::@2 main::@2: scope:[main] from main [4] main::$0_x = get::return_x#0 @@ -16,8 +16,8 @@ main::@1: scope:[main] from main::@2 main::@3 [8] main::i#2 = phi( main::@2/1, main::@3/main::i#1 ) [9] get::i#1 = main::i#2 [10] call get - [11] get::return_x#1 = get::return_x#5 - [12] get::return_y#1 = get::return_y#5 + [11] get::return_x#1 = get::return_x#7 + [12] get::return_y#1 = get::return_y#7 to:main::@3 main::@3: scope:[main] from main::@1 [13] main::$1_x = get::return_x#1 @@ -45,8 +45,8 @@ get::@4: scope:[get] from get::@3 [25] get::return_y#4 = *((byte*)p2+OFFSET_STRUCT_POINT_Y) to:get::@return get::@return: scope:[get] from get::@1 get::@2 get::@4 - [26] get::return_y#5 = phi( get::@1/get::return_y#2, get::@2/get::return_y#3, get::@4/get::return_y#4 ) - [26] get::return_x#5 = phi( get::@1/get::return_x#2, get::@2/get::return_x#3, get::@4/get::return_x#4 ) + [26] get::return_y#7 = phi( get::@1/get::return_y#2, get::@2/get::return_y#3, get::@4/get::return_y#4 ) + [26] get::return_x#7 = phi( get::@1/get::return_x#2, get::@2/get::return_x#3, get::@4/get::return_x#4 ) [27] return to:@return get::@2: scope:[get] from get::@3 diff --git a/src/test/ref/struct-ptr-16.log b/src/test/ref/struct-ptr-16.log index 6c695ca27..883b42363 100644 --- a/src/test/ref/struct-ptr-16.log +++ b/src/test/ref/struct-ptr-16.log @@ -3,8 +3,8 @@ Eliminating unused variable with no statement main::$0 Eliminating unused variable with no statement main::$1 Unwinding list assignment { main::$0_x, main::$0_y } = { get::return_x, get::return_y } Unwinding list assignment { main::$1_x, main::$1_y } = { get::return_x, get::return_y } -Unwinding list assignment { get::return_x#0, get::return_y#0 } = { get::return_x#5, get::return_y#5 } -Unwinding list assignment { get::return_x#1, get::return_y#1 } = { get::return_x#5, get::return_y#5 } +Unwinding list assignment { get::return_x#0, get::return_y#0 } = { get::return_x#7, get::return_y#7 } +Unwinding list assignment { get::return_x#1, get::return_y#1 } = { get::return_x#7, get::return_y#7 } CONTROL FLOW GRAPH SSA @@ -12,14 +12,14 @@ void main() main: scope:[main] from __start::@1 get::i#0 = 0 call get - get::return_x#0 = get::return_x#5 - get::return_y#0 = get::return_y#5 + get::return_x#0 = get::return_x#7 + get::return_y#0 = get::return_y#7 to:main::@2 main::@2: scope:[main] from main - get::return_y#6 = phi( main/get::return_y#0 ) - get::return_x#6 = phi( main/get::return_x#0 ) - main::$0_x = get::return_x#6 - main::$0_y = get::return_y#6 + get::return_y#5 = phi( main/get::return_y#0 ) + get::return_x#5 = phi( main/get::return_x#0 ) + main::$0_x = get::return_x#5 + main::$0_y = get::return_y#5 *((byte*)SCREEN+OFFSET_STRUCT_POINT_X) = main::$0_x *((byte*)SCREEN+OFFSET_STRUCT_POINT_Y) = main::$0_y main::i#0 = 1 @@ -28,15 +28,15 @@ main::@1: scope:[main] from main::@2 main::@3 main::i#2 = phi( main::@2/main::i#0, main::@3/main::i#1 ) get::i#1 = main::i#2 call get - get::return_x#1 = get::return_x#5 - get::return_y#1 = get::return_y#5 + get::return_x#1 = get::return_x#7 + get::return_y#1 = get::return_y#7 to:main::@3 main::@3: scope:[main] from main::@1 main::i#3 = phi( main::@1/main::i#2 ) - get::return_y#7 = phi( main::@1/get::return_y#1 ) - get::return_x#7 = phi( main::@1/get::return_x#1 ) - main::$1_x = get::return_x#7 - main::$1_y = get::return_y#7 + get::return_y#6 = phi( main::@1/get::return_y#1 ) + get::return_x#6 = phi( main::@1/get::return_x#1 ) + main::$1_x = get::return_x#6 + main::$1_y = get::return_y#6 main::$3 = main::i#3 * SIZEOF_STRUCT_POINT ((byte*)SCREEN+OFFSET_STRUCT_POINT_X)[main::$3] = main::$1_x ((byte*)SCREEN+OFFSET_STRUCT_POINT_Y)[main::$3] = main::$1_y @@ -87,11 +87,9 @@ get::@4: scope:[get] from get::@3 get::return#2 = struct-unwound {get::return_x#4, get::return_y#4} to:get::@return get::@return: scope:[get] from get::@1 get::@2 get::@4 - get::return_y#8 = phi( get::@1/get::return_y#2, get::@2/get::return_y#3, get::@4/get::return_y#4 ) - get::return_x#8 = phi( get::@1/get::return_x#2, get::@2/get::return_x#3, get::@4/get::return_x#4 ) - get::return_x#5 = get::return_x#8 - get::return_y#5 = get::return_y#8 - get::return#3 = struct-unwound {get::return_x#5, get::return_y#5} + get::return_y#7 = phi( get::@1/get::return_y#2, get::@2/get::return_y#3, get::@4/get::return_y#4 ) + get::return_x#7 = phi( get::@1/get::return_x#2, get::@2/get::return_x#3, get::@4/get::return_x#4 ) + get::return#3 = struct-unwound {} return to:@return @@ -149,7 +147,6 @@ byte get::return_x#4 byte get::return_x#5 byte get::return_x#6 byte get::return_x#7 -byte get::return_x#8 byte get::return_y byte get::return_y#0 byte get::return_y#1 @@ -159,7 +156,6 @@ byte get::return_y#4 byte get::return_y#5 byte get::return_y#6 byte get::return_y#7 -byte get::return_y#8 void main() byte~ main::$0_x byte~ main::$0_y @@ -194,14 +190,12 @@ Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 1 Successful SSA optimization PassNFinalizeNumberTypeConversions -Alias get::return_x#0 = get::return_x#6 -Alias get::return_y#0 = get::return_y#6 -Alias get::return_x#1 = get::return_x#7 -Alias get::return_y#1 = get::return_y#7 +Alias get::return_x#0 = get::return_x#5 +Alias get::return_y#0 = get::return_y#5 +Alias get::return_x#1 = get::return_x#6 +Alias get::return_y#1 = get::return_y#6 Alias main::i#2 = main::i#3 Alias get::i#2 = get::i#3 -Alias get::return_x#5 = get::return_x#8 -Alias get::return_y#5 = get::return_y#8 Successful SSA optimization Pass2AliasElimination Simple Condition main::$2 [21] if(main::i#1!=rangelast(1,2)) goto main::@1 Simple Condition get::$0 [25] if(get::i#2==0) goto get::@1 @@ -250,7 +244,7 @@ Eliminating unused variable get::return#1 and assignment [32] get::return#1 = st Eliminating unused variable get::$6 and assignment [33] get::$6 = get::$12 Eliminating unused variable get::$7 and assignment [35] get::$7 = get::$13 + OFFSET_STRUCT_POINT_Y Eliminating unused variable get::return#2 and assignment [37] get::return#2 = struct-unwound {get::return_x#4, get::return_y#4} -Eliminating unused variable get::return#3 and assignment [39] get::return#3 = struct-unwound {get::return_x#5, get::return_y#5} +Eliminating unused variable get::return#3 and assignment [39] get::return#3 = struct-unwound {} Eliminating unused constant OFFSET_STRUCT_POINT_X Successful SSA optimization PassNEliminateUnusedVars Removing unused procedure __start @@ -293,12 +287,12 @@ Calls in [main] to get:1 get:11 Created 4 initial phi equivalence classes Coalesced [10] get::i#4 = get::i#1 Coalesced [22] main::i#4 = main::i#1 -Coalesced [28] get::return_x#11 = get::return_x#4 -Coalesced [29] get::return_y#11 = get::return_y#4 -Coalesced [34] get::return_x#10 = get::return_x#3 -Coalesced [35] get::return_y#10 = get::return_y#3 -Coalesced [38] get::return_x#9 = get::return_x#2 -Coalesced [39] get::return_y#9 = get::return_y#2 +Coalesced [28] get::return_x#10 = get::return_x#4 +Coalesced [29] get::return_y#10 = get::return_y#4 +Coalesced [34] get::return_x#9 = get::return_x#3 +Coalesced [35] get::return_y#9 = get::return_y#3 +Coalesced [38] get::return_x#8 = get::return_x#2 +Coalesced [39] get::return_y#8 = get::return_y#2 Coalesced down to 4 phi equivalence classes Culled Empty Block label main::@4 Adding NOP phi() at start of main @@ -309,8 +303,8 @@ void main() main: scope:[main] from [0] phi() [1] call get - [2] get::return_x#0 = get::return_x#5 - [3] get::return_y#0 = get::return_y#5 + [2] get::return_x#0 = get::return_x#7 + [3] get::return_y#0 = get::return_y#7 to:main::@2 main::@2: scope:[main] from main [4] main::$0_x = get::return_x#0 @@ -322,8 +316,8 @@ main::@1: scope:[main] from main::@2 main::@3 [8] main::i#2 = phi( main::@2/1, main::@3/main::i#1 ) [9] get::i#1 = main::i#2 [10] call get - [11] get::return_x#1 = get::return_x#5 - [12] get::return_y#1 = get::return_y#5 + [11] get::return_x#1 = get::return_x#7 + [12] get::return_y#1 = get::return_y#7 to:main::@3 main::@3: scope:[main] from main::@1 [13] main::$1_x = get::return_x#1 @@ -351,8 +345,8 @@ get::@4: scope:[get] from get::@3 [25] get::return_y#4 = *((byte*)p2+OFFSET_STRUCT_POINT_Y) to:get::@return get::@return: scope:[get] from get::@1 get::@2 get::@4 - [26] get::return_y#5 = phi( get::@1/get::return_y#2, get::@2/get::return_y#3, get::@4/get::return_y#4 ) - [26] get::return_x#5 = phi( get::@1/get::return_x#2, get::@2/get::return_x#3, get::@4/get::return_x#4 ) + [26] get::return_y#7 = phi( get::@1/get::return_y#2, get::@2/get::return_y#3, get::@4/get::return_y#4 ) + [26] get::return_x#7 = phi( get::@1/get::return_x#2, get::@2/get::return_x#3, get::@4/get::return_x#4 ) [27] return to:@return get::@2: scope:[get] from get::@3 @@ -377,14 +371,14 @@ byte get::return_x#1 11.0 byte get::return_x#2 101.0 byte get::return_x#3 101.0 byte get::return_x#4 101.0 -byte get::return_x#5 79.0 +byte get::return_x#7 79.0 byte get::return_y byte get::return_y#0 2.0 byte get::return_y#1 11.0 byte get::return_y#2 202.0 byte get::return_y#3 202.0 byte get::return_y#4 202.0 -byte get::return_y#5 52.66666666666666 +byte get::return_y#7 52.66666666666666 void main() byte~ main::$0_x 2.0 byte~ main::$0_y 2.0 @@ -398,8 +392,8 @@ byte main::i#2 4.4 Initial phi equivalence classes [ main::i#2 main::i#1 ] [ get::i#2 get::i#1 ] -[ get::return_x#5 get::return_x#2 get::return_x#3 get::return_x#4 ] -[ get::return_y#5 get::return_y#2 get::return_y#3 get::return_y#4 ] +[ get::return_x#7 get::return_x#2 get::return_x#3 get::return_x#4 ] +[ get::return_y#7 get::return_y#2 get::return_y#3 get::return_y#4 ] Added variable get::return_x#0 to live range equivalence class [ get::return_x#0 ] Added variable get::return_y#0 to live range equivalence class [ get::return_y#0 ] Added variable main::$0_x to live range equivalence class [ main::$0_x ] @@ -412,8 +406,8 @@ Added variable main::$3 to live range equivalence class [ main::$3 ] Complete equivalence classes [ main::i#2 main::i#1 ] [ get::i#2 get::i#1 ] -[ get::return_x#5 get::return_x#2 get::return_x#3 get::return_x#4 ] -[ get::return_y#5 get::return_y#2 get::return_y#3 get::return_y#4 ] +[ get::return_x#7 get::return_x#2 get::return_x#3 get::return_x#4 ] +[ get::return_y#7 get::return_y#2 get::return_y#3 get::return_y#4 ] [ get::return_x#0 ] [ get::return_y#0 ] [ main::$0_x ] @@ -425,8 +419,8 @@ Complete equivalence classes [ main::$3 ] Allocated zp[1]:2 [ main::i#2 main::i#1 ] Allocated zp[1]:3 [ get::i#2 get::i#1 ] -Allocated zp[1]:4 [ get::return_x#5 get::return_x#2 get::return_x#3 get::return_x#4 ] -Allocated zp[1]:5 [ get::return_y#5 get::return_y#2 get::return_y#3 get::return_y#4 ] +Allocated zp[1]:4 [ get::return_x#7 get::return_x#2 get::return_x#3 get::return_x#4 ] +Allocated zp[1]:5 [ get::return_y#7 get::return_y#2 get::return_y#3 get::return_y#4 ] Allocated zp[1]:6 [ get::return_x#0 ] Allocated zp[1]:7 [ get::return_y#0 ] Allocated zp[1]:8 [ main::$0_x ] @@ -449,8 +443,8 @@ Statement [16] ((byte*)SCREEN)[main::$3] = main::$1_x [ main::i#2 main::$1_y mai Statement [17] ((byte*)SCREEN+OFFSET_STRUCT_POINT_Y)[main::$3] = main::$1_y [ main::i#2 ] ( [ main::i#2 ] { } ) always clobbers reg byte a Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y , Potential registers zp[1]:3 [ get::i#2 get::i#1 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:4 [ get::return_x#5 get::return_x#2 get::return_x#3 get::return_x#4 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:5 [ get::return_y#5 get::return_y#2 get::return_y#3 get::return_y#4 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:4 [ get::return_x#7 get::return_x#2 get::return_x#3 get::return_x#4 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:5 [ get::return_y#7 get::return_y#2 get::return_y#3 get::return_y#4 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:6 [ get::return_x#0 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:7 [ get::return_y#0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:8 [ main::$0_x ] : zp[1]:8 , reg byte a , reg byte x , reg byte y , @@ -462,12 +456,12 @@ Potential registers zp[1]:13 [ main::$1_y ] : zp[1]:13 , reg byte x , reg byte y Potential registers zp[1]:14 [ main::$3 ] : zp[1]:14 , reg byte x , reg byte y , REGISTER UPLIFT SCOPES -Uplift Scope [get] 658.67: zp[1]:5 [ get::return_y#5 get::return_y#2 get::return_y#3 get::return_y#4 ] 382: zp[1]:4 [ get::return_x#5 get::return_x#2 get::return_x#3 get::return_x#4 ] 128.5: zp[1]:3 [ get::i#2 get::i#1 ] 11: zp[1]:10 [ get::return_x#1 ] 11: zp[1]:11 [ get::return_y#1 ] 2: zp[1]:6 [ get::return_x#0 ] 2: zp[1]:7 [ get::return_y#0 ] +Uplift Scope [get] 658.67: zp[1]:5 [ get::return_y#7 get::return_y#2 get::return_y#3 get::return_y#4 ] 382: zp[1]:4 [ get::return_x#7 get::return_x#2 get::return_x#3 get::return_x#4 ] 128.5: zp[1]:3 [ get::i#2 get::i#1 ] 11: zp[1]:10 [ get::return_x#1 ] 11: zp[1]:11 [ get::return_y#1 ] 2: zp[1]:6 [ get::return_x#0 ] 2: zp[1]:7 [ get::return_y#0 ] Uplift Scope [main] 20.9: zp[1]:2 [ main::i#2 main::i#1 ] 16.5: zp[1]:14 [ main::$3 ] 7.33: zp[1]:12 [ main::$1_x ] 7.33: zp[1]:13 [ main::$1_y ] 2: zp[1]:8 [ main::$0_x ] 2: zp[1]:9 [ main::$0_y ] Uplift Scope [Point] Uplift Scope [] -Uplifting [get] best 853 combination reg byte x [ get::return_y#5 get::return_y#2 get::return_y#3 get::return_y#4 ] reg byte a [ get::return_x#5 get::return_x#2 get::return_x#3 get::return_x#4 ] reg byte a [ get::i#2 get::i#1 ] reg byte a [ get::return_x#1 ] zp[1]:11 [ get::return_y#1 ] zp[1]:6 [ get::return_x#0 ] zp[1]:7 [ get::return_y#0 ] +Uplifting [get] best 853 combination reg byte x [ get::return_y#7 get::return_y#2 get::return_y#3 get::return_y#4 ] reg byte a [ get::return_x#7 get::return_x#2 get::return_x#3 get::return_x#4 ] reg byte a [ get::i#2 get::i#1 ] reg byte a [ get::return_x#1 ] zp[1]:11 [ get::return_y#1 ] zp[1]:6 [ get::return_x#0 ] zp[1]:7 [ get::return_y#0 ] Limited combination testing to 100 combinations of 16384 possible. Uplifting [main] best 673 combination reg byte y [ main::i#2 main::i#1 ] reg byte x [ main::$3 ] zp[1]:12 [ main::$1_x ] zp[1]:13 [ main::$1_y ] zp[1]:8 [ main::$0_x ] zp[1]:9 [ main::$0_y ] Limited combination testing to 100 combinations of 1296 possible. @@ -519,8 +513,8 @@ main: { // [21] phi get::i#2 = 0 [phi:main->get#0] -- vbuaa=vbuc1 lda #0 jsr get - // [2] get::return_x#0 = get::return_x#5 - // [3] get::return_y#0 = get::return_y#5 + // [2] get::return_x#0 = get::return_x#7 + // [3] get::return_y#0 = get::return_y#7 jmp __b2 // main::@2 __b2: @@ -548,8 +542,8 @@ main: { get_from___b1: // [21] phi get::i#2 = get::i#1 [phi:main::@1->get#0] -- register_copy jsr get - // [11] get::return_x#1 = get::return_x#5 - // [12] get::return_y#1 = get::return_y#5 + // [11] get::return_x#1 = get::return_x#7 + // [12] get::return_y#1 = get::return_y#7 jmp __b3 // main::@3 __b3: @@ -601,8 +595,8 @@ get: { __breturn_from___b1: __breturn_from___b2: __breturn_from___b4: - // [26] phi get::return_y#5 = get::return_y#2 [phi:get::@1/get::@2/get::@4->get::@return#0] -- register_copy - // [26] phi get::return_x#5 = get::return_x#2 [phi:get::@1/get::@2/get::@4->get::@return#1] -- register_copy + // [26] phi get::return_y#7 = get::return_y#2 [phi:get::@1/get::@2/get::@4->get::@return#0] -- register_copy + // [26] phi get::return_x#7 = get::return_x#2 [phi:get::@1/get::@2/get::@4->get::@return#1] -- register_copy jmp __breturn // get::@return __breturn: @@ -673,14 +667,14 @@ byte get::return_x#1 reg byte a 11.0 byte get::return_x#2 reg byte a 101.0 byte get::return_x#3 reg byte a 101.0 byte get::return_x#4 reg byte a 101.0 -byte get::return_x#5 reg byte a 79.0 +byte get::return_x#7 reg byte a 79.0 byte get::return_y byte get::return_y#0 reg byte x 2.0 byte get::return_y#1 reg byte x 11.0 byte get::return_y#2 reg byte x 202.0 byte get::return_y#3 reg byte x 202.0 byte get::return_y#4 reg byte x 202.0 -byte get::return_y#5 reg byte x 52.66666666666666 +byte get::return_y#7 reg byte x 52.66666666666666 void main() byte~ main::$0_x reg byte a 2.0 byte~ main::$0_y reg byte x 2.0 @@ -696,8 +690,8 @@ constant struct Point* p2 = (struct Point*) 57344 reg byte y [ main::i#2 main::i#1 ] reg byte a [ get::i#2 get::i#1 ] -reg byte a [ get::return_x#5 get::return_x#2 get::return_x#3 get::return_x#4 ] -reg byte x [ get::return_y#5 get::return_y#2 get::return_y#3 get::return_y#4 ] +reg byte a [ get::return_x#7 get::return_x#2 get::return_x#3 get::return_x#4 ] +reg byte x [ get::return_y#7 get::return_y#2 get::return_y#3 get::return_y#4 ] reg byte a [ get::return_x#0 ] reg byte x [ get::return_y#0 ] reg byte a [ main::$0_x ] @@ -741,8 +735,8 @@ main: { lda #0 jsr get // get(0) - // [2] get::return_x#0 = get::return_x#5 - // [3] get::return_y#0 = get::return_y#5 + // [2] get::return_x#0 = get::return_x#7 + // [3] get::return_y#0 = get::return_y#7 // main::@2 // [4] main::$0_x = get::return_x#0 // [5] main::$0_y = get::return_y#0 @@ -766,8 +760,8 @@ main: { // [21] phi get::i#2 = get::i#1 [phi:main::@1->get#0] -- register_copy jsr get // get(i) - // [11] get::return_x#1 = get::return_x#5 - // [12] get::return_y#1 = get::return_y#5 + // [11] get::return_x#1 = get::return_x#7 + // [12] get::return_y#1 = get::return_y#7 // main::@3 // [13] main::$1_x = get::return_x#1 -- vbuz1=vbuaa sta.z __1_x @@ -814,8 +808,8 @@ get: { // [25] get::return_y#4 = *((byte*)p2+OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1 ldx p2+OFFSET_STRUCT_POINT_Y // [26] phi from get::@1 get::@2 get::@4 to get::@return [phi:get::@1/get::@2/get::@4->get::@return] - // [26] phi get::return_y#5 = get::return_y#2 [phi:get::@1/get::@2/get::@4->get::@return#0] -- register_copy - // [26] phi get::return_x#5 = get::return_x#2 [phi:get::@1/get::@2/get::@4->get::@return#1] -- register_copy + // [26] phi get::return_y#7 = get::return_y#2 [phi:get::@1/get::@2/get::@4->get::@return#0] -- register_copy + // [26] phi get::return_x#7 = get::return_x#2 [phi:get::@1/get::@2/get::@4->get::@return#1] -- register_copy // get::@return // } // [27] return diff --git a/src/test/ref/struct-ptr-16.sym b/src/test/ref/struct-ptr-16.sym index 5bc7263e0..e6a2d629e 100644 --- a/src/test/ref/struct-ptr-16.sym +++ b/src/test/ref/struct-ptr-16.sym @@ -11,14 +11,14 @@ byte get::return_x#1 reg byte a 11.0 byte get::return_x#2 reg byte a 101.0 byte get::return_x#3 reg byte a 101.0 byte get::return_x#4 reg byte a 101.0 -byte get::return_x#5 reg byte a 79.0 +byte get::return_x#7 reg byte a 79.0 byte get::return_y byte get::return_y#0 reg byte x 2.0 byte get::return_y#1 reg byte x 11.0 byte get::return_y#2 reg byte x 202.0 byte get::return_y#3 reg byte x 202.0 byte get::return_y#4 reg byte x 202.0 -byte get::return_y#5 reg byte x 52.66666666666666 +byte get::return_y#7 reg byte x 52.66666666666666 void main() byte~ main::$0_x reg byte a 2.0 byte~ main::$0_y reg byte x 2.0 @@ -34,8 +34,8 @@ constant struct Point* p2 = (struct Point*) 57344 reg byte y [ main::i#2 main::i#1 ] reg byte a [ get::i#2 get::i#1 ] -reg byte a [ get::return_x#5 get::return_x#2 get::return_x#3 get::return_x#4 ] -reg byte x [ get::return_y#5 get::return_y#2 get::return_y#3 get::return_y#4 ] +reg byte a [ get::return_x#7 get::return_x#2 get::return_x#3 get::return_x#4 ] +reg byte x [ get::return_y#7 get::return_y#2 get::return_y#3 get::return_y#4 ] reg byte a [ get::return_x#0 ] reg byte x [ get::return_y#0 ] reg byte a [ main::$0_x ] diff --git a/src/test/ref/struct-ptr-17.log b/src/test/ref/struct-ptr-17.log index 8a6aa3cf5..9dae1bb3b 100644 --- a/src/test/ref/struct-ptr-17.log +++ b/src/test/ref/struct-ptr-17.log @@ -3,8 +3,8 @@ Eliminating unused variable with no statement main::$0 Eliminating unused variable with no statement main::$1 Unwinding list assignment { main::$0_x, main::$0_y } = { get::return_x, get::return_y } Unwinding list assignment { main::$1_x, main::$1_y } = { get::return_x, get::return_y } -Unwinding list assignment { get::return_x#0, get::return_y#0 } = { get::return_x#3, get::return_y#3 } -Unwinding list assignment { get::return_x#1, get::return_y#1 } = { get::return_x#3, get::return_y#3 } +Unwinding list assignment { get::return_x#0, get::return_y#0 } = { get::return_x#5, get::return_y#5 } +Unwinding list assignment { get::return_x#1, get::return_y#1 } = { get::return_x#5, get::return_y#5 } CONTROL FLOW GRAPH SSA @@ -12,14 +12,14 @@ void main() main: scope:[main] from __start::@1 get::i#0 = 0 call get - get::return_x#0 = get::return_x#3 - get::return_y#0 = get::return_y#3 + get::return_x#0 = get::return_x#5 + get::return_y#0 = get::return_y#5 to:main::@2 main::@2: scope:[main] from main - get::return_y#4 = phi( main/get::return_y#0 ) - get::return_x#4 = phi( main/get::return_x#0 ) - main::$0_x = get::return_x#4 - main::$0_y = get::return_y#4 + get::return_y#3 = phi( main/get::return_y#0 ) + get::return_x#3 = phi( main/get::return_x#0 ) + main::$0_x = get::return_x#3 + main::$0_y = get::return_y#3 *((byte*)SCREEN+OFFSET_STRUCT_POINT_X) = main::$0_x *((byte*)SCREEN+OFFSET_STRUCT_POINT_Y) = main::$0_y main::i#0 = 1 @@ -28,15 +28,15 @@ main::@1: scope:[main] from main::@2 main::@3 main::i#2 = phi( main::@2/main::i#0, main::@3/main::i#1 ) get::i#1 = main::i#2 call get - get::return_x#1 = get::return_x#3 - get::return_y#1 = get::return_y#3 + get::return_x#1 = get::return_x#5 + get::return_y#1 = get::return_y#5 to:main::@3 main::@3: scope:[main] from main::@1 main::i#3 = phi( main::@1/main::i#2 ) - get::return_y#5 = phi( main::@1/get::return_y#1 ) - get::return_x#5 = phi( main::@1/get::return_x#1 ) - main::$1_x = get::return_x#5 - main::$1_y = get::return_y#5 + get::return_y#4 = phi( main::@1/get::return_y#1 ) + get::return_x#4 = phi( main::@1/get::return_x#1 ) + main::$1_x = get::return_x#4 + main::$1_y = get::return_y#4 main::$3 = main::i#3 * SIZEOF_STRUCT_POINT ((byte*)SCREEN+OFFSET_STRUCT_POINT_X)[main::$3] = main::$1_x ((byte*)SCREEN+OFFSET_STRUCT_POINT_Y)[main::$3] = main::$1_y @@ -57,11 +57,9 @@ get: scope:[get] from main main::@1 get::return#0 = struct-unwound {get::return_x#2, get::return_y#2} to:get::@return get::@return: scope:[get] from get - get::return_y#6 = phi( get/get::return_y#2 ) - get::return_x#6 = phi( get/get::return_x#2 ) - get::return_x#3 = get::return_x#6 - get::return_y#3 = get::return_y#6 - get::return#1 = struct-unwound {get::return_x#3, get::return_y#3} + get::return_y#5 = phi( get/get::return_y#2 ) + get::return_x#5 = phi( get/get::return_x#2 ) + get::return#1 = struct-unwound {} return to:@return @@ -103,7 +101,6 @@ byte get::return_x#2 byte get::return_x#3 byte get::return_x#4 byte get::return_x#5 -byte get::return_x#6 byte get::return_y byte get::return_y#0 byte get::return_y#1 @@ -111,7 +108,6 @@ byte get::return_y#2 byte get::return_y#3 byte get::return_y#4 byte get::return_y#5 -byte get::return_y#6 void main() byte~ main::$0_x byte~ main::$0_y @@ -134,13 +130,13 @@ Simplifying constant integer cast 0 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 0 Successful SSA optimization PassNFinalizeNumberTypeConversions -Alias get::return_x#0 = get::return_x#4 -Alias get::return_y#0 = get::return_y#4 -Alias get::return_x#1 = get::return_x#5 -Alias get::return_y#1 = get::return_y#5 +Alias get::return_x#0 = get::return_x#3 +Alias get::return_y#0 = get::return_y#3 +Alias get::return_x#1 = get::return_x#4 +Alias get::return_y#1 = get::return_y#4 Alias main::i#2 = main::i#3 -Alias get::return_x#2 = get::p_x#0 get::i#2 get::return_x#6 get::return_x#3 -Alias get::return_y#2 = get::return_y#6 get::return_y#3 +Alias get::return_x#2 = get::p_x#0 get::i#2 get::return_x#5 +Alias get::return_y#2 = get::return_y#5 Successful SSA optimization Pass2AliasElimination Simple Condition main::$2 [21] if(main::i#1!=rangelast(1,2)) goto main::@1 Successful SSA optimization Pass2ConditionalJumpSimplification @@ -160,7 +156,7 @@ Simplifying expression containing zero (byte*)SCREEN in [6] *((byte*)SCREEN+OFFS Simplifying expression containing zero (byte*)SCREEN in [17] ((byte*)SCREEN+OFFSET_STRUCT_POINT_X)[main::$3] = main::$1_x Successful SSA optimization PassNSimplifyExpressionWithZero Eliminating unused variable get::return#0 and assignment [17] get::return#0 = struct-unwound {get::return_x#2, get::return_y#2} -Eliminating unused variable get::return#1 and assignment [18] get::return#1 = struct-unwound {get::return_x#2, get::return_y#2} +Eliminating unused variable get::return#1 and assignment [18] get::return#1 = struct-unwound {} Eliminating unused constant OFFSET_STRUCT_POINT_X Successful SSA optimization PassNEliminateUnusedVars Removing unused procedure __start @@ -196,7 +192,7 @@ CALL GRAPH Calls in [main] to get:1 get:9 Created 2 initial phi equivalence classes -Coalesced [8] get::return_x#7 = get::i#1 +Coalesced [8] get::return_x#6 = get::i#1 Coalesced [18] main::i#4 = main::i#1 Coalesced down to 2 phi equivalence classes Culled Empty Block label main::@4 diff --git a/src/test/ref/tod-1.cfg b/src/test/ref/tod-1.cfg index 168ff0fc2..38a3c055e 100644 --- a/src/test/ref/tod-1.cfg +++ b/src/test/ref/tod-1.cfg @@ -50,16 +50,16 @@ main::@1: scope:[main] from main main::@4 main::@2: scope:[main] from main::@1 [23] phi() [24] call tod_read - [25] tod_read::return_TENTHS#2 = tod_read::return_TENTHS#0 - [26] tod_read::return_SEC#2 = tod_read::return_SEC#0 - [27] tod_read::return_MIN#2 = tod_read::return_MIN#0 - [28] tod_read::return_HOURS#2 = tod_read::return_HOURS#0 + [25] tod_read::return_TENTHS#1 = tod_read::return_TENTHS#0 + [26] tod_read::return_SEC#1 = tod_read::return_SEC#0 + [27] tod_read::return_MIN#1 = tod_read::return_MIN#0 + [28] tod_read::return_HOURS#1 = tod_read::return_HOURS#0 to:main::@3 main::@3: scope:[main] from main::@2 - [29] tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 - [30] tod_str::tod_SEC#0 = tod_read::return_SEC#2 - [31] tod_str::tod_MIN#0 = tod_read::return_MIN#2 - [32] tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 + [29] tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 + [30] tod_str::tod_SEC#0 = tod_read::return_SEC#1 + [31] tod_str::tod_MIN#0 = tod_read::return_MIN#1 + [32] tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 [33] call tod_str to:main::@4 main::@4: scope:[main] from main::@3 diff --git a/src/test/ref/tod-1.log b/src/test/ref/tod-1.log index 4142a8c92..9a5b8fb53 100644 --- a/src/test/ref/tod-1.log +++ b/src/test/ref/tod-1.log @@ -2,7 +2,7 @@ Inlined call vicSelectGfxBank::$0 = call toDd00 vicSelectGfxBank::gfx Inlined call call __init Eliminating unused variable with no statement main::$2 Unwinding list assignment { main::$2_TENTHS, main::$2_SEC, main::$2_MIN, main::$2_HOURS } = { tod_read::return_TENTHS, tod_read::return_SEC, tod_read::return_MIN, tod_read::return_HOURS } -Unwinding list assignment { tod_read::return_TENTHS#2, tod_read::return_SEC#2, tod_read::return_MIN#2, tod_read::return_HOURS#2 } = { tod_read::return_TENTHS#1, tod_read::return_SEC#1, tod_read::return_MIN#1, tod_read::return_HOURS#1 } +Unwinding list assignment { tod_read::return_TENTHS#1, tod_read::return_SEC#1, tod_read::return_MIN#1, tod_read::return_HOURS#1 } = { tod_read::return_TENTHS#2, tod_read::return_SEC#2, tod_read::return_MIN#2, tod_read::return_HOURS#2 } CONTROL FLOW GRAPH SSA @@ -308,15 +308,11 @@ tod_read: scope:[tod_read] from main::@4 tod_read::return#0 = struct-unwound {tod_read::return_TENTHS#0, tod_read::return_SEC#0, tod_read::return_MIN#0, tod_read::return_HOURS#0} to:tod_read::@return tod_read::@return: scope:[tod_read] from tod_read - tod_read::return_HOURS#3 = phi( tod_read/tod_read::return_HOURS#0 ) - tod_read::return_MIN#3 = phi( tod_read/tod_read::return_MIN#0 ) - tod_read::return_SEC#3 = phi( tod_read/tod_read::return_SEC#0 ) - tod_read::return_TENTHS#3 = phi( tod_read/tod_read::return_TENTHS#0 ) - tod_read::return_TENTHS#1 = tod_read::return_TENTHS#3 - tod_read::return_SEC#1 = tod_read::return_SEC#3 - tod_read::return_MIN#1 = tod_read::return_MIN#3 - tod_read::return_HOURS#1 = tod_read::return_HOURS#3 - tod_read::return#1 = struct-unwound {tod_read::return_TENTHS#1, tod_read::return_SEC#1, tod_read::return_MIN#1, tod_read::return_HOURS#1} + tod_read::return_HOURS#2 = phi( tod_read/tod_read::return_HOURS#0 ) + tod_read::return_MIN#2 = phi( tod_read/tod_read::return_MIN#0 ) + tod_read::return_SEC#2 = phi( tod_read/tod_read::return_SEC#0 ) + tod_read::return_TENTHS#2 = phi( tod_read/tod_read::return_TENTHS#0 ) + tod_read::return#1 = struct-unwound {} return to:@return @@ -379,20 +375,20 @@ main::@2: scope:[main] from main::@1 to:main::@4 main::@4: scope:[main] from main::@2 call tod_read - tod_read::return_TENTHS#2 = tod_read::return_TENTHS#1 - tod_read::return_SEC#2 = tod_read::return_SEC#1 - tod_read::return_MIN#2 = tod_read::return_MIN#1 - tod_read::return_HOURS#2 = tod_read::return_HOURS#1 + tod_read::return_TENTHS#1 = tod_read::return_TENTHS#2 + tod_read::return_SEC#1 = tod_read::return_SEC#2 + tod_read::return_MIN#1 = tod_read::return_MIN#2 + tod_read::return_HOURS#1 = tod_read::return_HOURS#2 to:main::@5 main::@5: scope:[main] from main::@4 - tod_read::return_HOURS#4 = phi( main::@4/tod_read::return_HOURS#2 ) - tod_read::return_MIN#4 = phi( main::@4/tod_read::return_MIN#2 ) - tod_read::return_SEC#4 = phi( main::@4/tod_read::return_SEC#2 ) - tod_read::return_TENTHS#4 = phi( main::@4/tod_read::return_TENTHS#2 ) - main::$2_TENTHS = tod_read::return_TENTHS#4 - main::$2_SEC = tod_read::return_SEC#4 - main::$2_MIN = tod_read::return_MIN#4 - main::$2_HOURS = tod_read::return_HOURS#4 + tod_read::return_HOURS#3 = phi( main::@4/tod_read::return_HOURS#1 ) + tod_read::return_MIN#3 = phi( main::@4/tod_read::return_MIN#1 ) + tod_read::return_SEC#3 = phi( main::@4/tod_read::return_SEC#1 ) + tod_read::return_TENTHS#3 = phi( main::@4/tod_read::return_TENTHS#1 ) + main::$2_TENTHS = tod_read::return_TENTHS#3 + main::$2_SEC = tod_read::return_SEC#3 + main::$2_MIN = tod_read::return_MIN#3 + main::$2_HOURS = tod_read::return_HOURS#3 tod_str::tod_TENTHS#0 = main::$2_TENTHS tod_str::tod_SEC#0 = main::$2_SEC tod_str::tod_MIN#0 = main::$2_MIN @@ -640,25 +636,21 @@ byte tod_read::return_HOURS#0 byte tod_read::return_HOURS#1 byte tod_read::return_HOURS#2 byte tod_read::return_HOURS#3 -byte tod_read::return_HOURS#4 byte tod_read::return_MIN byte tod_read::return_MIN#0 byte tod_read::return_MIN#1 byte tod_read::return_MIN#2 byte tod_read::return_MIN#3 -byte tod_read::return_MIN#4 byte tod_read::return_SEC byte tod_read::return_SEC#0 byte tod_read::return_SEC#1 byte tod_read::return_SEC#2 byte tod_read::return_SEC#3 -byte tod_read::return_SEC#4 byte tod_read::return_TENTHS byte tod_read::return_TENTHS#0 byte tod_read::return_TENTHS#1 byte tod_read::return_TENTHS#2 byte tod_read::return_TENTHS#3 -byte tod_read::return_TENTHS#4 byte tod_read::secs byte tod_read::secs#0 byte tod_read::tenths @@ -919,15 +911,15 @@ Alias memset::c#2 = memset::c#3 Alias memset::dst#2 = memset::dst#3 Alias memset::end#1 = memset::end#2 Alias memset::str#5 = memset::str#6 -Alias tod_read::return_TENTHS#0 = tod_read::tod_TENTHS#0 tod_read::tenths#0 tod_read::return_TENTHS#3 tod_read::return_TENTHS#1 -Alias tod_read::return_SEC#0 = tod_read::tod_SEC#0 tod_read::secs#0 tod_read::return_SEC#3 tod_read::return_SEC#1 -Alias tod_read::return_MIN#0 = tod_read::tod_MIN#0 tod_read::mins#0 tod_read::return_MIN#3 tod_read::return_MIN#1 -Alias tod_read::return_HOURS#0 = tod_read::tod_HOURS#0 tod_read::hours#0 tod_read::return_HOURS#3 tod_read::return_HOURS#1 +Alias tod_read::return_TENTHS#0 = tod_read::tod_TENTHS#0 tod_read::tenths#0 tod_read::return_TENTHS#2 +Alias tod_read::return_SEC#0 = tod_read::tod_SEC#0 tod_read::secs#0 tod_read::return_SEC#2 +Alias tod_read::return_MIN#0 = tod_read::tod_MIN#0 tod_read::mins#0 tod_read::return_MIN#2 +Alias tod_read::return_HOURS#0 = tod_read::tod_HOURS#0 tod_read::hours#0 tod_read::return_HOURS#2 Alias tod_str::return#0 = tod_str::return#3 tod_str::return#1 -Alias tod_read::return_TENTHS#2 = tod_read::return_TENTHS#4 -Alias tod_read::return_SEC#2 = tod_read::return_SEC#4 -Alias tod_read::return_MIN#2 = tod_read::return_MIN#4 -Alias tod_read::return_HOURS#2 = tod_read::return_HOURS#4 +Alias tod_read::return_TENTHS#1 = tod_read::return_TENTHS#3 +Alias tod_read::return_SEC#1 = tod_read::return_SEC#3 +Alias tod_read::return_MIN#1 = tod_read::return_MIN#3 +Alias tod_read::return_HOURS#1 = tod_read::return_HOURS#3 Alias tod_str::tod_TENTHS#0 = main::$2_TENTHS Alias tod_str::tod_SEC#0 = main::$2_SEC Alias tod_str::tod_MIN#0 = main::$2_MIN @@ -1025,7 +1017,7 @@ Eliminating unused variable memcpy::return#3 and assignment [60] memcpy::return# Eliminating unused variable memset::return#2 and assignment [62] memset::return#2 = memset::str#3 Eliminating unused variable memset::return#3 and assignment [64] memset::return#3 = memset::str#3 Eliminating unused variable tod_read::return#0 and assignment [86] tod_read::return#0 = struct-unwound {tod_read::return_TENTHS#0, tod_read::return_SEC#0, tod_read::return_MIN#0, tod_read::return_HOURS#0} -Eliminating unused variable tod_read::return#1 and assignment [87] tod_read::return#1 = struct-unwound {tod_read::return_TENTHS#0, tod_read::return_SEC#0, tod_read::return_MIN#0, tod_read::return_HOURS#0} +Eliminating unused variable tod_read::return#1 and assignment [87] tod_read::return#1 = struct-unwound {} Eliminating unused constant gotoxy::x#1 Eliminating unused constant gotoxy::y#1 Eliminating unused constant cputs::c#0 @@ -1282,16 +1274,16 @@ main::@1: scope:[main] from main main::@4 main::@2: scope:[main] from main::@1 [23] phi() [24] call tod_read - [25] tod_read::return_TENTHS#2 = tod_read::return_TENTHS#0 - [26] tod_read::return_SEC#2 = tod_read::return_SEC#0 - [27] tod_read::return_MIN#2 = tod_read::return_MIN#0 - [28] tod_read::return_HOURS#2 = tod_read::return_HOURS#0 + [25] tod_read::return_TENTHS#1 = tod_read::return_TENTHS#0 + [26] tod_read::return_SEC#1 = tod_read::return_SEC#0 + [27] tod_read::return_MIN#1 = tod_read::return_MIN#0 + [28] tod_read::return_HOURS#1 = tod_read::return_HOURS#0 to:main::@3 main::@3: scope:[main] from main::@2 - [29] tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 - [30] tod_str::tod_SEC#0 = tod_read::return_SEC#2 - [31] tod_str::tod_MIN#0 = tod_read::return_MIN#2 - [32] tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 + [29] tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 + [30] tod_str::tod_SEC#0 = tod_read::return_SEC#1 + [31] tod_str::tod_MIN#0 = tod_read::return_MIN#1 + [32] tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 [33] call tod_str to:main::@4 main::@4: scope:[main] from main::@3 @@ -1589,16 +1581,16 @@ byte tod_read::mins struct TIME_OF_DAY tod_read::return byte tod_read::return_HOURS byte tod_read::return_HOURS#0 122.44444444444446 -byte tod_read::return_HOURS#2 50.5 +byte tod_read::return_HOURS#1 50.5 byte tod_read::return_MIN byte tod_read::return_MIN#0 157.42857142857142 -byte tod_read::return_MIN#2 50.5 +byte tod_read::return_MIN#1 50.5 byte tod_read::return_SEC byte tod_read::return_SEC#0 220.39999999999998 -byte tod_read::return_SEC#2 50.5 +byte tod_read::return_SEC#1 50.5 byte tod_read::return_TENTHS byte tod_read::return_TENTHS#0 367.33333333333337 -byte tod_read::return_TENTHS#2 50.5 +byte tod_read::return_TENTHS#1 50.5 byte tod_read::secs byte tod_read::tenths byte tod_read::tod_HOURS @@ -1652,10 +1644,10 @@ Added variable tod_init::tod_TENTHS#0 to live range equivalence class [ tod_init Added variable tod_init::tod_SEC#0 to live range equivalence class [ tod_init::tod_SEC#0 ] Added variable tod_init::tod_MIN#0 to live range equivalence class [ tod_init::tod_MIN#0 ] Added variable tod_init::tod_HOURS#0 to live range equivalence class [ tod_init::tod_HOURS#0 ] -Added variable tod_read::return_TENTHS#2 to live range equivalence class [ tod_read::return_TENTHS#2 ] -Added variable tod_read::return_SEC#2 to live range equivalence class [ tod_read::return_SEC#2 ] -Added variable tod_read::return_MIN#2 to live range equivalence class [ tod_read::return_MIN#2 ] -Added variable tod_read::return_HOURS#2 to live range equivalence class [ tod_read::return_HOURS#2 ] +Added variable tod_read::return_TENTHS#1 to live range equivalence class [ tod_read::return_TENTHS#1 ] +Added variable tod_read::return_SEC#1 to live range equivalence class [ tod_read::return_SEC#1 ] +Added variable tod_read::return_MIN#1 to live range equivalence class [ tod_read::return_MIN#1 ] +Added variable tod_read::return_HOURS#1 to live range equivalence class [ tod_read::return_HOURS#1 ] Added variable tod_str::tod_TENTHS#0 to live range equivalence class [ tod_str::tod_TENTHS#0 ] Added variable tod_str::tod_SEC#0 to live range equivalence class [ tod_str::tod_SEC#0 ] Added variable tod_str::tod_MIN#0 to live range equivalence class [ tod_str::tod_MIN#0 ] @@ -1710,10 +1702,10 @@ Complete equivalence classes [ tod_init::tod_SEC#0 ] [ tod_init::tod_MIN#0 ] [ tod_init::tod_HOURS#0 ] -[ tod_read::return_TENTHS#2 ] -[ tod_read::return_SEC#2 ] -[ tod_read::return_MIN#2 ] -[ tod_read::return_HOURS#2 ] +[ tod_read::return_TENTHS#1 ] +[ tod_read::return_SEC#1 ] +[ tod_read::return_MIN#1 ] +[ tod_read::return_HOURS#1 ] [ tod_str::tod_TENTHS#0 ] [ tod_str::tod_SEC#0 ] [ tod_str::tod_MIN#0 ] @@ -1767,10 +1759,10 @@ Allocated zp[1]:25 [ tod_init::tod_TENTHS#0 ] Allocated zp[1]:26 [ tod_init::tod_SEC#0 ] Allocated zp[1]:27 [ tod_init::tod_MIN#0 ] Allocated zp[1]:28 [ tod_init::tod_HOURS#0 ] -Allocated zp[1]:29 [ tod_read::return_TENTHS#2 ] -Allocated zp[1]:30 [ tod_read::return_SEC#2 ] -Allocated zp[1]:31 [ tod_read::return_MIN#2 ] -Allocated zp[1]:32 [ tod_read::return_HOURS#2 ] +Allocated zp[1]:29 [ tod_read::return_TENTHS#1 ] +Allocated zp[1]:30 [ tod_read::return_SEC#1 ] +Allocated zp[1]:31 [ tod_read::return_MIN#1 ] +Allocated zp[1]:32 [ tod_read::return_HOURS#1 ] Allocated zp[1]:33 [ tod_str::tod_TENTHS#0 ] Allocated zp[1]:34 [ tod_str::tod_SEC#0 ] Allocated zp[1]:35 [ tod_str::tod_MIN#0 ] @@ -1827,18 +1819,18 @@ Removing always clobbered register reg byte a as potential for zp[1]:26 [ tod_in Removing always clobbered register reg byte a as potential for zp[1]:27 [ tod_init::tod_MIN#0 ] Removing always clobbered register reg byte a as potential for zp[1]:28 [ tod_init::tod_HOURS#0 ] Statement [52] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_TIMER_B_CONTROL) = *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_TIMER_B_CONTROL) & $7f [ tod_init::tod_TENTHS#0 tod_init::tod_SEC#0 tod_init::tod_MIN#0 tod_init::tod_HOURS#0 ] ( main:7::tod_init:20 [ tod_init::tod_TENTHS#0 tod_init::tod_SEC#0 tod_init::tod_MIN#0 tod_init::tod_HOURS#0 ] { } ) always clobbers reg byte a -Statement [63] tod_str::$0 = tod_str::tod_HOURS#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::tod_HOURS#0 tod_str::$0 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::tod_HOURS#0 tod_str::$0 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a +Statement [63] tod_str::$0 = tod_str::tod_HOURS#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::tod_HOURS#0 tod_str::$0 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::tod_HOURS#0 tod_str::$0 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:33 [ tod_str::tod_TENTHS#0 ] Removing always clobbered register reg byte a as potential for zp[1]:34 [ tod_str::tod_SEC#0 ] Removing always clobbered register reg byte a as potential for zp[1]:35 [ tod_str::tod_MIN#0 ] Removing always clobbered register reg byte a as potential for zp[1]:36 [ tod_str::tod_HOURS#0 ] -Statement [66] tod_str::$2 = tod_str::tod_HOURS#0 & $f [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$2 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$2 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [69] tod_str::$4 = tod_str::tod_MIN#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$4 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$4 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [72] tod_str::$6 = tod_str::tod_MIN#0 & $f [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$6 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$6 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [75] tod_str::$8 = tod_str::tod_SEC#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$8 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$8 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [78] tod_str::$10 = tod_str::tod_SEC#0 & $f [ tod_str::tod_TENTHS#0 tod_str::$10 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::$10 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [81] tod_str::$12 = tod_str::tod_TENTHS#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::$12 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::$12 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [84] tod_str::$14 = tod_str::tod_TENTHS#0 & $f [ tod_str::$14 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::$14 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a +Statement [66] tod_str::$2 = tod_str::tod_HOURS#0 & $f [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$2 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$2 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [69] tod_str::$4 = tod_str::tod_MIN#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$4 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$4 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [72] tod_str::$6 = tod_str::tod_MIN#0 & $f [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$6 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$6 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [75] tod_str::$8 = tod_str::tod_SEC#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$8 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$8 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [78] tod_str::$10 = tod_str::tod_SEC#0 & $f [ tod_str::tod_TENTHS#0 tod_str::$10 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::$10 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [81] tod_str::$12 = tod_str::tod_TENTHS#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::$12 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::$12 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [84] tod_str::$14 = tod_str::tod_TENTHS#0 & $f [ tod_str::$14 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::$14 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a Statement [90] cputs::c#1 = *cputs::s#2 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#2 cputs::c#1 ] ( main:7::cputs:35 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#2 cputs::c#1 ] { } ) always clobbers reg byte a reg byte y Statement [97] conio_line_text[conio_cursor_x] = cputc::c#0 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:35::cputc:95 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte y Statement [98] conio_line_color[conio_cursor_x] = LIGHT_BLUE [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:35::cputc:95 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y @@ -1875,14 +1867,14 @@ Statement [48] gotoxy::$6 = COLORRAM + gotoxy::line_offset#0 [ conio_cursor_x co Statement [49] conio_line_color = gotoxy::$6 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( gotoxy:14 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { gotoxy::y#2 = gotoxy::y#4 conio_c64_init::line#2 } } conio_c64_init:5::gotoxy:14 [ TOD_ZERO conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { gotoxy::y#2 = gotoxy::y#4 conio_c64_init::line#2 } } main:7::gotoxy:22 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { } ) always clobbers reg byte a Statement [51] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_TIMER_A_CONTROL) = *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_TIMER_A_CONTROL) | $80 [ tod_init::tod_TENTHS#0 tod_init::tod_SEC#0 tod_init::tod_MIN#0 tod_init::tod_HOURS#0 ] ( main:7::tod_init:20 [ tod_init::tod_TENTHS#0 tod_init::tod_SEC#0 tod_init::tod_MIN#0 tod_init::tod_HOURS#0 ] { } ) always clobbers reg byte a Statement [52] *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_TIMER_B_CONTROL) = *((byte*)CIA1+OFFSET_STRUCT_MOS6526_CIA_TIMER_B_CONTROL) & $7f [ tod_init::tod_TENTHS#0 tod_init::tod_SEC#0 tod_init::tod_MIN#0 tod_init::tod_HOURS#0 ] ( main:7::tod_init:20 [ tod_init::tod_TENTHS#0 tod_init::tod_SEC#0 tod_init::tod_MIN#0 tod_init::tod_HOURS#0 ] { } ) always clobbers reg byte a -Statement [63] tod_str::$0 = tod_str::tod_HOURS#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::tod_HOURS#0 tod_str::$0 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::tod_HOURS#0 tod_str::$0 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [66] tod_str::$2 = tod_str::tod_HOURS#0 & $f [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$2 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$2 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [69] tod_str::$4 = tod_str::tod_MIN#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$4 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$4 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [72] tod_str::$6 = tod_str::tod_MIN#0 & $f [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$6 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$6 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [75] tod_str::$8 = tod_str::tod_SEC#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$8 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$8 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [78] tod_str::$10 = tod_str::tod_SEC#0 & $f [ tod_str::tod_TENTHS#0 tod_str::$10 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::$10 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [81] tod_str::$12 = tod_str::tod_TENTHS#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::$12 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::$12 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a -Statement [84] tod_str::$14 = tod_str::tod_TENTHS#0 & $f [ tod_str::$14 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::$14 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 } { tod_str::tod_SEC#0 = tod_read::return_SEC#2 } { tod_str::tod_MIN#0 = tod_read::return_MIN#2 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 } } ) always clobbers reg byte a +Statement [63] tod_str::$0 = tod_str::tod_HOURS#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::tod_HOURS#0 tod_str::$0 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::tod_HOURS#0 tod_str::$0 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [66] tod_str::$2 = tod_str::tod_HOURS#0 & $f [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$2 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$2 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [69] tod_str::$4 = tod_str::tod_MIN#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$4 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::tod_MIN#0 tod_str::$4 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [72] tod_str::$6 = tod_str::tod_MIN#0 & $f [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$6 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$6 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [75] tod_str::$8 = tod_str::tod_SEC#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$8 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::tod_SEC#0 tod_str::$8 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [78] tod_str::$10 = tod_str::tod_SEC#0 & $f [ tod_str::tod_TENTHS#0 tod_str::$10 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::$10 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [81] tod_str::$12 = tod_str::tod_TENTHS#0 >> 4 [ tod_str::tod_TENTHS#0 tod_str::$12 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::tod_TENTHS#0 tod_str::$12 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a +Statement [84] tod_str::$14 = tod_str::tod_TENTHS#0 & $f [ tod_str::$14 ] ( main:7::tod_str:33 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color tod_str::$14 ] { { tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 } { tod_str::tod_SEC#0 = tod_read::return_SEC#1 } { tod_str::tod_MIN#0 = tod_read::return_MIN#1 } { tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 } } ) always clobbers reg byte a Statement [90] cputs::c#1 = *cputs::s#2 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#2 cputs::c#1 ] ( main:7::cputs:35 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color cputs::s#2 cputs::c#1 ] { } ) always clobbers reg byte a reg byte y Statement [97] conio_line_text[conio_cursor_x] = cputc::c#0 [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:35::cputc:95 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte y Statement [98] conio_line_color[conio_cursor_x] = LIGHT_BLUE [ conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] ( main:7::cputs:35::cputc:95 [ cputs::s#0 conio_cursor_x conio_cursor_y conio_line_text conio_line_color ] { { cputc::c#0 = cputs::c#1 } } ) always clobbers reg byte a reg byte y @@ -1920,10 +1912,10 @@ Potential registers zp[1]:25 [ tod_init::tod_TENTHS#0 ] : zp[1]:25 , reg byte x Potential registers zp[1]:26 [ tod_init::tod_SEC#0 ] : zp[1]:26 , reg byte x , reg byte y , Potential registers zp[1]:27 [ tod_init::tod_MIN#0 ] : zp[1]:27 , reg byte x , reg byte y , Potential registers zp[1]:28 [ tod_init::tod_HOURS#0 ] : zp[1]:28 , reg byte x , reg byte y , -Potential registers zp[1]:29 [ tod_read::return_TENTHS#2 ] : zp[1]:29 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:30 [ tod_read::return_SEC#2 ] : zp[1]:30 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:31 [ tod_read::return_MIN#2 ] : zp[1]:31 , reg byte a , reg byte x , reg byte y , -Potential registers zp[1]:32 [ tod_read::return_HOURS#2 ] : zp[1]:32 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:29 [ tod_read::return_TENTHS#1 ] : zp[1]:29 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:30 [ tod_read::return_SEC#1 ] : zp[1]:30 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:31 [ tod_read::return_MIN#1 ] : zp[1]:31 , reg byte a , reg byte x , reg byte y , +Potential registers zp[1]:32 [ tod_read::return_HOURS#1 ] : zp[1]:32 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:33 [ tod_str::tod_TENTHS#0 ] : zp[1]:33 , reg byte x , reg byte y , Potential registers zp[1]:34 [ tod_str::tod_SEC#0 ] : zp[1]:34 , reg byte x , reg byte y , Potential registers zp[1]:35 [ tod_str::tod_MIN#0 ] : zp[1]:35 , reg byte x , reg byte y , @@ -1968,7 +1960,7 @@ Uplift Scope [cputc] 1,050,001.5: zp[1]:70 [ cputc::c#0 ] Uplift Scope [cputs] 200,002: zp[2]:4 [ cputs::s#2 cputs::s#0 ] 100,001: zp[1]:69 [ cputs::c#1 ] Uplift Scope [tod_str] 2,002: zp[1]:53 [ tod_str::$0 ] 2,002: zp[1]:54 [ tod_str::$1 ] 2,002: zp[1]:55 [ tod_str::$2 ] 2,002: zp[1]:56 [ tod_str::$3 ] 2,002: zp[1]:57 [ tod_str::$4 ] 2,002: zp[1]:58 [ tod_str::$5 ] 2,002: zp[1]:59 [ tod_str::$6 ] 2,002: zp[1]:60 [ tod_str::$7 ] 2,002: zp[1]:61 [ tod_str::$8 ] 2,002: zp[1]:62 [ tod_str::$9 ] 2,002: zp[1]:63 [ tod_str::$10 ] 2,002: zp[1]:64 [ tod_str::$11 ] 2,002: zp[1]:65 [ tod_str::$12 ] 2,002: zp[1]:66 [ tod_str::$13 ] 2,002: zp[1]:67 [ tod_str::$14 ] 2,002: zp[1]:68 [ tod_str::$15 ] 525.75: zp[1]:36 [ tod_str::tod_HOURS#0 ] 191.18: zp[1]:35 [ tod_str::tod_MIN#0 ] 116.83: zp[1]:34 [ tod_str::tod_SEC#0 ] 84.12: zp[1]:33 [ tod_str::tod_TENTHS#0 ] Uplift Scope [gotoxy] 2,002: zp[2]:39 [ gotoxy::$8 ] 2,002: zp[2]:41 [ gotoxy::$9 ] 2,002: zp[2]:45 [ gotoxy::$5 ] 2,002: zp[2]:47 [ gotoxy::$6 ] 1,501.5: zp[2]:37 [ gotoxy::$7 ] 1,360.33: zp[1]:3 [ gotoxy::y#5 gotoxy::y#4 gotoxy::y#2 ] 1,001: zp[2]:43 [ gotoxy::line_offset#0 ] -Uplift Scope [tod_read] 367.33: zp[1]:52 [ tod_read::return_TENTHS#0 ] 220.4: zp[1]:51 [ tod_read::return_SEC#0 ] 157.43: zp[1]:50 [ tod_read::return_MIN#0 ] 122.44: zp[1]:49 [ tod_read::return_HOURS#0 ] 50.5: zp[1]:29 [ tod_read::return_TENTHS#2 ] 50.5: zp[1]:30 [ tod_read::return_SEC#2 ] 50.5: zp[1]:31 [ tod_read::return_MIN#2 ] 50.5: zp[1]:32 [ tod_read::return_HOURS#2 ] +Uplift Scope [tod_read] 367.33: zp[1]:52 [ tod_read::return_TENTHS#0 ] 220.4: zp[1]:51 [ tod_read::return_SEC#0 ] 157.43: zp[1]:50 [ tod_read::return_MIN#0 ] 122.44: zp[1]:49 [ tod_read::return_HOURS#0 ] 50.5: zp[1]:29 [ tod_read::return_TENTHS#1 ] 50.5: zp[1]:30 [ tod_read::return_SEC#1 ] 50.5: zp[1]:31 [ tod_read::return_MIN#1 ] 50.5: zp[1]:32 [ tod_read::return_HOURS#1 ] Uplift Scope [tod_init] 37.33: zp[1]:28 [ tod_init::tod_HOURS#0 ] 22.4: zp[1]:27 [ tod_init::tod_MIN#0 ] 16: zp[1]:26 [ tod_init::tod_SEC#0 ] 12.44: zp[1]:25 [ tod_init::tod_TENTHS#0 ] Uplift Scope [conio_c64_init] 33: zp[1]:2 [ conio_c64_init::line#2 conio_c64_init::line#0 ] Uplift Scope [cputln] @@ -1986,7 +1978,7 @@ Uplifting [] best 122806 combination zp[1]:20 [ conio_cursor_y ] zp[2]:23 [ coni Uplifting [cputc] best 122500 combination reg byte a [ cputc::c#0 ] Uplifting [cputs] best 121800 combination zp[2]:4 [ cputs::s#2 cputs::s#0 ] reg byte a [ cputs::c#1 ] Uplifting [gotoxy] best 121784 combination zp[2]:39 [ gotoxy::$8 ] zp[2]:41 [ gotoxy::$9 ] zp[2]:45 [ gotoxy::$5 ] zp[2]:47 [ gotoxy::$6 ] zp[2]:37 [ gotoxy::$7 ] reg byte x [ gotoxy::y#5 gotoxy::y#4 gotoxy::y#2 ] zp[2]:43 [ gotoxy::line_offset#0 ] -Uplifting [tod_read] best 121685 combination reg byte y [ tod_read::return_TENTHS#0 ] reg byte x [ tod_read::return_SEC#0 ] reg byte a [ tod_read::return_MIN#0 ] zp[1]:49 [ tod_read::return_HOURS#0 ] zp[1]:29 [ tod_read::return_TENTHS#2 ] zp[1]:30 [ tod_read::return_SEC#2 ] zp[1]:31 [ tod_read::return_MIN#2 ] zp[1]:32 [ tod_read::return_HOURS#2 ] +Uplifting [tod_read] best 121685 combination reg byte y [ tod_read::return_TENTHS#0 ] reg byte x [ tod_read::return_SEC#0 ] reg byte a [ tod_read::return_MIN#0 ] zp[1]:49 [ tod_read::return_HOURS#0 ] zp[1]:29 [ tod_read::return_TENTHS#1 ] zp[1]:30 [ tod_read::return_SEC#1 ] zp[1]:31 [ tod_read::return_MIN#1 ] zp[1]:32 [ tod_read::return_HOURS#1 ] Limited combination testing to 100 combinations of 65536 possible. Uplifting [tod_init] best 121673 combination reg byte y [ tod_init::tod_HOURS#0 ] reg byte x [ tod_init::tod_MIN#0 ] zp[1]:26 [ tod_init::tod_SEC#0 ] zp[1]:25 [ tod_init::tod_TENTHS#0 ] Uplifting [conio_c64_init] best 121661 combination reg byte x [ conio_c64_init::line#2 conio_c64_init::line#0 ] @@ -2044,14 +2036,14 @@ Attempting to uplift remaining variables inzp[1]:34 [ tod_str::tod_SEC#0 ] Uplifting [tod_str] best 121517 combination zp[1]:34 [ tod_str::tod_SEC#0 ] Attempting to uplift remaining variables inzp[1]:33 [ tod_str::tod_TENTHS#0 ] Uplifting [tod_str] best 121517 combination zp[1]:33 [ tod_str::tod_TENTHS#0 ] -Attempting to uplift remaining variables inzp[1]:29 [ tod_read::return_TENTHS#2 ] -Uplifting [tod_read] best 121457 combination reg byte y [ tod_read::return_TENTHS#2 ] -Attempting to uplift remaining variables inzp[1]:30 [ tod_read::return_SEC#2 ] -Uplifting [tod_read] best 121397 combination reg byte x [ tod_read::return_SEC#2 ] -Attempting to uplift remaining variables inzp[1]:31 [ tod_read::return_MIN#2 ] -Uplifting [tod_read] best 121397 combination zp[1]:31 [ tod_read::return_MIN#2 ] -Attempting to uplift remaining variables inzp[1]:32 [ tod_read::return_HOURS#2 ] -Uplifting [tod_read] best 121357 combination reg byte a [ tod_read::return_HOURS#2 ] +Attempting to uplift remaining variables inzp[1]:29 [ tod_read::return_TENTHS#1 ] +Uplifting [tod_read] best 121457 combination reg byte y [ tod_read::return_TENTHS#1 ] +Attempting to uplift remaining variables inzp[1]:30 [ tod_read::return_SEC#1 ] +Uplifting [tod_read] best 121397 combination reg byte x [ tod_read::return_SEC#1 ] +Attempting to uplift remaining variables inzp[1]:31 [ tod_read::return_MIN#1 ] +Uplifting [tod_read] best 121397 combination zp[1]:31 [ tod_read::return_MIN#1 ] +Attempting to uplift remaining variables inzp[1]:32 [ tod_read::return_HOURS#1 ] +Uplifting [tod_read] best 121357 combination reg byte a [ tod_read::return_HOURS#1 ] Attempting to uplift remaining variables inzp[1]:26 [ tod_init::tod_SEC#0 ] Uplifting [tod_init] best 121357 combination zp[1]:26 [ tod_init::tod_SEC#0 ] Attempting to uplift remaining variables inzp[1]:25 [ tod_init::tod_TENTHS#0 ] @@ -2063,7 +2055,7 @@ Coalescing zero page register [ zp[2]:37 [ gotoxy::$7 ] ] with [ zp[2]:41 [ goto Coalescing zero page register [ zp[2]:43 [ gotoxy::line_offset#0 ] ] with [ zp[2]:47 [ gotoxy::$6 ] ] - score: 1 Coalescing zero page register [ zp[2]:37 [ gotoxy::$7 gotoxy::$9 ] ] with [ zp[2]:43 [ gotoxy::line_offset#0 gotoxy::$6 ] ] - score: 1 Coalescing zero page register [ zp[2]:14 [ memset::str#3 memset::dst#2 memset::dst#4 memset::dst#1 ] ] with [ zp[2]:6 [ memcpy::source#2 memcpy::src#2 memcpy::src#4 memcpy::src#1 ] ] -Coalescing zero page register [ zp[1]:31 [ tod_read::return_MIN#2 ] ] with [ zp[1]:25 [ tod_init::tod_TENTHS#0 ] ] +Coalescing zero page register [ zp[1]:31 [ tod_read::return_MIN#1 ] ] with [ zp[1]:25 [ tod_init::tod_TENTHS#0 ] ] Coalescing zero page register [ zp[1]:33 [ tod_str::tod_TENTHS#0 ] ] with [ zp[1]:26 [ tod_init::tod_SEC#0 ] ] Coalescing zero page register [ zp[1]:49 [ tod_read::return_HOURS#0 ] ] with [ zp[1]:34 [ tod_str::tod_SEC#0 ] ] Coalescing zero page register [ zp[2]:73 [ memset::end#0 ] ] with [ zp[2]:8 [ memcpy::destination#2 memcpy::dst#2 memcpy::dst#4 memcpy::dst#1 ] ] @@ -2073,7 +2065,7 @@ Allocated (was zp[1]:19) zp[1]:6 [ conio_cursor_x ] Allocated (was zp[1]:20) zp[1]:7 [ conio_cursor_y ] Allocated (was zp[2]:21) zp[2]:8 [ conio_line_text ] Allocated (was zp[2]:23) zp[2]:10 [ conio_line_color ] -Allocated (was zp[1]:31) zp[1]:12 [ tod_read::return_MIN#2 tod_init::tod_TENTHS#0 ] +Allocated (was zp[1]:31) zp[1]:12 [ tod_read::return_MIN#1 tod_init::tod_TENTHS#0 ] Allocated (was zp[1]:33) zp[1]:13 [ tod_str::tod_TENTHS#0 tod_init::tod_SEC#0 ] Allocated (was zp[2]:37) zp[2]:14 [ gotoxy::$7 gotoxy::$9 gotoxy::line_offset#0 gotoxy::$6 ] Allocated (was zp[2]:39) zp[2]:16 [ gotoxy::$8 ] @@ -2235,22 +2227,22 @@ main: { __b2: // [24] call tod_read jsr tod_read - // [25] tod_read::return_TENTHS#2 = tod_read::return_TENTHS#0 - // [26] tod_read::return_SEC#2 = tod_read::return_SEC#0 - // [27] tod_read::return_MIN#2 = tod_read::return_MIN#0 -- vbuz1=vbuaa + // [25] tod_read::return_TENTHS#1 = tod_read::return_TENTHS#0 + // [26] tod_read::return_SEC#1 = tod_read::return_SEC#0 + // [27] tod_read::return_MIN#1 = tod_read::return_MIN#0 -- vbuz1=vbuaa sta.z tod_read.return_MIN - // [28] tod_read::return_HOURS#2 = tod_read::return_HOURS#0 -- vbuaa=vbuz1 + // [28] tod_read::return_HOURS#1 = tod_read::return_HOURS#0 -- vbuaa=vbuz1 lda.z tod_read.return_HOURS jmp __b3 // main::@3 __b3: - // [29] tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 -- vbuz1=vbuyy + // [29] tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 -- vbuz1=vbuyy sty.z tod_str.tod_TENTHS - // [30] tod_str::tod_SEC#0 = tod_read::return_SEC#2 -- vbuz1=vbuxx + // [30] tod_str::tod_SEC#0 = tod_read::return_SEC#1 -- vbuz1=vbuxx stx.z tod_str.tod_SEC - // [31] tod_str::tod_MIN#0 = tod_read::return_MIN#2 -- vbuyy=vbuz1 + // [31] tod_str::tod_MIN#0 = tod_read::return_MIN#1 -- vbuyy=vbuz1 ldy.z tod_read.return_MIN - // [32] tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 -- vbuxx=vbuaa + // [32] tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 -- vbuxx=vbuaa tax // [33] call tod_str jsr tod_str @@ -3056,16 +3048,16 @@ byte tod_read::mins struct TIME_OF_DAY tod_read::return byte tod_read::return_HOURS byte tod_read::return_HOURS#0 return_HOURS zp[1]:20 122.44444444444446 -byte tod_read::return_HOURS#2 reg byte a 50.5 +byte tod_read::return_HOURS#1 reg byte a 50.5 byte tod_read::return_MIN byte tod_read::return_MIN#0 reg byte a 157.42857142857142 -byte tod_read::return_MIN#2 return_MIN zp[1]:12 50.5 +byte tod_read::return_MIN#1 return_MIN zp[1]:12 50.5 byte tod_read::return_SEC byte tod_read::return_SEC#0 reg byte x 220.39999999999998 -byte tod_read::return_SEC#2 reg byte x 50.5 +byte tod_read::return_SEC#1 reg byte x 50.5 byte tod_read::return_TENTHS byte tod_read::return_TENTHS#0 reg byte y 367.33333333333337 -byte tod_read::return_TENTHS#2 reg byte y 50.5 +byte tod_read::return_TENTHS#1 reg byte y 50.5 byte tod_read::secs byte tod_read::tenths byte tod_read::tod_HOURS @@ -3111,10 +3103,10 @@ zp[2]:8 [ conio_line_text ] zp[2]:10 [ conio_line_color ] reg byte x [ tod_init::tod_MIN#0 ] reg byte y [ tod_init::tod_HOURS#0 ] -reg byte y [ tod_read::return_TENTHS#2 ] -reg byte x [ tod_read::return_SEC#2 ] -zp[1]:12 [ tod_read::return_MIN#2 tod_init::tod_TENTHS#0 ] -reg byte a [ tod_read::return_HOURS#2 ] +reg byte y [ tod_read::return_TENTHS#1 ] +reg byte x [ tod_read::return_SEC#1 ] +zp[1]:12 [ tod_read::return_MIN#1 tod_init::tod_TENTHS#0 ] +reg byte a [ tod_read::return_HOURS#1 ] zp[1]:13 [ tod_str::tod_TENTHS#0 tod_init::tod_SEC#0 ] reg byte y [ tod_str::tod_MIN#0 ] reg byte x [ tod_str::tod_HOURS#0 ] @@ -3290,21 +3282,21 @@ main: { // tod_read() // [24] call tod_read jsr tod_read - // [25] tod_read::return_TENTHS#2 = tod_read::return_TENTHS#0 - // [26] tod_read::return_SEC#2 = tod_read::return_SEC#0 - // [27] tod_read::return_MIN#2 = tod_read::return_MIN#0 -- vbuz1=vbuaa + // [25] tod_read::return_TENTHS#1 = tod_read::return_TENTHS#0 + // [26] tod_read::return_SEC#1 = tod_read::return_SEC#0 + // [27] tod_read::return_MIN#1 = tod_read::return_MIN#0 -- vbuz1=vbuaa sta.z tod_read.return_MIN - // [28] tod_read::return_HOURS#2 = tod_read::return_HOURS#0 -- vbuaa=vbuz1 + // [28] tod_read::return_HOURS#1 = tod_read::return_HOURS#0 -- vbuaa=vbuz1 lda.z tod_read.return_HOURS // main::@3 // tod_str(tod_read()) - // [29] tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#2 -- vbuz1=vbuyy + // [29] tod_str::tod_TENTHS#0 = tod_read::return_TENTHS#1 -- vbuz1=vbuyy sty.z tod_str.tod_TENTHS - // [30] tod_str::tod_SEC#0 = tod_read::return_SEC#2 -- vbuz1=vbuxx + // [30] tod_str::tod_SEC#0 = tod_read::return_SEC#1 -- vbuz1=vbuxx stx.z tod_str.tod_SEC - // [31] tod_str::tod_MIN#0 = tod_read::return_MIN#2 -- vbuyy=vbuz1 + // [31] tod_str::tod_MIN#0 = tod_read::return_MIN#1 -- vbuyy=vbuz1 ldy.z tod_read.return_MIN - // [32] tod_str::tod_HOURS#0 = tod_read::return_HOURS#2 -- vbuxx=vbuaa + // [32] tod_str::tod_HOURS#0 = tod_read::return_HOURS#1 -- vbuxx=vbuaa tax // [33] call tod_str jsr tod_str diff --git a/src/test/ref/tod-1.sym b/src/test/ref/tod-1.sym index d438a40a3..27a3a3ff7 100644 --- a/src/test/ref/tod-1.sym +++ b/src/test/ref/tod-1.sym @@ -94,16 +94,16 @@ byte tod_read::mins struct TIME_OF_DAY tod_read::return byte tod_read::return_HOURS byte tod_read::return_HOURS#0 return_HOURS zp[1]:20 122.44444444444446 -byte tod_read::return_HOURS#2 reg byte a 50.5 +byte tod_read::return_HOURS#1 reg byte a 50.5 byte tod_read::return_MIN byte tod_read::return_MIN#0 reg byte a 157.42857142857142 -byte tod_read::return_MIN#2 return_MIN zp[1]:12 50.5 +byte tod_read::return_MIN#1 return_MIN zp[1]:12 50.5 byte tod_read::return_SEC byte tod_read::return_SEC#0 reg byte x 220.39999999999998 -byte tod_read::return_SEC#2 reg byte x 50.5 +byte tod_read::return_SEC#1 reg byte x 50.5 byte tod_read::return_TENTHS byte tod_read::return_TENTHS#0 reg byte y 367.33333333333337 -byte tod_read::return_TENTHS#2 reg byte y 50.5 +byte tod_read::return_TENTHS#1 reg byte y 50.5 byte tod_read::secs byte tod_read::tenths byte tod_read::tod_HOURS @@ -149,10 +149,10 @@ zp[2]:8 [ conio_line_text ] zp[2]:10 [ conio_line_color ] reg byte x [ tod_init::tod_MIN#0 ] reg byte y [ tod_init::tod_HOURS#0 ] -reg byte y [ tod_read::return_TENTHS#2 ] -reg byte x [ tod_read::return_SEC#2 ] -zp[1]:12 [ tod_read::return_MIN#2 tod_init::tod_TENTHS#0 ] -reg byte a [ tod_read::return_HOURS#2 ] +reg byte y [ tod_read::return_TENTHS#1 ] +reg byte x [ tod_read::return_SEC#1 ] +zp[1]:12 [ tod_read::return_MIN#1 tod_init::tod_TENTHS#0 ] +reg byte a [ tod_read::return_HOURS#1 ] zp[1]:13 [ tod_str::tod_TENTHS#0 tod_init::tod_SEC#0 ] reg byte y [ tod_str::tod_MIN#0 ] reg byte x [ tod_str::tod_HOURS#0 ]