1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-27 04:49:27 +00:00

Fixed static optimization problem not detecting modified memory. Fixed thread problem not handling global variables properly. Added compiler switch -O0 doing less optimization for faster compiles.

This commit is contained in:
jespergravgaard 2019-05-31 12:46:50 +02:00
parent 29aa5322b2
commit 97f6051b12
4 changed files with 49 additions and 21 deletions

View File

@ -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();

View File

@ -54,6 +54,9 @@ public class KickC implements Callable<Void> {
@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<Void> {
compiler.setUpliftCombinations(optimizeUpliftCombinations);
}
if(optimizeMinimal) {
compiler.setOptimizeMinimal(true);
}
System.out.println("Compiling " + kcFile);
Program program = null;
try {

View File

@ -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());

View File

@ -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<ScopeRef> 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<ScopeRef> 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<ScopeRef> recursiveCallers = callGraph.getRecursiveCallers(scopeRef);
for(ScopeRef threadHead : threadHeads) {
if(recursiveCallers.contains(threadHead)) {
if(!threads.contains(threadHead)) {
threads.add(threadHead);
}
}
}
}