diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 8437b5157..01a0a1e4a 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -251,7 +251,7 @@ public class Compiler { optimizations.add(new Pass2RangeResolving(program)); optimizations.add(new Pass2ComparisonOptimization(program)); optimizations.add(new Pass2ConstantCallPointerIdentification(program)); - optimizations.add(new Pass2Multiply2sRewriting(program)); + optimizations.add(new Pass2MultiplyToShiftRewriting(program)); pass2Execute(optimizations); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2Multiply2sRewriting.java b/src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java similarity index 81% rename from src/main/java/dk/camelot64/kickc/passes/Pass2Multiply2sRewriting.java rename to src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java index 937f3375d..123efd721 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2Multiply2sRewriting.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2MultiplyToShiftRewriting.java @@ -17,10 +17,10 @@ import kickass.pass.expressions.expr.Constant; import java.util.ListIterator; -/** Pass that replaces multiplications with factors of 2 with shifts */ -public class Pass2Multiply2sRewriting extends Pass2SsaOptimization { +/** Pass that replaces multiplications / division with factors of 2 with shifts */ +public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization { - public Pass2Multiply2sRewriting(Program program) { + public Pass2MultiplyToShiftRewriting(Program program) { super(program); } @@ -38,7 +38,14 @@ public class Pass2Multiply2sRewriting extends Pass2SsaOptimization { if(constantLiteral instanceof ConstantInteger) { Long constantInt = ((ConstantInteger)constantLiteral).getInteger(); double power2 = Math.log(constantInt) / Math.log(2); - if(Math.round(power2)==power2) { + if(power2==0.0) { + // Found multiplication/division with 1 (ONE) + getLog().append("Rewriting multiplication to remove identity multiply/divide "+statement.toString(getProgram(), false)); + assignment.setOperator(null); + assignment.setrValue2(assignment.getrValue1()); + assignment.setrValue1(null); + optimized = true; + } else if(power2>0.0 && Math.round(power2)==power2 ) { // Found a whole power of 2 if(Operators.MULTIPLY.equals(assignment.getOperator())) { getLog().append("Rewriting multiplication to use shift "+statement.toString(getProgram(), false)); diff --git a/src/test/kc/divide-2s.kc b/src/test/kc/divide-2s.kc index 1a3ff7e6f..eaf5a87d7 100644 --- a/src/test/kc/divide-2s.kc +++ b/src/test/kc/divide-2s.kc @@ -4,12 +4,13 @@ void main() { const byte* SCREEN = $400; for(byte i: 0..10) { - SCREEN[i] = i/2; - (SCREEN+40)[i] = i/4; - (SCREEN+80)[i] = i/8; + (SCREEN+40*0)[i] = i/1; + (SCREEN+40*1)[i] = i/2; + (SCREEN+40*2)[i] = i/4; + (SCREEN+40*3)[i] = i/8; // And a single signed byte signed byte sb = -(signed byte)i; - (SCREEN+160)[i] = (byte)(sb/2); + (SCREEN+40*5)[i] = (byte)(sb/2); } } diff --git a/src/test/kc/multiply-2s.kc b/src/test/kc/multiply-2s.kc index fa58eefe9..f9a21bd9e 100644 --- a/src/test/kc/multiply-2s.kc +++ b/src/test/kc/multiply-2s.kc @@ -4,12 +4,13 @@ void main() { const byte* SCREEN = $400; for(byte i: 0..10) { - SCREEN[i] = i*2; - (SCREEN+40)[i] = i*4; - (SCREEN+80)[i] = i*8; + (SCREEN+0*40)[i] = i*1; + (SCREEN+1*40)[i] = i*2; + (SCREEN+2*40)[i] = i*4; + (SCREEN+3*40)[i] = i*8; // And a single signed byte signed byte sb = -(signed byte)i; - (SCREEN+160)[i] = (byte)(sb*2); + (SCREEN+5*40)[i] = (byte)(sb*2); } diff --git a/src/test/ref/divide-2s.asm b/src/test/ref/divide-2s.asm index 0494630b9..d308bca7f 100644 --- a/src/test/ref/divide-2s.asm +++ b/src/test/ref/divide-2s.asm @@ -7,24 +7,26 @@ main: { ldx #0 b1: txa - lsr sta SCREEN,x txa lsr + sta SCREEN+$28*1,x + txa lsr - sta SCREEN+$28,x + lsr + sta SCREEN+$28*2,x txa lsr lsr lsr - sta SCREEN+$50,x + sta SCREEN+$28*3,x txa eor #$ff clc adc #1 cmp #$80 ror - sta SCREEN+$a0,x + sta SCREEN+$28*5,x inx cpx #$b bne b1 diff --git a/src/test/ref/divide-2s.cfg b/src/test/ref/divide-2s.cfg index 36e1bd935..2dab54153 100644 --- a/src/test/ref/divide-2s.cfg +++ b/src/test/ref/divide-2s.cfg @@ -12,18 +12,19 @@ main: scope:[main] from @1 to:main::@1 main::@1: scope:[main] from main main::@1 [5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 ) - [6] (byte~) main::$0 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 - [7] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 - [8] (byte~) main::$2 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 - [9] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 - [10] (byte~) main::$4 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 - [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 + (byte) main::i#2) ← (byte~) main::$4 - [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 - [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 - [14] *((const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 + (byte) main::i#2) ← (byte)(signed byte~) main::$8 - [15] (byte) main::i#1 ← ++ (byte) main::i#2 - [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 + [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 + [7] (byte~) main::$5 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 + [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) main::i#2) ← (byte~) main::$5 + [9] (byte~) main::$8 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 + [10] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) main::i#2) ← (byte~) main::$8 + [11] (byte~) main::$11 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 + [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 3 + (byte) main::i#2) ← (byte~) main::$11 + [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 + [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 + [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 5 + (byte) main::i#2) ← (byte)(signed byte~) main::$16 + [16] (byte) main::i#1 ← ++ (byte) main::i#2 + [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 - [17] return + [18] return to:@return diff --git a/src/test/ref/divide-2s.log b/src/test/ref/divide-2s.log index 1d5c45e00..5fe7ee2bc 100644 --- a/src/test/ref/divide-2s.log +++ b/src/test/ref/divide-2s.log @@ -8,24 +8,33 @@ main: scope:[main] from @1 to:main::@1 main::@1: scope:[main] from main main::@1 (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 ) - (byte/signed word/word/dword/signed dword~) main::$0 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 2 - *((byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$0 - (byte*~) main::$1 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) $28 - (byte/signed word/word/dword/signed dword~) main::$2 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte/signed byte/word/signed word/dword/signed dword~) main::$0 ← (byte/signed byte/word/signed word/dword/signed dword) $28 * (byte/signed byte/word/signed word/dword/signed dword) 0 + (byte*~) main::$1 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword~) main::$0 + (byte/signed word/word/dword/signed dword~) main::$2 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 1 *((byte*~) main::$1 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$2 - (byte*~) main::$3 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) $50 - (byte/signed word/word/dword/signed dword~) main::$4 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 8 - *((byte*~) main::$3 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$4 - (signed byte~) main::$5 ← ((signed byte)) (byte) main::i#2 - (signed byte~) main::$6 ← - (signed byte~) main::$5 - (signed byte) main::sb#0 ← (signed byte~) main::$6 - (byte*~) main::$7 ← (byte*) main::SCREEN#0 + (byte/word/signed word/dword/signed dword) $a0 - (signed word/signed byte/signed dword~) main::$8 ← (signed byte) main::sb#0 / (byte/signed byte/word/signed word/dword/signed dword) 2 - (byte~) main::$9 ← ((byte)) (signed word/signed byte/signed dword~) main::$8 - *((byte*~) main::$7 + (byte) main::i#2) ← (byte~) main::$9 + (byte/signed byte/word/signed word/dword/signed dword~) main::$3 ← (byte/signed byte/word/signed word/dword/signed dword) $28 * (byte/signed byte/word/signed word/dword/signed dword) 1 + (byte*~) main::$4 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword~) main::$3 + (byte/signed word/word/dword/signed dword~) main::$5 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 2 + *((byte*~) main::$4 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$5 + (byte/signed byte/word/signed word/dword/signed dword~) main::$6 ← (byte/signed byte/word/signed word/dword/signed dword) $28 * (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte*~) main::$7 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword~) main::$6 + (byte/signed word/word/dword/signed dword~) main::$8 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 4 + *((byte*~) main::$7 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$8 + (byte/signed byte/word/signed word/dword/signed dword~) main::$9 ← (byte/signed byte/word/signed word/dword/signed dword) $28 * (byte/signed byte/word/signed word/dword/signed dword) 3 + (byte*~) main::$10 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword~) main::$9 + (byte/signed word/word/dword/signed dword~) main::$11 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 8 + *((byte*~) main::$10 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$11 + (signed byte~) main::$12 ← ((signed byte)) (byte) main::i#2 + (signed byte~) main::$13 ← - (signed byte~) main::$12 + (signed byte) main::sb#0 ← (signed byte~) main::$13 + (byte/word/signed word/dword/signed dword~) main::$14 ← (byte/signed byte/word/signed word/dword/signed dword) $28 * (byte/signed byte/word/signed word/dword/signed dword) 5 + (byte*~) main::$15 ← (byte*) main::SCREEN#0 + (byte/word/signed word/dword/signed dword~) main::$14 + (signed word/signed byte/signed dword~) main::$16 ← (signed byte) main::sb#0 / (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte~) main::$17 ← ((byte)) (signed word/signed byte/signed dword~) main::$16 + *((byte*~) main::$15 + (byte) main::i#2) ← (byte~) main::$17 (byte) main::i#1 ← (byte) main::i#2 + rangenext(0,$a) - (bool~) main::$10 ← (byte) main::i#1 != rangelast(0,$a) - if((bool~) main::$10) goto main::@1 + (bool~) main::$18 ← (byte) main::i#1 != rangelast(0,$a) + if((bool~) main::$18) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 return @@ -43,17 +52,25 @@ SYMBOL TABLE SSA (label) @begin (label) @end (void()) main() -(byte/signed word/word/dword/signed dword~) main::$0 +(byte/signed byte/word/signed word/dword/signed dword~) main::$0 (byte*~) main::$1 -(bool~) main::$10 +(byte*~) main::$10 +(byte/signed word/word/dword/signed dword~) main::$11 +(signed byte~) main::$12 +(signed byte~) main::$13 +(byte/word/signed word/dword/signed dword~) main::$14 +(byte*~) main::$15 +(signed word/signed byte/signed dword~) main::$16 +(byte~) main::$17 +(bool~) main::$18 (byte/signed word/word/dword/signed dword~) main::$2 -(byte*~) main::$3 -(byte/signed word/word/dword/signed dword~) main::$4 -(signed byte~) main::$5 -(signed byte~) main::$6 +(byte/signed byte/word/signed word/dword/signed dword~) main::$3 +(byte*~) main::$4 +(byte/signed word/word/dword/signed dword~) main::$5 +(byte/signed byte/word/signed word/dword/signed dword~) main::$6 (byte*~) main::$7 -(signed word/signed byte/signed dword~) main::$8 -(byte~) main::$9 +(byte/signed word/word/dword/signed dword~) main::$8 +(byte/signed byte/word/signed word/dword/signed dword~) main::$9 (label) main::@1 (label) main::@return (byte*) main::SCREEN @@ -67,37 +84,56 @@ SYMBOL TABLE SSA Culled Empty Block (label) @2 Successful SSA optimization Pass2CullEmptyBlocks -Alias (signed byte) main::sb#0 = (signed byte~) main::$6 +Alias (signed byte) main::sb#0 = (signed byte~) main::$13 Successful SSA optimization Pass2AliasElimination -Simple Condition (bool~) main::$10 [20] if((byte) main::i#1!=rangelast(0,$a)) goto main::@1 +Simple Condition (bool~) main::$18 [29] if((byte) main::i#1!=rangelast(0,$a)) goto main::@1 Successful SSA optimization Pass2ConditionalJumpSimplification Constant (const byte*) main::SCREEN#0 = ((byte*))$400 Constant (const byte) main::i#0 = 0 +Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$0 = $28*0 +Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$3 = $28*1 +Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$6 = $28*2 +Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$9 = $28*3 +Constant (const byte/word/signed word/dword/signed dword) main::$14 = $28*5 Successful SSA optimization Pass2ConstantIdentification -Constant (const byte*) main::$1 = main::SCREEN#0+$28 -Constant (const byte*) main::$3 = main::SCREEN#0+$50 -Constant (const byte*) main::$7 = main::SCREEN#0+$a0 +Constant (const byte*) main::$1 = main::SCREEN#0+main::$0 +Constant (const byte*) main::$4 = main::SCREEN#0+main::$3 +Constant (const byte*) main::$7 = main::SCREEN#0+main::$6 +Constant (const byte*) main::$10 = main::SCREEN#0+main::$9 +Constant (const byte*) main::$15 = main::SCREEN#0+main::$14 Successful SSA optimization Pass2ConstantIdentification -Eliminating Noop Cast (signed byte~) main::$5 ← ((signed byte)) (byte) main::i#2 -Eliminating Noop Cast (byte~) main::$9 ← ((byte)) (signed word/signed byte/signed dword~) main::$8 +Eliminating Noop Cast (signed byte~) main::$12 ← ((signed byte)) (byte) main::i#2 +Eliminating Noop Cast (byte~) main::$17 ← ((byte)) (signed word/signed byte/signed dword~) main::$16 Successful SSA optimization Pass2NopCastElimination Resolved ranged next value main::i#1 ← ++ main::i#2 to ++ Resolved ranged comparison value if(main::i#1!=rangelast(0,$a)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) $b -Rewriting division to use shift (byte/signed word/word/dword/signed dword~) main::$0 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 2 -Rewriting division to use shift (byte/signed word/word/dword/signed dword~) main::$2 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 4 -Rewriting division to use shift (byte/signed word/word/dword/signed dword~) main::$4 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 8 -Rewriting division to use shift (signed word/signed byte/signed dword~) main::$8 ← (signed byte) main::sb#0 / (byte/signed byte/word/signed word/dword/signed dword) 2 -Successful SSA optimization Pass2Multiply2sRewriting -Inferred type updated to byte in [1] (byte/signed word/word/dword/signed dword~) main::$0 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -Inferred type updated to byte in [3] (byte/signed word/word/dword/signed dword~) main::$2 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 -Inferred type updated to byte in [5] (byte/signed word/word/dword/signed dword~) main::$4 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 -Inferred type updated to signed byte in [8] (signed word/signed byte/signed dword~) main::$8 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 +Rewriting multiplication to remove identity multiply/divide (byte/signed word/word/dword/signed dword~) main::$2 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 1 +Rewriting division to use shift (byte/signed word/word/dword/signed dword~) main::$5 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 2 +Rewriting division to use shift (byte/signed word/word/dword/signed dword~) main::$8 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 4 +Rewriting division to use shift (byte/signed word/word/dword/signed dword~) main::$11 ← (byte) main::i#2 / (byte/signed byte/word/signed word/dword/signed dword) 8 +Rewriting division to use shift (signed word/signed byte/signed dword~) main::$16 ← (signed byte) main::sb#0 / (byte/signed byte/word/signed word/dword/signed dword) 2 +Successful SSA optimization Pass2MultiplyToShiftRewriting +Alias (byte) main::i#2 = (byte/signed word/word/dword/signed dword~) main::$2 +Successful SSA optimization Pass2AliasElimination +Inferred type updated to byte in [2] (byte/signed word/word/dword/signed dword~) main::$5 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 +Inferred type updated to byte in [4] (byte/signed word/word/dword/signed dword~) main::$8 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 +Inferred type updated to byte in [6] (byte/signed word/word/dword/signed dword~) main::$11 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 +Inferred type updated to signed byte in [9] (signed word/signed byte/signed dword~) main::$16 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 Inlining constant with var siblings (const byte) main::i#0 +Constant inlined main::$1 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 0 +Constant inlined main::$0 = (byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 0 Constant inlined main::i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 -Constant inlined main::$3 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 -Constant inlined main::$1 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 -Constant inlined main::$7 = (const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 +Constant inlined main::$6 = (byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 2 +Constant inlined main::$3 = (byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 1 +Constant inlined main::$14 = (byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 5 +Constant inlined main::$4 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 1 +Constant inlined main::$15 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 5 +Constant inlined main::$9 = (byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 3 +Constant inlined main::$7 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 2 +Constant inlined main::$10 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 3 Successful SSA optimization Pass2ConstantInlining +Simplifying constant multiply by zero $28*0 +Simplifying constant plus zero main::SCREEN#0+0 Added new block during phi lifting main::@3(between main::@1 and main::@1) Adding NOP phi() at start of @begin Adding NOP phi() at start of @1 @@ -107,7 +143,7 @@ CALL GRAPH Calls in [] to main:2 Created 1 initial phi equivalence classes -Coalesced [18] main::i#3 ← main::i#1 +Coalesced [19] main::i#3 ← main::i#1 Coalesced down to 1 phi equivalence classes Culled Empty Block (label) main::@3 Adding NOP phi() at start of @begin @@ -130,56 +166,57 @@ main: scope:[main] from @1 to:main::@1 main::@1: scope:[main] from main main::@1 [5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 ) - [6] (byte~) main::$0 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 - [7] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 - [8] (byte~) main::$2 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 - [9] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 - [10] (byte~) main::$4 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 - [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 + (byte) main::i#2) ← (byte~) main::$4 - [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 - [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 - [14] *((const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 + (byte) main::i#2) ← (byte)(signed byte~) main::$8 - [15] (byte) main::i#1 ← ++ (byte) main::i#2 - [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 + [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 + [7] (byte~) main::$5 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 + [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) main::i#2) ← (byte~) main::$5 + [9] (byte~) main::$8 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 + [10] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) main::i#2) ← (byte~) main::$8 + [11] (byte~) main::$11 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 + [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 3 + (byte) main::i#2) ← (byte~) main::$11 + [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 + [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 + [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 5 + (byte) main::i#2) ← (byte)(signed byte~) main::$16 + [16] (byte) main::i#1 ← ++ (byte) main::i#2 + [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 - [17] return + [18] return to:@return VARIABLE REGISTER WEIGHTS (void()) main() -(byte~) main::$0 22.0 -(byte~) main::$2 22.0 -(byte~) main::$4 22.0 -(signed byte~) main::$8 11.0 +(byte~) main::$11 22.0 +(signed byte~) main::$16 11.0 +(byte~) main::$5 22.0 +(byte~) main::$8 22.0 (byte*) main::SCREEN (byte) main::i (byte) main::i#1 16.5 -(byte) main::i#2 9.899999999999999 +(byte) main::i#2 11.0 (signed byte) main::sb (signed byte) main::sb#0 22.0 Initial phi equivalence classes [ main::i#2 main::i#1 ] -Added variable main::$0 to zero page equivalence class [ main::$0 ] -Added variable main::$2 to zero page equivalence class [ main::$2 ] -Added variable main::$4 to zero page equivalence class [ main::$4 ] -Added variable main::sb#0 to zero page equivalence class [ main::sb#0 ] +Added variable main::$5 to zero page equivalence class [ main::$5 ] Added variable main::$8 to zero page equivalence class [ main::$8 ] +Added variable main::$11 to zero page equivalence class [ main::$11 ] +Added variable main::sb#0 to zero page equivalence class [ main::sb#0 ] +Added variable main::$16 to zero page equivalence class [ main::$16 ] Complete equivalence classes [ main::i#2 main::i#1 ] -[ main::$0 ] -[ main::$2 ] -[ main::$4 ] -[ main::sb#0 ] +[ main::$5 ] [ main::$8 ] +[ main::$11 ] +[ main::sb#0 ] +[ main::$16 ] Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ] -Allocated zp ZP_BYTE:3 [ main::$0 ] -Allocated zp ZP_BYTE:4 [ main::$2 ] -Allocated zp ZP_BYTE:5 [ main::$4 ] +Allocated zp ZP_BYTE:3 [ main::$5 ] +Allocated zp ZP_BYTE:4 [ main::$8 ] +Allocated zp ZP_BYTE:5 [ main::$11 ] Allocated zp ZP_BYTE:6 [ main::sb#0 ] -Allocated zp ZP_BYTE:7 [ main::$8 ] +Allocated zp ZP_BYTE:7 [ main::$16 ] INITIAL ASM //SEG0 File Comments @@ -208,10 +245,10 @@ bend: //SEG10 main main: { .label SCREEN = $400 - .label _0 = 3 - .label _2 = 4 - .label _4 = 5 - .label _8 = 7 + .label _5 = 3 + .label _8 = 4 + .label _11 = 5 + .label _16 = 7 .label sb = 6 .label i = 2 //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] @@ -226,91 +263,96 @@ main: { jmp b1 //SEG15 main::@1 b1: - //SEG16 [6] (byte~) main::$0 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuz1=vbuz2_ror_1 - lda i - lsr - sta _0 - //SEG17 [7] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuz2 - lda _0 + //SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuz1=vbuz1 ldy i + tya sta SCREEN,y - //SEG18 [8] (byte~) main::$2 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuz1=vbuz2_ror_2 + //SEG17 [7] (byte~) main::$5 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuz1=vbuz2_ror_1 + lda i + lsr + sta _5 + //SEG18 [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) main::i#2) ← (byte~) main::$5 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _5 + ldy i + sta SCREEN+$28*1,y + //SEG19 [9] (byte~) main::$8 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuz1=vbuz2_ror_2 lda i lsr lsr - sta _2 - //SEG19 [9] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuz2 - lda _2 + sta _8 + //SEG20 [10] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) main::i#2) ← (byte~) main::$8 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _8 ldy i - sta SCREEN+$28,y - //SEG20 [10] (byte~) main::$4 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuz1=vbuz2_ror_3 + sta SCREEN+$28*2,y + //SEG21 [11] (byte~) main::$11 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuz1=vbuz2_ror_3 lda i lsr lsr lsr - sta _4 - //SEG21 [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 + (byte) main::i#2) ← (byte~) main::$4 -- pbuc1_derefidx_vbuz1=vbuz2 - lda _4 + sta _11 + //SEG22 [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 3 + (byte) main::i#2) ← (byte~) main::$11 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _11 ldy i - sta SCREEN+$50,y - //SEG22 [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsz1=_neg_vbsz2 + sta SCREEN+$28*3,y + //SEG23 [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsz1=_neg_vbsz2 lda i eor #$ff clc adc #1 sta sb - //SEG23 [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsz1=vbsz2_ror_1 + //SEG24 [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsz1=vbsz2_ror_1 lda sb cmp #$80 ror - sta _8 - //SEG24 [14] *((const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 + (byte) main::i#2) ← (byte)(signed byte~) main::$8 -- pbuc1_derefidx_vbuz1=vbuz2 - lda _8 + sta _16 + //SEG25 [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 5 + (byte) main::i#2) ← (byte)(signed byte~) main::$16 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _16 ldy i - sta SCREEN+$a0,y - //SEG25 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 + sta SCREEN+$28*5,y + //SEG26 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 inc i - //SEG26 [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 + //SEG27 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 lda #$b cmp i bne b1_from_b1 jmp breturn - //SEG27 main::@return + //SEG28 main::@return breturn: - //SEG28 [17] return + //SEG29 [18] return rts } REGISTER UPLIFT POTENTIAL REGISTERS -Statement [6] (byte~) main::$0 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$0 ] ( main:2 [ main::i#2 main::$0 ] ) always clobbers reg byte a +Statement [7] (byte~) main::$5 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$5 ] ( main:2 [ main::i#2 main::$5 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ] -Statement [8] (byte~) main::$2 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#2 main::$2 ] ( main:2 [ main::i#2 main::$2 ] ) always clobbers reg byte a -Statement [10] (byte~) main::$4 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 [ main::i#2 main::$4 ] ( main:2 [ main::i#2 main::$4 ] ) always clobbers reg byte a -Statement [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 [ main::i#2 main::sb#0 ] ( main:2 [ main::i#2 main::sb#0 ] ) always clobbers reg byte a -Statement [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$8 ] ( main:2 [ main::i#2 main::$8 ] ) always clobbers reg byte a -Statement [6] (byte~) main::$0 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$0 ] ( main:2 [ main::i#2 main::$0 ] ) always clobbers reg byte a -Statement [8] (byte~) main::$2 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#2 main::$2 ] ( main:2 [ main::i#2 main::$2 ] ) always clobbers reg byte a -Statement [10] (byte~) main::$4 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 [ main::i#2 main::$4 ] ( main:2 [ main::i#2 main::$4 ] ) always clobbers reg byte a -Statement [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 [ main::i#2 main::sb#0 ] ( main:2 [ main::i#2 main::sb#0 ] ) always clobbers reg byte a -Statement [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$8 ] ( main:2 [ main::i#2 main::$8 ] ) always clobbers reg byte a +Statement [9] (byte~) main::$8 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#2 main::$8 ] ( main:2 [ main::i#2 main::$8 ] ) always clobbers reg byte a +Statement [11] (byte~) main::$11 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 [ main::i#2 main::$11 ] ( main:2 [ main::i#2 main::$11 ] ) always clobbers reg byte a +Statement [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 [ main::i#2 main::sb#0 ] ( main:2 [ main::i#2 main::sb#0 ] ) always clobbers reg byte a +Statement [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$16 ] ( main:2 [ main::i#2 main::$16 ] ) always clobbers reg byte a +Statement [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a +Statement [7] (byte~) main::$5 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$5 ] ( main:2 [ main::i#2 main::$5 ] ) always clobbers reg byte a +Statement [9] (byte~) main::$8 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#2 main::$8 ] ( main:2 [ main::i#2 main::$8 ] ) always clobbers reg byte a +Statement [11] (byte~) main::$11 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 [ main::i#2 main::$11 ] ( main:2 [ main::i#2 main::$11 ] ) always clobbers reg byte a +Statement [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 [ main::i#2 main::sb#0 ] ( main:2 [ main::i#2 main::sb#0 ] ) always clobbers reg byte a +Statement [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$16 ] ( main:2 [ main::i#2 main::$16 ] ) always clobbers reg byte a Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:3 [ main::$0 ] : zp ZP_BYTE:3 , reg byte a , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:4 [ main::$2 ] : zp ZP_BYTE:4 , reg byte a , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:5 [ main::$4 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:3 [ main::$5 ] : zp ZP_BYTE:3 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:4 [ main::$8 ] : zp ZP_BYTE:4 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:5 [ main::$11 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y , Potential registers zp ZP_BYTE:6 [ main::sb#0 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:7 [ main::$8 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:7 [ main::$16 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y , REGISTER UPLIFT SCOPES -Uplift Scope [main] 26.4: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 22: zp ZP_BYTE:3 [ main::$0 ] 22: zp ZP_BYTE:4 [ main::$2 ] 22: zp ZP_BYTE:5 [ main::$4 ] 22: zp ZP_BYTE:6 [ main::sb#0 ] 11: zp ZP_BYTE:7 [ main::$8 ] +Uplift Scope [main] 27.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 22: zp ZP_BYTE:3 [ main::$5 ] 22: zp ZP_BYTE:4 [ main::$8 ] 22: zp ZP_BYTE:5 [ main::$11 ] 22: zp ZP_BYTE:6 [ main::sb#0 ] 11: zp ZP_BYTE:7 [ main::$16 ] Uplift Scope [] -Uplifting [main] best 813 combination reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::$0 ] reg byte a [ main::$2 ] reg byte a [ main::$4 ] zp ZP_BYTE:6 [ main::sb#0 ] zp ZP_BYTE:7 [ main::$8 ] +Uplifting [main] best 883 combination reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::$5 ] reg byte a [ main::$8 ] reg byte a [ main::$11 ] zp ZP_BYTE:6 [ main::sb#0 ] zp ZP_BYTE:7 [ main::$16 ] Limited combination testing to 100 combinations of 3072 possible. -Uplifting [] best 813 combination +Uplifting [] best 883 combination Attempting to uplift remaining variables inzp ZP_BYTE:6 [ main::sb#0 ] -Uplifting [main] best 753 combination reg byte a [ main::sb#0 ] -Attempting to uplift remaining variables inzp ZP_BYTE:7 [ main::$8 ] -Uplifting [main] best 693 combination reg byte a [ main::$8 ] +Uplifting [main] best 823 combination reg byte a [ main::sb#0 ] +Attempting to uplift remaining variables inzp ZP_BYTE:7 [ main::$16 ] +Uplifting [main] best 763 combination reg byte a [ main::$16 ] ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments @@ -350,43 +392,46 @@ main: { jmp b1 //SEG15 main::@1 b1: - //SEG16 [6] (byte~) main::$0 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_ror_1 + //SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx txa - lsr - //SEG17 [7] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuxx=vbuaa sta SCREEN,x - //SEG18 [8] (byte~) main::$2 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuaa=vbuxx_ror_2 + //SEG17 [7] (byte~) main::$5 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_ror_1 + txa + lsr + //SEG18 [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) main::i#2) ← (byte~) main::$5 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$28*1,x + //SEG19 [9] (byte~) main::$8 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuaa=vbuxx_ror_2 txa lsr lsr - //SEG19 [9] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$28,x - //SEG20 [10] (byte~) main::$4 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuaa=vbuxx_ror_3 + //SEG20 [10] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) main::i#2) ← (byte~) main::$8 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$28*2,x + //SEG21 [11] (byte~) main::$11 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuaa=vbuxx_ror_3 txa lsr lsr lsr - //SEG21 [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 + (byte) main::i#2) ← (byte~) main::$4 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$50,x - //SEG22 [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsaa=_neg_vbsxx + //SEG22 [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 3 + (byte) main::i#2) ← (byte~) main::$11 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$28*3,x + //SEG23 [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsaa=_neg_vbsxx txa eor #$ff clc adc #1 - //SEG23 [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsaa=vbsaa_ror_1 + //SEG24 [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsaa=vbsaa_ror_1 cmp #$80 ror - //SEG24 [14] *((const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 + (byte) main::i#2) ← (byte)(signed byte~) main::$8 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$a0,x - //SEG25 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx + //SEG25 [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 5 + (byte) main::i#2) ← (byte)(signed byte~) main::$16 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$28*5,x + //SEG26 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx inx - //SEG26 [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 + //SEG27 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 cpx #$b bne b1_from_b1 jmp breturn - //SEG27 main::@return + //SEG28 main::@return breturn: - //SEG28 [17] return + //SEG29 [18] return rts } @@ -420,30 +465,30 @@ FINAL SYMBOL TABLE (label) @begin (label) @end (void()) main() -(byte~) main::$0 reg byte a 22.0 -(byte~) main::$2 reg byte a 22.0 -(byte~) main::$4 reg byte a 22.0 -(signed byte~) main::$8 reg byte a 11.0 +(byte~) main::$11 reg byte a 22.0 +(signed byte~) main::$16 reg byte a 11.0 +(byte~) main::$5 reg byte a 22.0 +(byte~) main::$8 reg byte a 22.0 (label) main::@1 (label) main::@return (byte*) main::SCREEN (const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400 (byte) main::i (byte) main::i#1 reg byte x 16.5 -(byte) main::i#2 reg byte x 9.899999999999999 +(byte) main::i#2 reg byte x 11.0 (signed byte) main::sb (signed byte) main::sb#0 reg byte a 22.0 reg byte x [ main::i#2 main::i#1 ] -reg byte a [ main::$0 ] -reg byte a [ main::$2 ] -reg byte a [ main::$4 ] -reg byte a [ main::sb#0 ] +reg byte a [ main::$5 ] reg byte a [ main::$8 ] +reg byte a [ main::$11 ] +reg byte a [ main::sb#0 ] +reg byte a [ main::$16 ] FINAL ASSEMBLER -Score: 591 +Score: 661 //SEG0 File Comments // Check that division by factors of 2 is converted to shifts @@ -469,41 +514,44 @@ main: { //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy //SEG15 main::@1 b1: - //SEG16 [6] (byte~) main::$0 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_ror_1 + //SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx txa - lsr - //SEG17 [7] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuxx=vbuaa sta SCREEN,x - //SEG18 [8] (byte~) main::$2 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuaa=vbuxx_ror_2 + //SEG17 [7] (byte~) main::$5 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_ror_1 + txa + lsr + //SEG18 [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 1 + (byte) main::i#2) ← (byte~) main::$5 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$28*1,x + //SEG19 [9] (byte~) main::$8 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuaa=vbuxx_ror_2 txa lsr lsr - //SEG19 [9] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$28,x - //SEG20 [10] (byte~) main::$4 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuaa=vbuxx_ror_3 + //SEG20 [10] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 2 + (byte) main::i#2) ← (byte~) main::$8 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$28*2,x + //SEG21 [11] (byte~) main::$11 ← (byte) main::i#2 >> (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuaa=vbuxx_ror_3 txa lsr lsr lsr - //SEG21 [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 + (byte) main::i#2) ← (byte~) main::$4 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$50,x - //SEG22 [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsaa=_neg_vbsxx + //SEG22 [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 3 + (byte) main::i#2) ← (byte~) main::$11 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$28*3,x + //SEG23 [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsaa=_neg_vbsxx txa eor #$ff clc adc #1 - //SEG23 [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsaa=vbsaa_ror_1 + //SEG24 [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 >> (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsaa=vbsaa_ror_1 cmp #$80 ror - //SEG24 [14] *((const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 + (byte) main::i#2) ← (byte)(signed byte~) main::$8 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$a0,x - //SEG25 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx + //SEG25 [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28*(byte/signed byte/word/signed word/dword/signed dword) 5 + (byte) main::i#2) ← (byte)(signed byte~) main::$16 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+$28*5,x + //SEG26 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx inx - //SEG26 [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 + //SEG27 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 cpx #$b bne b1 - //SEG27 main::@return - //SEG28 [17] return + //SEG28 main::@return + //SEG29 [18] return rts } diff --git a/src/test/ref/divide-2s.sym b/src/test/ref/divide-2s.sym index d1c02caad..cdf521121 100644 --- a/src/test/ref/divide-2s.sym +++ b/src/test/ref/divide-2s.sym @@ -2,23 +2,23 @@ (label) @begin (label) @end (void()) main() -(byte~) main::$0 reg byte a 22.0 -(byte~) main::$2 reg byte a 22.0 -(byte~) main::$4 reg byte a 22.0 -(signed byte~) main::$8 reg byte a 11.0 +(byte~) main::$11 reg byte a 22.0 +(signed byte~) main::$16 reg byte a 11.0 +(byte~) main::$5 reg byte a 22.0 +(byte~) main::$8 reg byte a 22.0 (label) main::@1 (label) main::@return (byte*) main::SCREEN (const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400 (byte) main::i (byte) main::i#1 reg byte x 16.5 -(byte) main::i#2 reg byte x 9.899999999999999 +(byte) main::i#2 reg byte x 11.0 (signed byte) main::sb (signed byte) main::sb#0 reg byte a 22.0 reg byte x [ main::i#2 main::i#1 ] -reg byte a [ main::$0 ] -reg byte a [ main::$2 ] -reg byte a [ main::$4 ] -reg byte a [ main::sb#0 ] +reg byte a [ main::$5 ] reg byte a [ main::$8 ] +reg byte a [ main::$11 ] +reg byte a [ main::sb#0 ] +reg byte a [ main::$16 ] diff --git a/src/test/ref/multiply-2s.asm b/src/test/ref/multiply-2s.asm index a81811ee6..d760c058b 100644 --- a/src/test/ref/multiply-2s.asm +++ b/src/test/ref/multiply-2s.asm @@ -7,23 +7,25 @@ main: { ldx #0 b1: txa - asl sta SCREEN,x txa asl + sta SCREEN+1*$28,x + txa asl - sta SCREEN+$28,x + asl + sta SCREEN+2*$28,x txa asl asl asl - sta SCREEN+$50,x + sta SCREEN+3*$28,x txa eor #$ff clc adc #1 asl - sta SCREEN+$a0,x + sta SCREEN+5*$28,x inx cpx #$b bne b1 diff --git a/src/test/ref/multiply-2s.cfg b/src/test/ref/multiply-2s.cfg index 273324aff..1976b10bf 100644 --- a/src/test/ref/multiply-2s.cfg +++ b/src/test/ref/multiply-2s.cfg @@ -12,18 +12,19 @@ main: scope:[main] from @1 to:main::@1 main::@1: scope:[main] from main main::@1 [5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 ) - [6] (byte~) main::$0 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 - [7] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 - [8] (byte~) main::$2 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 - [9] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 - [10] (byte~) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 - [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 + (byte) main::i#2) ← (byte~) main::$4 - [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 - [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 - [14] *((const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 + (byte) main::i#2) ← (byte)(signed byte~) main::$8 - [15] (byte) main::i#1 ← ++ (byte) main::i#2 - [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 + [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 + [7] (byte~) main::$5 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 + [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$5 + [9] (byte~) main::$8 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 + [10] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$8 + [11] (byte~) main::$11 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 + [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$11 + [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 + [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 + [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte)(signed byte~) main::$16 + [16] (byte) main::i#1 ← ++ (byte) main::i#2 + [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 - [17] return + [18] return to:@return diff --git a/src/test/ref/multiply-2s.log b/src/test/ref/multiply-2s.log index 3994d0e72..e97b9b128 100644 --- a/src/test/ref/multiply-2s.log +++ b/src/test/ref/multiply-2s.log @@ -8,24 +8,33 @@ main: scope:[main] from @1 to:main::@1 main::@1: scope:[main] from main main::@1 (byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 ) - (byte/signed word/word/dword/signed dword~) main::$0 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 2 - *((byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$0 - (byte*~) main::$1 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) $28 - (byte/signed word/word/dword/signed dword~) main::$2 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 4 + (byte/signed byte/word/signed word/dword/signed dword~) main::$0 ← (byte/signed byte/word/signed word/dword/signed dword) 0 * (byte/signed byte/word/signed word/dword/signed dword) $28 + (byte*~) main::$1 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword~) main::$0 + (byte/signed word/word/dword/signed dword~) main::$2 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 1 *((byte*~) main::$1 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$2 - (byte*~) main::$3 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword) $50 - (byte/signed word/word/dword/signed dword~) main::$4 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 8 - *((byte*~) main::$3 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$4 - (signed byte~) main::$5 ← ((signed byte)) (byte) main::i#2 - (signed byte~) main::$6 ← - (signed byte~) main::$5 - (signed byte) main::sb#0 ← (signed byte~) main::$6 - (byte*~) main::$7 ← (byte*) main::SCREEN#0 + (byte/word/signed word/dword/signed dword) $a0 - (signed word/signed byte/signed dword~) main::$8 ← (signed byte) main::sb#0 * (byte/signed byte/word/signed word/dword/signed dword) 2 - (byte~) main::$9 ← ((byte)) (signed word/signed byte/signed dword~) main::$8 - *((byte*~) main::$7 + (byte) main::i#2) ← (byte~) main::$9 + (byte/signed byte/word/signed word/dword/signed dword~) main::$3 ← (byte/signed byte/word/signed word/dword/signed dword) 1 * (byte/signed byte/word/signed word/dword/signed dword) $28 + (byte*~) main::$4 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword~) main::$3 + (byte/signed word/word/dword/signed dword~) main::$5 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 2 + *((byte*~) main::$4 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$5 + (byte/signed byte/word/signed word/dword/signed dword~) main::$6 ← (byte/signed byte/word/signed word/dword/signed dword) 2 * (byte/signed byte/word/signed word/dword/signed dword) $28 + (byte*~) main::$7 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword~) main::$6 + (byte/signed word/word/dword/signed dword~) main::$8 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 4 + *((byte*~) main::$7 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$8 + (byte/signed byte/word/signed word/dword/signed dword~) main::$9 ← (byte/signed byte/word/signed word/dword/signed dword) 3 * (byte/signed byte/word/signed word/dword/signed dword) $28 + (byte*~) main::$10 ← (byte*) main::SCREEN#0 + (byte/signed byte/word/signed word/dword/signed dword~) main::$9 + (byte/signed word/word/dword/signed dword~) main::$11 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 8 + *((byte*~) main::$10 + (byte) main::i#2) ← (byte/signed word/word/dword/signed dword~) main::$11 + (signed byte~) main::$12 ← ((signed byte)) (byte) main::i#2 + (signed byte~) main::$13 ← - (signed byte~) main::$12 + (signed byte) main::sb#0 ← (signed byte~) main::$13 + (byte/word/signed word/dword/signed dword~) main::$14 ← (byte/signed byte/word/signed word/dword/signed dword) 5 * (byte/signed byte/word/signed word/dword/signed dword) $28 + (byte*~) main::$15 ← (byte*) main::SCREEN#0 + (byte/word/signed word/dword/signed dword~) main::$14 + (signed word/signed byte/signed dword~) main::$16 ← (signed byte) main::sb#0 * (byte/signed byte/word/signed word/dword/signed dword) 2 + (byte~) main::$17 ← ((byte)) (signed word/signed byte/signed dword~) main::$16 + *((byte*~) main::$15 + (byte) main::i#2) ← (byte~) main::$17 (byte) main::i#1 ← (byte) main::i#2 + rangenext(0,$a) - (bool~) main::$10 ← (byte) main::i#1 != rangelast(0,$a) - if((bool~) main::$10) goto main::@1 + (bool~) main::$18 ← (byte) main::i#1 != rangelast(0,$a) + if((bool~) main::$18) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 return @@ -43,17 +52,25 @@ SYMBOL TABLE SSA (label) @begin (label) @end (void()) main() -(byte/signed word/word/dword/signed dword~) main::$0 +(byte/signed byte/word/signed word/dword/signed dword~) main::$0 (byte*~) main::$1 -(bool~) main::$10 +(byte*~) main::$10 +(byte/signed word/word/dword/signed dword~) main::$11 +(signed byte~) main::$12 +(signed byte~) main::$13 +(byte/word/signed word/dword/signed dword~) main::$14 +(byte*~) main::$15 +(signed word/signed byte/signed dword~) main::$16 +(byte~) main::$17 +(bool~) main::$18 (byte/signed word/word/dword/signed dword~) main::$2 -(byte*~) main::$3 -(byte/signed word/word/dword/signed dword~) main::$4 -(signed byte~) main::$5 -(signed byte~) main::$6 +(byte/signed byte/word/signed word/dword/signed dword~) main::$3 +(byte*~) main::$4 +(byte/signed word/word/dword/signed dword~) main::$5 +(byte/signed byte/word/signed word/dword/signed dword~) main::$6 (byte*~) main::$7 -(signed word/signed byte/signed dword~) main::$8 -(byte~) main::$9 +(byte/signed word/word/dword/signed dword~) main::$8 +(byte/signed byte/word/signed word/dword/signed dword~) main::$9 (label) main::@1 (label) main::@return (byte*) main::SCREEN @@ -67,37 +84,56 @@ SYMBOL TABLE SSA Culled Empty Block (label) @2 Successful SSA optimization Pass2CullEmptyBlocks -Alias (signed byte) main::sb#0 = (signed byte~) main::$6 +Alias (signed byte) main::sb#0 = (signed byte~) main::$13 Successful SSA optimization Pass2AliasElimination -Simple Condition (bool~) main::$10 [20] if((byte) main::i#1!=rangelast(0,$a)) goto main::@1 +Simple Condition (bool~) main::$18 [29] if((byte) main::i#1!=rangelast(0,$a)) goto main::@1 Successful SSA optimization Pass2ConditionalJumpSimplification Constant (const byte*) main::SCREEN#0 = ((byte*))$400 Constant (const byte) main::i#0 = 0 +Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$0 = 0*$28 +Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$3 = 1*$28 +Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$6 = 2*$28 +Constant (const byte/signed byte/word/signed word/dword/signed dword) main::$9 = 3*$28 +Constant (const byte/word/signed word/dword/signed dword) main::$14 = 5*$28 Successful SSA optimization Pass2ConstantIdentification -Constant (const byte*) main::$1 = main::SCREEN#0+$28 -Constant (const byte*) main::$3 = main::SCREEN#0+$50 -Constant (const byte*) main::$7 = main::SCREEN#0+$a0 +Constant (const byte*) main::$1 = main::SCREEN#0+main::$0 +Constant (const byte*) main::$4 = main::SCREEN#0+main::$3 +Constant (const byte*) main::$7 = main::SCREEN#0+main::$6 +Constant (const byte*) main::$10 = main::SCREEN#0+main::$9 +Constant (const byte*) main::$15 = main::SCREEN#0+main::$14 Successful SSA optimization Pass2ConstantIdentification -Eliminating Noop Cast (signed byte~) main::$5 ← ((signed byte)) (byte) main::i#2 -Eliminating Noop Cast (byte~) main::$9 ← ((byte)) (signed word/signed byte/signed dword~) main::$8 +Eliminating Noop Cast (signed byte~) main::$12 ← ((signed byte)) (byte) main::i#2 +Eliminating Noop Cast (byte~) main::$17 ← ((byte)) (signed word/signed byte/signed dword~) main::$16 Successful SSA optimization Pass2NopCastElimination Resolved ranged next value main::i#1 ← ++ main::i#2 to ++ Resolved ranged comparison value if(main::i#1!=rangelast(0,$a)) goto main::@1 to (byte/signed byte/word/signed word/dword/signed dword) $b -Rewriting multiplication to use shift (byte/signed word/word/dword/signed dword~) main::$0 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 2 -Rewriting multiplication to use shift (byte/signed word/word/dword/signed dword~) main::$2 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 4 -Rewriting multiplication to use shift (byte/signed word/word/dword/signed dword~) main::$4 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 8 -Rewriting multiplication to use shift (signed word/signed byte/signed dword~) main::$8 ← (signed byte) main::sb#0 * (byte/signed byte/word/signed word/dword/signed dword) 2 -Successful SSA optimization Pass2Multiply2sRewriting -Inferred type updated to byte in [1] (byte/signed word/word/dword/signed dword~) main::$0 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 -Inferred type updated to byte in [3] (byte/signed word/word/dword/signed dword~) main::$2 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 -Inferred type updated to byte in [5] (byte/signed word/word/dword/signed dword~) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 -Inferred type updated to signed byte in [8] (signed word/signed byte/signed dword~) main::$8 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 +Rewriting multiplication to remove identity multiply/divide (byte/signed word/word/dword/signed dword~) main::$2 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 1 +Rewriting multiplication to use shift (byte/signed word/word/dword/signed dword~) main::$5 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 2 +Rewriting multiplication to use shift (byte/signed word/word/dword/signed dword~) main::$8 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 4 +Rewriting multiplication to use shift (byte/signed word/word/dword/signed dword~) main::$11 ← (byte) main::i#2 * (byte/signed byte/word/signed word/dword/signed dword) 8 +Rewriting multiplication to use shift (signed word/signed byte/signed dword~) main::$16 ← (signed byte) main::sb#0 * (byte/signed byte/word/signed word/dword/signed dword) 2 +Successful SSA optimization Pass2MultiplyToShiftRewriting +Alias (byte) main::i#2 = (byte/signed word/word/dword/signed dword~) main::$2 +Successful SSA optimization Pass2AliasElimination +Inferred type updated to byte in [2] (byte/signed word/word/dword/signed dword~) main::$5 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 +Inferred type updated to byte in [4] (byte/signed word/word/dword/signed dword~) main::$8 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 +Inferred type updated to byte in [6] (byte/signed word/word/dword/signed dword~) main::$11 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 +Inferred type updated to signed byte in [9] (signed word/signed byte/signed dword~) main::$16 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 Inlining constant with var siblings (const byte) main::i#0 +Constant inlined main::$1 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) $28 +Constant inlined main::$0 = (byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) $28 Constant inlined main::i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0 -Constant inlined main::$3 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 -Constant inlined main::$1 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 -Constant inlined main::$7 = (const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 +Constant inlined main::$6 = (byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 +Constant inlined main::$3 = (byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 +Constant inlined main::$14 = (byte/signed byte/word/signed word/dword/signed dword) 5*(byte/signed byte/word/signed word/dword/signed dword) $28 +Constant inlined main::$4 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 +Constant inlined main::$15 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5*(byte/signed byte/word/signed word/dword/signed dword) $28 +Constant inlined main::$9 = (byte/signed byte/word/signed word/dword/signed dword) 3*(byte/signed byte/word/signed word/dword/signed dword) $28 +Constant inlined main::$7 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 +Constant inlined main::$10 = (const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3*(byte/signed byte/word/signed word/dword/signed dword) $28 Successful SSA optimization Pass2ConstantInlining +Simplifying constant multiply by zero 0*$28 +Simplifying constant plus zero main::SCREEN#0+0 Added new block during phi lifting main::@3(between main::@1 and main::@1) Adding NOP phi() at start of @begin Adding NOP phi() at start of @1 @@ -107,7 +143,7 @@ CALL GRAPH Calls in [] to main:2 Created 1 initial phi equivalence classes -Coalesced [18] main::i#3 ← main::i#1 +Coalesced [19] main::i#3 ← main::i#1 Coalesced down to 1 phi equivalence classes Culled Empty Block (label) main::@3 Adding NOP phi() at start of @begin @@ -130,56 +166,57 @@ main: scope:[main] from @1 to:main::@1 main::@1: scope:[main] from main main::@1 [5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 ) - [6] (byte~) main::$0 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 - [7] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 - [8] (byte~) main::$2 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 - [9] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 - [10] (byte~) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 - [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 + (byte) main::i#2) ← (byte~) main::$4 - [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 - [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 - [14] *((const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 + (byte) main::i#2) ← (byte)(signed byte~) main::$8 - [15] (byte) main::i#1 ← ++ (byte) main::i#2 - [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 + [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 + [7] (byte~) main::$5 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 + [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$5 + [9] (byte~) main::$8 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 + [10] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$8 + [11] (byte~) main::$11 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 + [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$11 + [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 + [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 + [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte)(signed byte~) main::$16 + [16] (byte) main::i#1 ← ++ (byte) main::i#2 + [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 to:main::@return main::@return: scope:[main] from main::@1 - [17] return + [18] return to:@return VARIABLE REGISTER WEIGHTS (void()) main() -(byte~) main::$0 22.0 -(byte~) main::$2 22.0 -(byte~) main::$4 22.0 -(signed byte~) main::$8 11.0 +(byte~) main::$11 22.0 +(signed byte~) main::$16 11.0 +(byte~) main::$5 22.0 +(byte~) main::$8 22.0 (byte*) main::SCREEN (byte) main::i (byte) main::i#1 16.5 -(byte) main::i#2 9.899999999999999 +(byte) main::i#2 11.0 (signed byte) main::sb (signed byte) main::sb#0 22.0 Initial phi equivalence classes [ main::i#2 main::i#1 ] -Added variable main::$0 to zero page equivalence class [ main::$0 ] -Added variable main::$2 to zero page equivalence class [ main::$2 ] -Added variable main::$4 to zero page equivalence class [ main::$4 ] -Added variable main::sb#0 to zero page equivalence class [ main::sb#0 ] +Added variable main::$5 to zero page equivalence class [ main::$5 ] Added variable main::$8 to zero page equivalence class [ main::$8 ] +Added variable main::$11 to zero page equivalence class [ main::$11 ] +Added variable main::sb#0 to zero page equivalence class [ main::sb#0 ] +Added variable main::$16 to zero page equivalence class [ main::$16 ] Complete equivalence classes [ main::i#2 main::i#1 ] -[ main::$0 ] -[ main::$2 ] -[ main::$4 ] -[ main::sb#0 ] +[ main::$5 ] [ main::$8 ] +[ main::$11 ] +[ main::sb#0 ] +[ main::$16 ] Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ] -Allocated zp ZP_BYTE:3 [ main::$0 ] -Allocated zp ZP_BYTE:4 [ main::$2 ] -Allocated zp ZP_BYTE:5 [ main::$4 ] +Allocated zp ZP_BYTE:3 [ main::$5 ] +Allocated zp ZP_BYTE:4 [ main::$8 ] +Allocated zp ZP_BYTE:5 [ main::$11 ] Allocated zp ZP_BYTE:6 [ main::sb#0 ] -Allocated zp ZP_BYTE:7 [ main::$8 ] +Allocated zp ZP_BYTE:7 [ main::$16 ] INITIAL ASM //SEG0 File Comments @@ -208,10 +245,10 @@ bend: //SEG10 main main: { .label SCREEN = $400 - .label _0 = 3 - .label _2 = 4 - .label _4 = 5 - .label _8 = 7 + .label _5 = 3 + .label _8 = 4 + .label _11 = 5 + .label _16 = 7 .label sb = 6 .label i = 2 //SEG11 [5] phi from main to main::@1 [phi:main->main::@1] @@ -226,90 +263,95 @@ main: { jmp b1 //SEG15 main::@1 b1: - //SEG16 [6] (byte~) main::$0 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuz1=vbuz2_rol_1 - lda i - asl - sta _0 - //SEG17 [7] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuz1=vbuz2 - lda _0 + //SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuz1=vbuz1 ldy i + tya sta SCREEN,y - //SEG18 [8] (byte~) main::$2 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuz1=vbuz2_rol_2 + //SEG17 [7] (byte~) main::$5 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuz1=vbuz2_rol_1 + lda i + asl + sta _5 + //SEG18 [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$5 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _5 + ldy i + sta SCREEN+1*$28,y + //SEG19 [9] (byte~) main::$8 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuz1=vbuz2_rol_2 lda i asl asl - sta _2 - //SEG19 [9] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuz2 - lda _2 + sta _8 + //SEG20 [10] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$8 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _8 ldy i - sta SCREEN+$28,y - //SEG20 [10] (byte~) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuz1=vbuz2_rol_3 + sta SCREEN+2*$28,y + //SEG21 [11] (byte~) main::$11 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuz1=vbuz2_rol_3 lda i asl asl asl - sta _4 - //SEG21 [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 + (byte) main::i#2) ← (byte~) main::$4 -- pbuc1_derefidx_vbuz1=vbuz2 - lda _4 + sta _11 + //SEG22 [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$11 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _11 ldy i - sta SCREEN+$50,y - //SEG22 [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsz1=_neg_vbsz2 + sta SCREEN+3*$28,y + //SEG23 [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsz1=_neg_vbsz2 lda i eor #$ff clc adc #1 sta sb - //SEG23 [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsz1=vbsz2_rol_1 + //SEG24 [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsz1=vbsz2_rol_1 lda sb asl - sta _8 - //SEG24 [14] *((const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 + (byte) main::i#2) ← (byte)(signed byte~) main::$8 -- pbuc1_derefidx_vbuz1=vbuz2 - lda _8 + sta _16 + //SEG25 [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte)(signed byte~) main::$16 -- pbuc1_derefidx_vbuz1=vbuz2 + lda _16 ldy i - sta SCREEN+$a0,y - //SEG25 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 + sta SCREEN+5*$28,y + //SEG26 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1 inc i - //SEG26 [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 + //SEG27 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 lda #$b cmp i bne b1_from_b1 jmp breturn - //SEG27 main::@return + //SEG28 main::@return breturn: - //SEG28 [17] return + //SEG29 [18] return rts } REGISTER UPLIFT POTENTIAL REGISTERS -Statement [6] (byte~) main::$0 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$0 ] ( main:2 [ main::i#2 main::$0 ] ) always clobbers reg byte a +Statement [7] (byte~) main::$5 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$5 ] ( main:2 [ main::i#2 main::$5 ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ] -Statement [8] (byte~) main::$2 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#2 main::$2 ] ( main:2 [ main::i#2 main::$2 ] ) always clobbers reg byte a -Statement [10] (byte~) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 [ main::i#2 main::$4 ] ( main:2 [ main::i#2 main::$4 ] ) always clobbers reg byte a -Statement [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 [ main::i#2 main::sb#0 ] ( main:2 [ main::i#2 main::sb#0 ] ) always clobbers reg byte a -Statement [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$8 ] ( main:2 [ main::i#2 main::$8 ] ) always clobbers reg byte a -Statement [6] (byte~) main::$0 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$0 ] ( main:2 [ main::i#2 main::$0 ] ) always clobbers reg byte a -Statement [8] (byte~) main::$2 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#2 main::$2 ] ( main:2 [ main::i#2 main::$2 ] ) always clobbers reg byte a -Statement [10] (byte~) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 [ main::i#2 main::$4 ] ( main:2 [ main::i#2 main::$4 ] ) always clobbers reg byte a -Statement [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 [ main::i#2 main::sb#0 ] ( main:2 [ main::i#2 main::sb#0 ] ) always clobbers reg byte a -Statement [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$8 ] ( main:2 [ main::i#2 main::$8 ] ) always clobbers reg byte a +Statement [9] (byte~) main::$8 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#2 main::$8 ] ( main:2 [ main::i#2 main::$8 ] ) always clobbers reg byte a +Statement [11] (byte~) main::$11 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 [ main::i#2 main::$11 ] ( main:2 [ main::i#2 main::$11 ] ) always clobbers reg byte a +Statement [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 [ main::i#2 main::sb#0 ] ( main:2 [ main::i#2 main::sb#0 ] ) always clobbers reg byte a +Statement [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$16 ] ( main:2 [ main::i#2 main::$16 ] ) always clobbers reg byte a +Statement [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a +Statement [7] (byte~) main::$5 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$5 ] ( main:2 [ main::i#2 main::$5 ] ) always clobbers reg byte a +Statement [9] (byte~) main::$8 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 [ main::i#2 main::$8 ] ( main:2 [ main::i#2 main::$8 ] ) always clobbers reg byte a +Statement [11] (byte~) main::$11 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 [ main::i#2 main::$11 ] ( main:2 [ main::i#2 main::$11 ] ) always clobbers reg byte a +Statement [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 [ main::i#2 main::sb#0 ] ( main:2 [ main::i#2 main::sb#0 ] ) always clobbers reg byte a +Statement [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::$16 ] ( main:2 [ main::i#2 main::$16 ] ) always clobbers reg byte a Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:3 [ main::$0 ] : zp ZP_BYTE:3 , reg byte a , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:4 [ main::$2 ] : zp ZP_BYTE:4 , reg byte a , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:5 [ main::$4 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:3 [ main::$5 ] : zp ZP_BYTE:3 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:4 [ main::$8 ] : zp ZP_BYTE:4 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:5 [ main::$11 ] : zp ZP_BYTE:5 , reg byte a , reg byte x , reg byte y , Potential registers zp ZP_BYTE:6 [ main::sb#0 ] : zp ZP_BYTE:6 , reg byte a , reg byte x , reg byte y , -Potential registers zp ZP_BYTE:7 [ main::$8 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y , +Potential registers zp ZP_BYTE:7 [ main::$16 ] : zp ZP_BYTE:7 , reg byte a , reg byte x , reg byte y , REGISTER UPLIFT SCOPES -Uplift Scope [main] 26.4: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 22: zp ZP_BYTE:3 [ main::$0 ] 22: zp ZP_BYTE:4 [ main::$2 ] 22: zp ZP_BYTE:5 [ main::$4 ] 22: zp ZP_BYTE:6 [ main::sb#0 ] 11: zp ZP_BYTE:7 [ main::$8 ] +Uplift Scope [main] 27.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ] 22: zp ZP_BYTE:3 [ main::$5 ] 22: zp ZP_BYTE:4 [ main::$8 ] 22: zp ZP_BYTE:5 [ main::$11 ] 22: zp ZP_BYTE:6 [ main::sb#0 ] 11: zp ZP_BYTE:7 [ main::$16 ] Uplift Scope [] -Uplifting [main] best 793 combination reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::$0 ] reg byte a [ main::$2 ] reg byte a [ main::$4 ] zp ZP_BYTE:6 [ main::sb#0 ] zp ZP_BYTE:7 [ main::$8 ] +Uplifting [main] best 863 combination reg byte x [ main::i#2 main::i#1 ] reg byte a [ main::$5 ] reg byte a [ main::$8 ] reg byte a [ main::$11 ] zp ZP_BYTE:6 [ main::sb#0 ] zp ZP_BYTE:7 [ main::$16 ] Limited combination testing to 100 combinations of 3072 possible. -Uplifting [] best 793 combination +Uplifting [] best 863 combination Attempting to uplift remaining variables inzp ZP_BYTE:6 [ main::sb#0 ] -Uplifting [main] best 733 combination reg byte a [ main::sb#0 ] -Attempting to uplift remaining variables inzp ZP_BYTE:7 [ main::$8 ] -Uplifting [main] best 673 combination reg byte a [ main::$8 ] +Uplifting [main] best 803 combination reg byte a [ main::sb#0 ] +Attempting to uplift remaining variables inzp ZP_BYTE:7 [ main::$16 ] +Uplifting [main] best 743 combination reg byte a [ main::$16 ] ASSEMBLER BEFORE OPTIMIZATION //SEG0 File Comments @@ -349,42 +391,45 @@ main: { jmp b1 //SEG15 main::@1 b1: - //SEG16 [6] (byte~) main::$0 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_rol_1 + //SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx txa - asl - //SEG17 [7] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuxx=vbuaa sta SCREEN,x - //SEG18 [8] (byte~) main::$2 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuaa=vbuxx_rol_2 + //SEG17 [7] (byte~) main::$5 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_rol_1 + txa + asl + //SEG18 [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$5 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+1*$28,x + //SEG19 [9] (byte~) main::$8 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuaa=vbuxx_rol_2 txa asl asl - //SEG19 [9] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$28,x - //SEG20 [10] (byte~) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuaa=vbuxx_rol_3 + //SEG20 [10] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$8 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+2*$28,x + //SEG21 [11] (byte~) main::$11 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuaa=vbuxx_rol_3 txa asl asl asl - //SEG21 [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 + (byte) main::i#2) ← (byte~) main::$4 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$50,x - //SEG22 [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsaa=_neg_vbsxx + //SEG22 [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$11 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+3*$28,x + //SEG23 [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsaa=_neg_vbsxx txa eor #$ff clc adc #1 - //SEG23 [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsaa=vbsaa_rol_1 + //SEG24 [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsaa=vbsaa_rol_1 asl - //SEG24 [14] *((const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 + (byte) main::i#2) ← (byte)(signed byte~) main::$8 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$a0,x - //SEG25 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx + //SEG25 [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte)(signed byte~) main::$16 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+5*$28,x + //SEG26 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx inx - //SEG26 [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 + //SEG27 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 cpx #$b bne b1_from_b1 jmp breturn - //SEG27 main::@return + //SEG28 main::@return breturn: - //SEG28 [17] return + //SEG29 [18] return rts } @@ -418,30 +463,30 @@ FINAL SYMBOL TABLE (label) @begin (label) @end (void()) main() -(byte~) main::$0 reg byte a 22.0 -(byte~) main::$2 reg byte a 22.0 -(byte~) main::$4 reg byte a 22.0 -(signed byte~) main::$8 reg byte a 11.0 +(byte~) main::$11 reg byte a 22.0 +(signed byte~) main::$16 reg byte a 11.0 +(byte~) main::$5 reg byte a 22.0 +(byte~) main::$8 reg byte a 22.0 (label) main::@1 (label) main::@return (byte*) main::SCREEN (const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400 (byte) main::i (byte) main::i#1 reg byte x 16.5 -(byte) main::i#2 reg byte x 9.899999999999999 +(byte) main::i#2 reg byte x 11.0 (signed byte) main::sb (signed byte) main::sb#0 reg byte a 22.0 reg byte x [ main::i#2 main::i#1 ] -reg byte a [ main::$0 ] -reg byte a [ main::$2 ] -reg byte a [ main::$4 ] -reg byte a [ main::sb#0 ] +reg byte a [ main::$5 ] reg byte a [ main::$8 ] +reg byte a [ main::$11 ] +reg byte a [ main::sb#0 ] +reg byte a [ main::$16 ] FINAL ASSEMBLER -Score: 571 +Score: 641 //SEG0 File Comments // Check that multiplication by factors of 2 is converted to shifts @@ -467,40 +512,43 @@ main: { //SEG14 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy //SEG15 main::@1 b1: - //SEG16 [6] (byte~) main::$0 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_rol_1 + //SEG16 [6] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte) main::i#2 -- pbuc1_derefidx_vbuxx=vbuxx txa - asl - //SEG17 [7] *((const byte*) main::SCREEN#0 + (byte) main::i#2) ← (byte~) main::$0 -- pbuc1_derefidx_vbuxx=vbuaa sta SCREEN,x - //SEG18 [8] (byte~) main::$2 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuaa=vbuxx_rol_2 + //SEG17 [7] (byte~) main::$5 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbuaa=vbuxx_rol_1 + txa + asl + //SEG18 [8] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 1*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$5 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+1*$28,x + //SEG19 [9] (byte~) main::$8 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 2 -- vbuaa=vbuxx_rol_2 txa asl asl - //SEG19 [9] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$2 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$28,x - //SEG20 [10] (byte~) main::$4 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuaa=vbuxx_rol_3 + //SEG20 [10] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 2*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$8 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+2*$28,x + //SEG21 [11] (byte~) main::$11 ← (byte) main::i#2 << (byte/signed byte/word/signed word/dword/signed dword) 3 -- vbuaa=vbuxx_rol_3 txa asl asl asl - //SEG21 [11] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) $50 + (byte) main::i#2) ← (byte~) main::$4 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$50,x - //SEG22 [12] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsaa=_neg_vbsxx + //SEG22 [12] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte~) main::$11 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+3*$28,x + //SEG23 [13] (signed byte) main::sb#0 ← - (signed byte)(byte) main::i#2 -- vbsaa=_neg_vbsxx txa eor #$ff clc adc #1 - //SEG23 [13] (signed byte~) main::$8 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsaa=vbsaa_rol_1 + //SEG24 [14] (signed byte~) main::$16 ← (signed byte) main::sb#0 << (byte/signed byte/word/signed word/dword/signed dword) 1 -- vbsaa=vbsaa_rol_1 asl - //SEG24 [14] *((const byte*) main::SCREEN#0+(byte/word/signed word/dword/signed dword) $a0 + (byte) main::i#2) ← (byte)(signed byte~) main::$8 -- pbuc1_derefidx_vbuxx=vbuaa - sta SCREEN+$a0,x - //SEG25 [15] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx + //SEG25 [15] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 5*(byte/signed byte/word/signed word/dword/signed dword) $28 + (byte) main::i#2) ← (byte)(signed byte~) main::$16 -- pbuc1_derefidx_vbuxx=vbuaa + sta SCREEN+5*$28,x + //SEG26 [16] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuxx=_inc_vbuxx inx - //SEG26 [16] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 + //SEG27 [17] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) $b) goto main::@1 -- vbuxx_neq_vbuc1_then_la1 cpx #$b bne b1 - //SEG27 main::@return - //SEG28 [17] return + //SEG28 main::@return + //SEG29 [18] return rts } diff --git a/src/test/ref/multiply-2s.sym b/src/test/ref/multiply-2s.sym index d1c02caad..cdf521121 100644 --- a/src/test/ref/multiply-2s.sym +++ b/src/test/ref/multiply-2s.sym @@ -2,23 +2,23 @@ (label) @begin (label) @end (void()) main() -(byte~) main::$0 reg byte a 22.0 -(byte~) main::$2 reg byte a 22.0 -(byte~) main::$4 reg byte a 22.0 -(signed byte~) main::$8 reg byte a 11.0 +(byte~) main::$11 reg byte a 22.0 +(signed byte~) main::$16 reg byte a 11.0 +(byte~) main::$5 reg byte a 22.0 +(byte~) main::$8 reg byte a 22.0 (label) main::@1 (label) main::@return (byte*) main::SCREEN (const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) $400 (byte) main::i (byte) main::i#1 reg byte x 16.5 -(byte) main::i#2 reg byte x 9.899999999999999 +(byte) main::i#2 reg byte x 11.0 (signed byte) main::sb (signed byte) main::sb#0 reg byte a 22.0 reg byte x [ main::i#2 main::i#1 ] -reg byte a [ main::$0 ] -reg byte a [ main::$2 ] -reg byte a [ main::$4 ] -reg byte a [ main::sb#0 ] +reg byte a [ main::$5 ] reg byte a [ main::$8 ] +reg byte a [ main::$11 ] +reg byte a [ main::sb#0 ] +reg byte a [ main::$16 ]