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

Moved uplift combination testing to separate pass. Made interface for limiting the relevant registers for each equivalence class - improving speed of the combination testing.

This commit is contained in:
Jesper Gravgaard 2017-08-03 15:05:36 +02:00
parent 3b99b6671c
commit 0e5bd97e21
3 changed files with 121 additions and 77 deletions

View File

@ -71,66 +71,10 @@ public class Compiler {
program.getLog().append("REGISTER UPLIFT SCOPES"); program.getLog().append("REGISTER UPLIFT SCOPES");
program.getLog().append(program.getRegisterUpliftProgram().toString((program.getVariableRegisterWeights()))); program.getLog().append(program.getRegisterUpliftProgram().toString((program.getVariableRegisterWeights())));
// Test uplift combinations to find the best one. // Attempt uplifting registers through a lot of combinations
Set<String> unknownFragments = new LinkedHashSet<>(); new Pass3RegisterUpliftCombinations(program).performUplift();
for (RegisterUpliftScope upliftScope : program.getRegisterUpliftProgram().getRegisterUpliftScopes()) {
int bestScore = Integer.MAX_VALUE;
RegisterUpliftScope.Combination bestCombination = null;
Iterator<RegisterUpliftScope.Combination> combinationIterator = upliftScope.geCombinationIterator();
while (combinationIterator.hasNext()) {
RegisterUpliftScope.Combination combination = combinationIterator.next();
// Reset register allocation to original zero page allocation
new Pass3RegistersFinalize(program).allocate(false);
// Apply the uplift combination
combination.allocate(program.getAllocation());
// Generate ASM
try {
new Pass3CodeGeneration(program).generate();
} catch (AsmFragment.UnknownFragmentException e) {
unknownFragments.add(e.getFragmentSignature());
StringBuilder msg = new StringBuilder();
msg.append("Uplift attempt [" + upliftScope.getScopeRef() + "] ");
msg.append("missing fragment " + e.getFragmentSignature());
program.getLog().append(msg.toString());
continue;
} catch (AsmFragment.AluNotApplicableException e) {
StringBuilder msg = new StringBuilder();
msg.append("Uplift attempt [" + upliftScope.getScopeRef() + "] ");
msg.append("alu not applicable");
program.getLog().append(msg.toString());
continue;
}
// If no clobber - Find value of the resulting allocation
boolean hasClobberProblem = new Pass3AssertNoCpuClobber(program).hasClobberProblem(false);
int combinationScore = getAsmScore(program);
StringBuilder msg = new StringBuilder();
msg.append("Uplift attempt [" + upliftScope.getScopeRef() + "] ");
if (hasClobberProblem) {
msg.append("clobber");
} else {
msg.append(combinationScore);
}
msg.append(" allocation: ").append(combination.toString());
program.getLog().append(msg.toString());
if (!hasClobberProblem) {
if (combinationScore < bestScore) {
bestScore = combinationScore;
bestCombination = combination;
}
}
}
// Save the best combination in the equivalence class
bestCombination.store(program.getLiveRangeEquivalenceClassSet());
program.getLog().append("Uplifting [" + upliftScope.getScopeRef() + "] best " + bestScore + " combination " + bestCombination.toString());
}
if (unknownFragments.size() > 0) {
program.getLog().append("MISSING FRAGMENTS");
for (String unknownFragment : unknownFragments) {
program.getLog().append(" " + unknownFragment);
}
}
// Final register coalesce and code generation // Final register coalesce and code generation
new Pass3ZeroPageCoalesce(program).allocate(); new Pass3ZeroPageCoalesce(program).allocate();
@ -138,23 +82,6 @@ public class Compiler {
} }
private int getAsmScore(Program program) {
int score = 0;
AsmProgram asm = program.getAsm();
ControlFlowGraph graph = program.getGraph();
NaturalLoopSet loopSet = program.getLoopSet();
for (AsmSegment asmSegment : asm.getSegments()) {
double asmSegmentCycles = asmSegment.getCycles();
if (asmSegmentCycles > 0) {
Integer statementIdx = asmSegment.getStatementIdx();
ControlFlowBlock block = graph.getBlockFromStatementIdx(statementIdx);
int maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
score += asmSegmentCycles * Math.pow(10, maxLoopDepth);
}
}
return score;
}
private void pass3Analysis(Program program) { private void pass3Analysis(Program program) {
new Pass3BlockSequencePlanner(program).plan(); new Pass3BlockSequencePlanner(program).plan();
@ -211,8 +138,6 @@ public class Compiler {
} }
public void pass2OptimizeSSA(Program program) { public void pass2OptimizeSSA(Program program) {
List<Pass2SsaOptimization> optimizations = new ArrayList<>(); List<Pass2SsaOptimization> optimizations = new ArrayList<>();
optimizations.add(new Pass2CullEmptyBlocks(program)); optimizations.add(new Pass2CullEmptyBlocks(program));

View File

@ -143,6 +143,23 @@ public class RegisterUpliftScope {
this.nextIterationId = 0; this.nextIterationId = 0;
} }
/**
* Examine the control flow graph to determine which registers could be usable for
* optimizing the variables in a specific live range equivalence class.
*
* The optimizer will only test combinations with these registers
*
* @param equivalenceClass The equivalence class
* @return The registers to try to optimize the variables of the equivalence class into
*/
public List<RegisterAllocation.Register> getPotentialRegisters(LiveRangeEquivalenceClass equivalenceClass) {
// TODO!!
}
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return nextIterationId < getNumIterations(); return nextIterationId < getNumIterations();

View File

@ -0,0 +1,102 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.asm.AsmFragment;
import dk.camelot64.kickc.asm.AsmProgram;
import dk.camelot64.kickc.asm.AsmSegment;
import dk.camelot64.kickc.icl.*;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/*** Find the variable equivalence classes to attempt to uplift in each scope */
public class Pass3RegisterUpliftCombinations extends Pass2Base {
public Pass3RegisterUpliftCombinations(Program program) {
super(program);
}
public void performUplift() {
// Test uplift combinations to find the best one.
Set<String> unknownFragments = new LinkedHashSet<>();
List<RegisterUpliftScope> registerUpliftScopes = getProgram().getRegisterUpliftProgram().getRegisterUpliftScopes();
for (RegisterUpliftScope upliftScope : registerUpliftScopes) {
int bestScore = Integer.MAX_VALUE;
RegisterUpliftScope.Combination bestCombination = null;
Iterator<RegisterUpliftScope.Combination> combinationIterator = upliftScope.geCombinationIterator();
while (combinationIterator.hasNext()) {
RegisterUpliftScope.Combination combination = combinationIterator.next();
// Reset register allocation to original zero page allocation
new Pass3RegistersFinalize(getProgram()).allocate(false);
// Apply the uplift combination
combination.allocate(getProgram().getAllocation());
// Generate ASM
try {
new Pass3CodeGeneration(getProgram()).generate();
} catch (AsmFragment.UnknownFragmentException e) {
unknownFragments.add(e.getFragmentSignature());
StringBuilder msg = new StringBuilder();
msg.append("Uplift attempt [" + upliftScope.getScopeRef() + "] ");
msg.append("missing fragment " + e.getFragmentSignature());
getLog().append(msg.toString());
continue;
} catch (AsmFragment.AluNotApplicableException e) {
StringBuilder msg = new StringBuilder();
msg.append("Uplift attempt [" + upliftScope.getScopeRef() + "] ");
msg.append("alu not applicable");
getLog().append(msg.toString());
continue;
}
// If no clobber - Find value of the resulting allocation
boolean hasClobberProblem = new Pass3AssertNoCpuClobber(getProgram()).hasClobberProblem(false);
int combinationScore = getAsmScore(getProgram());
StringBuilder msg = new StringBuilder();
msg.append("Uplift attempt [" + upliftScope.getScopeRef() + "] ");
if (hasClobberProblem) {
msg.append("clobber");
} else {
msg.append(combinationScore);
}
msg.append(" allocation: ").append(combination.toString());
getLog().append(msg.toString());
if (!hasClobberProblem) {
if (combinationScore < bestScore) {
bestScore = combinationScore;
bestCombination = combination;
}
}
}
// Save the best combination in the equivalence class
bestCombination.store(getProgram().getLiveRangeEquivalenceClassSet());
getLog().append("Uplifting [" + upliftScope.getScopeRef() + "] best " + bestScore + " combination " + bestCombination.toString());
}
if (unknownFragments.size() > 0) {
getLog().append("MISSING FRAGMENTS");
for (String unknownFragment : unknownFragments) {
getLog().append(" " + unknownFragment);
}
}
}
private int getAsmScore(Program program) {
int score = 0;
AsmProgram asm = program.getAsm();
ControlFlowGraph graph = program.getGraph();
NaturalLoopSet loopSet = program.getLoopSet();
for (AsmSegment asmSegment : asm.getSegments()) {
double asmSegmentCycles = asmSegment.getCycles();
if (asmSegmentCycles > 0) {
Integer statementIdx = asmSegment.getStatementIdx();
ControlFlowBlock block = graph.getBlockFromStatementIdx(statementIdx);
int maxLoopDepth = loopSet.getMaxLoopDepth(block.getLabel());
score += asmSegmentCycles * Math.pow(10, maxLoopDepth);
}
}
return score;
}
}