1
0
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:
jespergravgaard 2019-09-06 07:44:09 +02:00
parent daa963dbbb
commit 01008ccb26
2 changed files with 41 additions and 25 deletions

View File

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

View File

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