1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-10-11 12:23:45 +00:00

Caching Variable Reference Infos to improve uplift performance.

This commit is contained in:
jespergravgaard 2017-11-09 22:34:46 +01:00
parent baa84880ea
commit fdf4e7ac3a
9 changed files with 143 additions and 37 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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