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:
parent
b81349b3de
commit
c9cce92509
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user