1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-01-02 20:29:38 +00:00

make live range analysis use statement index instead of statement where it helps with speed

This commit is contained in:
Travis Fisher 2019-04-11 00:14:31 -04:00
parent b81349b3de
commit c9cce92509
6 changed files with 27 additions and 52 deletions

View File

@ -22,24 +22,6 @@ public class LiveRange {
this.intervals = new ArrayList<>();
}
/**
* Add a statement to the live range
*
* @param statement The statement to add
* @return true if the live range was modified by the addition. false otherwise
*/
public boolean add(Statement statement) {
return add(getIndex(statement));
}
private Integer getIndex(Statement statement) {
Integer index = statement.getIndex();
if(index == null) {
throw new RuntimeException("Statement index not defined! Live Ranges only work after defining statement indexes (Pass3LiveRangesAnalysis.generateStatementIndices).");
}
return index;
}
/**
* Get the number of statements in the live range.
*
@ -125,23 +107,13 @@ public class LiveRange {
}
}
/**
* Determines if the live range contains a statement
*
* @param statement The statement to examine
* @return true if the live range contains the statement
*/
public boolean contains(Statement statement) {
return contains(getIndex(statement));
}
/**
* Determines if the live range contains an index
*
* @param index
* @return true if the live range contains the index
*/
private boolean contains(int index) {
public boolean contains(int index) {
for(LiveInterval interval : intervals) {
if(interval.lastStatementIdx >= index) {
if(interval.firstStatementIdx <= index) {

View File

@ -8,6 +8,7 @@ import dk.camelot64.kickc.passes.PassNCallGraphAnalysis;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Live ranges for all variables.
@ -28,16 +29,16 @@ public class LiveRangeVariables {
* Add a single statement to the live range of a variable.
*
* @param variable The variable
* @param statement The statement to add
* @param statementIdx Index of the statement to add
* @return true if a live range was modified by the addition
*/
public boolean addAlive(VariableRef variable, Statement statement) {
public boolean addAlive(VariableRef variable, int statementIdx) {
LiveRange liveRange = liveRanges.get(variable);
if(liveRange == null) {
liveRange = new LiveRange();
liveRanges.put(variable, liveRange);
}
return liveRange.add(statement);
return liveRange.add(statementIdx);
}
/**
@ -56,15 +57,14 @@ public class LiveRangeVariables {
/**
* Get all variables alive at a specific statement
*
* @param statement The statement
* @param statementIdx Index of the statement
* @return List of all live variables.
*/
public List<VariableRef> getAlive(Statement statement) {
public List<VariableRef> getAlive(int statementIdx) {
ArrayList<VariableRef> aliveVars = new ArrayList<>();
for(VariableRef variable : liveRanges.keySet()) {
LiveRange liveRange = liveRanges.get(variable);
if(liveRange.contains(statement)) {
aliveVars.add(variable);
for(Map.Entry<VariableRef,LiveRange> entry : liveRanges.entrySet()) {
if(entry.getValue().contains(statementIdx)) {
aliveVars.add(entry.getKey());
}
}
return aliveVars;

View File

@ -43,7 +43,7 @@ public class LiveRangeVariablesEffective {
this.statementLiveVariables = new LinkedHashMap<>();
for(ControlFlowBlock block : program.getGraph().getAllBlocks()) {
for(Statement statement : block.getStatements()) {
statementLiveVariables.put(statement.getIndex(), liveRangeVariables.getAlive(statement));
statementLiveVariables.put(statement.getIndex(), liveRangeVariables.getAlive(statement.getIndex()));
}
}
}

View File

@ -80,7 +80,7 @@ public abstract class StatementBase implements Statement {
}
LiveRangeVariables liveRanges = program.getLiveRangeVariables();
StringBuilder alive = new StringBuilder();
alive.append(getAliveString(liveRanges.getAlive(this)));
alive.append(getAliveString(liveRanges.getAlive(index)));
LiveRangeVariablesEffective liveRangeVariablesEffective = program.getLiveRangeVariablesEffective();
if(liveRangeVariablesEffective != null) {
LiveRangeVariablesEffective.AliveCombinations aliveCombinations = liveRangeVariablesEffective.getAliveCombinations(this);

View File

@ -65,7 +65,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
boolean modified = false;
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
for(Statement stmt : block.getStatements()) {
List<VariableRef> aliveNextStmt = liveRanges.getAlive(stmt);
List<VariableRef> aliveNextStmt = liveRanges.getAlive(stmt.getIndex());
Collection<VariableRef> definedNextStmt = referenceInfo.getDefinedVars(stmt);
initLiveRange(liveRanges, definedNextStmt);
Collection<PreviousStatement> previousStmts = getPreviousStatements(stmt);
@ -76,7 +76,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
// Add all vars alive in the next statement
for(VariableRef aliveVar : aliveNextStmt) {
if(!definedNextStmt.contains(aliveVar)) {
boolean addAlive = liveRanges.addAlive(aliveVar, previousStmt.getStatement());
boolean addAlive = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
modified |= addAlive;
if(addAlive && getLog().isVerboseLiveRanges()) {
getLog().append("Propagated alive var " + aliveVar + " to " + previousStmt.getStatement());
@ -92,7 +92,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
for(VariableRef aliveVar : aliveNextStmt) {
// Add all variables to previous that are not used inside the method
if(procUsed.contains(aliveVar)) {
boolean addUsedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatement());
boolean addUsedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
modified |= addUsedVar;
if(addUsedVar && getLog().isVerboseLiveRanges()) {
getLog().append("Propagated alive var used in method into method " + aliveVar + " to " + previousStmt.getStatement());
@ -108,7 +108,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
for(VariableRef aliveVar : aliveNextStmt) {
// Add all variables to previous that are not used inside the method
if(!procUsed.contains(aliveVar)) {
boolean addSkipVar = liveRanges.addAlive(aliveVar, previousStmt.getStatement());
boolean addSkipVar = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
modified |= addSkipVar;
if(addSkipVar && getLog().isVerboseLiveRanges()) {
getLog().append("Propagated alive var unused in method by skipping call " + aliveVar + " to " + previousStmt.getStatement());
@ -127,7 +127,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
// Add all variables to previous that are used inside the method
if(procUsed.contains(aliveVar)) {
if(!definedNextStmt.contains(aliveVar)) {
boolean usedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatement());
boolean usedVar = liveRanges.addAlive(aliveVar, previousStmt.getStatementIdx());
modified |= usedVar;
if(usedVar && getLog().isVerboseLiveRanges()) {
getLog().append("Propagated alive used in method out of method " + aliveVar + " to " + previousStmt.getStatement());
@ -164,13 +164,13 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
// If current statement is a phi add the used variables to previous based on the phi entries
StatementPhiBlock phi = (StatementPhiBlock) stmt;
ControlFlowBlock previousBlock =
getProgram().getStatementInfos().getBlock(previousStmt.getStatement());
getProgram().getStatementInfos().getBlock(previousStmt.getStatementIdx());
for(StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
if(phiRValue.getPredecessor().equals(previousBlock.getLabel())) {
if(phiRValue.getrValue() instanceof VariableRef) {
VariableRef usedVar = (VariableRef) phiRValue.getrValue();
boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatement());
boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatementIdx());
modified |= addUsed;
if(addUsed && getLog().isVerboseLiveRanges()) {
getLog().append("Adding used phi var " + usedVar + " to " + previousStmt.getStatement());
@ -182,7 +182,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
} else {
// Not a phi block - add used vars to all previous blocks
for(VariableRef usedVar : usedNextStmt) {
boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatement());
boolean addUsed = liveRanges.addAlive(usedVar, previousStmt.getStatementIdx());
modified |= addUsed;
if(addUsed && getLog().isVerboseLiveRanges()) {
getLog().append("Adding used var " + usedVar + " to " + previousStmt.getStatement());
@ -346,6 +346,10 @@ public class Pass3LiveRangesAnalysis extends Pass2Base {
return statement;
}
public int getStatementIdx() {
return statement.getIndex();
}
public Type getType() {
return type;
}

View File

@ -75,9 +75,8 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
getProgram().getCallGraph().getCallers(procedure.getRef());
for(CallGraph.CallBlock.Call caller : callers) {
// Each caller creates its own call-paths
StatementCall callStatement =
(StatementCall) getProgram().getStatementInfos().getStatement(caller.getCallStatementIdx());
ControlFlowBlock callBlock = getProgram().getStatementInfos().getBlock(callStatement);
int callStatementIdx = caller.getCallStatementIdx();
ControlFlowBlock callBlock = getProgram().getStatementInfos().getBlock(callStatementIdx);
ScopeRef callScopeRef = callBlock.getScope();
Scope callScope = getProgram().getScope().getScope(callScopeRef);
if(callScope instanceof Procedure) {
@ -95,7 +94,7 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
Collection<VariableRef> alive = new LinkedHashSet<>();
alive.addAll(callerPath.getAlive());
alive.removeAll(referencedInCaller);
alive.addAll(liveRangeVariables.getAlive(callStatement));
alive.addAll(liveRangeVariables.getAlive(callStatementIdx));
Pass2AliasElimination.Aliases innerAliases = getCallAliases(procedure, callBlock);
Pass2AliasElimination.Aliases pathAliases = new Pass2AliasElimination.Aliases();
pathAliases.addAll(callerPath.getPathAliases());