diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index a84672de1..f7a603c82 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -29,6 +29,9 @@ public class Compiler { /** The number of combinations to test when uplifting variables into registers. */ private int upliftCombinations = 100; + /** Tell the compiler to mimimize optimizations to increase performance. */ + private boolean optimizeMinimal = false; + public Compiler() { this.program = new Program(); } @@ -37,6 +40,10 @@ public class Compiler { this.upliftCombinations = upliftCombinations; } + public void setOptimizeMinimal(boolean optimizeMinimal) { + this.optimizeMinimal = optimizeMinimal; + } + public void setLog(CompileLog compileLog) { program.setLog(compileLog); } @@ -252,7 +259,7 @@ public class Compiler { optimizations.add(new Pass2DuplicateRValueIdentification(program)); optimizations.add(new Pass2ConditionalJumpSimplification(program)); optimizations.add(new Pass2ConditionalAndOrRewriting(program)); - optimizations.add(new Pass2ConditionalJumpSequenceImprovement(program)); + optimizations.add(new Pass2ConditionalJumpSequenceImprovement(program)); optimizations.add(new Pass2ConstantRValueConsolidation(program)); optimizations.add(new Pass2ConstantIdentification(program)); optimizations.add(new Pass2ConstantValues(program)); @@ -464,21 +471,23 @@ public class Compiler { } while(change); getLog().append(program.getRegisterPotentials().toString()); - // Find register uplift scopes - getLog().append("REGISTER UPLIFT SCOPES"); - new Pass4RegisterUpliftScopeAnalysis(program).findScopes(); - getLog().append(program.getRegisterUpliftProgram().toString((program.getVariableRegisterWeights()))); + if(!optimizeMinimal) { + // Find register uplift scopes + getLog().append("REGISTER UPLIFT SCOPES"); + new Pass4RegisterUpliftScopeAnalysis(program).findScopes(); + getLog().append(program.getRegisterUpliftProgram().toString((program.getVariableRegisterWeights()))); - // Attempt uplifting registers through a lot of combinations - //getLog().setVerboseUplift(true); - new Pass4RegisterUpliftCombinations(program).performUplift(upliftCombinations); + // Attempt uplifting registers through a lot of combinations + //getLog().setVerboseUplift(true); + new Pass4RegisterUpliftCombinations(program).performUplift(upliftCombinations); - //getLog().setVerboseUplift(true); - //new Pass4RegisterUpliftStatic(program).performUplift(); - //getLog().setVerboseUplift(false); + //getLog().setVerboseUplift(true); + //new Pass4RegisterUpliftStatic(program).performUplift(); + //getLog().setVerboseUplift(false); - // Attempt uplifting registers one at a time to catch remaining potential not realized by combination search - new Pass4RegisterUpliftRemains(program).performUplift(upliftCombinations); + // Attempt uplifting registers one at a time to catch remaining potential not realized by combination search + new Pass4RegisterUpliftRemains(program).performUplift(upliftCombinations); + } // Final register coalesce and finalization new Pass4ZeroPageCoalesceAssignment(program).coalesce(); diff --git a/src/main/java/dk/camelot64/kickc/KickC.java b/src/main/java/dk/camelot64/kickc/KickC.java index 1efac1a0a..e162c39a1 100644 --- a/src/main/java/dk/camelot64/kickc/KickC.java +++ b/src/main/java/dk/camelot64/kickc/KickC.java @@ -54,6 +54,9 @@ public class KickC implements Callable { @CommandLine.Option(names = {"-Ouplift" }, description = "Optimization Option. Number of combinations to test when uplifting variables to registers in a scope. By default 100 combinations are tested.") private Integer optimizeUpliftCombinations = null; + @CommandLine.Option(names = {"-O0" }, description = "Optimization Option. Perform minimal optimization to increase the speed of the compiler.") + private boolean optimizeMinimal = false; + @CommandLine.Option(names = {"-v" }, description = "Verbose output describing the compilation process") private boolean verbose= false; @@ -158,6 +161,10 @@ public class KickC implements Callable { compiler.setUpliftCombinations(optimizeUpliftCombinations); } + if(optimizeMinimal) { + compiler.setOptimizeMinimal(true); + } + System.out.println("Compiling " + kcFile); Program program = null; try { diff --git a/src/main/java/dk/camelot64/kickc/asm/AsmProgramStaticRegisterValues.java b/src/main/java/dk/camelot64/kickc/asm/AsmProgramStaticRegisterValues.java index 8ed96dc8a..c220df035 100644 --- a/src/main/java/dk/camelot64/kickc/asm/AsmProgramStaticRegisterValues.java +++ b/src/main/java/dk/camelot64/kickc/asm/AsmProgramStaticRegisterValues.java @@ -141,6 +141,8 @@ public class AsmProgramStaticRegisterValues { } if(mnemnonic.equals("sta") && (addressingMode.equals(AsmAddressingMode.ZP) || addressingMode.equals(AsmAddressingMode.ABS))) { current.setaMem(instruction.getParameter()); + if(instruction.getParameter().equals(current.getyMem())) current.setyMem(null); + if(instruction.getParameter().equals(current.getxMem())) current.setxMem(null); } if(mnemnonic.equals("ldx") && addressingMode.equals(AsmAddressingMode.IMM)) { current.setX(instruction.getParameter()); @@ -157,6 +159,8 @@ public class AsmProgramStaticRegisterValues { } if(mnemnonic.equals("stx") && (addressingMode.equals(AsmAddressingMode.ZP) || addressingMode.equals(AsmAddressingMode.ABS))) { current.setxMem(instruction.getParameter()); + if(instruction.getParameter().equals(current.getyMem())) current.setyMem(null); + if(instruction.getParameter().equals(current.getaMem())) current.setaMem(null); } if(mnemnonic.equals("ldy") && addressingMode.equals(AsmAddressingMode.IMM)) { current.setY(instruction.getParameter()); @@ -172,7 +176,8 @@ public class AsmProgramStaticRegisterValues { } if(mnemnonic.equals("sty") && (addressingMode.equals(AsmAddressingMode.ZP) || addressingMode.equals(AsmAddressingMode.ABS))) { current.setyMem(instruction.getParameter()); - current.setY(null); + if(instruction.getParameter().equals(current.getxMem())) current.setxMem(null); + if(instruction.getParameter().equals(current.getaMem())) current.setaMem(null); } if(mnemnonic.equals("txa")) { current.setA(current.getX()); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4ZeroPageCoalesce.java b/src/main/java/dk/camelot64/kickc/passes/Pass4ZeroPageCoalesce.java index 7b3206e03..13cc2a77d 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4ZeroPageCoalesce.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4ZeroPageCoalesce.java @@ -2,8 +2,8 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.symbols.Procedure; -import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.symbols.Variable; +import dk.camelot64.kickc.model.values.ProcedureRef; import dk.camelot64.kickc.model.values.ScopeRef; import dk.camelot64.kickc.model.values.SymbolRef; import dk.camelot64.kickc.model.values.VariableRef; @@ -110,7 +110,7 @@ public class Pass4ZeroPageCoalesce extends Pass2Base { * @return True if the two equivalence classes can be coalesced into one without problems. */ private static boolean canCoalesceThreads(LiveRangeEquivalenceClass ec1, LiveRangeEquivalenceClass ec2, Collection threadHeads, Program program) { - if(threadHeads.size()<=1) { + if(threadHeads.size() <= 1) { return true; } CallGraph callGraph = program.getCallGraph(); @@ -136,11 +136,18 @@ public class Pass4ZeroPageCoalesce extends Pass2Base { for(VariableRef varRef : equivalenceClass.getVariables()) { Variable variable = program.getScope().getVariable(varRef); ScopeRef scopeRef = variable.getScope().getRef(); - Collection recursiveCallers = callGraph.getRecursiveCallers(scopeRef); - for(ScopeRef threadHead : threadHeads) { - if(recursiveCallers.contains(threadHead)) { - if(!threads.contains(threadHead)) { - threads.add(threadHead); + if(scopeRef.equals(ScopeRef.ROOT)) { + ProcedureRef mainThreadHead = program.getScope().getProcedure(SymbolRef.MAIN_PROC_NAME).getRef(); + if(!threads.contains(mainThreadHead)) { + threads.add(mainThreadHead); + } + } else { + Collection recursiveCallers = callGraph.getRecursiveCallers(scopeRef); + for(ScopeRef threadHead : threadHeads) { + if(recursiveCallers.contains(threadHead)) { + if(!threads.contains(threadHead)) { + threads.add(threadHead); + } } } }