mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-30 15:31:17 +00:00
speed improvement in pass n variable reference infos
This commit is contained in:
parent
2ee07b0806
commit
7393d095b9
@ -1,17 +1,14 @@
|
||||
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.StatementCall;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A named/labelled sequence of SSA statements connected to other basic blocks.
|
||||
@ -41,6 +38,9 @@ public class ControlFlowBlock {
|
||||
/** The comments for the block. */
|
||||
private List<Comment> comments;
|
||||
|
||||
/** The variables referenced in this block. Set by setReferencedVars(). */
|
||||
private LinkedHashSet<VariableRef> referencedVars = null;
|
||||
|
||||
public ControlFlowBlock(LabelRef label, ScopeRef scope) {
|
||||
this.label = label;
|
||||
this.scope = scope;
|
||||
@ -48,6 +48,7 @@ public class ControlFlowBlock {
|
||||
this.defaultSuccessor = null;
|
||||
this.conditionalSuccessor = null;
|
||||
this.comments = new ArrayList<>();
|
||||
this.referencedVars = null;
|
||||
}
|
||||
|
||||
public List<Comment> getComments() {
|
||||
@ -122,6 +123,22 @@ public class ControlFlowBlock {
|
||||
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.
|
||||
*
|
||||
|
@ -31,9 +31,12 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
|
||||
LinkedHashMap<Integer, Collection<VariableRef>> stmtReferenced = new LinkedHashMap<>();
|
||||
LinkedHashMap<Integer, Collection<VariableRef>> stmtDefined = new LinkedHashMap<>();
|
||||
Map<SymbolVariableRef, Collection<VariableReferenceInfos.ReferenceToSymbolVar>> symbolVarReferences = new LinkedHashMap<>();
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
block.setReferencedVars();
|
||||
}
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
LabelRef blockLabel = block.getLabel();
|
||||
blockReferencedVars.put(blockLabel, getReferencedVars(blockLabel, new ArrayList<>()));
|
||||
blockReferencedVars.put(blockLabel, getReferencedVars(block));
|
||||
blockUsedVars.put(blockLabel, getUsedVars(blockLabel, new ArrayList<>()));
|
||||
for(Statement statement : block.getStatements()) {
|
||||
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)
|
||||
*
|
||||
* @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 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
|
||||
* @return All used variables
|
||||
*/
|
||||
private Collection<VariableRef> getReferencedVars(LabelRef labelRef, Collection<LabelRef> visited) {
|
||||
if(labelRef == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
if(visited.contains(labelRef)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
private void addReferencedVars(LabelRef labelRef, ControlFlowBlock block, LinkedHashSet<VariableRef> referencedVars, Collection<LabelRef> visited) {
|
||||
if(labelRef == null || visited.contains(labelRef))
|
||||
return;
|
||||
visited.add(labelRef);
|
||||
ControlFlowBlock block = getProgram().getGraph().getBlock(labelRef);
|
||||
if(block == null) {
|
||||
return new ArrayList<>();
|
||||
block = getProgram().getGraph().getBlock(labelRef);
|
||||
if(block == null)
|
||||
return;
|
||||
}
|
||||
LinkedHashSet<VariableRef> referenced = new LinkedHashSet<>();
|
||||
for(Statement statement : block.getStatements()) {
|
||||
referenced.addAll(getReferencedVars(statement));
|
||||
if(statement instanceof StatementCall) {
|
||||
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;
|
||||
referencedVars.addAll(block.getReferencedVars());
|
||||
addReferencedVars(block.getDefaultSuccessor(), null, referencedVars, visited);
|
||||
addReferencedVars(block.getConditionalSuccessor(), null, referencedVars, visited);
|
||||
addReferencedVars(block.getCallSuccessor(), null, referencedVars, visited);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user