diff --git a/src/main/java/dk/camelot64/kickc/model/LiveRange.java b/src/main/java/dk/camelot64/kickc/model/LiveRange.java index f124b12e9..288cdbf51 100644 --- a/src/main/java/dk/camelot64/kickc/model/LiveRange.java +++ b/src/main/java/dk/camelot64/kickc/model/LiveRange.java @@ -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) { diff --git a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java index 689f1ff16..ded3dee6b 100644 --- a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java +++ b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java @@ -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 getAlive(Statement statement) { + public List getAlive(int statementIdx) { ArrayList aliveVars = new ArrayList<>(); - for(VariableRef variable : liveRanges.keySet()) { - LiveRange liveRange = liveRanges.get(variable); - if(liveRange.contains(statement)) { - aliveVars.add(variable); + for(Map.Entry entry : liveRanges.entrySet()) { + if(entry.getValue().contains(statementIdx)) { + aliveVars.add(entry.getKey()); } } return aliveVars; diff --git a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java index 70566cf77..02b0f347a 100644 --- a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java +++ b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java @@ -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())); } } } diff --git a/src/main/java/dk/camelot64/kickc/model/statements/StatementBase.java b/src/main/java/dk/camelot64/kickc/model/statements/StatementBase.java index efcab4a06..34ef15104 100644 --- a/src/main/java/dk/camelot64/kickc/model/statements/StatementBase.java +++ b/src/main/java/dk/camelot64/kickc/model/statements/StatementBase.java @@ -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); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesAnalysis.java index 5b0c0a47a..9d2234f0b 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesAnalysis.java @@ -65,7 +65,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base { boolean modified = false; for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) { for(Statement stmt : block.getStatements()) { - List aliveNextStmt = liveRanges.getAlive(stmt); + List aliveNextStmt = liveRanges.getAlive(stmt.getIndex()); Collection definedNextStmt = referenceInfo.getDefinedVars(stmt); initLiveRange(liveRanges, definedNextStmt); Collection 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; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java index d6b91e25c..04d82407a 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java @@ -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 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());