mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-28 16:31:36 +00:00
Removed last GB of memory usage. Closes #306
This commit is contained in:
parent
9c5de66830
commit
c7fd528709
@ -4,7 +4,10 @@ import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.calcs.PassNCalcVariableReferenceInfos;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -17,9 +20,6 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
public class VariableReferenceInfos {
|
||||
|
||||
/** Variables used in each block. */
|
||||
private Map<LabelRef, Collection<VariableRef>> blockUsedVars;
|
||||
|
||||
/** For each block this is the closure of all successor blocks. */
|
||||
private Map<LabelRef, Collection<LabelRef>> blockSuccessorClosure;
|
||||
|
||||
@ -124,13 +124,11 @@ public class VariableReferenceInfos {
|
||||
}
|
||||
|
||||
public VariableReferenceInfos(
|
||||
Map<LabelRef, Collection<VariableRef>> blockUsedVars,
|
||||
Map<LabelRef, Collection<LabelRef>> blockSuccessorClosure,
|
||||
Map<SymbolVariableRef, Collection<ReferenceToSymbolVar>> symbolVarReferences,
|
||||
Map<LabelRef, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> blockVarReferences,
|
||||
Map<Integer, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> statementVarReferences
|
||||
) {
|
||||
this.blockUsedVars = blockUsedVars;
|
||||
this.blockSuccessorClosure = blockSuccessorClosure;
|
||||
this.symbolVarReferences = symbolVarReferences;
|
||||
this.blockVarReferences = blockVarReferences;
|
||||
@ -147,14 +145,6 @@ public class VariableReferenceInfos {
|
||||
}
|
||||
sizeInfo.append(" ").append(sub).append(" labels").append("\n");
|
||||
}
|
||||
if(blockUsedVars != null) {
|
||||
sizeInfo.append("blockUsedVars ").append(blockUsedVars.size()).append(" labels ");
|
||||
int sub = 0;
|
||||
for(Collection<VariableRef> variableRefs : blockUsedVars.values()) {
|
||||
sub += variableRefs.size();
|
||||
}
|
||||
sizeInfo.append(" ").append(sub).append(" varrefs").append("\n");
|
||||
}
|
||||
{
|
||||
sizeInfo.append("symbolVarReferences ").append(symbolVarReferences.size()).append(" SymbolVariableRefs ");
|
||||
int sub = 0;
|
||||
@ -214,16 +204,6 @@ public class VariableReferenceInfos {
|
||||
return variableRefs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all variables used inside a block and its successors (including any called method)
|
||||
*
|
||||
* @param labelRef The block to examine
|
||||
* @return All used variables
|
||||
*/
|
||||
public Collection<VariableRef> getUsedVars(LabelRef labelRef) {
|
||||
return blockUsedVars.get(labelRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the variables defined by a statement
|
||||
*
|
||||
@ -248,16 +228,12 @@ public class VariableReferenceInfos {
|
||||
* @return The referenced variables
|
||||
*/
|
||||
public Collection<VariableRef> getReferencedVars(Statement stmt) {
|
||||
// Test if new structure is compatible
|
||||
Collection<ReferenceToSymbolVar> referenceToSymbolVars = statementVarReferences.get(stmt.getIndex());
|
||||
List<VariableRef> variableRefs =
|
||||
referenceToSymbolVars
|
||||
.stream()
|
||||
.filter(referenceToSymbolVar -> referenceToSymbolVar.getReferenced() instanceof VariableRef)
|
||||
.map(ReferenceToSymbolVar::getReferenced)
|
||||
.map(symbolVariableRef -> (VariableRef) symbolVariableRef)
|
||||
.collect(Collectors.toList());
|
||||
return variableRefs;
|
||||
return statementVarReferences.get(stmt.getIndex())
|
||||
.stream()
|
||||
.filter(referenceToSymbolVar -> referenceToSymbolVar.getReferenced() instanceof VariableRef)
|
||||
.map(ReferenceToSymbolVar::getReferenced)
|
||||
.map(symbolVariableRef -> (VariableRef) symbolVariableRef)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -267,15 +243,13 @@ public class VariableReferenceInfos {
|
||||
* @return The used variables (not including defined variables)
|
||||
*/
|
||||
public Collection<VariableRef> getUsedVars(Statement stmt) {
|
||||
Collection<ReferenceToSymbolVar> referenceToSymbolVars = statementVarReferences.get(stmt.getIndex());
|
||||
List<VariableRef> variableRefs = referenceToSymbolVars
|
||||
return statementVarReferences.get(stmt.getIndex())
|
||||
.stream()
|
||||
.filter(referenceToSymbolVar -> referenceToSymbolVar.getReferenced() instanceof VariableRef)
|
||||
.filter(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE.equals(referenceToSymbolVar.getReferenceType()))
|
||||
.map(ReferenceToSymbolVar::getReferenced)
|
||||
.map(symbolVariableRef -> (VariableRef) symbolVariableRef)
|
||||
.collect(Collectors.toList());
|
||||
return variableRefs;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -286,8 +260,7 @@ public class VariableReferenceInfos {
|
||||
public boolean isUnused(SymbolVariableRef variableRef) {
|
||||
Collection<ReferenceToSymbolVar> refs = symbolVarReferences.get(variableRef);
|
||||
if(refs == null) return true;
|
||||
return !refs.stream()
|
||||
.anyMatch(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE.equals(referenceToSymbolVar.getReferenceType()));
|
||||
return refs.stream().noneMatch(referenceToSymbolVar -> ReferenceToSymbolVar.ReferenceType.USE.equals(referenceToSymbolVar.getReferenceType()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,13 +5,13 @@ package dk.camelot64.kickc.passes.calcs;
|
||||
*/
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
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;
|
||||
@ -123,7 +123,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.getUsedVars(procedure.getRef().getLabelRef());
|
||||
Collection<VariableRef> procUsed = referenceInfo.getReferencedVars(procedure.getRef().getLabelRef());
|
||||
// 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
|
||||
|
@ -22,37 +22,26 @@ public class PassNCalcVariableReferenceInfos extends PassNCalcBase<VariableRefer
|
||||
super(program);
|
||||
}
|
||||
|
||||
private LinkedHashMap<LabelRef, Collection<VariableRef>> blockDirectUsedVarsMap = null;
|
||||
|
||||
@Override
|
||||
public VariableReferenceInfos calculate() {
|
||||
LinkedHashMap<LabelRef, Collection<VariableRef>> blockUsedVars = new LinkedHashMap<>();
|
||||
LinkedHashMap<LabelRef, Collection<LabelRef>> blockSuccessors = new LinkedHashMap<>();
|
||||
|
||||
Map<SymbolVariableRef, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> symbolVarReferences = new LinkedHashMap<>();
|
||||
Map<LabelRef, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> blockVarReferences = new LinkedHashMap<>();
|
||||
Map<Integer, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> statementVarReferences = new LinkedHashMap<>();
|
||||
|
||||
blockDirectUsedVarsMap = new LinkedHashMap<>();
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
LinkedHashSet<VariableRef> blockDirectUsedVars = new LinkedHashSet<>();
|
||||
blockVarReferences.putIfAbsent(block.getLabel(), new ArrayList<>());
|
||||
Collection<VariableReferenceInfos.ReferenceToSymbolVar> blockSymbols = blockVarReferences.get(block.getLabel());
|
||||
for(Statement statement : block.getStatements()) {
|
||||
LinkedHashSet<SymbolVariableRef> stmtSymbolVarRefs = new LinkedHashSet<>();
|
||||
LinkedHashSet<VariableRef> stmtVarRefs = new LinkedHashSet<>();
|
||||
ProgramValueIterator.execute(statement,
|
||||
(programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(programValue.get() instanceof SymbolVariableRef)
|
||||
stmtSymbolVarRefs.add((SymbolVariableRef) programValue.get());
|
||||
if(programValue.get() instanceof VariableRef)
|
||||
stmtVarRefs.add((VariableRef) programValue.get());
|
||||
}
|
||||
, null, null);
|
||||
Collection<VariableRef> stmtDefinedVars = getDefinedVars(statement);
|
||||
LinkedHashSet<VariableRef> stmtUsedVars = new LinkedHashSet<>(stmtVarRefs);
|
||||
stmtUsedVars.removeAll(stmtDefinedVars);
|
||||
blockDirectUsedVars.addAll(stmtUsedVars);
|
||||
// Add variable definitions to the statement
|
||||
statementVarReferences.putIfAbsent(statement.getIndex(), new ArrayList<>());
|
||||
Collection<VariableReferenceInfos.ReferenceToSymbolVar> stmtSymbols = statementVarReferences.get(statement.getIndex());
|
||||
@ -77,14 +66,9 @@ public class PassNCalcVariableReferenceInfos extends PassNCalcBase<VariableRefer
|
||||
}
|
||||
}
|
||||
}
|
||||
LabelRef blockLabel = block.getLabel();
|
||||
blockDirectUsedVarsMap.put(blockLabel, blockDirectUsedVars);
|
||||
}
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
LabelRef blockLabel = block.getLabel();
|
||||
LinkedHashSet<VariableRef> blockRecursiveUsedVars = new LinkedHashSet<>();
|
||||
findReferencedVars(block.getLabel(), block, blockRecursiveUsedVars, new ArrayList<>());
|
||||
blockUsedVars.put(blockLabel, blockRecursiveUsedVars);
|
||||
LinkedHashSet<LabelRef> successorClosure = new LinkedHashSet<>();
|
||||
findSuccessorClosure(block.getLabel(), successorClosure, new ArrayList<>());
|
||||
blockSuccessors.put(blockLabel, successorClosure);
|
||||
@ -103,7 +87,7 @@ public class PassNCalcVariableReferenceInfos extends PassNCalcBase<VariableRefer
|
||||
}
|
||||
});
|
||||
}
|
||||
VariableReferenceInfos variableReferenceInfos = new VariableReferenceInfos(blockUsedVars, blockSuccessors, symbolVarReferences, blockVarReferences, statementVarReferences);
|
||||
VariableReferenceInfos variableReferenceInfos = new VariableReferenceInfos(blockSuccessors, symbolVarReferences, blockVarReferences, statementVarReferences);
|
||||
if(getLog().isVerboseSSAOptimize()) {
|
||||
getLog().append(variableReferenceInfos.getSizeInfo());
|
||||
}
|
||||
@ -158,29 +142,6 @@ public class PassNCalcVariableReferenceInfos extends PassNCalcBase<VariableRefer
|
||||
return referenced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively get all variables used or defined inside a block and its successors (including any called method)
|
||||
*
|
||||
* @param labelRef The block to examine
|
||||
* @param block The block to examine (optional, saves lookup)
|
||||
* @param usedVars the set of referenced variables
|
||||
* @param visited The blocks already visited during the search. Used to stop infinite recursion
|
||||
*/
|
||||
private void findReferencedVars(LabelRef labelRef, ControlFlowBlock block, LinkedHashSet<VariableRef> usedVars, Collection<LabelRef> visited) {
|
||||
if(labelRef == null || visited.contains(labelRef))
|
||||
return;
|
||||
visited.add(labelRef);
|
||||
if(block == null) {
|
||||
block = getProgram().getGraph().getBlock(labelRef);
|
||||
if(block == null)
|
||||
return;
|
||||
}
|
||||
usedVars.addAll(blockDirectUsedVarsMap.get(labelRef));
|
||||
findReferencedVars(block.getDefaultSuccessor(), null, usedVars, visited);
|
||||
findReferencedVars(block.getConditionalSuccessor(), null, usedVars, visited);
|
||||
findReferencedVars(block.getCallSuccessor(), null, usedVars, visited);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively get all blocks in the closure of successors & calls for a specific block
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user