1
0
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:
jespergravgaard 2019-08-02 01:25:32 +02:00
parent 0a39633ed8
commit aceea6d8ec
13 changed files with 120 additions and 124 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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;
} }

View File

@ -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");
} }
} }

View File

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

View File

@ -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;
} }
/** /**

View File

@ -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");
} }

View File

@ -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;
} }
/** /**

View File

@ -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;
} }

View File

@ -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;
} }

View File

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