1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-20 00:29:10 +00:00

speed improvement in pass n variable reference infos

This commit is contained in:
Travis Fisher 2019-04-07 23:09:50 -04:00
parent 2ee07b0806
commit 7393d095b9
2 changed files with 51 additions and 27 deletions

View File

@ -1,17 +1,14 @@
package dk.camelot64.kickc.model; package dk.camelot64.kickc.model;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
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;
import dk.camelot64.kickc.model.statements.StatementPhiBlock; import dk.camelot64.kickc.model.statements.StatementPhiBlock;
import dk.camelot64.kickc.model.symbols.Procedure; import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.Symbol; import dk.camelot64.kickc.model.symbols.Symbol;
import dk.camelot64.kickc.model.values.LabelRef; import dk.camelot64.kickc.model.values.*;
import dk.camelot64.kickc.model.values.ScopeRef;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
/** /**
* A named/labelled sequence of SSA statements connected to other basic blocks. * A named/labelled sequence of SSA statements connected to other basic blocks.
@ -41,6 +38,9 @@ public class ControlFlowBlock {
/** The comments for the block. */ /** The comments for the block. */
private List<Comment> comments; private List<Comment> comments;
/** The variables referenced in this block. Set by setReferencedVars(). */
private LinkedHashSet<VariableRef> referencedVars = null;
public ControlFlowBlock(LabelRef label, ScopeRef scope) { public ControlFlowBlock(LabelRef label, ScopeRef scope) {
this.label = label; this.label = label;
this.scope = scope; this.scope = scope;
@ -48,6 +48,7 @@ public class ControlFlowBlock {
this.defaultSuccessor = null; this.defaultSuccessor = null;
this.conditionalSuccessor = null; this.conditionalSuccessor = null;
this.comments = new ArrayList<>(); this.comments = new ArrayList<>();
this.referencedVars = null;
} }
public List<Comment> getComments() { public List<Comment> getComments() {
@ -122,6 +123,22 @@ public class ControlFlowBlock {
return statements; return statements;
} }
public void setReferencedVars() {
referencedVars = new LinkedHashSet<>();
for(Statement statement : this.getStatements()) {
ProgramValueIterator.execute(statement,
(programValue, currentStmt, stmtIt, currentBlock) -> {
if(programValue.get() instanceof VariableRef)
referencedVars.add((VariableRef) programValue.get());
}
, null, null);
}
}
public LinkedHashSet<VariableRef> getReferencedVars() {
return referencedVars;
}
/** /**
* Is the block the entry of a procedure, ie. the first block of the code of the procedure. * Is the block the entry of a procedure, ie. the first block of the code of the procedure.
* *

View File

@ -31,9 +31,12 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
LinkedHashMap<Integer, Collection<VariableRef>> stmtReferenced = new LinkedHashMap<>(); LinkedHashMap<Integer, Collection<VariableRef>> stmtReferenced = new LinkedHashMap<>();
LinkedHashMap<Integer, Collection<VariableRef>> stmtDefined = new LinkedHashMap<>(); LinkedHashMap<Integer, Collection<VariableRef>> stmtDefined = new LinkedHashMap<>();
Map<SymbolVariableRef, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> symbolVarReferences = new LinkedHashMap<>(); Map<SymbolVariableRef, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> symbolVarReferences = new LinkedHashMap<>();
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
block.setReferencedVars();
}
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) { for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
LabelRef blockLabel = block.getLabel(); LabelRef blockLabel = block.getLabel();
blockReferencedVars.put(blockLabel, getReferencedVars(blockLabel, new ArrayList<>())); blockReferencedVars.put(blockLabel, getReferencedVars(block));
blockUsedVars.put(blockLabel, getUsedVars(blockLabel, new ArrayList<>())); blockUsedVars.put(blockLabel, getUsedVars(blockLabel, new ArrayList<>()));
for(Statement statement : block.getStatements()) { for(Statement statement : block.getStatements()) {
Collection<SymbolVariableRef> referenced = getReferenced(statement); Collection<SymbolVariableRef> referenced = getReferenced(statement);
@ -168,33 +171,37 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
/** /**
* Get all variables used or defined inside a block and its successors (including any called method) * Get all variables used or defined inside a block and its successors (including any called method)
* *
* @param block The block to examine
* @return All used variables
*/
private Collection<VariableRef> getReferencedVars(ControlFlowBlock block) {
LinkedHashSet<VariableRef> referencedVars = new LinkedHashSet<>();
addReferencedVars(block.getLabel(), block, referencedVars, new ArrayList<>());
return referencedVars;
}
/**
* Recursively get all variables used or defined inside a block and its successors (including any called method)
*
* @param labelRef The block to examine * @param labelRef The block to examine
* @param block The block to examine (optional, saves lookup)
* @param referencedVars the set of referenced variables
* @param visited The blocks already visited during the search. Used to stop infinite recursion * @param visited The blocks already visited during the search. Used to stop infinite recursion
* @return All used variables * @return All used variables
*/ */
private Collection<VariableRef> getReferencedVars(LabelRef labelRef, Collection<LabelRef> visited) { private void addReferencedVars(LabelRef labelRef, ControlFlowBlock block, LinkedHashSet<VariableRef> referencedVars, Collection<LabelRef> visited) {
if(labelRef == null) { if(labelRef == null || visited.contains(labelRef))
return new ArrayList<>(); return;
}
if(visited.contains(labelRef)) {
return new ArrayList<>();
}
visited.add(labelRef); visited.add(labelRef);
ControlFlowBlock block = getProgram().getGraph().getBlock(labelRef);
if(block == null) { if(block == null) {
return new ArrayList<>(); block = getProgram().getGraph().getBlock(labelRef);
if(block == null)
return;
} }
LinkedHashSet<VariableRef> referenced = new LinkedHashSet<>(); referencedVars.addAll(block.getReferencedVars());
for(Statement statement : block.getStatements()) { addReferencedVars(block.getDefaultSuccessor(), null, referencedVars, visited);
referenced.addAll(getReferencedVars(statement)); addReferencedVars(block.getConditionalSuccessor(), null, referencedVars, visited);
if(statement instanceof StatementCall) { addReferencedVars(block.getCallSuccessor(), null, referencedVars, visited);
ProcedureRef procedure = ((StatementCall) statement).getProcedure();
referenced.addAll(getReferencedVars(procedure.getLabelRef(), visited));
}
}
referenced.addAll(getReferencedVars(block.getDefaultSuccessor(), visited));
referenced.addAll(getReferencedVars(block.getConditionalSuccessor(), visited));
return referenced;
} }
/** /**