1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-23 23:32:55 +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
public void check() throws AssertionFailed {
HashSet<String> codeSymbolFullNames = new HashSet<>();
HashSet<Symbol> codeSymbols = new HashSet<>();
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
if(programValue.get() instanceof SymbolRef) {
Symbol symbol = getScope().getSymbol((SymbolRef) programValue.get());
if(symbol != null)
if(symbol != null) {
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
Collection<Symbol> tableSymbols = getScope().getAllSymbols(true);
for(Symbol tableSymbol : tableSymbols) {
if(tableSymbol instanceof VariableUnversioned) continue;
if(tableSymbol instanceof ConstantVar) continue;
@ -45,20 +49,10 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
if(tableSymbol instanceof EnumDefinition) continue;
if(tableSymbol instanceof TypeDefsScope) continue;
if(tableSymbol.getType() instanceof SymbolTypeStruct) continue;
Symbol codeSymbol = null;
String codeSymbolFullName = tableSymbol.getFullName();
for(Symbol symbol : codeSymbols) {
if(codeSymbolFullName.equals(symbol.getFullName())) {
codeSymbol = symbol;
break;
}
}
if(codeSymbol == null) {
if(tableSymbol.getType() instanceof SymbolTypeStruct) {
getLog().append("Struct no longer used in code "+codeSymbolFullName);
} else {
if(!codeSymbolFullNames.contains(codeSymbolFullName)) {
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;
/**
* Identify the alive intervals for all variables. Add the intervals to the ProgramScope.
*/
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.statements.Statement;
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.VariableRef;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.*;
/**
* Identify the alive intervals for all variables. Add the intervals to the ProgramScope.
*/
public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariables> {
public PassNCalcLiveRangeVariables(Program program) {
@ -26,6 +22,7 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
@Override
public LiveRangeVariables calculate() {
calculateProcedureReferencedVars();
LiveRangeVariables liveRanges = new LiveRangeVariables(getProgram());
boolean propagating;
do {
@ -40,6 +37,29 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
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.
* 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)
*/
private boolean calculateLiveRanges(LiveRangeVariables liveRanges) {
VariableReferenceInfos referenceInfo = getProgram().getVariableReferenceInfos();
boolean modified = false;
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
for(Statement stmt : block.getStatements()) {
@ -89,7 +111,7 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
// Add all vars that are referenced in the method
StatementCall call = (StatementCall) stmt;
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
for(VariableRef aliveVar : aliveNextStmt) {
// 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
StatementCall call = (StatementCall) stmt;
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
for(VariableRef aliveVar : aliveNextStmt) {
// 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
ControlFlowBlock procBlock = getProgram().getStatementInfos().getBlock(stmt);
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
for(VariableRef aliveVar : aliveNextStmt) {
// Add all variables to previous that are used inside the method