mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-27 19:50:10 +00:00
Refactored more program data to be calculated on demand.
This commit is contained in:
parent
0a39633ed8
commit
aceea6d8ec
@ -315,9 +315,9 @@ public class Compiler {
|
||||
List<PassStep> loopUnrolling = new ArrayList<>();
|
||||
loopUnrolling.add(new PassNStatementIndices(program));
|
||||
loopUnrolling.add(() -> { program.clearVariableReferenceInfos(); return false; });
|
||||
loopUnrolling.add(new PassNStatementInfos(program));
|
||||
loopUnrolling.add(() -> { program.clearStatementInfos(); return false; });
|
||||
loopUnrolling.add(() -> { program.clearDominators(); return false; });
|
||||
loopUnrolling.add(new PassNLoopAnalysis(program));
|
||||
loopUnrolling.add(() -> { program.clearLoopSet(); return false; });
|
||||
loopUnrolling.add(new Pass2LoopUnrollPhiPrepare(program));
|
||||
loopUnrolling.add(new Pass2LoopUnroll(program));
|
||||
|
||||
@ -422,9 +422,8 @@ public class Compiler {
|
||||
|
||||
//getLog().setVerboseLiveRanges(true);
|
||||
|
||||
new PassNStatementInfos(program).execute();
|
||||
program.clearStatementInfos();
|
||||
program.clearVariableReferenceInfos();
|
||||
new Pass3LiveRangesAnalysis(program).findLiveRanges();
|
||||
//getLog().append("CONTROL FLOW GRAPH - LIVE RANGES FOUND");
|
||||
//getLog().append(program.getGraph().toString(program));
|
||||
pass2AssertSSA();
|
||||
@ -439,10 +438,10 @@ public class Compiler {
|
||||
new Pass3AddNopBeforeCallOns(program).generate();
|
||||
new PassNStatementIndices(program).execute();
|
||||
program.clearCallGraph();
|
||||
new PassNStatementInfos(program).execute();
|
||||
program.clearStatementInfos();
|
||||
program.clearVariableReferenceInfos();
|
||||
new Pass3LiveRangesAnalysis(program).findLiveRanges();
|
||||
new Pass3LiveRangesEffectiveAnalysis(program).findLiveRangesEffective();
|
||||
program.clearLiveRangeVariables();
|
||||
program.clearLiveRangeVariablesEffective();
|
||||
pass2AssertSSA();
|
||||
|
||||
getLog().append("\nFINAL CONTROL FLOW GRAPH");
|
||||
@ -463,7 +462,7 @@ public class Compiler {
|
||||
if(getLog().isVerboseLoopAnalysis()) {
|
||||
getLog().append("NATURAL LOOPS");
|
||||
}
|
||||
new PassNLoopAnalysis(program).step();
|
||||
program.clearLoopSet();
|
||||
if(getLog().isVerboseLoopAnalysis()) {
|
||||
getLog().append(program.getLoopSet().toString());
|
||||
}
|
||||
@ -477,7 +476,7 @@ public class Compiler {
|
||||
}
|
||||
|
||||
getLog().append("\nVARIABLE REGISTER WEIGHTS");
|
||||
new Pass3VariableRegisterWeightAnalysis(program).findWeights();
|
||||
program.getVariableRegisterWeights();
|
||||
getLog().append(program.getScope().toString(program, Variable.class));
|
||||
|
||||
new Pass4LiveRangeEquivalenceClassesFinalize(program).allocate();
|
||||
@ -502,7 +501,6 @@ public class Compiler {
|
||||
|
||||
// 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
|
||||
|
@ -1,7 +1,7 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.passes.Pass3LiveRangesAnalysis;
|
||||
import dk.camelot64.kickc.passes.PassNCalcLiveRangeVariables;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -10,7 +10,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Live ranges for all variables.
|
||||
* Created by {@link Pass3LiveRangesAnalysis}
|
||||
* Created by {@link PassNCalcLiveRangeVariables}
|
||||
*/
|
||||
public class LiveRangeVariables {
|
||||
|
||||
|
@ -8,13 +8,14 @@ import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.passes.Pass2AliasElimination;
|
||||
import dk.camelot64.kickc.passes.PassNCalcLiveRangesEffective;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Effective variable live ranges for all statements.
|
||||
* (Including variables alive in calling methods).
|
||||
* Created by {@link dk.camelot64.kickc.passes.Pass3LiveRangesEffectiveAnalysis}
|
||||
* Created by {@link PassNCalcLiveRangesEffective}
|
||||
*/
|
||||
public class LiveRangeVariablesEffective {
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.passes.PassNLoopAnalysis;
|
||||
import dk.camelot64.kickc.passes.PassNCalcLoopSet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A set of natural loops in a control flow graph.
|
||||
* <p>For definitions and more see http://www.cs.colostate.edu/~cs553/ClassNotes/lecture09-control-dominators.ppt.pdf
|
||||
* <p>Created by {@link PassNLoopAnalysis}
|
||||
* <p>Created by {@link PassNCalcLoopSet}
|
||||
*/
|
||||
public class NaturalLoopSet {
|
||||
|
||||
|
@ -51,6 +51,8 @@ public class Program {
|
||||
private ProgramScope scope;
|
||||
/** The control flow graph. PASS 1-5 (DYNAMIC) */
|
||||
private ControlFlowGraph graph;
|
||||
/** Registers potentially usable as allocation for each live range equivalence class. PASS 4 (DYNAMIC) */
|
||||
private RegisterPotentials registerPotentials;
|
||||
/** Live range equivalence classes containing variables that do not have overlapping live ranges. PASS 3-5 (DYNAMIC) */
|
||||
private LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet;
|
||||
/** The 6502 ASM program. PASS 4-5 (DYNAMIC) */
|
||||
@ -67,22 +69,19 @@ public class Program {
|
||||
private DominatorsGraph dominators;
|
||||
/** Cached information about symbols. Contains a symbol table cache for fast access. PASS 3-4 (CACHED ON-DEMAND) */
|
||||
private SymbolInfos symbolInfos;
|
||||
/** Cached phi transitions into each block. PASS 4 (CACHED) */
|
||||
/** Cached phi transitions into each block. PASS 4 (CACHED ON-DEMAND) */
|
||||
private Map<LabelRef, PhiTransitions> phiTransitions;
|
||||
/** The live ranges of all variables. PASS 3-4 (CACHED) */
|
||||
/** The live ranges of all variables. PASS 3-4 (CACHED ON-DEMAND) */
|
||||
private LiveRangeVariables liveRangeVariables;
|
||||
/** The effective live ranges of all variables. PASS 3-4 (CACHED) */
|
||||
/** The effective live ranges of all variables. PASS 3-4 (CACHED ON-DEMAND) */
|
||||
private LiveRangeVariablesEffective liveRangeVariablesEffective;
|
||||
/** Registers potentially usable as allocation for each live range equivalence class. PASS 4 (CACHED) */
|
||||
private RegisterPotentials registerPotentials;
|
||||
/** Separation of live range equivalence classes into scopes - used for register uplift. PASS 4 (CACHED) */
|
||||
/** Separation of live range equivalence classes into scopes - used for register uplift. PASS 4 (CACHED ON-DEMAND) */
|
||||
private RegisterUpliftProgram registerUpliftProgram;
|
||||
|
||||
/** Cached information about which block is each statement a part of. PASS 2U-5 (CACHED) */
|
||||
/** Cached information about which block is each statement a part of. PASS 2U-5 (CACHED ON-DEMAND) */
|
||||
private StatementInfos statementInfos;
|
||||
/** Information about loops. PASS 2U-5 (CACHED) */
|
||||
/** Information about loops. PASS 2U-5 (CACHED ON-DEMAND) */
|
||||
private NaturalLoopSet loopSet;
|
||||
/** The register weight of all variables describing how much the variable would theoretically gain from being in a register. PASS 3-5 (CACHED) */
|
||||
/** The register weight of all variables describing how much the variable would theoretically gain from being in a register. PASS 3-5 (CACHED ON-DEMAND) */
|
||||
private VariableRegisterWeights variableRegisterWeights;
|
||||
|
||||
public Program() {
|
||||
@ -279,22 +278,28 @@ public class Program {
|
||||
this.phiTransitions = null;
|
||||
}
|
||||
|
||||
|
||||
public NaturalLoopSet getLoopSet() {
|
||||
return loopSet;
|
||||
public LiveRangeVariables getLiveRangeVariables() {
|
||||
if(liveRangeVariables==null)
|
||||
this.liveRangeVariables = new PassNCalcLiveRangeVariables(this).calculate();
|
||||
return liveRangeVariables;
|
||||
}
|
||||
|
||||
public void setLoopSet(NaturalLoopSet loopSet) {
|
||||
this.loopSet = loopSet;
|
||||
public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) {
|
||||
this.liveRangeVariables = liveRangeVariables;
|
||||
}
|
||||
|
||||
public void clearLiveRangeVariables() {
|
||||
this.liveRangeVariables = null;
|
||||
}
|
||||
|
||||
public StatementInfos getStatementInfos() {
|
||||
if(statementInfos==null)
|
||||
this.statementInfos = new PassNCalcStatementInfos(this).calculate();
|
||||
return statementInfos;
|
||||
}
|
||||
|
||||
public void setStatementInfos(StatementInfos statementInfos) {
|
||||
this.statementInfos = statementInfos;
|
||||
public void clearStatementInfos() {
|
||||
this.statementInfos = null;
|
||||
}
|
||||
|
||||
public SymbolInfos getSymbolInfos() {
|
||||
@ -303,20 +308,40 @@ public class Program {
|
||||
return symbolInfos;
|
||||
}
|
||||
|
||||
public LiveRangeVariables getLiveRangeVariables() {
|
||||
return liveRangeVariables;
|
||||
}
|
||||
|
||||
public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) {
|
||||
this.liveRangeVariables = liveRangeVariables;
|
||||
}
|
||||
|
||||
public LiveRangeVariablesEffective getLiveRangeVariablesEffective() {
|
||||
if(liveRangeVariablesEffective==null)
|
||||
this.liveRangeVariablesEffective = new PassNCalcLiveRangesEffective(this).calculate();
|
||||
return liveRangeVariablesEffective;
|
||||
}
|
||||
|
||||
public void setLiveRangeVariablesEffective(LiveRangeVariablesEffective liveRangeVariablesEffective) {
|
||||
this.liveRangeVariablesEffective = liveRangeVariablesEffective;
|
||||
public void clearLiveRangeVariablesEffective() {
|
||||
this.liveRangeVariablesEffective = null;
|
||||
}
|
||||
|
||||
public RegisterUpliftProgram getRegisterUpliftProgram() {
|
||||
if(registerUpliftProgram==null)
|
||||
this.registerUpliftProgram = new PassNCalcRegisterUpliftProgram(this).calculate();
|
||||
return registerUpliftProgram;
|
||||
}
|
||||
|
||||
public NaturalLoopSet getLoopSet() {
|
||||
if(loopSet==null)
|
||||
this.loopSet = new PassNCalcLoopSet(this).calculate();
|
||||
return loopSet;
|
||||
}
|
||||
|
||||
public void clearLoopSet() {
|
||||
this.loopSet = null;
|
||||
}
|
||||
|
||||
public VariableRegisterWeights getVariableRegisterWeights() {
|
||||
if(variableRegisterWeights==null)
|
||||
this.variableRegisterWeights = new PassNCalcVariableRegisterWeight(this).calculate();
|
||||
return variableRegisterWeights;
|
||||
}
|
||||
|
||||
public VariableRegisterWeights getOrNullVariableRegisterWeights() {
|
||||
return variableRegisterWeights;
|
||||
}
|
||||
|
||||
public LiveRangeEquivalenceClassSet getLiveRangeEquivalenceClassSet() {
|
||||
@ -327,14 +352,6 @@ public class Program {
|
||||
this.liveRangeEquivalenceClassSet = liveRangeEquivalenceClassSet;
|
||||
}
|
||||
|
||||
public VariableRegisterWeights getVariableRegisterWeights() {
|
||||
return variableRegisterWeights;
|
||||
}
|
||||
|
||||
public void setVariableRegisterWeights(VariableRegisterWeights variableRegisterWeights) {
|
||||
this.variableRegisterWeights = variableRegisterWeights;
|
||||
}
|
||||
|
||||
public RegisterPotentials getRegisterPotentials() {
|
||||
return registerPotentials;
|
||||
}
|
||||
@ -343,14 +360,6 @@ public class Program {
|
||||
this.registerPotentials = registerPotentials;
|
||||
}
|
||||
|
||||
public RegisterUpliftProgram getRegisterUpliftProgram() {
|
||||
return registerUpliftProgram;
|
||||
}
|
||||
|
||||
public void setRegisterUpliftProgram(RegisterUpliftProgram registerUpliftProgram) {
|
||||
this.registerUpliftProgram = registerUpliftProgram;
|
||||
}
|
||||
|
||||
public Collection<VariableRef> getEarlyIdentifiedConstants() {
|
||||
return earlyIdentifiedConstants;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public class ProgramScope extends Scope {
|
||||
if(liveRangeEquivalenceClassSet != null) {
|
||||
out.append("\n");
|
||||
for(LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
||||
out.append(liveRangeEquivalenceClass);
|
||||
out.append(liveRangeEquivalenceClass.toString());
|
||||
out.append("\n");
|
||||
}
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ public abstract class Scope implements Symbol {
|
||||
}
|
||||
|
||||
public String toString(Program program, Class symbolClass) {
|
||||
VariableRegisterWeights registerWeights = program.getVariableRegisterWeights();
|
||||
VariableRegisterWeights registerWeights = program.getOrNullVariableRegisterWeights();
|
||||
StringBuilder res = new StringBuilder();
|
||||
Set<String> names = symbols.keySet();
|
||||
List<String> sortedNames = new ArrayList<>(names);
|
||||
|
@ -18,13 +18,14 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariables> {
|
||||
|
||||
public Pass3LiveRangesAnalysis(Program program) {
|
||||
public PassNCalcLiveRangeVariables(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
public void findLiveRanges() {
|
||||
@Override
|
||||
public LiveRangeVariables calculate() {
|
||||
LiveRangeVariables liveRanges = new LiveRangeVariables(getProgram());
|
||||
boolean propagating;
|
||||
do {
|
||||
@ -36,6 +37,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
getLog().append(getProgram().getGraph().toString(getProgram()));
|
||||
}
|
||||
} while(propagating);
|
||||
return liveRanges;
|
||||
}
|
||||
|
||||
/**
|
@ -1,21 +1,24 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Find effective alive intervals for all variables in all statements. Add the intervals to the Program.
|
||||
*/
|
||||
public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||
public class PassNCalcLiveRangesEffective extends PassNCalcBase<LiveRangeVariablesEffective> {
|
||||
|
||||
public PassNCalcLiveRangesEffective(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call-paths for all procedures.
|
||||
@ -32,18 +35,14 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||
*/
|
||||
private VariableReferenceInfos referenceInfo;
|
||||
|
||||
|
||||
public Pass3LiveRangesEffectiveAnalysis(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
public void findLiveRangesEffective() {
|
||||
@Override
|
||||
public LiveRangeVariablesEffective calculate() {
|
||||
this.liveRangeVariables = getProgram().getLiveRangeVariables();
|
||||
this.referenceInfo = getProgram().getVariableReferenceInfos();
|
||||
this.procedureCallPaths = new LinkedHashMap<>();
|
||||
populateProcedureCallPaths();
|
||||
LiveRangeVariablesEffective aliveEffective = new LiveRangeVariablesEffective(getProgram(), procedureCallPaths, liveRangeVariables, referenceInfo);
|
||||
getProgram().setLiveRangeVariablesEffective(aliveEffective);
|
||||
return aliveEffective;
|
||||
//getLog().append("Calculated effective variable live ranges");
|
||||
}
|
||||
|
@ -11,13 +11,12 @@ import java.util.*;
|
||||
* <p>
|
||||
* See http://www.cs.colostate.edu/~cs553/ClassNotes/lecture09-control-dominators.ppt.pdf
|
||||
*/
|
||||
public class PassNLoopAnalysis extends Pass2SsaOptimization {
|
||||
public class PassNCalcLoopSet extends PassNCalcBase<NaturalLoopSet> {
|
||||
|
||||
public PassNLoopAnalysis(Program program) {
|
||||
public PassNCalcLoopSet(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds loops and nested loops in the control flow graph.
|
||||
* Uses the dominators of the graph to find loops.
|
||||
@ -25,7 +24,7 @@ public class PassNLoopAnalysis extends Pass2SsaOptimization {
|
||||
* See http://www.cs.colostate.edu/~cs553/ClassNotes/lecture09-control-dominators.ppt.pdf
|
||||
*/
|
||||
@Override
|
||||
public boolean step() {
|
||||
public NaturalLoopSet calculate() {
|
||||
DominatorsGraph dominators = getProgram().getDominators();
|
||||
Collection<ControlFlowBlock> blocks = getGraph().getAllBlocks();
|
||||
|
||||
@ -74,8 +73,7 @@ public class PassNLoopAnalysis extends Pass2SsaOptimization {
|
||||
while(coalesceMore) {
|
||||
coalesceMore = coalesceLoops(loopSet);
|
||||
}
|
||||
getProgram().setLoopSet(loopSet);
|
||||
return false;
|
||||
return loopSet;
|
||||
}
|
||||
|
||||
/**
|
@ -1,9 +1,9 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -11,26 +11,25 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/*** Find the variable equivalence classes to attempt to uplift in each scope */
|
||||
public class Pass4RegisterUpliftScopeAnalysis extends Pass2Base {
|
||||
public class PassNCalcRegisterUpliftProgram extends PassNCalcBase<RegisterUpliftProgram> {
|
||||
|
||||
public Pass4RegisterUpliftScopeAnalysis(Program program) {
|
||||
public PassNCalcRegisterUpliftProgram(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
/*** Find the variable equivalence classes to attempt to uplift in each scope */
|
||||
public void findScopes() {
|
||||
|
||||
/*** Find the variable equivalence classes to attempt to uplift in each scope */
|
||||
@Override
|
||||
public RegisterUpliftProgram calculate() {
|
||||
LiveRangeEquivalenceClassSet equivalenceClassSet = getProgram().getLiveRangeEquivalenceClassSet();
|
||||
final VariableRegisterWeights registerWeights = getProgram().getVariableRegisterWeights();
|
||||
|
||||
RegisterUpliftProgram registerUpliftProgram = new RegisterUpliftProgram();
|
||||
|
||||
Collection<Scope> allScopes = getProgram().getScope().getAllScopes(true);
|
||||
allScopes.add(getSymbols());
|
||||
allScopes.add(getScope());
|
||||
for(Scope scope : allScopes) {
|
||||
ScopeRef scopeRef = scope.getRef();
|
||||
RegisterUpliftScope registerUpliftScope = registerUpliftProgram.addRegisterUpliftScope(scopeRef);
|
||||
|
||||
// Find live range equivalence classes for the scope
|
||||
List<LiveRangeEquivalenceClass> equivalenceClasses = new ArrayList<>();
|
||||
for(LiveRangeEquivalenceClass equivalenceClass : equivalenceClassSet.getEquivalenceClasses()) {
|
||||
@ -43,12 +42,11 @@ public class Pass4RegisterUpliftScopeAnalysis extends Pass2Base {
|
||||
registerUpliftScope.setEquivalenceClasses(equivalenceClasses);
|
||||
}
|
||||
|
||||
|
||||
List<RegisterUpliftScope> upliftScopes = registerUpliftProgram.getRegisterUpliftScopes();
|
||||
Collections.sort(upliftScopes, (o1, o2) -> Double.compare(registerWeights.getTotalWeights(o2), registerWeights.getTotalWeights(o1)));
|
||||
registerUpliftProgram.setRegisterUpliftScopes(upliftScopes);
|
||||
|
||||
getProgram().setRegisterUpliftProgram(registerUpliftProgram);
|
||||
return registerUpliftProgram;
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,9 @@ import java.util.LinkedHashMap;
|
||||
/**
|
||||
* Identify the block for each statement.
|
||||
*/
|
||||
public class PassNStatementInfos extends Pass2SsaOptimization {
|
||||
public class PassNCalcStatementInfos extends PassNCalcBase<StatementInfos> {
|
||||
|
||||
public PassNStatementInfos(Program program) {
|
||||
public PassNCalcStatementInfos(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ public class PassNStatementInfos extends Pass2SsaOptimization {
|
||||
* Create map from statement index to block
|
||||
*/
|
||||
@Override
|
||||
public boolean step() {
|
||||
public StatementInfos calculate() {
|
||||
LinkedHashMap<Integer, ControlFlowBlock> stmtBlocks = new LinkedHashMap<>();
|
||||
LinkedHashMap<Integer, Statement> stmtIdx = new LinkedHashMap<>();
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
@ -31,8 +31,7 @@ public class PassNStatementInfos extends Pass2SsaOptimization {
|
||||
stmtIdx.put(statement.getIndex(), statement);
|
||||
}
|
||||
}
|
||||
getProgram().setStatementInfos(new StatementInfos(getProgram(), stmtBlocks, stmtIdx));
|
||||
return false;
|
||||
return new StatementInfos(getProgram(), stmtBlocks, stmtIdx);
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,11 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
/**
|
||||
* Finds register weights for all variables.
|
||||
@ -17,24 +16,20 @@ import dk.camelot64.kickc.model.symbols.Variable;
|
||||
* <p>
|
||||
* Based on ComputeWeight from http://compilers.cs.ucla.edu/fernando/projects/soc/reports/short_tech.pdf
|
||||
*/
|
||||
public class Pass3VariableRegisterWeightAnalysis extends Pass2Base {
|
||||
public class PassNCalcVariableRegisterWeight extends PassNCalcBase<VariableRegisterWeights> {
|
||||
|
||||
private NaturalLoopSet loopSet;
|
||||
private VariableRegisterWeights variableRegisterWeights;
|
||||
private LiveRangeVariables liveRangeVariables;
|
||||
|
||||
public Pass3VariableRegisterWeightAnalysis(Program program) {
|
||||
public PassNCalcVariableRegisterWeight(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find register weights for all variables
|
||||
*/
|
||||
public void findWeights() {
|
||||
|
||||
variableRegisterWeights = new VariableRegisterWeights();
|
||||
loopSet = getProgram().getLoopSet();
|
||||
liveRangeVariables = getProgram().getLiveRangeVariables();
|
||||
@Override
|
||||
public VariableRegisterWeights calculate() {
|
||||
NaturalLoopSet loopSet = getProgram().getLoopSet();
|
||||
LiveRangeVariables liveRangeVariables = getProgram().getLiveRangeVariables();
|
||||
VariableRegisterWeights variableRegisterWeights = new VariableRegisterWeights();
|
||||
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
@ -44,47 +39,44 @@ public class Pass3VariableRegisterWeightAnalysis extends Pass2Base {
|
||||
VariableRef philVariable = phiVariable.getVariable();
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
if(phiRValue.getrValue() instanceof VariableRef) {
|
||||
double w = addWeight(philVariable, phiRValue.getPredecessor());
|
||||
double w = addWeight(philVariable, phiRValue.getPredecessor(), variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
//log.append("Definition of " + philVariable + " w+:" + w + " - [" + statement.getIndex()+"]");
|
||||
}
|
||||
}
|
||||
// Add weights for each usage of a variable
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
addUsageWeightRValue(phiRValue.getrValue(), statement, phiRValue.getPredecessor());
|
||||
addUsageWeightRValue(phiRValue.getrValue(), statement, phiRValue.getPredecessor(), variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
}
|
||||
}
|
||||
} else if(statement instanceof StatementAssignment) {
|
||||
// Add weights for the definition of the variable
|
||||
addUsageWeightRValue(((StatementAssignment) statement).getlValue(), statement, block.getLabel());
|
||||
addUsageWeightRValue(((StatementAssignment) statement).getlValue(), statement, block.getLabel(), variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
// Add weights for each usage of variables
|
||||
addUsageWeightRValue(((StatementAssignment) statement).getrValue1(), statement, block.getLabel());
|
||||
addUsageWeightRValue(((StatementAssignment) statement).getrValue2(), statement, block.getLabel());
|
||||
addUsageWeightRValue(((StatementAssignment) statement).getrValue1(), statement, block.getLabel(), variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
addUsageWeightRValue(((StatementAssignment) statement).getrValue2(), statement, block.getLabel(), variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
} else if(statement instanceof StatementConditionalJump) {
|
||||
// Add weights for each usage of variables
|
||||
addUsageWeightRValue(((StatementConditionalJump) statement).getrValue1(), statement, block.getLabel());
|
||||
addUsageWeightRValue(((StatementConditionalJump) statement).getrValue2(), statement, block.getLabel());
|
||||
addUsageWeightRValue(((StatementConditionalJump) statement).getrValue1(), statement, block.getLabel(), variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
addUsageWeightRValue(((StatementConditionalJump) statement).getrValue2(), statement, block.getLabel(), variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getProgram().setVariableRegisterWeights(variableRegisterWeights);
|
||||
|
||||
return variableRegisterWeights;
|
||||
}
|
||||
|
||||
private void addUsageWeightRValue(Value rValue, Statement statement, LabelRef block) {
|
||||
private static void addUsageWeightRValue(Value rValue, Statement statement, LabelRef block, VariableRegisterWeights variableRegisterWeights, NaturalLoopSet loopSet, LiveRangeVariables liveRangeVariables) {
|
||||
if(rValue instanceof VariableRef) {
|
||||
double w = addWeight((VariableRef) rValue, block);
|
||||
double w = addWeight((VariableRef) rValue, block, variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
//log.append("Usage of " + rValue + " w+:" + w + " - [" + statement.getIndex()+"]");
|
||||
} else if(rValue instanceof PointerDereferenceSimple) {
|
||||
addUsageWeightRValue(((PointerDereferenceSimple) rValue).getPointer(), statement, block);
|
||||
addUsageWeightRValue(((PointerDereferenceSimple) rValue).getPointer(), statement, block, variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
} else if(rValue instanceof PointerDereferenceIndexed) {
|
||||
addUsageWeightRValue(((PointerDereferenceIndexed) rValue).getPointer(), statement, block);
|
||||
addUsageWeightRValue(((PointerDereferenceIndexed) rValue).getIndex(), statement, block);
|
||||
addUsageWeightRValue(((PointerDereferenceIndexed) rValue).getPointer(), statement, block, variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
addUsageWeightRValue(((PointerDereferenceIndexed) rValue).getIndex(), statement, block, variableRegisterWeights, loopSet, liveRangeVariables);
|
||||
}
|
||||
}
|
||||
|
||||
private double addWeight(VariableRef variable, LabelRef block) {
|
||||
Variable var = getProgram().getScope().getVariable(variable);
|
||||
private static double addWeight(VariableRef variable, LabelRef block, VariableRegisterWeights variableRegisterWeights, NaturalLoopSet loopSet, LiveRangeVariables liveRangeVariables) {
|
||||
int depth = loopSet.getMaxLoopDepth(block);
|
||||
double w = 1.0 + Math.pow(10.0, depth);
|
||||
LiveRange liveRange = liveRangeVariables.getLiveRange(variable);
|
Loading…
Reference in New Issue
Block a user