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