mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-18 04:08:58 +00:00
put caches associated to pass n variable reference infos back out of control flow block class
This commit is contained in:
parent
b7b01a89a8
commit
47d2f74690
@ -39,20 +39,12 @@ 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;
|
||||
|
||||
/** The variables used in this block. Set by setReferencedVars(). */
|
||||
private LinkedHashSet<VariableRef> usedVars = null;
|
||||
|
||||
public ControlFlowBlock(LabelRef label, ScopeRef scope) {
|
||||
this.label = label;
|
||||
this.scope = scope;
|
||||
this.statements = new ArrayList<>();
|
||||
this.conditionalSuccessor = null;
|
||||
this.comments = new ArrayList<>();
|
||||
this.referencedVars = null;
|
||||
this.usedVars = null;
|
||||
}
|
||||
|
||||
public List<Comment> getComments() {
|
||||
@ -127,59 +119,6 @@ public class ControlFlowBlock {
|
||||
return statements;
|
||||
}
|
||||
|
||||
private Collection<VariableRef> getDefinedVars(Statement stmt) {
|
||||
if(stmt instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) stmt;
|
||||
LValue lValue = assignment.getlValue();
|
||||
if(lValue instanceof VariableRef) {
|
||||
return Arrays.asList((VariableRef) lValue);
|
||||
}
|
||||
} else if(stmt instanceof StatementPhiBlock) {
|
||||
List<VariableRef> defined = new ArrayList<>();
|
||||
StatementPhiBlock phi = (StatementPhiBlock) stmt;
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : phi.getPhiVariables()) {
|
||||
defined.add(phiVariable.getVariable());
|
||||
}
|
||||
return defined;
|
||||
} else if(stmt instanceof StatementCall) {
|
||||
List<VariableRef> defined = new ArrayList<>();
|
||||
if(((StatementCall) stmt).getlValue() instanceof VariableRef) {
|
||||
defined.add((VariableRef) ((StatementCall) stmt).getlValue());
|
||||
}
|
||||
return defined;
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
public void setReferencedVars() {
|
||||
referencedVars = new LinkedHashSet<>();
|
||||
usedVars = new LinkedHashSet<>();
|
||||
for(Statement statement : this.getStatements()) {
|
||||
LinkedHashSet<VariableRef> stmtReferencedVars = new LinkedHashSet<>();
|
||||
LinkedHashSet<VariableRef> stmtUsedVars = new LinkedHashSet<>();
|
||||
ProgramValueIterator.execute(statement,
|
||||
(programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(programValue.get() instanceof VariableRef)
|
||||
stmtReferencedVars.add((VariableRef) programValue.get());
|
||||
}
|
||||
, null, null);
|
||||
Collection<VariableRef> stmtDefinedVars = getDefinedVars(statement);
|
||||
stmtUsedVars.addAll(stmtReferencedVars);
|
||||
stmtUsedVars.removeAll(stmtDefinedVars);
|
||||
referencedVars.addAll(stmtReferencedVars);
|
||||
usedVars.addAll(stmtUsedVars);
|
||||
}
|
||||
}
|
||||
|
||||
public LinkedHashSet<VariableRef> getReferencedVars() {
|
||||
return referencedVars;
|
||||
}
|
||||
|
||||
public LinkedHashSet<VariableRef> getUsedVars() {
|
||||
return usedVars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the block the entry of a procedure, ie. the first block of the code of the procedure.
|
||||
*
|
||||
|
@ -23,6 +23,9 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
|
||||
super(program);
|
||||
}
|
||||
|
||||
private LinkedHashMap<LabelRef, Collection<VariableRef>> blockDirectVarRefsMap = null;
|
||||
private LinkedHashMap<LabelRef, Collection<VariableRef>> blockDirectUsedVarsMap = null;
|
||||
|
||||
/** Create defined/referenced maps */
|
||||
@Override
|
||||
public boolean step() {
|
||||
@ -31,31 +34,40 @@ 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<>();
|
||||
blockDirectVarRefsMap = new LinkedHashMap<>();
|
||||
blockDirectUsedVarsMap = new LinkedHashMap<>();
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
block.setReferencedVars();
|
||||
}
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
LabelRef blockLabel = block.getLabel();
|
||||
blockReferencedVars.put(blockLabel, getReferencedVars(block));
|
||||
blockUsedVars.put(blockLabel, getUsedVars(block));
|
||||
LinkedHashSet<VariableRef> blockDirectVarRefs = new LinkedHashSet<>();;
|
||||
LinkedHashSet<VariableRef> blockDirectUsedVars = new LinkedHashSet<>();;
|
||||
for(Statement statement : block.getStatements()) {
|
||||
Collection<SymbolVariableRef> referenced = getReferenced(statement);
|
||||
Collection<VariableRef> defined = getDefinedVars(statement);
|
||||
LinkedHashSet<SymbolVariableRef> stmtSymbolVarRefs = new LinkedHashSet<>();
|
||||
LinkedHashSet<VariableRef> stmtVarRefs = new LinkedHashSet<>();
|
||||
LinkedHashSet<VariableRef> stmtUsedVars = 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);
|
||||
stmtUsedVars.addAll(stmtVarRefs);
|
||||
stmtUsedVars.removeAll(stmtDefinedVars);
|
||||
blockDirectVarRefs.addAll(stmtVarRefs);
|
||||
blockDirectUsedVars.addAll(stmtUsedVars);
|
||||
|
||||
// Add variable definitions to the statement
|
||||
stmtDefined.put(statement.getIndex(), defined);
|
||||
stmtDefined.put(statement.getIndex(), stmtDefinedVars);
|
||||
// Identify statement defining variables
|
||||
for(VariableRef variableRef : defined) {
|
||||
for(VariableRef variableRef : stmtDefinedVars) {
|
||||
symbolVarReferences.putIfAbsent(variableRef, new ArrayList<>());
|
||||
Collection<VariableReferenceInfos.ReferenceToSymbolVar> references = symbolVarReferences.get(variableRef);
|
||||
references.add(new VariableReferenceInfos.ReferenceInStatement(statement.getIndex(), VariableReferenceInfos.ReferenceToSymbolVar.ReferenceType.DEFINE, variableRef));
|
||||
}
|
||||
// Gather statements referencing variables/constants
|
||||
Collection<VariableRef> varRefs = new ArrayList<>();
|
||||
for(SymbolVariableRef referencedVarRef : referenced) {
|
||||
if(referencedVarRef instanceof VariableRef) {
|
||||
varRefs.add((VariableRef) referencedVarRef);
|
||||
}
|
||||
if(!defined.contains(referencedVarRef)) {
|
||||
for(SymbolVariableRef referencedVarRef : stmtSymbolVarRefs) {
|
||||
if(!stmtDefinedVars.contains(referencedVarRef)) {
|
||||
symbolVarReferences.putIfAbsent(referencedVarRef, new ArrayList<>());
|
||||
Collection<VariableReferenceInfos.ReferenceToSymbolVar> references = symbolVarReferences.get(referencedVarRef);
|
||||
references.add(
|
||||
@ -66,8 +78,19 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
|
||||
}
|
||||
}
|
||||
// Add variable reference to the statement
|
||||
stmtReferenced.put(statement.getIndex(), varRefs);
|
||||
stmtReferenced.put(statement.getIndex(), stmtVarRefs);
|
||||
}
|
||||
LabelRef blockLabel = block.getLabel();
|
||||
blockDirectVarRefsMap.put(blockLabel, blockDirectVarRefs);
|
||||
blockDirectUsedVarsMap.put(blockLabel, blockDirectUsedVars);
|
||||
}
|
||||
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
|
||||
LabelRef blockLabel = block.getLabel();
|
||||
LinkedHashSet<VariableRef> blockRecursiveVarRefs = new LinkedHashSet<>();
|
||||
LinkedHashSet<VariableRef> blockRecursiveUsedVars = new LinkedHashSet<>();
|
||||
addReferencedVars(block.getLabel(), block, blockRecursiveVarRefs, blockRecursiveUsedVars, new ArrayList<>());
|
||||
blockReferencedVars.put(blockLabel, blockRecursiveVarRefs);
|
||||
blockUsedVars.put(blockLabel, blockRecursiveUsedVars);
|
||||
}
|
||||
// Gather symbols in the symbol table referencing other variables/constants
|
||||
Collection<SymbolVariable> allSymbolVariables = getProgram().getScope().getAllSymbolVariables(true);
|
||||
@ -87,7 +110,6 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get all variables referenced in an rValue
|
||||
*
|
||||
@ -136,64 +158,17 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
|
||||
return referenced;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 void addReferencedVars(LabelRef labelRef, ControlFlowBlock block, LinkedHashSet<VariableRef> referencedVars, 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;
|
||||
}
|
||||
referencedVars.addAll(block.getReferencedVars());
|
||||
addReferencedVars(block.getDefaultSuccessor(), null, referencedVars, visited);
|
||||
addReferencedVars(block.getConditionalSuccessor(), null, referencedVars, visited);
|
||||
addReferencedVars(block.getCallSuccessor(), null, referencedVars, visited);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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> getUsedVars(ControlFlowBlock block) {
|
||||
LinkedHashSet<VariableRef> usedVars = new LinkedHashSet<>();
|
||||
addUsedVars(block.getLabel(), block, usedVars, new ArrayList<>());
|
||||
return usedVars;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return All used variables
|
||||
*/
|
||||
private void addUsedVars(LabelRef labelRef, ControlFlowBlock block, LinkedHashSet<VariableRef> usedVars, Collection<LabelRef> visited) {
|
||||
private void addReferencedVars(LabelRef labelRef, ControlFlowBlock block, LinkedHashSet<VariableRef> referencedVars, LinkedHashSet<VariableRef> usedVars, Collection<LabelRef> visited) {
|
||||
if(labelRef == null || visited.contains(labelRef))
|
||||
return;
|
||||
visited.add(labelRef);
|
||||
@ -202,13 +177,13 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
|
||||
if(block == null)
|
||||
return;
|
||||
}
|
||||
usedVars.addAll(block.getUsedVars());
|
||||
addUsedVars(block.getDefaultSuccessor(), null, usedVars, visited);
|
||||
addUsedVars(block.getConditionalSuccessor(), null, usedVars, visited);
|
||||
addUsedVars(block.getCallSuccessor(), null, usedVars, visited);
|
||||
referencedVars.addAll(blockDirectVarRefsMap.get(labelRef));
|
||||
usedVars.addAll(blockDirectUsedVarsMap.get(labelRef));
|
||||
addReferencedVars(block.getDefaultSuccessor(), null, referencedVars, usedVars, visited);
|
||||
addReferencedVars(block.getConditionalSuccessor(), null, referencedVars, usedVars, visited);
|
||||
addReferencedVars(block.getCallSuccessor(), null, referencedVars, usedVars, visited);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the variables defined by a statement
|
||||
*
|
||||
@ -239,50 +214,4 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the variables used, but not defined, in a statement
|
||||
*
|
||||
* @param statement The statement to examine
|
||||
* @return The used variables (not including defined variables)
|
||||
*/
|
||||
private Collection<VariableRef> getUsedVars(Statement statement) {
|
||||
LinkedHashSet<VariableRef> used = new LinkedHashSet<>();
|
||||
used.addAll(getReferencedVars(statement));
|
||||
used.removeAll(getDefinedVars(statement));
|
||||
return used;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the variables referenced (used or defined) in a statement
|
||||
*
|
||||
* @param statement The statement to examine
|
||||
* @return The referenced variables
|
||||
*/
|
||||
private Collection<VariableRef> getReferencedVars(Statement statement) {
|
||||
LinkedHashSet<VariableRef> referencedVars = new LinkedHashSet<>();
|
||||
getReferenced(statement)
|
||||
.stream()
|
||||
.filter(symbolVariableRef -> symbolVariableRef instanceof VariableRef)
|
||||
.forEach(symbolVariableRef -> referencedVars.add((VariableRef) symbolVariableRef));
|
||||
return referencedVars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the variables / constants referenced (used or defined) in a statement
|
||||
*
|
||||
* @param statement The statement to examine
|
||||
* @return The referenced variables / constants (VariableRef / ConstantRef)
|
||||
*/
|
||||
private Collection<SymbolVariableRef> getReferenced(Statement statement) {
|
||||
LinkedHashSet<SymbolVariableRef> referenced = new LinkedHashSet<>();
|
||||
ProgramValueIterator.execute(statement,
|
||||
(programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(programValue.get() instanceof SymbolVariableRef)
|
||||
referenced.add((SymbolVariableRef) programValue.get());
|
||||
}
|
||||
, null, null);
|
||||
return referenced;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user