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:
parent
3b99b6671c
commit
0e5bd97e21
@ -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));
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user