mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-08 14:37:40 +00:00
Eliminated old getAssignment() method.
This commit is contained in:
parent
3d7914c31f
commit
687705f5d2
src/main/java/dk/camelot64/kickc
@ -65,119 +65,6 @@ public class ControlFlowGraph implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the assignment of the passed variable. Assumes that only a single assignment exists.
|
||||
*
|
||||
* @param variable The variable to find the assignment for
|
||||
* @return The assignment. null if the variable is not assigned. The variable is assigned by a Phi-statement instead.
|
||||
*/
|
||||
public StatementLValue getAssignment(VariableRef variable) {
|
||||
for(ControlFlowBlock block : getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementLValue) {
|
||||
StatementLValue assignment = (StatementLValue) statement;
|
||||
if(variable.equals(assignment.getlValue())) {
|
||||
return assignment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Any assignment of a value to a SymbolVariable.
|
||||
* Potential assignments include StatementLValue, StatementPhi and Variable.initValue
|
||||
* */
|
||||
public static class VarAssignment {
|
||||
|
||||
public enum Type {
|
||||
STATEMENT_LVALUE,
|
||||
STATEMENT_PHI,
|
||||
INIT_VALUE
|
||||
}
|
||||
|
||||
/** The type of assignment. */
|
||||
public final Type type;
|
||||
|
||||
/** The block containing the assignment statement. Null if type is not STATEMENT_LVALUE or STATEMENT_PHI */
|
||||
public final ControlFlowBlock block;
|
||||
|
||||
/* The LValue-statement. Null if type is not STATEMENT_LVALUE. */
|
||||
public final StatementLValue statementLValue;
|
||||
|
||||
/* The PHI-statement. Null if type is not STATEMENT_PHI. */
|
||||
public final StatementPhiBlock statementPhi;
|
||||
public final StatementPhiBlock.PhiVariable statementPhiVariable;
|
||||
|
||||
/* The Variable with initValue. Null if type is not INIT_VALUE. */
|
||||
public final Variable variableInitValue;
|
||||
|
||||
public VarAssignment(Type type, ControlFlowBlock block, StatementLValue statementLValue, StatementPhiBlock statementPhi, StatementPhiBlock.PhiVariable statementPhiVariable, Variable variableInitValue) {
|
||||
this.type = type;
|
||||
this.block = block;
|
||||
this.statementLValue = statementLValue;
|
||||
this.statementPhi = statementPhi;
|
||||
this.statementPhiVariable = statementPhiVariable;
|
||||
this.variableInitValue = variableInitValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
if(block!=null)
|
||||
s.append(block.getLabel()).append("::");
|
||||
if(statementLValue!=null)
|
||||
s.append(statementLValue.toString());
|
||||
if(statementPhi!=null)
|
||||
s.append(statementPhi.toString()).append(" ");
|
||||
if(statementPhiVariable!=null)
|
||||
s.append(statementPhiVariable.toString());
|
||||
if(variableInitValue!=null)
|
||||
s.append(variableInitValue.toString());
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public StatementSource getSource() {
|
||||
if(statementLValue!=null)
|
||||
return statementLValue.getSource();
|
||||
if(statementPhi!=null)
|
||||
return statementPhi.getSource();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all assignments of value to a variable.
|
||||
*
|
||||
* @param variable The variable to find the assignment for
|
||||
* @return All assignments of values to the variable
|
||||
*/
|
||||
public static List<VarAssignment> getVarAssignments(SymbolVariableRef variable, ControlFlowGraph graph, ProgramScope programScope) {
|
||||
ArrayList<VarAssignment> varAssignments = new ArrayList<>();
|
||||
Variable varDef = programScope.getVariable(variable);
|
||||
if(varDef.getInitValue()!=null) {
|
||||
varAssignments.add(new VarAssignment(VarAssignment.Type.INIT_VALUE, null, null, null, null, varDef));
|
||||
}
|
||||
for(ControlFlowBlock block : graph.getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementLValue) {
|
||||
StatementLValue assignment = (StatementLValue) statement;
|
||||
if(variable.equals(assignment.getlValue())) {
|
||||
varAssignments.add(new VarAssignment(VarAssignment.Type.STATEMENT_LVALUE, block, assignment, null, null, null));
|
||||
}
|
||||
} else if(statement instanceof StatementPhiBlock) {
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
|
||||
if(phiVariable.getVariable().equals(variable)) {
|
||||
varAssignments.add(new VarAssignment(VarAssignment.Type.STATEMENT_PHI, block, null, (StatementPhiBlock) statement, phiVariable, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return varAssignments;
|
||||
}
|
||||
|
||||
public ControlFlowBlock getDefaultSuccessor(ControlFlowBlock block) {
|
||||
if(block.getDefaultSuccessor() != null) {
|
||||
return getBlock(block.getDefaultSuccessor());
|
||||
@ -293,7 +180,7 @@ public class ControlFlowGraph implements Serializable {
|
||||
|
||||
if(!blocks.equals(that.blocks)) return false;
|
||||
if(!firstBlockRef.equals(that.firstBlockRef)) return false;
|
||||
return sequence != null ? sequence.equals(that.sequence) : that.sequence == null;
|
||||
return Objects.equals(sequence, that.sequence);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,13 +2,13 @@ package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.ControlFlowGraph;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementLValue;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.LvalueIntermediate;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.passes.utils.VarAssignments;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -29,8 +29,8 @@ public class Pass1AssertNoLValueIntermediate extends Pass1Base {
|
||||
LValue lValue = ((StatementLValue) statement).getlValue();
|
||||
if(lValue instanceof LvalueIntermediate) {
|
||||
VariableRef intermediateVar = ((LvalueIntermediate) lValue).getVariable();
|
||||
final List<ControlFlowGraph.VarAssignment> varAssignments = ControlFlowGraph.getVarAssignments(intermediateVar, getGraph(), getScope());
|
||||
final ControlFlowGraph.VarAssignment varAssignment = varAssignments.get(0);
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(intermediateVar, getGraph(), getScope());
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
throw new CompileError("Error! LValue is illegal. " + statement + " - definition of lValue " + varAssignment, varAssignment.getSource());
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import dk.camelot64.kickc.model.types.SymbolTypeConversion;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeIntegerFixed;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.utils.AliasReplacer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -1,7 +1,6 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.ControlFlowGraph;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
@ -15,6 +14,7 @@ import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.LvalueIntermediate;
|
||||
import dk.camelot64.kickc.model.values.SymbolVariableRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.passes.utils.VarAssignments;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -44,10 +44,10 @@ public class Pass1FixLValuesLoHi extends Pass1Base {
|
||||
if(statement instanceof StatementLValue && ((StatementLValue) statement).getlValue() instanceof LvalueIntermediate) {
|
||||
StatementLValue statementLValue = (StatementLValue) statement;
|
||||
LvalueIntermediate intermediate = (LvalueIntermediate) statementLValue.getlValue();
|
||||
final List<ControlFlowGraph.VarAssignment> varAssignments = ControlFlowGraph.getVarAssignments(intermediate.getVariable(), getGraph(), programScope);
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(intermediate.getVariable(), getGraph(), programScope);
|
||||
if(varAssignments.size() == 1) {
|
||||
final ControlFlowGraph.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(varAssignment.type.equals(ControlFlowGraph.VarAssignment.Type.STATEMENT_LVALUE) && varAssignment.statementLValue instanceof StatementAssignment) {
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(varAssignment.type.equals(VarAssignments.VarAssignment.Type.STATEMENT_LVALUE) && varAssignment.statementLValue instanceof StatementAssignment) {
|
||||
StatementAssignment intermediateAssignment = (StatementAssignment) varAssignment.statementLValue;
|
||||
if(Operators.LOWBYTE.equals(intermediateAssignment.getOperator()) && intermediateAssignment.getrValue1() == null) {
|
||||
// Found assignment to an intermediate low byte lValue <x = ...
|
||||
|
@ -1,13 +1,13 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.ControlFlowGraph;
|
||||
import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.*;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.utils.VarAssignments;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -128,15 +128,15 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
if(assignment.getrValue1() == null && assignment.getOperator() == null && assignment.getrValue2() instanceof VariableRef) {
|
||||
// Alias assignment
|
||||
VariableRef alias = (VariableRef) assignment.getrValue2();
|
||||
List<ControlFlowGraph.VarAssignment> assignments = ControlFlowGraph.getVarAssignments(alias, program.getGraph(), program.getScope());
|
||||
List<VarAssignments.VarAssignment> assignments = VarAssignments.get(alias, program.getGraph(), program.getScope());
|
||||
if(assignments.size() == 0)
|
||||
throw new InternalError("Error! Var is never assigned! " + variable);
|
||||
else if(assignments.size() > 1)
|
||||
// Multiple assignments exist
|
||||
continue;
|
||||
// assignments.size()==1
|
||||
ControlFlowGraph.VarAssignment varAssignment = assignments.get(0);
|
||||
if(ControlFlowGraph.VarAssignment.Type.INIT_VALUE.equals(varAssignment.type)) {
|
||||
VarAssignments.VarAssignment varAssignment = assignments.get(0);
|
||||
if(VarAssignments.VarAssignment.Type.INIT_VALUE.equals(varAssignment.type)) {
|
||||
aliases.add(variable, alias);
|
||||
} else {
|
||||
// Examine if the alias is assigned inside another scope
|
||||
@ -169,7 +169,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
alias = null;
|
||||
break;
|
||||
}
|
||||
List<ControlFlowGraph.VarAssignment> assignments = ControlFlowGraph.getVarAssignments(alias, program.getGraph(), program.getScope());
|
||||
List<VarAssignments.VarAssignment> assignments = VarAssignments.get(alias, program.getGraph(), program.getScope());
|
||||
if(assignments.size() == 0)
|
||||
throw new InternalError("Error! Var is never assigned! " + variable);
|
||||
if(assignments.size() > 1) {
|
||||
@ -178,8 +178,8 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
break;
|
||||
}
|
||||
// assignments.size()==1
|
||||
ControlFlowGraph.VarAssignment varAssignment = assignments.get(0);
|
||||
if(!ControlFlowGraph.VarAssignment.Type.INIT_VALUE.equals(varAssignment.type)) {
|
||||
VarAssignments.VarAssignment varAssignment = assignments.get(0);
|
||||
if(!VarAssignments.VarAssignment.Type.INIT_VALUE.equals(varAssignment.type)) {
|
||||
// Examine if the alias is assigned inside another scope
|
||||
ScopeRef varAssignmentScope = block.getScope();
|
||||
ScopeRef aliasAssignmentScope = varAssignment.block.getScope();
|
||||
@ -247,9 +247,13 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
StatementSource bestSource = null;
|
||||
List<Statement> assignments = new ArrayList<>();
|
||||
for(VariableRef aliasVar : aliasSet.getVars()) {
|
||||
|
||||
Statement assignment = getGraph().getAssignment(aliasVar);
|
||||
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(aliasVar, getGraph(), getScope());
|
||||
if(varAssignments.size()!=1)
|
||||
continue;
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(!VarAssignments.VarAssignment.Type.STATEMENT_LVALUE.equals(varAssignment.type))
|
||||
continue;
|
||||
Statement assignment = varAssignment.statementLValue;
|
||||
if(assignment != null) {
|
||||
assignments.add(assignment);
|
||||
StatementSource source = assignment.getSource();
|
||||
|
@ -10,6 +10,7 @@ import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementLValue;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.utils.VarAssignments;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -191,11 +192,11 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
|
||||
final Variable var = getScope().getVar(variable);
|
||||
if(var.isKindLoadStore())
|
||||
return null;
|
||||
final List<ControlFlowGraph.VarAssignment> varAssignments = ControlFlowGraph.getVarAssignments(variable, getGraph(), getScope());
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(variable, getGraph(), getScope());
|
||||
if(varAssignments.size()!=1)
|
||||
return null;
|
||||
final ControlFlowGraph.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(!ControlFlowGraph.VarAssignment.Type.STATEMENT_LVALUE.equals(varAssignment.type))
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(!VarAssignments.VarAssignment.Type.STATEMENT_LVALUE.equals(varAssignment.type))
|
||||
return null;
|
||||
StatementLValue statementLValue = varAssignment.statementLValue;
|
||||
if(statementLValue instanceof StatementAssignment) {
|
||||
|
@ -7,7 +7,6 @@ import dk.camelot64.kickc.model.operators.OperatorUnary;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementLValue;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
@ -16,6 +15,7 @@ import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.utils.VarAssignments;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -167,10 +167,10 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
if(variable.isVolatile() || !variable.isKindLoadStore())
|
||||
// Do not examine volatiles, non-constants or versioned variables
|
||||
continue;
|
||||
final List<ControlFlowGraph.VarAssignment> varAssignments = ControlFlowGraph.getVarAssignments(variable.getRef(), getGraph(), getScope());
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(variable.getRef(), getGraph(), getScope());
|
||||
if(varAssignments.size() == 1) {
|
||||
final ControlFlowGraph.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(!ControlFlowGraph.VarAssignment.Type.STATEMENT_LVALUE.equals(varAssignment.type) || !(varAssignment.statementLValue instanceof StatementAssignment))
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(!VarAssignments.VarAssignment.Type.STATEMENT_LVALUE.equals(varAssignment.type) || !(varAssignment.statementLValue instanceof StatementAssignment))
|
||||
// Only look at assignments
|
||||
continue;
|
||||
StatementAssignment assignment = (StatementAssignment) varAssignment.statementLValue;
|
||||
|
@ -7,6 +7,7 @@ import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.utils.AliasReplacer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.ControlFlowGraph;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.operators.OperatorCastPtr;
|
||||
@ -13,6 +12,7 @@ import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.utils.VarAssignments;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -54,11 +54,11 @@ public class Pass2InlineDerefIdx extends Pass2SsaOptimization {
|
||||
final Variable var = getScope().getVar(derefVar);
|
||||
if(var.isKindLoadStore())
|
||||
return null;
|
||||
final List<ControlFlowGraph.VarAssignment> varAssignments = ControlFlowGraph.getVarAssignments(derefVar, getGraph(), getScope());
|
||||
final List<VarAssignments.VarAssignment> varAssignments = VarAssignments.get(derefVar, getGraph(), getScope());
|
||||
if(varAssignments.size()!=1)
|
||||
return null;
|
||||
final ControlFlowGraph.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(!ControlFlowGraph.VarAssignment.Type.STATEMENT_LVALUE.equals(varAssignment.type))
|
||||
final VarAssignments.VarAssignment varAssignment = varAssignments.get(0);
|
||||
if(!VarAssignments.VarAssignment.Type.STATEMENT_LVALUE.equals(varAssignment.type))
|
||||
return null;
|
||||
StatementLValue derefVarDefined = varAssignment.statementLValue;
|
||||
if(derefVarDefined instanceof StatementAssignment) {
|
||||
|
@ -6,6 +6,7 @@ import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.model.statements.*;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.passes.utils.AliasReplacer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
package dk.camelot64.kickc.passes.utils;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValue;
|
@ -0,0 +1,114 @@
|
||||
package dk.camelot64.kickc.passes.utils;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.ControlFlowGraph;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementLValue;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.statements.StatementSource;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.SymbolVariableRef;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility for finding all assignments for a variable.
|
||||
*/
|
||||
public class VarAssignments {
|
||||
|
||||
/**
|
||||
* Get all assignments of value to a variable.
|
||||
*
|
||||
* @param variable The variable to find the assignment for
|
||||
* @return All assignments of values to the variable
|
||||
*/
|
||||
public static List<VarAssignment> get(SymbolVariableRef variable, ControlFlowGraph graph, ProgramScope programScope) {
|
||||
ArrayList<VarAssignment> varAssignments = new ArrayList<>();
|
||||
Variable varDef = programScope.getVariable(variable);
|
||||
if(varDef.getInitValue() != null) {
|
||||
varAssignments.add(new VarAssignment(VarAssignment.Type.INIT_VALUE, null, null, null, null, varDef));
|
||||
}
|
||||
for(ControlFlowBlock block : graph.getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementLValue) {
|
||||
StatementLValue assignment = (StatementLValue) statement;
|
||||
if(variable.equals(assignment.getlValue())) {
|
||||
varAssignments.add(new VarAssignment(VarAssignment.Type.STATEMENT_LVALUE, block, assignment, null, null, null));
|
||||
}
|
||||
} else if(statement instanceof StatementPhiBlock) {
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
|
||||
if(phiVariable.getVariable().equals(variable)) {
|
||||
varAssignments.add(new VarAssignment(VarAssignment.Type.STATEMENT_PHI, block, null, (StatementPhiBlock) statement, phiVariable, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return varAssignments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any assignment of a value to a SymbolVariable.
|
||||
* Potential assignments include StatementLValue, StatementPhi and Variable.initValue
|
||||
*/
|
||||
public static class VarAssignment {
|
||||
|
||||
public enum Type {
|
||||
STATEMENT_LVALUE,
|
||||
STATEMENT_PHI,
|
||||
INIT_VALUE
|
||||
}
|
||||
|
||||
/** The type of assignment. */
|
||||
public final Type type;
|
||||
|
||||
/** The block containing the assignment statement. Null if type is not STATEMENT_LVALUE or STATEMENT_PHI */
|
||||
public final ControlFlowBlock block;
|
||||
|
||||
/* The LValue-statement. Null if type is not STATEMENT_LVALUE. */
|
||||
public final StatementLValue statementLValue;
|
||||
|
||||
/* The PHI-statement. Null if type is not STATEMENT_PHI. */
|
||||
public final StatementPhiBlock statementPhi;
|
||||
public final StatementPhiBlock.PhiVariable statementPhiVariable;
|
||||
|
||||
/* The Variable with initValue. Null if type is not INIT_VALUE. */
|
||||
public final Variable variableInitValue;
|
||||
|
||||
public VarAssignment(Type type, ControlFlowBlock block, StatementLValue statementLValue, StatementPhiBlock statementPhi, StatementPhiBlock.PhiVariable statementPhiVariable, Variable variableInitValue) {
|
||||
this.type = type;
|
||||
this.block = block;
|
||||
this.statementLValue = statementLValue;
|
||||
this.statementPhi = statementPhi;
|
||||
this.statementPhiVariable = statementPhiVariable;
|
||||
this.variableInitValue = variableInitValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
if(block != null)
|
||||
s.append(block.getLabel()).append("::");
|
||||
if(statementLValue != null)
|
||||
s.append(statementLValue.toString());
|
||||
if(statementPhi != null)
|
||||
s.append(statementPhi.toString()).append(" ");
|
||||
if(statementPhiVariable != null)
|
||||
s.append(statementPhiVariable.toString());
|
||||
if(variableInitValue != null)
|
||||
s.append(variableInitValue.toString());
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public StatementSource getSource() {
|
||||
if(statementLValue != null)
|
||||
return statementLValue.getSource();
|
||||
if(statementPhi != null)
|
||||
return statementPhi.getSource();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user