mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-20 02:32:36 +00:00
Caching Variable Reference Infos to improve uplift performance.
This commit is contained in:
parent
baa84880ea
commit
fdf4e7ac3a
@ -194,6 +194,7 @@ public class Compiler {
|
||||
|
||||
//program.getLog().setVerboseLiveRanges(true);
|
||||
|
||||
new Pass3VariableReferenceInfos(program).generateVariableReferenceInfos();
|
||||
new Pass3LiveRangesAnalysis(program).findLiveRanges();
|
||||
program.getLog().append("CONTROL FLOW GRAPH - LIVE RANGES FOUND");
|
||||
program.getLog().append(program.getGraph().toString(program));
|
||||
@ -208,6 +209,7 @@ public class Compiler {
|
||||
new Pass3AddNopBeforeCallOns(program).generate();
|
||||
new Pass3StatementIndices(program).generateStatementIndices();
|
||||
new Pass3CallGraphAnalysis(program).findCallGraph();
|
||||
new Pass3VariableReferenceInfos(program).generateVariableReferenceInfos();
|
||||
new Pass3LiveRangesAnalysis(program).findLiveRanges();
|
||||
program.getLog().append("CONTROL FLOW GRAPH - BEFORE EFFECTIVE LIVE RANGES");
|
||||
program.getLog().append(program.getGraph().toString(program));
|
||||
|
@ -29,9 +29,9 @@ public class LiveRangeVariablesEffective {
|
||||
/**
|
||||
* Information about which procedures reference which variables.
|
||||
*/
|
||||
private VariableReferenceInfo referenceInfo;
|
||||
private VariableReferenceInfos referenceInfo;
|
||||
|
||||
public LiveRangeVariablesEffective(Program program, Map<ProcedureRef, CallPaths> procedureCallPaths, LiveRangeVariables liveRangeVariables, VariableReferenceInfo referenceInfo) {
|
||||
public LiveRangeVariablesEffective(Program program, Map<ProcedureRef, CallPaths> procedureCallPaths, LiveRangeVariables liveRangeVariables, VariableReferenceInfos referenceInfo) {
|
||||
this.program = program;
|
||||
this.procedureCallPaths = procedureCallPaths;
|
||||
this.liveRangeVariables = liveRangeVariables;
|
||||
|
@ -27,6 +27,8 @@ public class Program {
|
||||
/** Information about loops. */
|
||||
private NaturalLoopSet loopSet;
|
||||
|
||||
/** The variables freferenced by blocks/statements. */
|
||||
private VariableReferenceInfos variableReferenceInfos;
|
||||
/** The live ranges of all variables. */
|
||||
private LiveRangeVariables liveRangeVariables;
|
||||
/** Live range equivalence classes containing variables that do not have overlapping live ranges. */
|
||||
@ -111,6 +113,14 @@ public class Program {
|
||||
return loopSet;
|
||||
}
|
||||
|
||||
public VariableReferenceInfos getVariableReferenceInfos() {
|
||||
return variableReferenceInfos;
|
||||
}
|
||||
|
||||
public void setVariableReferenceInfos(VariableReferenceInfos variableReferenceInfos) {
|
||||
this.variableReferenceInfos = variableReferenceInfos;
|
||||
}
|
||||
|
||||
public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) {
|
||||
this.liveRangeVariables = liveRangeVariables;
|
||||
}
|
||||
|
@ -0,0 +1,94 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.passes.Pass3VariableReferenceInfos;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
|
||||
/** */
|
||||
public class VariableReferenceInfos {
|
||||
|
||||
/** Variables referenced in each block. */
|
||||
private Map<LabelRef, Collection<VariableRef>> blockReferenced;
|
||||
|
||||
/** Variables used in each block. */
|
||||
private Map<LabelRef, Collection<VariableRef>> blockUsed;
|
||||
|
||||
/** Variables referenced in each statement. */
|
||||
private Map<Integer, Collection<VariableRef>> stmtReferenced;
|
||||
|
||||
/** Variables defined in each statement. */
|
||||
private Map<Integer, Collection<VariableRef>> stmtDefined;
|
||||
|
||||
|
||||
public VariableReferenceInfos(
|
||||
Map<LabelRef, Collection<VariableRef>> blockReferenced,
|
||||
Map<LabelRef, Collection<VariableRef>> blockUsed,
|
||||
Map<Integer, Collection<VariableRef>> stmtReferenced, Map<Integer, Collection<VariableRef>> stmtDefined) {
|
||||
this.blockReferenced = blockReferenced;
|
||||
this.blockUsed = blockUsed;
|
||||
this.stmtDefined = stmtDefined;
|
||||
this.stmtReferenced = stmtReferenced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all variables used or defined inside a block and its successors (including any called method)
|
||||
* @param labelRef The block to examine
|
||||
* @return All used variables
|
||||
*/
|
||||
public Collection<VariableRef> getReferenced(LabelRef labelRef) {
|
||||
return blockReferenced.get(labelRef);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all variables used inside a block and its successors (including any called method)
|
||||
* @param labelRef The block to examine
|
||||
* @return All used variables
|
||||
*/
|
||||
public Collection<VariableRef> getUsed(LabelRef labelRef) {
|
||||
return blockUsed.get(labelRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the variables defined by a statement
|
||||
* @param stmt The statement
|
||||
* @return Variables defined by the statement
|
||||
*/
|
||||
public Collection<VariableRef> getDefined(Statement stmt) {
|
||||
return stmtDefined.get(stmt.getIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the variables referenced (used or defined) in a statement
|
||||
* @param statement The statement to examine
|
||||
* @return The referenced variables
|
||||
*/
|
||||
public Collection<VariableRef> getReferenced(Statement statement) {
|
||||
return stmtReferenced.get(statement.getIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the variables used, but not defined, in a statement
|
||||
* @param statement The statement to examine
|
||||
* @return The used variables (not including defined variables)
|
||||
*/
|
||||
public Collection<VariableRef> getUsed(Statement statement) {
|
||||
LinkedHashSet<VariableRef> used = new LinkedHashSet<>();
|
||||
used.addAll(getReferenced(statement));
|
||||
used.removeAll(getDefined(statement));
|
||||
return used;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all variables referenced in an rValue
|
||||
* @param rValue The rValue
|
||||
* @return All referenced variables
|
||||
*/
|
||||
public static Collection<VariableRef> getReferenced(RValue rValue) {
|
||||
return Pass3VariableReferenceInfos.getReferenced(rValue);
|
||||
}
|
||||
|
||||
}
|
@ -51,7 +51,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
* @return true if any live ranges was modified. false if no modification was performed (and the propagation is complete)
|
||||
*/
|
||||
private boolean calculateLiveRanges(LiveRangeVariables liveRanges) {
|
||||
VariableReferenceInfo referenceInfo = new VariableReferenceInfo(getProgram());
|
||||
VariableReferenceInfos referenceInfo = getProgram().getVariableReferenceInfos();
|
||||
boolean modified = false;
|
||||
for (ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
for (Statement stmt : block.getStatements()) {
|
||||
@ -147,7 +147,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
|
||||
Statement stmt,
|
||||
PreviousStatement previousStmt) {
|
||||
boolean modified = false;
|
||||
VariableReferenceInfo referenceInfo = new VariableReferenceInfo(getProgram());
|
||||
VariableReferenceInfos referenceInfo = getProgram().getVariableReferenceInfos();
|
||||
Collection<VariableRef> usedNextStmt = referenceInfo.getUsed(stmt);
|
||||
if (stmt instanceof StatementPhiBlock) {
|
||||
// If current statement is a phi add the used variables to previous based on the phi entries
|
||||
|
@ -22,7 +22,7 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||
/**
|
||||
* Information about which procedures reference which variables.
|
||||
*/
|
||||
private VariableReferenceInfo referenceInfo;
|
||||
private VariableReferenceInfos referenceInfo;
|
||||
|
||||
|
||||
public Pass3LiveRangesEffectiveAnalysis(Program program) {
|
||||
@ -31,7 +31,7 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||
|
||||
public void findLiveRangesEffective() {
|
||||
this.liveRangeVariables = getProgram().getLiveRangeVariables();
|
||||
this.referenceInfo = new VariableReferenceInfo(getProgram());
|
||||
this.referenceInfo = getProgram().getVariableReferenceInfos();
|
||||
this.procedureCallPaths = new LinkedHashMap<>();
|
||||
populateProcedureCallPaths();
|
||||
LiveRangeVariablesEffective aliveEffective = new LiveRangeVariablesEffective(getProgram(), procedureCallPaths, liveRangeVariables, referenceInfo);
|
||||
|
@ -1,37 +1,36 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/** Information about variable referenced/used/defined in statements/blocks */
|
||||
public class VariableReferenceInfo {
|
||||
/**
|
||||
* Identify variables defined/referenced for each block & statement.
|
||||
*/
|
||||
public class Pass3VariableReferenceInfos extends Pass2Base {
|
||||
|
||||
private Program program;
|
||||
|
||||
public VariableReferenceInfo(Program program) {
|
||||
this.program = program;
|
||||
public Pass3VariableReferenceInfos(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
public Program getProgram() {
|
||||
return program;
|
||||
/** Create defined/referenced maps */
|
||||
public void generateVariableReferenceInfos() {
|
||||
LinkedHashMap<LabelRef, Collection<VariableRef>> blockReferenced = new LinkedHashMap<>();
|
||||
LinkedHashMap<LabelRef, Collection<VariableRef>> blockUsed = new LinkedHashMap<>();
|
||||
LinkedHashMap<Integer, Collection<VariableRef>> stmtReferenced = new LinkedHashMap<>();
|
||||
LinkedHashMap<Integer, Collection<VariableRef>> stmtDefined = new LinkedHashMap<>();
|
||||
for (ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
LabelRef blockLabel = block.getLabel();
|
||||
blockReferenced.put(blockLabel, getReferenced(blockLabel, new ArrayList<LabelRef>()));
|
||||
blockUsed.put(blockLabel, getUsed(blockLabel, new ArrayList<LabelRef>()));
|
||||
for (Statement statement : block.getStatements()) {
|
||||
stmtDefined.put(statement.getIndex(), getDefined(statement));
|
||||
stmtReferenced.put(statement.getIndex(), getReferenced(statement));
|
||||
}
|
||||
}
|
||||
getProgram().setVariableReferenceInfos(new VariableReferenceInfos(blockReferenced, blockUsed, stmtReferenced, stmtDefined));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all variables used or defined inside a block and its successors (including any called method)
|
||||
* @param labelRef The block to examine
|
||||
* @return All used variables
|
||||
*/
|
||||
public Collection<VariableRef> getReferenced(LabelRef labelRef) {
|
||||
return getReferenced(labelRef, new ArrayList<LabelRef>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all variables used inside a block and its successors (including any called method)
|
||||
* @param labelRef The block to examine
|
||||
* @return All used variables
|
||||
*/
|
||||
public Collection<VariableRef> getUsed(LabelRef labelRef) {
|
||||
return getUsed(labelRef, new ArrayList<LabelRef>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all variables used inside a block and its successors (including any called method)
|
||||
@ -100,7 +99,7 @@ public class VariableReferenceInfo {
|
||||
* @param stmt The statement
|
||||
* @return Variables defined by the statement
|
||||
*/
|
||||
public Collection<VariableRef> getDefined(Statement stmt) {
|
||||
private Collection<VariableRef> getDefined(Statement stmt) {
|
||||
if (stmt instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) stmt;
|
||||
LValue lValue = assignment.getlValue();
|
||||
@ -123,7 +122,7 @@ public class VariableReferenceInfo {
|
||||
* @param statement The statement to examine
|
||||
* @return The used variables (not including defined variables)
|
||||
*/
|
||||
public Collection<VariableRef> getUsed(Statement statement) {
|
||||
private Collection<VariableRef> getUsed(Statement statement) {
|
||||
LinkedHashSet<VariableRef> used = new LinkedHashSet<>();
|
||||
used.addAll(getReferenced(statement));
|
||||
used.removeAll(getDefined(statement));
|
||||
@ -135,7 +134,7 @@ public class VariableReferenceInfo {
|
||||
* @param statement The statement to examine
|
||||
* @return The referenced variables
|
||||
*/
|
||||
public Collection<VariableRef> getReferenced(Statement statement) {
|
||||
private Collection<VariableRef> getReferenced(Statement statement) {
|
||||
LinkedHashSet<VariableRef> referenced = new LinkedHashSet<>();
|
||||
if (statement instanceof StatementPhiBlock) {
|
||||
StatementPhiBlock phiBlock = (StatementPhiBlock) statement;
|
||||
@ -198,4 +197,5 @@ public class VariableReferenceInfo {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -56,7 +56,7 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
||||
// IF the assignment is later than the current one
|
||||
if(phiAssignment.getAssignmentIdx()>transitionAssignmentIdx) {
|
||||
RValue rValue = phiAssignment.getrValue();
|
||||
Collection<VariableRef> alive = VariableReferenceInfo.getReferenced(rValue);
|
||||
Collection<VariableRef> alive = VariableReferenceInfos.getReferenced(rValue);
|
||||
aliveVars.addAll(alive);
|
||||
VariableRef assignedVar = phiAssignment.getVariable();
|
||||
assignedVars.remove(assignedVar);
|
||||
|
@ -32,7 +32,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
|
||||
RegisterPotentials registerPotentials = getProgram().getRegisterPotentials();
|
||||
|
||||
VariableReferenceInfo referenceInfo = new VariableReferenceInfo(getProgram());
|
||||
VariableReferenceInfos referenceInfo = getProgram().getVariableReferenceInfos();
|
||||
for (ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
for (Statement statement : block.getStatements()) {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user