mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-08 12:30:58 +00:00
New alias elimination implementation. Optimized register allocation for test.
This commit is contained in:
parent
a5204acf79
commit
790feb1dcc
2
src/dk/camelot64/kickc/asm/fragment/aby=aby_plus_1.asm
Normal file
2
src/dk/camelot64/kickc/asm/fragment/aby=aby_plus_1.asm
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
clc
|
||||||
|
adc #1
|
1
src/dk/camelot64/kickc/asm/fragment/aby=zpby1.asm
Normal file
1
src/dk/camelot64/kickc/asm/fragment/aby=zpby1.asm
Normal file
@ -0,0 +1 @@
|
|||||||
|
lda {zpby1}
|
3
src/dk/camelot64/kickc/asm/fragment/zpby1=aby_plus_1.asm
Normal file
3
src/dk/camelot64/kickc/asm/fragment/zpby1=aby_plus_1.asm
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
clc
|
||||||
|
adc #1
|
||||||
|
sta {zpby1}
|
@ -26,6 +26,15 @@ public class Label implements Symbol {
|
|||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getScopeDepth() {
|
||||||
|
if(scope==null) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return scope.getScopeDepth()+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getFullName() {
|
public String getFullName() {
|
||||||
return Scope.getFullName(this);
|
return Scope.getFullName(this);
|
||||||
|
@ -40,7 +40,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
|||||||
if (lValue instanceof VariableUnversioned) {
|
if (lValue instanceof VariableUnversioned) {
|
||||||
// Assignment to a non-versioned non-intermediary variable
|
// Assignment to a non-versioned non-intermediary variable
|
||||||
VariableUnversioned assignedSymbol = (VariableUnversioned) lValue;
|
VariableUnversioned assignedSymbol = (VariableUnversioned) lValue;
|
||||||
VariableVersion version = symbols.createVersion(assignedSymbol);
|
VariableVersion version = assignedSymbol.createVersion();
|
||||||
assignment.setLValue(version);
|
assignment.setLValue(version);
|
||||||
}
|
}
|
||||||
} else if(statement instanceof StatementCall) {
|
} else if(statement instanceof StatementCall) {
|
||||||
@ -49,7 +49,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
|||||||
if (lValue instanceof VariableUnversioned) {
|
if (lValue instanceof VariableUnversioned) {
|
||||||
// Assignment to a non-versioned non-intermediary variable
|
// Assignment to a non-versioned non-intermediary variable
|
||||||
VariableUnversioned assignedSymbol = (VariableUnversioned) lValue;
|
VariableUnversioned assignedSymbol = (VariableUnversioned) lValue;
|
||||||
VariableVersion version = symbols.createVersion(assignedSymbol);
|
VariableVersion version = assignedSymbol.createVersion();
|
||||||
call.setLValue(version);
|
call.setLValue(version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
|||||||
}
|
}
|
||||||
if (version == null) {
|
if (version == null) {
|
||||||
// create a new phi function
|
// create a new phi function
|
||||||
version = symbols.createVersion(rSymbol);
|
version = rSymbol.createVersion();
|
||||||
blockNewPhis.put(rSymbol, version);
|
blockNewPhis.put(rSymbol, version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ public class Pass1GenerateSingleStaticAssignmentForm {
|
|||||||
previousSymbol = predecessorNewPhis.get(unversioned);
|
previousSymbol = predecessorNewPhis.get(unversioned);
|
||||||
if (previousSymbol == null) {
|
if (previousSymbol == null) {
|
||||||
// No previous symbol found in predecessor block. Add a new phi function to the predecessor.
|
// No previous symbol found in predecessor block. Add a new phi function to the predecessor.
|
||||||
previousSymbol = symbols.createVersion(unversioned);
|
previousSymbol = unversioned.createVersion();
|
||||||
predecessorNewPhis.put(unversioned, previousSymbol);
|
predecessorNewPhis.put(unversioned, previousSymbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ package dk.camelot64.kickc.icl;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/** Compiler Pass eliminating alias assignments */
|
/**
|
||||||
|
* Compiler Pass eliminating alias assignments
|
||||||
|
*/
|
||||||
public class Pass2AliasElimination extends Pass2SsaOptimization {
|
public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||||
|
|
||||||
public Pass2AliasElimination(ControlFlowGraph graph, Scope scope) {
|
public Pass2AliasElimination(ControlFlowGraph graph, Scope scope) {
|
||||||
@ -16,50 +18,77 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
|||||||
@Override
|
@Override
|
||||||
public boolean optimize() {
|
public boolean optimize() {
|
||||||
final Aliases aliases = findAliases();
|
final Aliases aliases = findAliases();
|
||||||
removeAssignments(aliases.getAssignmentsToRemove());
|
removeAliasAssignments(aliases);
|
||||||
replaceVariables(aliases.getReplacements());
|
replaceVariables(aliases.getReplacements());
|
||||||
deleteSymbols(aliases.getSymbolsToRemove());
|
deleteSymbols(aliases.getSymbolsToRemove());
|
||||||
for (Alias alias : aliases.getAliases()) {
|
for (AliasSet aliasSet : aliases.getAliasSets()) {
|
||||||
System.out.println("Alias " + alias.getKeep() + " " + alias.getEliminate());
|
StringBuilder str = new StringBuilder();
|
||||||
|
str.append(aliasSet.getKeepVar());
|
||||||
|
str.append(" = ");
|
||||||
|
for (Variable var : aliasSet.getEliminateVars()) {
|
||||||
|
str.append(var + " ");
|
||||||
|
}
|
||||||
|
System.out.println("Alias " + str);
|
||||||
}
|
}
|
||||||
return (aliases.size()>0);
|
return (aliases.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Aliases {
|
/**
|
||||||
private List<Alias> aliases;
|
* Remove all assignments that just assign an alias to itself
|
||||||
|
*
|
||||||
|
* @param aliases The aliases
|
||||||
|
*/
|
||||||
|
|
||||||
|
private void removeAliasAssignments(Aliases aliases) {
|
||||||
|
for (ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||||
|
for (Iterator<Statement> iterator = block.getStatements().iterator(); iterator.hasNext(); ) {
|
||||||
|
Statement statement = iterator.next();
|
||||||
|
if (statement instanceof StatementAssignment) {
|
||||||
|
StatementAssignment assignment = (StatementAssignment) statement;
|
||||||
|
AliasSet aliasSet = aliases.findAliasSet(assignment.getLValue());
|
||||||
|
if (aliasSet != null) {
|
||||||
|
if ((assignment.getRValue1() == null) && (assignment.getOperator() == null) && aliasSet.contains(assignment.getRValue2())) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (statement instanceof StatementPhi) {
|
||||||
|
StatementPhi phi = (StatementPhi) statement;
|
||||||
|
AliasSet aliasSet = aliases.findAliasSet(phi.getLValue());
|
||||||
|
if (aliasSet != null) {
|
||||||
|
if (phi.getPreviousVersions().size() == 1 && aliasSet.contains(phi.getPreviousVersion(0).getRValue())) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Aliases {
|
||||||
|
|
||||||
|
private List<AliasSet> aliases;
|
||||||
|
|
||||||
public Aliases() {
|
public Aliases() {
|
||||||
this.aliases = new ArrayList<>();
|
this.aliases = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Alias> getAliases() {
|
|
||||||
return aliases;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Variable> getAssignmentsToRemove() {
|
|
||||||
ArrayList<Variable> eliminates = new ArrayList<>();
|
|
||||||
for (Alias alias : aliases) {
|
|
||||||
if(alias.isKeepHasDefinition()) {
|
|
||||||
eliminates.add(alias.getEliminate());
|
|
||||||
} else {
|
|
||||||
eliminates.add(alias.getKeep());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return eliminates;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Variable> getSymbolsToRemove() {
|
public List<Variable> getSymbolsToRemove() {
|
||||||
ArrayList<Variable> eliminates = new ArrayList<>();
|
ArrayList<Variable> eliminates = new ArrayList<>();
|
||||||
for (Alias alias : aliases) {
|
for (AliasSet alias : aliases) {
|
||||||
eliminates.add(alias.getEliminate());
|
eliminates.addAll(alias.getEliminateVars());
|
||||||
}
|
}
|
||||||
return eliminates;
|
return eliminates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Variable, Variable> getReplacements() {
|
public Map<Variable, Variable> getReplacements() {
|
||||||
HashMap<Variable, Variable> replacements = new HashMap<>();
|
HashMap<Variable, Variable> replacements = new HashMap<>();
|
||||||
for (Alias alias : aliases) {
|
for (AliasSet aliasSet : aliases) {
|
||||||
replacements.put(alias.getEliminate(), alias.getKeep());
|
Variable keepVar = aliasSet.getKeepVar();
|
||||||
|
for (Variable var : aliasSet.getEliminateVars()) {
|
||||||
|
if(!var.equals(keepVar)) {
|
||||||
|
replacements.put(var, keepVar);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return replacements;
|
return replacements;
|
||||||
}
|
}
|
||||||
@ -68,42 +97,111 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
|||||||
return aliases.size();
|
return aliases.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(Variable lValue, Variable rValue) {
|
public void add(Variable var1, Variable var2) {
|
||||||
if(lValue instanceof VariableVersion && rValue instanceof VariableIntermediate) {
|
AliasSet aliasSet1 = findAliasSet(var1);
|
||||||
aliases.add(new Alias(lValue, rValue, false));
|
AliasSet aliasSet2 = findAliasSet(var2);
|
||||||
|
if (aliasSet1 != null) {
|
||||||
|
if (aliasSet2 != null) {
|
||||||
|
aliasSet1.addAll(aliasSet2);
|
||||||
|
aliases.remove(aliasSet2);
|
||||||
|
} else {
|
||||||
|
aliasSet1.add(var2);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
aliases.add(new Alias(rValue, lValue, true));
|
if (aliasSet2 != null) {
|
||||||
|
aliasSet2.add(var1);
|
||||||
|
} else {
|
||||||
|
AliasSet newSet = new AliasSet();
|
||||||
|
newSet.add(var1);
|
||||||
|
newSet.add(var2);
|
||||||
|
aliases.add(newSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AliasSet findAliasSet(LValue lValue) {
|
||||||
|
if (lValue instanceof Variable) {
|
||||||
|
for (AliasSet alias : aliases) {
|
||||||
|
if (alias.contains(lValue)) {
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AliasSet> getAliasSets() {
|
||||||
|
return aliases;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AliasSet {
|
||||||
|
|
||||||
|
private List<Variable> vars;
|
||||||
|
|
||||||
|
public AliasSet() {
|
||||||
|
this.vars = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Variable variable) {
|
||||||
|
vars.add(variable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(RValue rValue) {
|
||||||
|
if (rValue instanceof Variable) {
|
||||||
|
return vars.contains(rValue);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Variable> getVars() {
|
||||||
|
return vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAll(AliasSet aliasSet) {
|
||||||
|
vars.addAll(aliasSet.getVars());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Variable getKeepVar() {
|
||||||
|
Variable keep = null;
|
||||||
|
for (Variable var : vars) {
|
||||||
|
if (keep == null) {
|
||||||
|
keep = var;
|
||||||
|
} else {
|
||||||
|
if (var instanceof VariableVersion) {
|
||||||
|
if (keep instanceof VariableVersion) {
|
||||||
|
if (var.getScopeDepth() < keep.getScopeDepth()) {
|
||||||
|
keep = var;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keep = var;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keep;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Variable> getEliminateVars() {
|
||||||
|
List<Variable> eliminate = new ArrayList<>();
|
||||||
|
Variable keepVar = getKeepVar();
|
||||||
|
for (Variable var : vars) {
|
||||||
|
if(!var.equals(keepVar)) {
|
||||||
|
eliminate.add(var);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return eliminate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(RValue rValue) {
|
||||||
|
if(rValue instanceof Variable) {
|
||||||
|
vars.remove(rValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Alias {
|
|
||||||
private Variable keep;
|
|
||||||
private Variable eliminate;
|
|
||||||
// true if the symbol to keep has the proper definition of the value.
|
|
||||||
private boolean keepHasDefinition;
|
|
||||||
|
|
||||||
public Alias(Variable keep, Variable eliminate, boolean keepHasDefinition) {
|
|
||||||
this.keep = keep;
|
|
||||||
this.eliminate = eliminate;
|
|
||||||
this.keepHasDefinition = keepHasDefinition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variable getEliminate() {
|
|
||||||
return eliminate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Variable getKeep() {
|
|
||||||
return keep;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isKeepHasDefinition() {
|
|
||||||
return keepHasDefinition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Aliases findAliases() {
|
private Aliases findAliases() {
|
||||||
Aliases candidates = findAliasesCandidates();
|
Aliases candidates = findAliasesCandidates();
|
||||||
@ -113,41 +211,42 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
|||||||
|
|
||||||
// Remove all candidates that are used after assignment in phi blocks
|
// Remove all candidates that are used after assignment in phi blocks
|
||||||
private void cleanupCandidates(Aliases candidates) {
|
private void cleanupCandidates(Aliases candidates) {
|
||||||
Iterator<Alias> candidateIt = candidates.getAliases().iterator();
|
for (final AliasSet aliasSet : candidates.aliases) {
|
||||||
while (candidateIt.hasNext()) {
|
|
||||||
Alias candidate = candidateIt.next();
|
|
||||||
final Variable varEliminate = candidate.getEliminate();
|
|
||||||
final Variable varKeep = candidate.getKeep();
|
|
||||||
final Boolean[] rMatch = {false};
|
|
||||||
final Boolean[] lMatch = {false};
|
final Boolean[] lMatch = {false};
|
||||||
ControlFlowGraphBaseVisitor<Void> candidateEliminator = new ControlFlowGraphBaseVisitor<Void>() {
|
ControlFlowGraphBaseVisitor<Void> candidateEliminator = new ControlFlowGraphBaseVisitor<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void visitBlock(ControlFlowBlock block) {
|
||||||
|
lMatch[0] = false;
|
||||||
|
return super.visitBlock(block);
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public Void visitPhi(StatementPhi phi) {
|
public Void visitPhi(StatementPhi phi) {
|
||||||
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
|
if(lMatch[0]) {
|
||||||
if (previousSymbol.getRValue().equals(varKeep)) {
|
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
|
||||||
rMatch[0] = true;
|
RValue phiRValue = previousSymbol.getRValue();
|
||||||
break;
|
if (aliasSet.contains(phiRValue)) {
|
||||||
|
System.out.println("Alias candidate removed " + phiRValue);
|
||||||
|
aliasSet.remove(phiRValue);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (phi.getLValue().equals(varEliminate)) {
|
if (aliasSet.contains(phi.getLValue())) {
|
||||||
lMatch[0] = true;
|
lMatch[0] = true;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
candidateEliminator.visitGraph(getGraph());
|
candidateEliminator.visitGraph(getGraph());
|
||||||
if (rMatch[0] && lMatch[0]) {
|
|
||||||
System.out.println("Alias candidate removed " + varEliminate + " " + varKeep);
|
|
||||||
candidateIt.remove();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find variables that have constant values.
|
* Find variables that have constant values.
|
||||||
|
*
|
||||||
* @return Map from Variable to the Constant value
|
* @return Map from Variable to the Constant value
|
||||||
*/
|
*/
|
||||||
private Aliases findAliasesCandidates() {
|
private Aliases findAliasesCandidates() {
|
||||||
final Aliases aliases = new Aliases();
|
final Aliases aliases = new Aliases();
|
||||||
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
||||||
@Override
|
@Override
|
||||||
@ -165,9 +264,9 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitPhi(StatementPhi phi) {
|
public Void visitPhi(StatementPhi phi) {
|
||||||
if(phi.getPreviousVersions().size()==1) {
|
if (phi.getPreviousVersions().size() == 1) {
|
||||||
StatementPhi.PreviousSymbol previousSymbol = phi.getPreviousVersions().get(0);
|
StatementPhi.PreviousSymbol previousSymbol = phi.getPreviousVersions().get(0);
|
||||||
if(previousSymbol.getRValue() instanceof Variable) {
|
if (previousSymbol.getRValue() instanceof Variable) {
|
||||||
VariableVersion variable = phi.getLValue();
|
VariableVersion variable = phi.getLValue();
|
||||||
Variable alias = (Variable) previousSymbol.getRValue();
|
Variable alias = (Variable) previousSymbol.getRValue();
|
||||||
aliases.add(variable, alias);
|
aliases.add(variable, alias);
|
||||||
|
@ -106,14 +106,23 @@ public abstract class Pass2SsaOptimization {
|
|||||||
if (getAlias(aliases, aReturn.getValue()) != null) {
|
if (getAlias(aliases, aReturn.getValue()) != null) {
|
||||||
aReturn.setValue(getAlias(aliases, aReturn.getValue()));
|
aReturn.setValue(getAlias(aliases, aReturn.getValue()));
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visitCallLValue(StatementCallLValue callLValue) {
|
public Void visitCallLValue(StatementCall call) {
|
||||||
|
if(call.getParameters()!=null) {
|
||||||
for (RValue parameter: callLValue.getParameters()) {
|
List<RValue> newParams = new ArrayList<>();
|
||||||
|
for (RValue parameter : call.getParameters()) {
|
||||||
|
RValue newParam = parameter;
|
||||||
|
if (getAlias(aliases, parameter) != null) {
|
||||||
|
newParam = getAlias(aliases, parameter);
|
||||||
|
}
|
||||||
|
newParams.add(newParam);
|
||||||
|
}
|
||||||
|
call.setParameters(newParams);
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,7 +71,10 @@ public class Pass3RegisterAllocation {
|
|||||||
allocation.allocate(symbols.getVariable("$4"), new RegisterAllocation.RegisterAByte());
|
allocation.allocate(symbols.getVariable("$4"), new RegisterAllocation.RegisterAByte());
|
||||||
allocation.allocate(symbols.getVariable("$6"), new RegisterAllocation.RegisterALUByte());
|
allocation.allocate(symbols.getVariable("$6"), new RegisterAllocation.RegisterALUByte());
|
||||||
allocation.allocate(symbols.getVariable("$7"), new RegisterAllocation.RegisterAByte());
|
allocation.allocate(symbols.getVariable("$7"), new RegisterAllocation.RegisterAByte());
|
||||||
|
allocation.allocate(symbols.getVariable("inc::a#2"), new RegisterAllocation.RegisterAByte());
|
||||||
|
allocation.allocate(symbols.getVariable("bv#0"), new RegisterAllocation.RegisterAByte());
|
||||||
symbols.setAllocation(allocation);
|
symbols.setAllocation(allocation);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,10 +40,10 @@ public class Scope implements Symbol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getFullName(Symbol symbol) {
|
public static String getFullName(Symbol symbol) {
|
||||||
if(symbol.getScope()!=null) {
|
if (symbol.getScope() != null) {
|
||||||
String scopeName = symbol.getScope().getFullName();
|
String scopeName = symbol.getScope().getFullName();
|
||||||
if(scopeName.length()>0) {
|
if (scopeName.length() > 0) {
|
||||||
return scopeName+"::"+symbol.getLocalName();
|
return scopeName + "::" + symbol.getLocalName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return symbol.getLocalName();
|
return symbol.getLocalName();
|
||||||
@ -65,6 +65,15 @@ public class Scope implements Symbol {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getScopeDepth() {
|
||||||
|
if (parentScope == null) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return parentScope.getScopeDepth() + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Symbol add(Symbol symbol) {
|
public Symbol add(Symbol symbol) {
|
||||||
if (symbols.get(symbol.getLocalName()) != null) {
|
if (symbols.get(symbol.getLocalName()) != null) {
|
||||||
throw new RuntimeException("Symbol already declared " + symbol.getLocalName());
|
throw new RuntimeException("Symbol already declared " + symbol.getLocalName());
|
||||||
@ -90,10 +99,28 @@ public class Scope implements Symbol {
|
|||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Variable getVariable(String name) {
|
public Symbol getSymbol(String name) {
|
||||||
return (Variable) symbols.get(name);
|
int pos = name.indexOf("::");
|
||||||
|
if (pos >= 0) {
|
||||||
|
String scopeName = name.substring(0, pos);
|
||||||
|
String rest = name.substring(pos + 2);
|
||||||
|
Symbol scopeSym = symbols.get(scopeName);
|
||||||
|
if (scopeSym instanceof Scope) {
|
||||||
|
return ((Scope) scopeSym).getSymbol(rest);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Error looking up symbol " + name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return symbols.get(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Variable getVariable(String name) {
|
||||||
|
return (Variable) getSymbol(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Collection<Variable> getAllVariables() {
|
public Collection<Variable> getAllVariables() {
|
||||||
Collection<Variable> vars = new ArrayList<>();
|
Collection<Variable> vars = new ArrayList<>();
|
||||||
for (Symbol symbol : symbols.values()) {
|
for (Symbol symbol : symbols.values()) {
|
||||||
@ -140,14 +167,13 @@ public class Scope implements Symbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public VariableVersion createVersion(VariableUnversioned symbol) {
|
|
||||||
VariableVersion version = new VariableVersion(symbol, symbol.getNextVersionNumber());
|
|
||||||
symbols.put(version.getLocalName(), version);
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAllocation(RegisterAllocation allocation) {
|
public void setAllocation(RegisterAllocation allocation) {
|
||||||
this.allocation = allocation;
|
this.allocation = allocation;
|
||||||
|
for (Symbol symbol : symbols.values()) {
|
||||||
|
if(symbol instanceof Scope) {
|
||||||
|
((Scope) symbol).setAllocation(allocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegisterAllocation.Register getRegister(Variable variable) {
|
public RegisterAllocation.Register getRegister(Variable variable) {
|
||||||
|
@ -47,6 +47,10 @@ public class StatementCall implements StatementLValue {
|
|||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setParameters(List<RValue> parameters) {
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
public int getNumParameters() {
|
public int getNumParameters() {
|
||||||
return parameters.size();
|
return parameters.size();
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,10 @@ public class StatementPhi implements StatementLValue {
|
|||||||
this.previousVersions = new ArrayList<>();
|
this.previousVersions = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PreviousSymbol getPreviousVersion(int i) {
|
||||||
|
return previousVersions.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A previous version of the rValue that the phi function might take its value from.
|
* A previous version of the rValue that the phi function might take its value from.
|
||||||
* Which value is chosen depends on which block transition was made.
|
* Which value is chosen depends on which block transition was made.
|
||||||
|
@ -25,7 +25,4 @@ public class StatementReturn implements Statement {
|
|||||||
return "return "+(value==null?"":value);
|
return "return "+(value==null?"":value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(RValue value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -13,5 +13,5 @@ public interface Symbol extends Value {
|
|||||||
|
|
||||||
Scope getScope();
|
Scope getScope();
|
||||||
|
|
||||||
|
int getScopeDepth();
|
||||||
}
|
}
|
||||||
|
@ -93,4 +93,14 @@ public abstract class Variable implements Symbol, RValue, LValue {
|
|||||||
public Scope getScope() {
|
public Scope getScope() {
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getScopeDepth() {
|
||||||
|
if(scope==null) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return scope.getScopeDepth()+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,4 +31,10 @@ public class VariableUnversioned extends Variable {
|
|||||||
public boolean isIntermediate() {
|
public boolean isIntermediate() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public VariableVersion createVersion() {
|
||||||
|
VariableVersion version = new VariableVersion(this, this.getNextVersionNumber());
|
||||||
|
getScope().add(version);
|
||||||
|
return version;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ public class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("SYMBOLS");
|
System.out.println("SYMBOLS");
|
||||||
System.out.println(programScope.toString());
|
System.out.println(programScope.getSymbolTableContents());
|
||||||
System.out.println("CONTROL FLOW GRAPH");
|
System.out.println("CONTROL FLOW GRAPH");
|
||||||
System.out.println(controlFlowGraph.toString());
|
System.out.println(controlFlowGraph.toString());
|
||||||
System.out.println("ASSEMBLER");
|
System.out.println("ASSEMBLER");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user