diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index eb8f14abf..3aa809b1b 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -267,10 +267,10 @@ public class Compiler { optimizations.add(new Pass2ComparisonOptimization(program)); optimizations.add(new Pass2ConstantCallPointerIdentification(program)); optimizations.add(new Pass2SizeOfSimplification(program)); - optimizations.add(new Pass2InlineDerefIdx(program)); optimizations.add(new Pass2InlineCast(program)); - optimizations.add(new Pass2DeInlineWordDerefIdx(program)); optimizations.add(new PassNCastSimplification(program)); + optimizations.add(new Pass2InlineDerefIdx(program)); + optimizations.add(new Pass2DeInlineWordDerefIdx(program)); pass2Execute(optimizations); } @@ -303,6 +303,8 @@ public class Compiler { private void pass2InlineConstants() { // Constant inlining optimizations - as the last step to ensure that constant identification has been completed List constantOptimizations = new ArrayList<>(); + constantOptimizations.add(new PassNStatementIndices(program)); + constantOptimizations.add(new PassNVariableReferenceInfos(program)); constantOptimizations.add(new Pass2MultiplyToShiftRewriting(program)); constantOptimizations.add(new Pass2AliasElimination(program)); constantOptimizations.add(new Pass2ConstantInlining(program)); @@ -315,6 +317,9 @@ public class Compiler { constantOptimizations.add(new Pass2ConstantSimplification(program)); constantOptimizations.add(new PassNCastSimplification(program)); constantOptimizations.add(new Pass2ConstantIfs(program)); + constantOptimizations.add(new Pass2InlineDerefIdx(program)); + constantOptimizations.add(new PassNEliminateUnusedVars(program, true)); + pass2Execute(constantOptimizations); } diff --git a/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java b/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java index fec6f0316..a799b28bd 100644 --- a/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java +++ b/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java @@ -224,9 +224,11 @@ public class VariableReferenceInfos { public Collection getConstRefStatements(ConstantRef constRef) { Collection refs = symbolVarReferences.get(constRef); LinkedHashSet stmts = new LinkedHashSet<>(); - refs.stream() - .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) - .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + if(refs!=null) { + refs.stream() + .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) + .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + } return stmts; } @@ -239,9 +241,11 @@ public class VariableReferenceInfos { public Collection getVarRefStatements(VariableRef varRef) { Collection refs = symbolVarReferences.get(varRef); LinkedHashSet stmts = new LinkedHashSet<>(); - refs.stream() - .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) - .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + if(refs!=null) { + refs.stream() + .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) + .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + } return stmts; } @@ -254,10 +258,12 @@ public class VariableReferenceInfos { public Collection getVarUseStatements(VariableRef varRef) { Collection refs = symbolVarReferences.get(varRef); LinkedHashSet stmts = new LinkedHashSet<>(); - refs.stream() - .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) - .filter(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE == referenceToSymbolVar.getReferenceType()) - .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + if(refs!=null) { + refs.stream() + .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInStatement) + .filter(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE == referenceToSymbolVar.getReferenceType()) + .forEach(referenceToSymbolVar -> stmts.add(((ReferenceInStatement) referenceToSymbolVar).getStatementIdx())); + } return stmts; } @@ -271,10 +277,12 @@ public class VariableReferenceInfos { public Collection getSymbolRefConsts(ConstantRef constRef) { Collection refs = symbolVarReferences.get(constRef); LinkedHashSet constRefs = new LinkedHashSet<>(); - refs.stream() - .filter(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE.equals(referenceToSymbolVar.getReferenceType())) - .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInSymbol) - .forEach(referenceToSymbolVar -> constRefs.add(((ReferenceInSymbol) referenceToSymbolVar).getReferencingSymbol())); + if(refs!=null) { + refs.stream() + .filter(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE.equals(referenceToSymbolVar.getReferenceType())) + .filter(referenceToSymbolVar -> referenceToSymbolVar instanceof ReferenceInSymbol) + .forEach(referenceToSymbolVar -> constRefs.add(((ReferenceInSymbol) referenceToSymbolVar).getReferencingSymbol())); + } return constRefs; } diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index d14adcd43..9f56c9b5e 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -63,6 +63,26 @@ public class TestPrograms { */ + @Test + public void testDoubleIndexingArrays() throws IOException, URISyntaxException { + compileAndCompare("double-indexing-arrays"); + } + + @Test + public void testDerefidxWord2() throws IOException, URISyntaxException { + compileAndCompare("derefidx-word-2"); + } + + @Test + public void testDerefidxWord1() throws IOException, URISyntaxException { + compileAndCompare("derefidx-word-1"); + } + + @Test + public void testDerefidxWord0() throws IOException, URISyntaxException { + compileAndCompare("derefidx-word-0"); + } + @Test public void testTernaryInference() throws IOException, URISyntaxException { compileAndCompare("ternary-inference", log()); @@ -574,11 +594,6 @@ public class TestPrograms { compileAndCompare("irq-idx-problem"); } - @Test - public void testDoubleIndexingArrays() throws IOException, URISyntaxException { - compileAndCompare("double-indexing-arrays"); - } - @Test public void testInlineKickAsmClobber() throws IOException, URISyntaxException { compileAndCompare("inline-kasm-clobber"); diff --git a/src/test/kc/derefidx-word-0.kc b/src/test/kc/derefidx-word-0.kc new file mode 100644 index 000000000..7b5117853 --- /dev/null +++ b/src/test/kc/derefidx-word-0.kc @@ -0,0 +1,10 @@ +// Tests that array-indexing by a word variable is turned into pointer addition + +void main() { + const byte* screen = 0x0400; + for( word i=0;i<1000;i+=40) { + screen[i] = 'a'; + } + +} + diff --git a/src/test/kc/derefidx-word-1.kc b/src/test/kc/derefidx-word-1.kc new file mode 100644 index 000000000..5124674fa --- /dev/null +++ b/src/test/kc/derefidx-word-1.kc @@ -0,0 +1,7 @@ +// Tests that array-indexing by a constant word is turned into a constant pointer + +void main() { + const byte* screen = 0x0400; + screen[40*10] = 'a'; +} + diff --git a/src/test/kc/derefidx-word-2.kc b/src/test/kc/derefidx-word-2.kc new file mode 100644 index 000000000..af8417918 --- /dev/null +++ b/src/test/kc/derefidx-word-2.kc @@ -0,0 +1,9 @@ +// Tests that array-indexing by a word variable that is a sum of a constant word and a byte is turned back into derefidx + +void main() { + const byte* screen = 0x0400; + for( byte i : 0..39) { + screen[40*10+i] = 'a'; + } +} +