1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-01 02:29:30 +00:00

Removed last GB of memory usage. Closes #306

This commit is contained in:
jespergravgaard 2019-09-04 00:03:16 +02:00
parent 9c5de66830
commit c7fd528709
3 changed files with 17 additions and 83 deletions

View File

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

View File

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

View File

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