mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-27 19:50:10 +00:00
Optimized Pass2AssertSymbols and PassNCalcLiveRangeVariables.
This commit is contained in:
parent
daa963dbbb
commit
01008ccb26
@ -19,12 +19,15 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
|
|||||||
@Override
|
@Override
|
||||||
public void check() throws AssertionFailed {
|
public void check() throws AssertionFailed {
|
||||||
|
|
||||||
|
HashSet<String> codeSymbolFullNames = new HashSet<>();
|
||||||
HashSet<Symbol> codeSymbols = new HashSet<>();
|
HashSet<Symbol> codeSymbols = new HashSet<>();
|
||||||
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||||
if(programValue.get() instanceof SymbolRef) {
|
if(programValue.get() instanceof SymbolRef) {
|
||||||
Symbol symbol = getScope().getSymbol((SymbolRef) programValue.get());
|
Symbol symbol = getScope().getSymbol((SymbolRef) programValue.get());
|
||||||
if(symbol != null)
|
if(symbol != null) {
|
||||||
codeSymbols.add(symbol);
|
codeSymbols.add(symbol);
|
||||||
|
codeSymbolFullNames.add(symbol.getFullName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -38,6 +41,7 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
|
|||||||
}
|
}
|
||||||
// Check that all symbols in the symbol table is also in the code
|
// Check that all symbols in the symbol table is also in the code
|
||||||
Collection<Symbol> tableSymbols = getScope().getAllSymbols(true);
|
Collection<Symbol> tableSymbols = getScope().getAllSymbols(true);
|
||||||
|
|
||||||
for(Symbol tableSymbol : tableSymbols) {
|
for(Symbol tableSymbol : tableSymbols) {
|
||||||
if(tableSymbol instanceof VariableUnversioned) continue;
|
if(tableSymbol instanceof VariableUnversioned) continue;
|
||||||
if(tableSymbol instanceof ConstantVar) continue;
|
if(tableSymbol instanceof ConstantVar) continue;
|
||||||
@ -45,20 +49,10 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
|
|||||||
if(tableSymbol instanceof EnumDefinition) continue;
|
if(tableSymbol instanceof EnumDefinition) continue;
|
||||||
if(tableSymbol instanceof TypeDefsScope) continue;
|
if(tableSymbol instanceof TypeDefsScope) continue;
|
||||||
if(tableSymbol.getType() instanceof SymbolTypeStruct) continue;
|
if(tableSymbol.getType() instanceof SymbolTypeStruct) continue;
|
||||||
Symbol codeSymbol = null;
|
|
||||||
String codeSymbolFullName = tableSymbol.getFullName();
|
String codeSymbolFullName = tableSymbol.getFullName();
|
||||||
for(Symbol symbol : codeSymbols) {
|
if(!codeSymbolFullNames.contains(codeSymbolFullName)) {
|
||||||
if(codeSymbolFullName.equals(symbol.getFullName())) {
|
throw new AssertionFailed("Compile process error. Symbol found in symbol table, but not in code. " + codeSymbolFullName);
|
||||||
codeSymbol = symbol;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(codeSymbol == null) {
|
|
||||||
if(tableSymbol.getType() instanceof SymbolTypeStruct) {
|
|
||||||
getLog().append("Struct no longer used in code "+codeSymbolFullName);
|
|
||||||
} else {
|
|
||||||
throw new AssertionFailed("Compile process error. Symbol found in symbol table, but not in code. " + codeSymbolFullName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
package dk.camelot64.kickc.passes.calcs;
|
package dk.camelot64.kickc.passes.calcs;
|
||||||
|
|
||||||
/**
|
|
||||||
* Identify the alive intervals for all variables. Add the intervals to the ProgramScope.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import dk.camelot64.kickc.model.*;
|
import dk.camelot64.kickc.model.*;
|
||||||
import dk.camelot64.kickc.model.statements.Statement;
|
import dk.camelot64.kickc.model.statements.Statement;
|
||||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
import dk.camelot64.kickc.model.statements.StatementCall;
|
||||||
@ -13,11 +9,11 @@ import dk.camelot64.kickc.model.values.LabelRef;
|
|||||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||||
import dk.camelot64.kickc.model.values.VariableRef;
|
import dk.camelot64.kickc.model.values.VariableRef;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identify the alive intervals for all variables. Add the intervals to the ProgramScope.
|
||||||
|
*/
|
||||||
public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariables> {
|
public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariables> {
|
||||||
|
|
||||||
public PassNCalcLiveRangeVariables(Program program) {
|
public PassNCalcLiveRangeVariables(Program program) {
|
||||||
@ -26,6 +22,7 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LiveRangeVariables calculate() {
|
public LiveRangeVariables calculate() {
|
||||||
|
calculateProcedureReferencedVars();
|
||||||
LiveRangeVariables liveRanges = new LiveRangeVariables(getProgram());
|
LiveRangeVariables liveRanges = new LiveRangeVariables(getProgram());
|
||||||
boolean propagating;
|
boolean propagating;
|
||||||
do {
|
do {
|
||||||
@ -40,6 +37,29 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
|
|||||||
return liveRanges;
|
return liveRanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Variables referenced inside each procedure and all it's sub-calls. */
|
||||||
|
private Map<ProcedureRef, Collection<VariableRef>> procedureReferencedVars;
|
||||||
|
|
||||||
|
static int callCount = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the variables referenced inside each procedure and all it's sub-calls.
|
||||||
|
*/
|
||||||
|
private void calculateProcedureReferencedVars() {
|
||||||
|
//getLog().append("calculateLiveRanges starting "+callCount);
|
||||||
|
VariableReferenceInfos referenceInfo = getProgram().getVariableReferenceInfos();
|
||||||
|
Collection<Procedure> allProcedures = getScope().getAllProcedures(true);
|
||||||
|
Map<ProcedureRef, Collection<VariableRef>> procReferencedVars = new LinkedHashMap<>();
|
||||||
|
for(Procedure procedure : allProcedures) {
|
||||||
|
Collection<VariableRef> referencedVars = referenceInfo.getReferencedVars(procedure.getRef().getLabelRef());
|
||||||
|
procReferencedVars.put(procedure.getRef(), referencedVars);
|
||||||
|
}
|
||||||
|
//getLog().append("calculateLiveRanges done "+callCount);
|
||||||
|
callCount++;
|
||||||
|
this.procedureReferencedVars = procReferencedVars;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs through all statements propagating variable live ranges.
|
* Runs through all statements propagating variable live ranges.
|
||||||
* Variable live ranges of a statement is defined as all variables that are defined before or in the statement and used after the statement.
|
* Variable live ranges of a statement is defined as all variables that are defined before or in the statement and used after the statement.
|
||||||
@ -63,7 +83,9 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
|
|||||||
* @return true if any live ranges was modified. false if no modification was performed (and the propagation is complete)
|
* @return true if any live ranges was modified. false if no modification was performed (and the propagation is complete)
|
||||||
*/
|
*/
|
||||||
private boolean calculateLiveRanges(LiveRangeVariables liveRanges) {
|
private boolean calculateLiveRanges(LiveRangeVariables liveRanges) {
|
||||||
|
|
||||||
VariableReferenceInfos referenceInfo = getProgram().getVariableReferenceInfos();
|
VariableReferenceInfos referenceInfo = getProgram().getVariableReferenceInfos();
|
||||||
|
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||||
for(Statement stmt : block.getStatements()) {
|
for(Statement stmt : block.getStatements()) {
|
||||||
@ -89,7 +111,7 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
|
|||||||
// Add all vars that are referenced in the method
|
// Add all vars that are referenced in the method
|
||||||
StatementCall call = (StatementCall) stmt;
|
StatementCall call = (StatementCall) stmt;
|
||||||
ProcedureRef procedure = call.getProcedure();
|
ProcedureRef procedure = call.getProcedure();
|
||||||
Collection<VariableRef> procUsed = referenceInfo.getReferencedVars(procedure.getLabelRef());
|
Collection<VariableRef> procUsed = procedureReferencedVars.get(procedure);
|
||||||
// The call statement has no used or defined by itself so only work with the alive vars
|
// The call statement has no used or defined by itself so only work with the alive vars
|
||||||
for(VariableRef aliveVar : aliveNextStmt) {
|
for(VariableRef aliveVar : aliveNextStmt) {
|
||||||
// Add all variables to previous that are not used inside the method
|
// Add all variables to previous that are not used inside the method
|
||||||
@ -105,7 +127,7 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
|
|||||||
// Add all vars that the method does not use
|
// Add all vars that the method does not use
|
||||||
StatementCall call = (StatementCall) stmt;
|
StatementCall call = (StatementCall) stmt;
|
||||||
ProcedureRef procedure = call.getProcedure();
|
ProcedureRef procedure = call.getProcedure();
|
||||||
Collection<VariableRef> procUsed = referenceInfo.getReferencedVars(procedure.getLabelRef());
|
Collection<VariableRef> procUsed = procedureReferencedVars.get(procedure);
|
||||||
// The call statement has no used or defined by itself so only work with the alive vars
|
// The call statement has no used or defined by itself so only work with the alive vars
|
||||||
for(VariableRef aliveVar : aliveNextStmt) {
|
for(VariableRef aliveVar : aliveNextStmt) {
|
||||||
// Add all variables to previous that are not used inside the method
|
// Add all variables to previous that are not used inside the method
|
||||||
@ -123,7 +145,7 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
|
|||||||
// Add all alive variables to previous that are used inside the method
|
// Add all alive variables to previous that are used inside the method
|
||||||
ControlFlowBlock procBlock = getProgram().getStatementInfos().getBlock(stmt);
|
ControlFlowBlock procBlock = getProgram().getStatementInfos().getBlock(stmt);
|
||||||
Procedure procedure = (Procedure) getProgram().getScope().getSymbol(procBlock.getLabel());
|
Procedure procedure = (Procedure) getProgram().getScope().getSymbol(procBlock.getLabel());
|
||||||
Collection<VariableRef> procUsed = referenceInfo.getReferencedVars(procedure.getRef().getLabelRef());
|
Collection<VariableRef> procUsed = procedureReferencedVars.get(procedure.getRef());
|
||||||
// The call statement has no used or defined by itself so only work with the alive vars
|
// The call statement has no used or defined by itself so only work with the alive vars
|
||||||
for(VariableRef aliveVar : aliveNextStmt) {
|
for(VariableRef aliveVar : aliveNextStmt) {
|
||||||
// Add all variables to previous that are used inside the method
|
// Add all variables to previous that are used inside the method
|
||||||
|
Loading…
Reference in New Issue
Block a user